@atlas-viewer/atlas 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +29 -23
- package/dist/index.d.cts +1724 -736
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1724 -736
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["scopedUrlAlphabet","event: keyof SupportedEvents","e","scale","scale","scale","cos","sin","objects: Paintable[]","arr: Paint[]","len","objects: Array<[WorldObject, Paintable[]]>","layers: Paint[]","defaultConfig: Required<ZoneConfig>","defaultConfig","borderRegex","borderRegexCache: any","styleProps: Array<keyof BoxStyle>","borderRegexCache","styleProps","bounceOut: EasingFunction","easingFunctions: { [key in EasingFunctionNames]: EasingFunction }","scale","borderRegexCache: any","styleProps: Array<keyof GeometryStyle>","AbortController","AbortSignal","v","shadowRegexCache: any","imageCache: { [id: string]: HTMLImageElement }","LRUCache","scale","imageBuffer: ImageBuffer","transform","scale","UserAgent_DEPRECATED","ExecutionEnvironment","isEventSupported","normalizeWheel","defaultConfig: Required<PopmotionControllerConfig>","useMode: () => ViewerMode","getCurrentTime: () => number","instance: BaseObject<any, any>","world: World","now","React","AtlasWithReconciler: React.FC<AtlasWithReconcilerProps>","AtlasRoot","scale","classNames","scale","element: HTMLDivElement","scale","element: HTMLImageElement","presets: { [key in PresetNames]: (options: any) => Preset }","changes: Record<string, { before: any; after: any }>","Atlas: React.FC<\n AtlasProps & {\n width: number;\n height: number;\n }\n>","Atlas","rt: Runtime","Canvas","props","AtlasAuto: React.FC<\n AtlasProps & {\n height?: number | string;\n width?: number | string;\n resizeHash?: number;\n containerProps?: any;\n aspectRatio?: number;\n }\n>","AtlasAuto","DrawBox: React.FC<{\n children?: ReactNode;\n onCreate: (bounds: { x: number; y: number; width: number; height: number }) => void;\n}>","module","unmountComponentAtNode","HTMLPortal: React.FC<\n {\n children?: ReactNode;\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n } & React.RefAttributes<Box>\n>","translate","baseStyle: CSSProperties","TileSet: React.FC<{\n tiles: GetTile;\n x?: number;\n y?: number;\n width: number;\n height: number;\n rotation?: number;\n crop?: any;\n children?: ReactNode;\n enableThumbnail?: boolean;\n enableSizes?: boolean;\n onClick?: (e: any) => void;\n renderOptions?: CompositeResourceProps;\n}>","scale","tiles","moduleState: {\n vault: Vault;\n loader: ImageServiceLoader;\n helper: any;\n}","tiles: any[]","ImageService: React.FC<{\n id: string;\n width: number;\n height: number;\n x?: number;\n y?: number;\n rotation?: number;\n scale?: number;\n children?: ReactNode;\n crop?: any;\n enableSizes?: boolean;\n enableThumbnail?: boolean;\n renderOptions?: CompositeResourceProps;\n}>","useAtlasImage: (\n children: any,\n options: AtlasProps\n) => { uri: string | undefined; loading?: boolean; imageError?: string }","rt: Runtime","Canvas"],"sources":["../src/events.ts","../node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/url-alphabet/index.js","../node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/index.browser.js","../src/objects/base-object.ts","../src/spacial-content/single-image.ts","../src/spacial-content/image-texture.ts","../src/utils.ts","../src/spacial-content/tiled-image.ts","../src/spacial-content/abstract-content.ts","../src/spacial-content/composite-resource.ts","../src/world-objects/world-object.ts","../src/world.ts","../src/world-objects/image.ts","../src/world-objects/zone.ts","../src/objects/box.ts","../src/objects/text.ts","../src/utility/easing-functions.ts","../src/modules/transition-manager/transition-manager.ts","../src/renderer/runtime.ts","../src/objects/geometry.ts","../node_modules/.pnpm/lru-cache@7.18.3/node_modules/lru-cache/index.mjs","../src/modules/canvas-renderer/canvas-renderer.ts","../src/modules/composite-renderer/composite-renderer.ts","../src/modules/debug-renderer/debug-renderer.ts","../src/modules/grid-builder/grid-builder.ts","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/UserAgent_DEPRECATED.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/ExecutionEnvironment.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/isEventSupported.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/normalizeWheel.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/index.js","../src/modules/popmotion-controller/popmotion-controller.ts","../src/modules/react-reconciler/hooks/use-mode.tsx","../src/modules/react-reconciler/components/AtlasContext.tsx","../src/modules/react-reconciler/utility/now.ts","../src/modules/react-reconciler/reconciler.ts","../src/modules/react-reconciler/utility/react.ts","../src/modules/react-reconciler/components/AtlasWithReconciler.tsx","../src/modules/webgl-renderer/webgl-renderer.ts","../src/utility/hash.ts","../src/utility/stylesheet.ts","../src/modules/overlay-renderer/overlay-renderer.ts","../src/modules/browser-event-manager/browser-event-manager.ts","../src/modules/react-reconciler/presets/default-preset.ts","../src/modules/static-renderer/static-renderer.ts","../src/modules/react-reconciler/presets/static-preset.ts","../src/modules/react-reconciler/presets/index.ts","../src/modules/react-reconciler/hooks/use-preset.ts","../src/modules/react-reconciler/hooks/use-classname.ts","../src/modules/react-reconciler/components/Container.tsx","../src/modules/react-reconciler/hooks/use-diff-props.ts","../src/modules/react-reconciler/Atlas.tsx","../src/modules/react-reconciler/utility/to-px.ts","../src/modules/react-reconciler/components/AtlasAuto.tsx","../src/modules/react-reconciler/hooks/use-atlas.ts","../src/modules/react-reconciler/hooks/use-runtime.ts","../src/modules/react-reconciler/hooks/use-after-frame.ts","../src/modules/react-reconciler/hooks/use-frame.ts","../src/modules/react-reconciler/hooks/use-canvas.ts","../src/modules/react-reconciler/hooks/use-canvas-position.ts","../src/modules/react-reconciler/components/BoxDraw.tsx","../src/modules/react-reconciler/utility/react-dom.ts","../src/modules/react-reconciler/components/HTMLPortal.tsx","../src/modules/react-reconciler/hooks/use-world-event.ts","../src/modules/react-reconciler/utility/get-ratio.ts","../src/modules/react-reconciler/hooks/use-modifier-keys.ts","../src/modules/react-reconciler/hooks/use-resize-world-item.ts","../src/modules/react-reconciler/components/ResizeWorldItem.tsx","../src/modules/react-reconciler/components/RegionHighlight.tsx","../src/modules/react-reconciler/components/TileSet.tsx","../src/modules/iiif/shared.ts","../src/modules/iiif/get-vault-helper.ts","../src/modules/iiif/get-tiles.ts","../src/modules/react-reconciler/components/ImageService.tsx","../src/modules/react-reconciler/hooks/use-after-paint.ts","../src/modules/react-reconciler/hooks/use-atlas-image.tsx","../src/modules/react-reconciler/hooks/use-before-frame.ts","../src/modules/react-reconciler/hooks/use-controlled-annotation-list.ts","../src/modules/react-reconciler/utility/can-drag.ts","../src/utility/merge-styles.ts"],"sourcesContent":["export const supportedEventAttributes = [\n 'onMouseDown',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseMove',\n 'onMouseOut',\n 'onMouseOver',\n 'onMouseUp',\n 'onTouchCancel',\n 'onTouchEnd',\n 'onTouchMove',\n 'onTouchStart',\n 'onPointerDown',\n 'onPointerMove',\n 'onPointerUp',\n 'onPointerCancel',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerOver',\n 'onPointerOut',\n 'onScroll',\n 'onWheel',\n 'onClick',\n // Drag.\n 'onDragStart',\n 'onDragEnd',\n 'onDragEnter',\n 'onDragExit',\n 'onDrag',\n 'onDragOver',\n 'onContextMenu',\n] as const;\n\nexport function createDefaultEventMap(): SupportedEventMap {\n return supportedEventAttributes.reduce((acc, next) => {\n (acc as any)[next] = [];\n return acc;\n }, {} as SupportedEventMap);\n}\n\nexport const supportedEventMap = supportedEventAttributes.reduce((acc, ev) => {\n (acc as any)[ev.slice(2).toLowerCase()] = ev;\n (acc as any)[ev] = ev;\n return acc;\n}, {} as { [ev in SupportedEventNames]: keyof SupportedEvents });\n\nexport type SupportedEvents = {\n onMouseDown(e: any): void;\n onMouseEnter(e: any): void;\n onMouseLeave(e: any): void;\n onMouseMove(e: any): void;\n onMouseOut(e: any): void;\n onMouseOver(e: any): void;\n onMouseUp(e: any): void;\n onTouchCancel(e: any): void;\n onTouchEnd(e: any): void;\n onTouchMove(e: any): void;\n onTouchStart(e: any): void;\n onPointerDown(e: any): void;\n onPointerMove(e: any): void;\n onPointerUp(e: any): void;\n onPointerCancel(e: any): void;\n onPointerEnter(e: any): void;\n onPointerLeave(e: any): void;\n onPointerOver(e: any): void;\n onPointerOut(e: any): void;\n onScroll(e: any): void;\n onWheel(e: any): void;\n onClick(e: any): void;\n onDragStart(e: any): void;\n onDragEnd(e: any): void;\n onDragEnter(e: any): void;\n onDragExit(e: any): void;\n onDrag(e: any): void;\n onDragOver(e: any): void;\n onContextMenu(e: any): void;\n};\n\nexport type SupportedEventNames =\n | 'mousedown'\n | 'mouseenter'\n | 'mouseleave'\n | 'mousemove'\n | 'mouseout'\n | 'mouseover'\n | 'mouseup'\n | 'touchcancel'\n | 'touchend'\n | 'touchmove'\n | 'touchstart'\n | 'pointerdown'\n | 'pointermove'\n | 'pointerup'\n | 'pointercancel'\n | 'pointerenter'\n | 'pointerleave'\n | 'pointerover'\n | 'pointerout'\n | 'scroll'\n | 'wheel'\n | 'click'\n | 'dragstart'\n | 'dragend'\n | 'dragenter'\n | 'dragexit'\n | 'drag'\n | 'dragover'\n | 'contextmenu';\n\nexport type SupportedEventMap = {\n [Name in keyof SupportedEvents]: Array<SupportedEvents[Name]>;\n};\n","export const urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n","import { urlAlphabet as scopedUrlAlphabet } from './url-alphabet/index.js'\nexport { urlAlphabet } from './url-alphabet/index.js'\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1\n let step = -~((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step\n while (j--) {\n id += alphabet[bytes[j] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nexport let nanoid = (size = 21) => {\n let id = ''\n let bytes = crypto.getRandomValues(new Uint8Array(size))\n while (size--) {\n id += scopedUrlAlphabet[bytes[size] & 63]\n }\n return id\n}\n","import { AtlasObjectModel } from '../aom';\nimport { WorldTime } from '../types';\nimport { dna, mutate, scaleAtOrigin, Strand, translate } from '@atlas-viewer/dna';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\nimport { CompositeResource } from '../spacial-content/composite-resource';\nimport {\n createDefaultEventMap,\n SupportedEventMap,\n supportedEventMap,\n SupportedEventNames,\n SupportedEvents,\n} from '../events';\nimport { WorldObject } from '../world-objects';\n\nexport abstract class BaseObject<Props = any, SupportedChildElements = never>\n implements AtlasObjectModel<Props, SupportedChildElements>\n{\n __id: string;\n __revision = 0;\n __host: any;\n __onCreate?: () => void;\n __parent?: CompositeResource;\n __owner: { value: WorldObject | undefined } = { value: undefined };\n __state: any = {};\n // Base properties.\n eventHandlers: SupportedEventMap;\n scale = 1;\n layers: SupportedChildElements[] = [];\n time: WorldTime[] = [];\n\n // crop?: Strand;\n _crop?: Strand;\n cropData?: { x: number; y: number; width: number; height: number };\n\n get crop(): Strand | undefined {\n return this._crop;\n }\n\n set crop(crop: Strand | undefined) {\n this._crop = crop;\n }\n\n // To be set by implementation constructor.\n id: string;\n abstract points: Strand;\n\n getObjectsAt(target: Strand): SupportedChildElements[] | Array<[SupportedChildElements, any[]]> {\n return [];\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand, scale: number): Paint[] {\n return [];\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n return [];\n }\n\n protected constructor() {\n this.id = this.__id = nanoid();\n this.eventHandlers = createDefaultEventMap();\n }\n\n addEventListener = <Name extends SupportedEventNames>(\n name: Name,\n cb: (e: any) => void,\n options?: { capture: boolean; passive: boolean }\n ) => {\n const event: keyof SupportedEvents = supportedEventMap[name];\n if (!this.eventHandlers[event]) {\n throw new Error(`Unknown event ${event}`);\n }\n\n if (this.eventHandlers[event].indexOf(cb) === -1) {\n this.eventHandlers[event].push(cb);\n }\n };\n\n removeEventListener = <Name extends SupportedEventNames>(name: Name, cb: (e: any) => void) => {\n const event = supportedEventMap[name];\n if (!this.eventHandlers[event]) {\n console.warn(`Unknown event ${event}`);\n return;\n }\n if (this.eventHandlers[event].indexOf(cb) !== -1) {\n this.eventHandlers[event] = (this.eventHandlers[event] as any).filter((e: any) => e !== cb);\n }\n };\n\n dispatchEvent<Name extends keyof SupportedEvents>(name: Name, e: any) {\n const listeners = this.eventHandlers[name];\n const len = listeners ? listeners.length : 0;\n let didFire = false;\n if (len) {\n for (let x = 0; x < len; x++) {\n try {\n listeners[x]?.(e);\n didFire = true;\n } catch (e) {\n console.error(name, e);\n }\n }\n }\n return didFire;\n }\n\n get x(): number {\n return this.points[1];\n }\n get y(): number {\n return this.points[2];\n }\n get width(): number {\n return this.points[3] - this.points[1];\n }\n get height(): number {\n return this.points[4] - this.points[2];\n }\n\n translate(x: number, y: number) {\n mutate(this.points, translate(x, y));\n }\n\n atScale(factor: number) {\n mutate(this.points, scaleAtOrigin(factor, this.x, this.y));\n this.scale *= factor;\n }\n\n transform(op: Strand): void {\n mutate(this.points, op);\n }\n\n applyProps(props: Props): void {\n // do nothing.\n this.__revision++;\n }\n appendChild(item: SupportedChildElements): void {\n // do nothing.\n }\n removeChild(item: SupportedChildElements): void {\n // do nothing.\n }\n insertBefore(item: SupportedChildElements, before: SupportedChildElements): void {\n // do nothing.\n }\n hideInstance(): void {\n // do nothing.\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { dna, DnaFactory, mutate, Strand, transform, translate } from '@atlas-viewer/dna';\nimport { DisplayData, SpacialSize } from '../types';\nimport { BaseObject } from '../objects/base-object';\nimport { Paint } from '../world-objects/paint';\n\ntype SingleImageProps = {\n uri: string;\n id?: string;\n display?: { width: number; height: number; rotation?: number };\n target: { width: number; height: number; x?: number; y?: number };\n crop?: { x: number; y: number; width: number; height: number };\n scale?: number;\n priority?: boolean;\n style?: any;\n};\n\nexport class SingleImage extends BaseObject implements SpacialContent {\n readonly type = 'spacial-content';\n\n /**\n * An identifier for this image. Will default to the image URI.\n */\n id: string;\n\n /**\n * The URI of the image being painted.\n */\n uri: string;\n\n /**\n * The real height and width of the image. For example a 1000x1000 painted at 100x100 would contain\n * the display data for 1000x1000 and `this.points` would scale that down to 100x100. This is used to\n * calculate the scale.\n */\n display: DisplayData;\n\n /**\n * Points are relative to the world object.\n * Does not change when viewport moves\n * Does not change if world object position changes.\n * */\n points: Strand;\n\n /**\n * Displayed as priority\n */\n priority?: boolean;\n\n /**\n * Some simple styling options\n */\n style: { opacity: number } = { opacity: 1 };\n\n constructor(data?: {\n id?: string;\n uri: string;\n width: number;\n height: number;\n scale?: number;\n x?: number;\n y?: number;\n rotation?: number;\n }) {\n super();\n if (!data) {\n this.id = '';\n this.uri = '';\n this.display = { x: 0, y: 0, scale: 1, width: 0, height: 0, points: dna(5) };\n this.points = dna(5);\n } else {\n const scale = data.scale || 1;\n this.id = data.id || data.uri;\n this.uri = data.uri;\n this.points = DnaFactory.singleBox(data.width, data.height, data.x, data.y);\n\n this.display = {\n x: 0,\n y: 0,\n scale: scale,\n width: data.width / scale,\n height: data.height / scale,\n points: DnaFactory.singleBox(data.width / scale, data.height / scale),\n rotation: data?.rotation,\n };\n }\n }\n\n applyProps(props: SingleImageProps) {\n const width = props.display ? props.display.width : props.target.width;\n const scale = props.target.width / width;\n\n this.id = props.id || props.uri;\n this.uri = props.uri;\n this.points.set(DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y));\n\n if (props.style && typeof props.style.opacity !== 'undefined') {\n this.style.opacity = props.style.opacity;\n }\n\n if (props.crop) {\n this.cropData = props.crop;\n const crop = DnaFactory.singleBox(props.crop.width, props.crop.height, props.crop.x, props.crop.y);\n mutate(crop, translate(-props.crop.x, -props.crop.y));\n if (!this.crop) {\n this.crop = dna(crop);\n } else {\n this.crop.set(crop);\n }\n }\n\n if (props.display) {\n this.display.scale = scale;\n this.display.width = props.display.width;\n this.display.height = props.display.height;\n this.display.rotation = props.display.rotation;\n this.display.points = DnaFactory.singleBox(props.display.width, props.display.height);\n } else {\n this.display.scale = scale;\n this.display.width = props.target.width / scale;\n this.display.height = props.target.height / scale;\n this.display.points = DnaFactory.singleBox(props.target.width / scale, props.target.height / scale);\n }\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.crop || this.points, aggregate]];\n }\n\n // This works, but should be improved.\n // It should create a layered image similar to IIIF with different scale factors of the SVG.\n // And implement its own get points function, to return the right layer.\n // Would also be great if the ID field wasn't the entire SVG.\n static fromSvg(svg: string, target: SpacialSize, display?: SpacialSize, id?: string): SingleImage {\n return SingleImage.fromImage('data:image/svg+xml;base64,' + btoa(svg), target, display, id);\n }\n\n static fromImage(uri: string, target: SpacialSize, display?: SpacialSize, id?: string): SingleImage {\n const instance = new SingleImage();\n\n instance.applyProps({\n uri,\n id,\n display,\n target,\n });\n\n return instance;\n }\n\n getImageUrl() {\n return this.uri;\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { DisplayData } from '../types';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { Paint } from '../world-objects/paint';\nimport { BaseObject } from '../objects/base-object';\n\nexport type UpdateTextureFunction = () => { source: TexImageSource | undefined; hash: any };\n\nexport type ImageTextureProps = {\n id: string;\n display?: { width: number; height: number };\n target: { width: number; height: number };\n scale?: number;\n getTexture: UpdateTextureFunction;\n};\n\nexport class ImageTexture extends BaseObject implements SpacialContent {\n readonly type = 'spacial-content';\n id: string;\n uri: string;\n display: DisplayData;\n points: Strand;\n getTexture: UpdateTextureFunction;\n\n constructor(data?: { id?: string; uri: string; width: number; height: number; scale?: number }) {\n super();\n\n this.getTexture = () => {\n // no-op\n return { source: undefined, hash: -1 };\n };\n\n if (!data) {\n this.id = '';\n this.uri = '';\n this.display = { x: 0, y: 0, scale: 1, width: 0, height: 0, points: dna(5) };\n this.points = dna(5);\n } else {\n const scale = data.scale || 1;\n this.id = data.id || data.uri;\n this.uri = data.uri;\n this.points = DnaFactory.singleBox(data.width, data.height);\n\n this.display = {\n x: 0,\n y: 0,\n scale: scale,\n width: data.width / scale,\n height: data.height / scale,\n points: scale !== 1 ? DnaFactory.singleBox(data.width / scale, data.height / scale) : this.points,\n };\n }\n }\n\n applyProps(props: ImageTextureProps) {\n const width = props.display ? props.display.width : props.target.width;\n const scale = props.target.width / width;\n\n this.id = props.id;\n this.points.set(DnaFactory.singleBox(props.target.width, props.target.height));\n\n this.display.scale = scale;\n this.display.width = props.target.width / scale;\n this.display.height = props.target.height / scale;\n this.getTexture = props.getTexture;\n this.display.points =\n scale !== 1 ? DnaFactory.singleBox(props.target.width / scale, props.target.height / scale) : this.points;\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n}\n","import { SpacialContent } from './spacial-content/spacial-content';\n\nexport function bestResourceAtRatio<T extends SpacialContent>(ratio: number, resources: T[]): T | never {\n const len = resources.length;\n if (len === 0) {\n throw new Error('No resources passed in.');\n }\n\n let best = resources[0];\n let bestDistance = Infinity;\n for (let i = 0; i < len; i++) {\n if (!resources[i] || !resources[i].display) {\n break;\n }\n const distanceScale = distance1D(\n resources[i].display.scale,\n ratio\n );\n\n if (distanceScale < bestDistance) {\n bestDistance = distanceScale;\n best = resources[i];\n }\n }\n return best;\n}\n\nexport function bestResourceIndexAtRatio<T extends SpacialContent>(\n ratio: number,\n resources: T[],\n quality = 1\n): number | never {\n const len = resources.length;\n if (len === 0) {\n throw new Error('No resources passed in.');\n }\n\n let best = 0;\n let bestDistance = Infinity;\n for (let i = 0; i < len; i++) {\n if (!resources[i] || !resources[i].display) {\n break;\n }\n const distanceScale = distance1D(\n resources[i].display.scale,\n ratio / (quality || 1)\n );\n\n if (distanceScale < bestDistance) {\n bestDistance = distanceScale;\n best = i;\n }\n }\n\n return best;\n}\n\nexport function distance1D(a: number, b: number) {\n return Math.abs(a - b);\n}\n\nexport function distance(a: { x: number; y: number }, b: { x: number; y: number }) {\n const xDelta = distance1D(a.x, b.x);\n const yDelta = distance1D(a.y, b.y);\n return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2));\n}\n\nexport function stripInfoJson(id: string): string {\n const len = id.length;\n if (id.indexOf('/info.json') === len - 10) {\n return id.slice(0, -10);\n }\n return id;\n}\n","import {\n DnaFactory,\n hidePointsOutsideRegion,\n mutate,\n scale,\n transform,\n Strand,\n dna,\n getIntersection,\n Projection,\n translate,\n} from '@atlas-viewer/dna';\nimport { DisplayData } from '../types';\nimport { Paint } from '../world-objects';\nimport { BaseObject } from '../objects/base-object';\nimport { SpacialContent } from './spacial-content';\nimport { stripInfoJson } from '../utils';\nimport { ImageService } from '@iiif/presentation-3';\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport class TiledImage extends BaseObject implements SpacialContent {\n readonly id: string;\n readonly type = 'spacial-content';\n readonly display: DisplayData;\n tileWidth: number;\n style: { opacity: number } = { opacity: 1 };\n points: Strand;\n service?: ImageService;\n format = 'jpg';\n crop2?: Strand;\n version3?: boolean;\n\n tileUrl: string;\n constructor(data: {\n url: string;\n scaleFactor: number;\n points: Strand;\n displayPoints?: Strand;\n tileWidth: number;\n width: number;\n height: number;\n format?: string;\n id?: string;\n version3?: boolean;\n }) {\n super();\n this.tileUrl = stripInfoJson(data.url);\n this.id = data.id || `${this.tileUrl}--${data.scaleFactor}`;\n this.points = data.displayPoints ? data.displayPoints : transform(data.points, scale(data.scaleFactor));\n this.tileWidth = data.tileWidth;\n this.version3 = data.version3;\n this.display = {\n x: 0,\n y: 0,\n width: data.width / data.scaleFactor,\n height: data.height / data.scaleFactor,\n points: data.points,\n scale: data.scaleFactor,\n };\n if (data.format) {\n this.format = data.format;\n }\n }\n\n applyProps(props: any) {\n if (props.style && typeof props.style.opacity !== 'undefined') {\n this.style.opacity = props.style.opacity;\n }\n if (props.service !== this.service) {\n this.service = props.service;\n }\n if (props.format) {\n this.format = props.format;\n } else {\n this.format = 'jpg';\n }\n\n if (typeof props.version3 !== 'undefined') {\n this.version3 = props.version3;\n }\n\n if (props.crop) {\n this.cropData = props.crop;\n\n const crop = dna([...this.points]);\n const len = crop.length / 5;\n\n const minX = props.crop.x || 0;\n const minY = props.crop.y || 0;\n const maxX = props.crop.x + props.crop.width;\n const maxY = props.crop.y + props.crop.height;\n\n for (let i = 0; i < len; i++) {\n const index = i * 5;\n if (\n /* x1 */ crop[index + 1] < maxX && // x1 left - x2 right\n /* x2 */ crop[index + 3] > minX && // x2 right - x1 left\n /* y1 */ crop[index + 2] < maxY && // y1 top - y2 bottom\n /* y2 */ crop[index + 4] > minY // y2 bottom - y1 top\n ) {\n crop[index + 1] = clamp(crop[index + 1], minX, maxX);\n crop[index + 3] = clamp(crop[index + 3], minX, maxX);\n crop[index + 2] = clamp(crop[index + 2], minY, maxY);\n crop[index + 4] = clamp(crop[index + 4], minY, maxY);\n } else {\n crop[index] = 0;\n }\n }\n\n mutate(crop, translate(-props.crop.x, -props.crop.y));\n\n if (!this.crop) {\n this.crop = crop;\n } else {\n this.crop.set(crop);\n }\n }\n }\n\n static fromTile(\n url: string,\n canvas: { width: number; height: number },\n tile: { width: number; height?: number },\n scaleFactor: number,\n service?: ImageService,\n format?: string,\n useFloorCalc?: boolean,\n version3?: boolean\n ): TiledImage {\n // Always set a height.\n tile.height = tile.height ? tile.height : tile.width;\n // Dimensions of full image (scaled).\n const fullWidth = useFloorCalc ? Math.floor(canvas.width / scaleFactor) : Math.ceil(canvas.width / scaleFactor);\n const fullHeight = useFloorCalc ? Math.floor(canvas.height / scaleFactor) : Math.ceil(canvas.height / scaleFactor);\n // number of points in the x direction.\n const mWidth = Math.ceil(fullWidth / tile.width);\n // number of points in the y direction\n const mHeight = Math.ceil(fullHeight / tile.height);\n\n const pointsFactory = DnaFactory.grid(mWidth, mHeight);\n const displayPoints = DnaFactory.grid(mWidth, mHeight);\n\n const ctx = service ? service['@context']\n ? Array.isArray(service['@context'])\n ? service['@context']\n : [service['@context']]\n : [] : [];\n const isV3 = typeof version3 !== 'undefined' ? version3 : ctx.indexOf('http://iiif.io/api/image/3/context.json') !== -1;\n\n // Create matrix\n for (let y = 0; y < mHeight; y++) {\n for (let x = 0; x < mWidth; x++) {\n const rx = x * tile.width;\n const ry = y * tile.height;\n\n displayPoints.addPoints(\n rx * scaleFactor,\n ry * scaleFactor,\n x === mWidth - 1 ? canvas.width : (rx + tile.width) * scaleFactor,\n y === mHeight - 1 ? canvas.height : (ry + tile.height) * scaleFactor\n );\n\n pointsFactory.addPoints(\n rx,\n ry,\n x === mWidth - 1 ? fullWidth : rx + tile.width,\n y === mHeight - 1 ? fullHeight : ry + tile.height\n );\n }\n }\n\n const tiledImage = new TiledImage({\n url,\n scaleFactor,\n points: pointsFactory.build(),\n displayPoints: displayPoints.build(),\n width: canvas.width,\n height: canvas.height,\n tileWidth: tile.width,\n format,\n version3: isV3,\n });\n\n tiledImage.applyProps({\n service,\n });\n\n return tiledImage;\n }\n\n getImageUrl(index: number): string {\n // Replace this with image service wrapper that recalculates its toString()\n // when SETTING new variables, so that this becomes just a return.\n // We can store these based on the index.\n\n const im = this.points.slice(index * 5, index * 5 + 5);\n const x2 = im[3] - im[1];\n const y2 = im[4] - im[2];\n const w = Math.ceil(x2 / this.display.scale);\n const h = Math.ceil(y2 / this.display.scale);\n\n let widthString = `${w > this.tileWidth ? this.tileWidth : w},`;\n\n if (this.version3) {\n widthString += `${h > this.tileWidth ? this.tileWidth : h}`;\n }\n\n return `${this.tileUrl}/${im[1]},${im[2]},${x2},${y2}/${widthString}/0/default.${this.format || 'jpg'\n }`;\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scaleFactor?: number): Paint[] {\n const points = hidePointsOutsideRegion(this.crop || this.points, target);\n return [[this as any, points, aggregate]];\n }\n\n transform(op: Strand): void {\n mutate(this.points, op);\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => Promise<void>> {\n return [];\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { DisplayData } from '../types';\nimport { Paint } from '../world-objects';\nimport { Strand } from '@atlas-viewer/dna';\nimport { BaseObject } from '../objects/base-object';\n\n/**\n * @deprecated\n */\nexport abstract class AbstractContent<Props = any, SupportedLayers = never>\n extends BaseObject<Props, SupportedLayers>\n implements SpacialContent\n{\n abstract readonly id: string;\n readonly type: 'spacial-content' = 'spacial-content';\n abstract points: Strand;\n abstract readonly display: DisplayData;\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { compose, dna, DnaFactory, Strand, translate } from '@atlas-viewer/dna';\nimport { DisplayData } from '../types';\nimport { Paint } from '../world-objects';\nimport { bestResourceIndexAtRatio } from '../utils';\nimport { AbstractContent } from './abstract-content';\nimport { AtlasObjectModel } from '../aom';\nimport { SingleImage } from './single-image';\n\ntype RenderOptions = {\n renderSmallestFallback: boolean;\n renderLayers: number;\n minSize: number;\n maxImageSize: number;\n quality: number;\n};\n\nexport type CompositeResourceProps = RenderOptions;\n\nexport class CompositeResource\n extends AbstractContent\n implements SpacialContent, AtlasObjectModel<CompositeResourceProps, SpacialContent> {\n readonly id: string;\n readonly display: DisplayData;\n points: Strand;\n images: SpacialContent[] = [];\n allImages: SpacialContent[] = [];\n scaleFactors: number[] = [];\n aggregateBuffer = dna(9);\n lazyLoader?: () => Promise<SpacialContent[]>;\n isFullyLoaded = false;\n maxScaleFactor = 0;\n\n renderOptions: RenderOptions;\n\n constructor(data: {\n id: string;\n width: number;\n height: number;\n images: SpacialContent[];\n loadFullImages?: () => Promise<SpacialContent[]>;\n renderOptions?: RenderOptions;\n }) {\n super();\n this.id = data.id;\n this.points = DnaFactory.singleBox(data.width, data.height);\n this.lazyLoader = data.loadFullImages;\n if (!data.loadFullImages) {\n this.isFullyLoaded = true;\n }\n this.display = {\n x: 0,\n y: 0,\n points: DnaFactory.singleBox(data.width, data.height),\n height: data.height,\n width: data.width,\n scale: 1,\n };\n this.renderOptions = {\n renderSmallestFallback: true,\n renderLayers: 3,\n minSize: 255,\n maxImageSize: 2048,\n quality: 1.5,\n ...(data.renderOptions || {}),\n };\n\n this.addImages(data.images);\n }\n\n applyProps(props: CompositeResourceProps) {\n if (\n typeof props.renderSmallestFallback !== 'undefined' &&\n props.renderSmallestFallback !== this.renderOptions.renderSmallestFallback\n ) {\n this.renderOptions.renderSmallestFallback = props.renderSmallestFallback;\n }\n if (typeof props.renderLayers !== 'undefined' && props.renderLayers !== this.renderOptions.renderLayers) {\n this.renderOptions.renderLayers = props.renderLayers;\n }\n if (typeof props.minSize !== 'undefined' && props.minSize !== this.renderOptions.minSize) {\n this.renderOptions.minSize = props.minSize;\n }\n if (typeof props.maxImageSize !== 'undefined' && props.maxImageSize !== this.renderOptions.maxImageSize) {\n this.renderOptions.maxImageSize = props.maxImageSize;\n }\n if (typeof props.quality !== 'undefined' && props.quality !== this.renderOptions.quality) {\n this.renderOptions.quality = props.quality;\n }\n }\n\n appendChild(item: SpacialContent) {\n this.addImages([item]);\n }\n\n removeChild(item: SpacialContent) {\n if (this.images.indexOf(item) === -1) {\n return;\n }\n\n this.images = this.images.filter((image) => image !== item);\n this.sortByScales();\n }\n\n insertBefore(item: SpacialContent, before: SpacialContent) {\n // @todo this is pre-sorted by size. We could change this, but this\n // drives other behaviours.\n this.addImages([item]);\n }\n\n hideInstance() {\n // @todo not yet implemented. this.points[0] = 0 ???\n }\n\n addImages(images: SpacialContent[]) {\n for (const image of images) {\n image.__parent = this;\n image.__owner = this.__owner;\n }\n this.allImages.push(...images.filter(Boolean));\n this.sortByScales();\n }\n\n sortByScales() {\n this._scheduleSortByScales = true;\n }\n\n _scheduleSortByScales = false;\n _sortByScales = () => {\n this._scheduleSortByScales = false;\n this.allImages.sort((a: SpacialContent, b: SpacialContent) => b.display.width - a.display.width);\n this.images = [];\n let lastScale = 0.1;\n for (const image of this.allImages) {\n if (\n image.display.width < this.renderOptions.minSize &&\n image.display.height < this.renderOptions.minSize &&\n !image.priority\n ) {\n continue;\n }\n\n if (\n image instanceof SingleImage &&\n (image.display.width > this.renderOptions.maxImageSize ||\n image.display.height > this.renderOptions.maxImageSize) &&\n !image.priority\n ) {\n continue;\n }\n\n const diff = Math.abs(image.display.scale - lastScale);\n if (diff < 0.25 || image.priority) {\n const otherImage = this.images.pop();\n if (otherImage && (otherImage instanceof SingleImage || otherImage.priority)) {\n if (image.priority) {\n this.images.push(image);\n }\n this.images.push(otherImage);\n } else {\n if (image) {\n this.images.push(image);\n }\n }\n } else {\n if (image) {\n this.images.push(image);\n }\n }\n\n lastScale = image.display.scale;\n }\n\n if (this.images.length === 0) {\n // Workaround for bad filtering.\n this.images = [...this.allImages];\n }\n\n this.scaleFactors = this.images.map((singleImage) => singleImage.display.scale);\n this.maxScaleFactor = Math.max(...this.scaleFactors);\n };\n\n loadFullResource = async () => {\n if (this.isFullyLoaded) {\n return;\n }\n if (this.lazyLoader) {\n // Reads: resource has already been requested.\n this.isFullyLoaded = true;\n const newImages = await this.lazyLoader();\n this.addImages(newImages);\n }\n };\n\n fallback = [this.loadFullResource];\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => Promise<void>> {\n if (this._scheduleSortByScales) {\n return [this._sortByScales] as any[];\n }\n if (this.isFullyLoaded) {\n return [];\n }\n if (scaleFactor > 1 / this.maxScaleFactor) {\n return this.fallback;\n }\n return [];\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n if (this.images.length === 0) {\n return [];\n }\n\n const bestIndex = bestResourceIndexAtRatio(\n 1 / (scale || 1) / (window.devicePixelRatio || 1),\n this.images,\n this.renderOptions.quality\n );\n\n const len = this.images.length;\n const newAggregate = aggregate ? compose(aggregate, translate(this.x, this.y)) : translate(this.x, this.y);\n\n if (bestIndex !== this.images.length - 1 && this.images[bestIndex + 1]) {\n let toPaintIdx = [];\n for (let i = len - 1; i >= bestIndex; i--) {\n toPaintIdx.push(i);\n }\n const smallestIdx = toPaintIdx[0];\n if (this.renderOptions.renderLayers) {\n toPaintIdx = toPaintIdx.slice(-Math.min(toPaintIdx.length, this.renderOptions.renderLayers));\n }\n\n if (this.renderOptions.renderSmallestFallback && toPaintIdx.indexOf(smallestIdx) === -1) {\n toPaintIdx.unshift(smallestIdx);\n }\n\n const toPaint = [];\n for (let i = 0; i < toPaintIdx.length; i++) {\n toPaint.push(...this.images[toPaintIdx[i]].getAllPointsAt(target, newAggregate, scale));\n }\n\n return toPaint;\n }\n return this.images[bestIndex].getAllPointsAt(target, newAggregate, scale);\n }\n}\n","import { Paint, Paintable } from './paint';\nimport { AbstractObject } from './abstract-object';\nimport {\n Strand,\n dna,\n compose,\n getIntersection,\n scale,\n transform,\n translate,\n hidePointsOutsideRegion,\n} from '@atlas-viewer/dna';\nimport { BaseObject } from '../objects/base-object';\nimport { SpacialContent } from '../spacial-content';\nimport { Geometry } from '../objects/geometry';\n\nfunction rotate(cx: number, cy: number, x: number, y: number, angle: number) {\n const radians = (Math.PI / 180) * angle,\n cos = Math.cos(radians),\n sin = Math.sin(radians),\n nx = cos * (x - cx) + sin * (y - cy) + cx,\n ny = cos * (y - cy) - sin * (x - cx) + cy;\n return [nx, ny];\n}\n\ntype WorldObjectProps = {\n id: string;\n width: number;\n height: number;\n scale?: number;\n x?: number;\n y?: number;\n rotation?: number;\n};\n\nexport class WorldObject extends BaseObject<WorldObjectProps, Paintable> {\n id: string;\n type = 'world-object';\n scale: number;\n layers: Paintable[];\n\n /**\n * This position in the world local to the scale of the object.\n * So a 1000x1000 drawn at 0.1 scale at x=5, y=10 on the world would have world points 50,100,1000,1000\n *\n * To get it's world-relative position you need to multiple the scale out.\n */\n points: Strand;\n\n /**\n * These are relative to where to object is in the world at the scale of the world.\n * So a 1000x1000 drawn at 0.1 scale at x=5, y=10 on the world would have world points 0,0,100,100\n */\n worldPoints: Strand;\n\n intersectionBuffer = dna(5);\n aggregateBuffer = dna(9);\n invertedBuffer = dna(9);\n rotation = 0;\n filteredPointsBuffer: Strand;\n _updatedList: any[] = [];\n geometry?: any;\n\n constructor(props?: AbstractObject, position?: { x: number; y: number }) {\n super();\n const { x = 0, y = 0 } = position || {};\n\n if (!props) {\n this.id = '';\n this.scale = 1;\n this.layers = [];\n this.points = dna(5);\n this.worldPoints = dna(5);\n this.filteredPointsBuffer = dna(5);\n } else {\n // @deprecated.\n this.id = props.id || '';\n this.scale = 1;\n this.layers = props.layers;\n\n this.points = dna([1, x, y, x + props.width, y + props.height]);\n this.worldPoints = dna([1, x, y, x + props.width, y + props.height]);\n this.filteredPointsBuffer = dna(props.layers.length * 5);\n }\n }\n\n static createWithProps(props: WorldObjectProps) {\n const instance = new WorldObject();\n instance.applyProps(props);\n return instance;\n }\n\n applyProps(props: WorldObjectProps) {\n const x = props.x || 0;\n const y = props.y || 0;\n\n this.id = props.id;\n const s = typeof props.scale !== 'undefined' ? props.scale : this.scale;\n\n this.points[0] = 1;\n this.points[1] = x;\n this.points[2] = y;\n this.points[3] = x + props.width;\n this.points[4] = y + props.height;\n this.rotation = props.rotation || 0;\n\n this.worldPoints[3] = this.worldPoints[1] + props.width;\n this.worldPoints[4] = this.worldPoints[2] + props.height;\n\n if (props.scale && props.scale !== 1) {\n this.atScale(s);\n }\n\n this.scale = s;\n\n // @todo this will be a bit tricky as we have to use the translate\n // function to update the props. It will be a case of checking\n // the props, and applying the difference. x = 2 => 3 = (x + 1)\n // For the reconciler, we could also give access to the bare transforms\n // Although that might be painful as the props would be out of sync.\n }\n\n appendChild(item: Paintable) {\n // Not set manually.\n if (item.points[0] === 0) {\n item.points.set(this.points);\n }\n item.__owner.value = this;\n\n this.addLayers([item]);\n }\n\n removeChild(item: Paintable) {\n this.layers = this.layers.filter((layer) => layer !== item);\n this.filteredPointsBuffer = dna(this.layers.length * 5);\n }\n\n insertBefore(item: Paintable, before: Paintable) {\n const index = this.layers.indexOf(before);\n if (index === -1) {\n return;\n }\n if (this.layers.indexOf(item) !== -1) {\n return;\n }\n\n // const beforeLayers = this.layers.slice(0, index - 1);\n const beforeLayers = this.layers.slice(0, index);\n const afterLayers = this.layers.slice(index);\n\n this.layers = [...beforeLayers, item, ...afterLayers];\n }\n\n hideInstance() {\n console.warn('hideInstance: not yet implemented');\n }\n\n getObjectsAt(target: Strand, all?: boolean): Paintable[] {\n if (this.rotation) {\n target = this.applyRotation(target);\n }\n\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n if (filteredPoints[0] === 0) {\n return [];\n }\n\n const len = this.layers.length;\n const objects: Paintable[] = [];\n for (let index = 0; index < len; index++) {\n const layer = this.layers[index] as SpacialContent | WorldObject;\n\n if (all && (layer as Geometry).isShape) {\n const t = transform(layer.points, translate(this.x, this.y));\n const int = (layer as Geometry).intersects([target[1] - t[1], target[2] - t[2]]);\n if (!int) continue;\n }\n\n const filter = hidePointsOutsideRegion(\n transform(layer.points, translate(this.x, this.y)),\n target,\n this.filteredPointsBuffer\n );\n\n if (filter[0] !== 0) {\n objects.push(layer as SpacialContent);\n }\n\n if (all) {\n const object = layer as WorldObject;\n objects.push(...object.getObjectsAt(target, all));\n }\n }\n return objects;\n }\n\n applyRotation(target: Strand) {\n if (this.rotation) {\n const a = { x: target[1], y: target[2] };\n const b = { x: target[1], y: target[4] };\n const c = { x: target[3], y: target[2] };\n const d = { x: target[3], y: target[4] };\n\n const x = this.points[1] + (this.points[3] - this.points[1]) / 2;\n const y = this.points[2] + (this.points[4] - this.points[2]) / 2;\n\n const [x1, y1] = rotate(x, y, a.x, a.y, this.rotation);\n const [x2, y2] = rotate(x, y, b.x, b.y, this.rotation);\n const [x3, y3] = rotate(x, y, c.x, c.y, this.rotation);\n const [x4, y4] = rotate(x, y, d.x, d.y, this.rotation);\n\n const rx1 = Math.min(x1, x2, x3, x4);\n const rx2 = Math.max(x1, x2, x3, x4);\n const ry1 = Math.min(y1, y2, y3, y4);\n const ry2 = Math.max(y1, y2, y3, y4);\n\n return dna([target[0], rx1, ry1, rx2, ry2]);\n }\n return target;\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n const transformer = compose(translate(this.x, this.y), scale(this.scale), this.aggregateBuffer);\n\n if (this.rotation) {\n target = this.applyRotation(target);\n }\n\n const inter = getIntersection(target, this.points, this.intersectionBuffer);\n const len = this.layers.length;\n const arr: Paint[] = [];\n\n const t = transform(inter, compose(scale(1 / this.scale), translate(-this.x, -this.y), this.invertedBuffer));\n const agg = aggregate ? compose(aggregate, transformer, this.aggregateBuffer) : transformer;\n const s = scaleFactor * this.scale;\n\n for (let i = 0; i < len; i++) {\n // Crop intersection.\n arr.push(...this.layers[i].getAllPointsAt(t, agg, s));\n }\n return arr;\n }\n\n addLayers(paintables: Paintable[]) {\n const paintablesToAdd = [];\n for (const paintable of paintables) {\n if (this.layers.indexOf(paintable) !== -1) {\n continue;\n }\n paintablesToAdd.push(paintable);\n // Check for crop.\n if (\n paintable.points.length === 5 &&\n // Paint.x < 0\n (paintable.points[1] < this.worldPoints[1] / this.scale ||\n // Paint.y < 0\n paintable.points[2] < this.worldPoints[2] / this.scale ||\n // Paint.width > this.width\n paintable.points[3] > this.worldPoints[3] / this.scale ||\n // Paint.height > this.height\n paintable.points[4] > this.worldPoints[4] / this.scale)\n ) {\n // @todo support for tiled crops.\n paintable.crop =\n paintable.crop ||\n dna([\n 1,\n Math.max(this.worldPoints[1] / this.scale, paintable.points[1]),\n Math.max(this.worldPoints[2] / this.scale, paintable.points[2]),\n Math.min(this.worldPoints[3] / this.scale, paintable.points[3]),\n Math.min(this.worldPoints[4] / this.scale, paintable.points[4]),\n ]);\n }\n }\n\n this.layers = this.layers.concat(paintablesToAdd);\n\n this.filteredPointsBuffer = dna(this.layers.length * 5);\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n const len = this.layers.length;\n this._updatedList = [];\n const s = scaleFactor * this.scale;\n for (let i = 0; i < len; i++) {\n const updates = this.layers[i].getScheduledUpdates(target, s);\n if (updates) {\n this._updatedList.push(...updates);\n }\n }\n return this._updatedList;\n }\n}\n","import { Viewer, ViewingDirection } from './types';\nimport {\n compose,\n DnaFactory,\n dnaLength,\n hidePointsOutsideRegion,\n mutate,\n scale,\n scaleAtOrigin,\n translate,\n dna,\n Strand,\n} from '@atlas-viewer/dna';\nimport { WorldObject } from './world-objects/world-object';\nimport { AbstractObject } from './world-objects/abstract-object';\nimport { Paint, Paintable } from './world-objects/paint';\nimport { ZoneInterface } from './world-objects/zone';\nimport { BaseObject } from './objects/base-object';\nimport { SpacialContent } from './spacial-content/spacial-content';\nimport { SupportedEvents } from './events';\nimport { Geometry } from './objects/geometry';\n\ntype WorldTarget = { x: number; y: number; width?: number; height?: number };\n\ntype WorldProps = {\n width: number;\n height: number;\n viewingDirection: ViewingDirection;\n};\n\nexport class World extends BaseObject<WorldProps, WorldObject> {\n id = 'world';\n _width: number;\n _height: number;\n aspectRatio: number;\n viewingDirection: ViewingDirection;\n aggregateBuffer = dna(9);\n isDirty = false;\n zones: ZoneInterface[] = [];\n filteredPointsBuffer: Strand;\n selectedZone?: number;\n triggerQueue: Array<[string, any]> = [];\n activatedEvents: string[] = [];\n _updatedList: any[] = [];\n translationBuffer = dna(9);\n needsRecalculate = true;\n emptyPaintables = [];\n renderOrder: number[] = [];\n\n get x(): number {\n return 0;\n }\n get y(): number {\n return 0;\n }\n get width(): number {\n return this._width;\n }\n get height(): number {\n return this._height;\n }\n\n points: Strand;\n\n // These should be the same size.\n private objects: Array<WorldObject | null> = [];\n subscriptions: Array<(type: string, changes?: unknown) => void> = [];\n\n constructor(width = 0, height = 0, worldObjectCount = 100, viewingDirection: ViewingDirection = 'left-to-right') {\n super();\n this._width = width;\n this._height = height;\n this.aspectRatio = Number.isNaN(width / height) ? 1 : width / height;\n this.viewingDirection = viewingDirection;\n this.points = dna(worldObjectCount * 5);\n this.filteredPointsBuffer = dna(worldObjectCount * 5);\n }\n\n static withProps(props: WorldProps) {\n const instance = new World();\n instance.applyProps(props);\n return instance;\n }\n\n applyProps(props: WorldProps) {\n if (\n typeof props.width !== 'undefined' &&\n typeof props.height !== 'undefined' &&\n (props.width !== this._width || props.height !== this._height)\n ) {\n this.resize(props.width, props.height);\n }\n if (props.viewingDirection !== this.viewingDirection) {\n this.viewingDirection = props.viewingDirection;\n this.triggerRepaint();\n }\n }\n\n propagateTouchEvent(eventName: string, e: TouchEvent, touchTargets: Array<{ x: number; y: number }>) {\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n\n const targets = [];\n for (const touch of touchTargets) {\n if (touch.x && touch.y) {\n const point = DnaFactory.singleBox(1, 1, touch.x, touch.y);\n targets.push(this.getObjectsAt(point, true).reverse());\n }\n }\n\n return targets.map((target) => this.propagateEvent(eventName, e, target, { bubbles: true, cancelable: true }));\n }\n\n propagatePointerEvent<Name extends keyof SupportedEvents>(\n eventName: Name,\n e: any,\n x: number,\n y: number,\n opts: { bubbles?: boolean; cancelable?: boolean } = {}\n ) {\n // @todo re-add activated events, but smarter.\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n const point = DnaFactory.singleBox(1, 1, x, y);\n const worldObjects = this.getObjectsAt(point, true).reverse();\n\n // Here there is more we can handle.\n // - When a move move event is detected:\n // - Handle mouse enter / leave\n // - Handle drag / drag start / drag end / drag-over\n // - When a mouse leave\n // - Reset mouse over items\n // - When a mouse down event is detected:\n // - Store click / clickStart / drag items\n\n return this.propagateEvent(eventName, e, worldObjects, opts);\n }\n\n _propagateEventTargets: any[] = [];\n propagateEvent(\n eventName: string,\n e: any,\n worldObjects: [WorldObject, SpacialContent[]][],\n { bubbles = false, cancelable = false }: { bubbles?: boolean; cancelable?: boolean } = {}\n ) {\n // @todo re-add activated events, but smarter.\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n // Modify event if we need to.\n e.atlasTarget = this;\n\n // Store the stack of targets.\n this._propagateEventTargets.length = 1;\n this._propagateEventTargets[0] = this;\n\n // Set up a stop propagation\n let stopped = false;\n e.stopPropagation = () => {\n stopped = true;\n };\n\n const woLen = worldObjects.length;\n for (let w = woLen - 1; w >= 0; w--) {\n // @todo unsure why this was here.\n // if (w === 1) break;\n this._propagateEventTargets.unshift(worldObjects[w][0]);\n const len = worldObjects[w][1].length;\n if (len) {\n for (let i = 0; i < len; i++) {\n this._propagateEventTargets.unshift(worldObjects[w][1][i]);\n }\n }\n }\n\n const len = this._propagateEventTargets.length;\n let didFire = false;\n for (let i = 0; i < len; i++) {\n e.atlasTarget = this._propagateEventTargets[i];\n e.atlasWorld = this;\n didFire = this._propagateEventTargets[i].dispatchEvent(eventName as any, e) || didFire;\n if (stopped) break;\n }\n\n if (didFire) {\n this.triggerRepaint();\n }\n return this._propagateEventTargets;\n }\n\n appendChild(item: WorldObject) {\n const idx = this.appendWorldObject(item);\n this.renderOrder.push(idx / 5);\n }\n\n removeChild(item: WorldObject) {\n const index = this.objects.indexOf(item);\n\n if (index === -1) {\n for (const obj of this.objects) {\n if (obj && obj.id === item.id) {\n this.removeChild(obj);\n return;\n }\n }\n return;\n }\n\n this.objects[index] = null;\n this.renderOrder = this.renderOrder.filter((t) => t !== index);\n this.points[index * 5] = 0;\n this.triggerRepaint();\n this.needsRecalculate = true;\n }\n\n insertBefore(item: WorldObject, before: WorldObject) {\n const beforeIndex = this.objects.indexOf(before);\n if (beforeIndex === -1) {\n return;\n }\n\n const idx = this.appendWorldObject(item);\n this.renderOrder.splice(beforeIndex - 1, 0, idx / 5);\n }\n\n hideInstance() {\n // not yet implemented.\n // console.warn('hideInstance: Not yet implemented');\n }\n\n asWorldObject(): WorldObject | null {\n // @todo.\n return null;\n }\n\n addZone(zone: ZoneInterface) {\n this.zones.push(zone);\n }\n\n selectZone(id: string | number) {\n if (typeof id === 'string') {\n const len = this.zones.length;\n for (let i = 0; i < len; i++) {\n if (this.zones[i].id === id) {\n this.selectedZone = i;\n this.trigger('zone-changed');\n return;\n }\n }\n } else {\n if (this.zones[id]) {\n this.selectedZone = id;\n this.trigger('zone-changed');\n }\n }\n }\n\n deselectZone() {\n this.selectedZone = undefined;\n }\n\n getActiveZone(): ZoneInterface | undefined {\n if (this.selectedZone) {\n return this.zones[this.selectedZone];\n }\n return undefined;\n }\n\n hasActiveZone(): boolean {\n return typeof this.selectedZone !== 'undefined';\n }\n\n private checkResizeInternalBuffer() {\n if (dnaLength(this.points) === this.objects.length) {\n // resize, doubles each time, @todo change.\n const points = this.points;\n const newPoints = dna(this.points.length * 2);\n newPoints.set(points, 0);\n this.points = newPoints;\n }\n }\n\n appendWorldObject(object: WorldObject) {\n this.checkResizeInternalBuffer();\n\n const index = this.objects.length * 5;\n const pointValues = object.points;\n object.points = this.points.subarray(this.objects.length * 5, this.objects.length * 5 + 5);\n object.points[1] = pointValues[1];\n object.points[2] = pointValues[2];\n object.points[3] = pointValues[3];\n object.points[4] = pointValues[4];\n\n this.objects.push(object);\n this.filteredPointsBuffer = dna(this.objects.length * 5);\n this.needsRecalculate = true;\n\n this.triggerRepaint();\n\n return index;\n }\n\n recalculateWorldSize() {\n let didChange = false;\n if (this.needsRecalculate) {\n const wBuffer = new Int32Array(this.objects.length);\n const hBuffer = new Int32Array(this.objects.length);\n const len = this.renderOrder.length;\n for (let _index = 0; _index < len; _index++) {\n const index = this.renderOrder[_index];\n const object = this.objects[index];\n if (object) {\n wBuffer[_index] = this.points[index * 5 + 3];\n hBuffer[_index] = this.points[index * 5 + 4];\n }\n }\n const newWidth = Math.max(...wBuffer);\n if (newWidth !== this._width) {\n this._width = newWidth;\n didChange = true;\n }\n const newHeight = Math.max(...hBuffer);\n if (newHeight !== this._height) {\n this._height = newHeight;\n didChange = true;\n }\n if (didChange) {\n this.trigger('recalculate-world-size', { width: newWidth, height: newHeight });\n }\n this.needsRecalculate = false;\n }\n\n return didChange;\n }\n\n /**\n * @deprecated\n */\n addObjectAt(object: AbstractObject, target: WorldTarget): WorldObject {\n // @todo make target optional, default layout management\n // to be applied that will simply line up all of the\n // images in a row. The target is mainly to be used\n // by a builder. Also support adding a world object\n // here, which is itself an abstract object.\n\n if (target.width && !target.height) {\n target.height = (target.width / object.width) * object.height;\n } else if (target.height && !target.width) {\n target.width = (target.height / object.height) * object.width;\n }\n if (!target || !target.width || !target.height) {\n target.width = object.width;\n target.height = object.height;\n }\n\n const { width, x, y } = target;\n\n const scaleFactor = width / object.width;\n\n this.checkResizeInternalBuffer();\n\n // @todo integrity to ensure these remain.\n this.points.set(DnaFactory.singleBox(object.width, object.height, 0, 0), this.objects.length * 5);\n\n const worldObject = new WorldObject(object);\n\n worldObject.points = this.points.subarray(this.objects.length * 5, this.objects.length * 5 + 5);\n // worldObject.atScale(scaleFactor);\n // worldObject.translate(x, y);\n this.objects.push(worldObject);\n this.scaleWorldObject(this.objects.length - 1, scaleFactor);\n this.translateWorldObject(this.objects.length - 1, x, y);\n this.filteredPointsBuffer = dna(this.points.length * 2);\n\n this.triggerRepaint();\n this.needsRecalculate = true;\n\n return worldObject;\n }\n\n scaleWorldObject(index: number, factor: number) {\n mutate(\n this.points.subarray(index * 5, index * 5 + 5),\n scaleAtOrigin(factor, this.points[index * 5 + 1], this.points[index * 5 + 2])\n );\n const obj = this.objects[index];\n if (obj) {\n obj.atScale(factor);\n this.triggerRepaint();\n }\n }\n\n translateWorldObject(index: number, x: number, y: number) {\n mutate(this.points.subarray(index * 5, index * 5 + 5), translate(x, y));\n const obj = this.objects[index];\n if (obj) {\n obj.translate(x, y);\n this.triggerRepaint();\n }\n }\n\n resize(width: number, height: number) {\n this._width = width;\n this._height = height;\n\n this.aspectRatio = width / height;\n\n // @todo what happens when projections are out of bounds?\n // @todo what happens when objects are out of bounds?\n this.triggerRepaint();\n\n return this;\n }\n\n getObjects() {\n return this.objects;\n }\n\n getPoints() {\n return this.points;\n }\n\n getPointsFromViewer(target: Viewer, aggregate?: Strand) {\n const targetPoints = DnaFactory.singleBox(target.width, target.height, target.x, target.y);\n return this.getPointsAt(targetPoints, aggregate, target.scale);\n }\n\n addLayoutSubscriber(subscription: (type: string, data: unknown) => void) {\n this.subscriptions.push(subscription);\n\n return () => {\n this.subscriptions.splice(this.subscriptions.indexOf(subscription), 1);\n };\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n\n const len = this.objects.length;\n this._updatedList = [];\n\n\n for (let index = 0; index < len; index++) {\n if (filteredPoints[index * 5] !== 0) {\n if (!this.objects[index]) continue;\n this._updatedList.push(...(this.objects[index] as WorldObject).getScheduledUpdates(target, scaleFactor));\n }\n }\n return this._updatedList;\n }\n\n getObjectsAt(target: Strand, all = false): Array<[WorldObject, Paintable[]]> {\n const zone = this.getActiveZone();\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n\n const len = this.renderOrder.length;\n const objects: Array<[WorldObject, Paintable[]]> = [];\n\n for (let _index = 0; _index < len; _index++) {\n const index = this.renderOrder[_index];\n if (filteredPoints[index * 5] !== 0) {\n const object = this.objects[index];\n if (!object || (zone && zone.objects.indexOf(object) === -1)) {\n continue;\n }\n if (object.type !== 'world-object') {\n objects.push([object, [object]] as any);\n continue;\n }\n if (all) {\n objects.push([object, object.getObjectsAt(target, all)]);\n } else {\n objects.push([object, this.emptyPaintables]);\n }\n }\n }\n\n return objects;\n }\n\n getPointsAt(target: Strand, aggregate?: Strand, scaleFactor = 1): Paint[] {\n const objects = this.getObjectsAt(target);\n const translation = compose(scale(scaleFactor), translate(-target[1], -target[2]), this.translationBuffer);\n const transformer = aggregate ? compose(aggregate, translation, this.aggregateBuffer) : translation;\n const len = objects.length;\n\n const layers: Paint[] = [];\n for (let index = 0; index < len; index++) {\n if (objects[index]) {\n layers.push(...objects[index][0].getAllPointsAt(target, transformer, scaleFactor));\n }\n }\n return layers;\n }\n\n _alreadyFlushed: any = [];\n flushSubscriptions() {\n if (this.triggerQueue.length) {\n this._alreadyFlushed = [];\n const queueLen = this.triggerQueue.length;\n for (let x = 0; x < queueLen; x++) {\n if (this._alreadyFlushed.indexOf(this.triggerQueue[x][0]) !== -1) {\n continue;\n }\n if (typeof this.triggerQueue[x][1] === 'undefined') {\n this._alreadyFlushed.push(this.triggerQueue[x][0]);\n }\n const len = this.subscriptions.length;\n for (let i = 0; i < len; i++) {\n // eslint-disable-next-line prefer-spread\n (this.subscriptions[i] as any).apply(null, this.triggerQueue[x]);\n }\n }\n this.triggerQueue = [];\n }\n }\n\n trigger<T>(type: string, data?: T) {\n this.triggerQueue.push([type, data]);\n }\n\n triggerEventActivation() {\n this.trigger('event-activation');\n }\n\n triggerRepaint() {\n this.trigger('repaint');\n }\n\n gotoRegion(data: {\n x: number;\n y: number;\n height: number;\n width: number;\n // padding in world units (symmetric)\n padding?: number;\n // optional CSS-pixel padding which will be converted to world units by runtime before applying.\n // Can be a number (symmetric) or an object with any of `left`, `right`, `top`, `bottom` in CSS pixels.\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n nudge?: boolean;\n immediate?: boolean;\n }) {\n this.trigger('goto-region', data);\n }\n\n goHome(immediate = false, paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number }) {\n this.trigger('go-home', {\n immediate,\n paddingPx,\n });\n }\n\n zoomTo(factor: number, point?: { x: number; y: number }, stream?: boolean) {\n this.trigger('zoom-to', {\n point,\n factor,\n stream,\n });\n }\n\n zoomIn(point?: { x: number; y: number }) {\n this.trigger('zoom-to', {\n point,\n factor: 0.5,\n });\n }\n\n zoomOut(point?: { x: number; y: number }) {\n this.trigger('zoom-to', {\n point,\n factor: 2,\n });\n }\n\n constraintBounds(immediate?: boolean) {\n this.trigger('constrain-bounds', { immediate });\n }\n}\n","import { WorldObject } from './world-object';\nimport { SingleImage } from '../spacial-content';\n\nexport function fromImage(image: {\n src: string;\n height: number;\n width: number;\n target?: { width: number; height: number };\n}): WorldObject {\n const { src, target } = image;\n const width = target ? target.width : image.width;\n const height = target ? target.height : image.height;\n\n return new WorldObject({\n id: src,\n height,\n width,\n layers: [SingleImage.fromImage(src, { height, width }, { width: image.width, height: image.height })],\n });\n}\n","import { Paint } from './paint';\nimport { WorldObject } from './world-object';\nimport { Strand, dna } from '@atlas-viewer/dna';\n\nexport interface ZoneInterface {\n id: string;\n config: Required<ZoneConfig>;\n objects: WorldObject[];\n points: Strand;\n recalculateBounds(): void;\n getPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[];\n}\n\nexport type ZoneConfig = {\n margin?: number;\n};\n\nconst defaultConfig: Required<ZoneConfig> = {\n margin: 0,\n};\n\nexport class Zone implements ZoneInterface {\n id: string;\n config: Required<ZoneConfig>;\n points: Strand;\n objects: WorldObject[];\n\n constructor(objects: [WorldObject, ...WorldObject[]], config: ZoneConfig = {}) {\n this.id = objects.map(obj => obj.id).join('$$');\n this.config = {\n ...defaultConfig,\n ...config,\n };\n\n this.points = dna(5);\n this.objects = objects;\n this.recalculateBounds();\n }\n\n recalculateBounds(): void {\n // To create the points we need to take the world objects and get the min x1, y1 and the max x2, y2\n // After that we need to add the margin around.\n // Zone is just a logical grouping of work objects, as such they can't change the positions of world objects\n // They can however be queries for visible points, like WorldObjects.\n this.points.set([\n 1,\n Math.min(...this.objects.map(obj => (obj as WorldObject).points[1])) - this.config.margin,\n Math.min(...this.objects.map(obj => (obj as WorldObject).points[2])) - this.config.margin,\n Math.max(...this.objects.map(obj => (obj as WorldObject).points[3])) + this.config.margin,\n Math.max(...this.objects.map(obj => (obj as WorldObject).points[4])) + this.config.margin,\n ]);\n }\n\n getPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return [];\n }\n}\n","import { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\n\nconst borderRegex = /([0-9]+(px|em)\\s+)+(solid)\\s+(.*)/g;\nconst borderRegexCache: any = {};\n\nexport type BoxProps = {\n id: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n\n className?: string;\n href?: string;\n title?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n // New style.\n style?: BoxStyle;\n\n // Deprecated\n backgroundColor?: string;\n border?: string;\n};\n\nexport type BoxStyle = _BoxStyle & {\n ':hover'?: _BoxStyle;\n ':active'?: _BoxStyle;\n};\n\ntype _BoxStyle = Partial<{\n // In order\n backgroundColor: string; // colour or gradient function\n opacity: number;\n boxShadow: string; // to parse, splitting /,(?![^\\(]*\\))/\n borderColor: string;\n borderWidth: string;\n borderStyle: string; // 'solid' only\n outlineColor: string;\n outlineWidth: string;\n outlineOffset: string;\n outlineStyle: string; // 'solid' only\n\n // Parsed.\n border: string;\n outline: string;\n background: string;\n\n // transform: string; // scale() rotate() transform() transformX() transformY() - pixels\n // transformOrigin: string; // using translate(x, y); rotate(); translate(-x, -y);\n // backgroundImage: string; // possibly.\n // backgroundRepeat: string; // repeat | repeat-x | repeat-y | no-repeat\n //borderRadius: string; // maybe? Future?\n}>;\n\nconst styleProps: Array<keyof BoxStyle> = [\n 'backgroundColor',\n 'opacity',\n 'boxShadow',\n 'borderColor',\n 'borderWidth',\n 'borderStyle',\n 'outlineColor',\n 'outlineWidth',\n 'outlineOffset',\n 'outlineStyle',\n];\n\n// const mapping = [\n// // Common\n// ['opacity', 'globalAlpha'],\n// ['transform', ['translate', 'scale', 'rotate']],\n//\n// // Fill rect\n// [\n// 'backgroundColor',\n// ['fillStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['boxShadow', ['shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor']],\n//\n// // Stroke rect\n// ['outline', 'same-as-below'],\n// [\n// 'borderColor',\n// ['strokeStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['borderWidth', 'strokeWidth'],\n// ['borderStyle', ['setLineDash', 'lineDashOffset']],\n// ];\n\nexport class Box extends BaseObject<BoxProps> implements SpacialContent {\n id: string;\n type: 'spacial-content' = 'spacial-content';\n points: Strand;\n hoverEvents = false;\n activeEvents = false;\n\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: -1,\n height: -1,\n points: dna(5),\n };\n\n _parsed: { border: { id: string | null; match: string[] }; outline: { id: string | null; match: string[] } } = {\n border: { id: null, match: [] },\n outline: { id: null, match: [] },\n };\n\n hovering?: boolean;\n pressing?: boolean;\n props: {\n href?: string;\n hrefTarget?: string;\n title?: string;\n backgroundColor?: string;\n border?: string;\n interactive?: boolean;\n className?: string;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n style?: BoxStyle;\n hoverStyles?: BoxStyle;\n pressStyles?: BoxStyle;\n } = {};\n\n constructor() {\n super();\n this.id = nanoid(12);\n this.points = dna(5);\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n // this.points[0] = 1;\n return [[this as any, this.points, aggregate]];\n }\n\n addHover = () => {\n this.hovering = true;\n this.__revision++;\n };\n\n removeHover = () => {\n this.hovering = false;\n this.pressing = false;\n this.__revision++;\n };\n\n addPress = () => {\n this.pressing = true;\n this.__revision++;\n };\n\n removePress = () => {\n this.pressing = false;\n this.__revision++;\n };\n\n applyProps(props: Partial<BoxProps> = {}) {\n let didUpdate = false;\n\n if (props.interactive !== this.props.interactive) {\n didUpdate = true;\n this.props.interactive = props.interactive;\n }\n\n if (props.style) {\n // pre-process props.\n const borderStyle = props.border || props.style.border;\n if (borderStyle !== this._parsed.border.id) {\n if (!borderStyle) {\n this._parsed.border.id = null;\n this._parsed.border.match = [];\n } else {\n const match = borderRegexCache[borderStyle] || borderRegex.exec(borderStyle) || borderRegex.exec(borderStyle);\n if (match) {\n this._parsed.border.id = borderStyle;\n this._parsed.border.match = borderRegexCache[borderStyle] = match;\n }\n }\n }\n if (this._parsed.border.id) {\n props.style.borderWidth = this._parsed.border.match[1];\n props.style.borderStyle = 'solid'; // only support this.\n props.style.borderColor = this._parsed.border.match[4];\n }\n\n if (props.style.outline !== this._parsed.outline.id) {\n if (!props.style.outline) {\n this._parsed.outline.id = null;\n this._parsed.outline.match = [];\n } else {\n const match =\n borderRegexCache[props.style.outline] ||\n borderRegex.exec(props.style.outline) ||\n borderRegex.exec(props.style.outline);\n\n if (match) {\n this._parsed.outline.id = props.style.outline;\n this._parsed.outline.match = borderRegexCache[props.style.outline] = match;\n }\n }\n }\n if (this._parsed.outline.id) {\n props.style.outlineWidth = this._parsed.outline.match[1];\n props.style.outlineStyle = 'solid'; // only support this.\n props.style.outlineColor = this._parsed.outline.match[4];\n }\n\n this.props.style = props.style;\n // BC fix.\n if (props.backgroundColor && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.backgroundColor;\n didUpdate = true;\n }\n if (props.style.background && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.style.background;\n didUpdate = true;\n }\n\n for (const prop of styleProps) {\n if (this.props.style[prop] !== props.style[prop]) {\n didUpdate = true;\n break;\n }\n }\n\n if (props.style[':hover'] !== this.props.hoverStyles) {\n this.props.hoverStyles = props.style[':hover'];\n if (!this.hoverEvents) {\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n didUpdate = true;\n }\n if (props.style[':active'] !== this.props.pressStyles) {\n this.props.pressStyles = props.style[':active'];\n if (!this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n }\n\n if (props.href !== this.props.href) {\n this.props.href = props.href;\n didUpdate = true;\n }\n\n if (props.hrefTarget !== this.props.hrefTarget) {\n this.props.hrefTarget = props.hrefTarget;\n didUpdate = true;\n }\n\n if (props.title !== this.props.title) {\n this.props.title = props.title;\n didUpdate = true;\n }\n\n if (props.className !== this.props.className) {\n this.props.className = props.className;\n if (props.className && !this.hoverEvents) {\n // Only if class name.\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n if (props.className && !this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n\n if (props.relativeSize !== this.props.relativeSize) {\n this.props.relativeSize = props.relativeSize;\n didUpdate = true;\n }\n if (props.relativeStyle !== this.props.relativeStyle) {\n this.props.relativeStyle = props.relativeStyle;\n didUpdate = true;\n }\n if (props.html !== this.props.html) {\n this.props.html = props.html;\n didUpdate = true;\n }\n\n if (props.target) {\n if (\n props.target.width !== this.display.width ||\n props.target.height !== this.display.height ||\n props.target.x !== this.points[1] ||\n props.target.y !== this.points[2]\n ) {\n didUpdate = true;\n this.points = DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y);\n this.display.points = DnaFactory.singleBox(\n props.target.width,\n props.target.height,\n props.target.x,\n props.target.y\n );\n this.display.width = props.target.width;\n this.display.height = props.target.height;\n }\n }\n\n if (didUpdate) {\n // Bump revision.\n this.__revision++;\n }\n }\n}\n","import { TextWrapperOptions } from '../types';\nimport { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\n\nexport type TextProps = TextWrapperOptions & {\n id: string;\n text: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n color: string;\n backgroundColor: string;\n fontSize: number;\n fontFamily: string;\n interactive?: boolean;\n};\n\nexport class Text extends BaseObject<TextProps> implements SpacialContent {\n type: 'spacial-content' = 'spacial-content';\n id: string;\n points: Strand;\n color = '#000';\n backgroundColor?: string;\n hovering?: boolean;\n pressing?: boolean;\n text = '';\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: 100,\n height: 100,\n points: dna(5),\n };\n className?: string;\n html?: boolean;\n interactive = false;\n props: TextWrapperOptions & {\n title?: string;\n href?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n className?: string;\n html?: boolean;\n } = {\n font: '18px Arial, sans-serif',\n lineHeight: 1,\n textAlign: 'left',\n verticalAlign: 'top',\n paddingX: 0,\n paddingY: 0,\n fitParent: false,\n lineBreak: 'auto',\n strokeText: false,\n sizeToFill: false,\n maxFontSizeToFill: undefined,\n allowNewLine: true,\n justifyLines: false,\n renderHDPI: false,\n textDecoration: 'none',\n interactive: false,\n relativeSize: false,\n };\n\n constructor() {\n super();\n this.id = '';\n this.points = dna(5);\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n\n applyProps({\n id,\n target,\n text,\n color,\n backgroundColor,\n fontSize = 18,\n interactive,\n fontFamily = 'Arial, sans-serif',\n ...props\n }: Partial<TextProps>) {\n props.font = `${fontSize}px ${fontFamily}`;\n\n this.interactive = interactive || false;\n\n if (typeof text !== 'undefined') {\n this.text = text || '';\n }\n if (color) {\n this.color = color;\n }\n if (backgroundColor) {\n this.backgroundColor = backgroundColor;\n }\n if (id) {\n this.id = id;\n }\n if (target) {\n this.points = DnaFactory.singleBox(target.width, target.height, target.x, target.y);\n this.display.points = this.points;\n this.display.width = target.width;\n this.display.height = target.height;\n }\n this.props = { ...this.props, ...props };\n // Bump revision.\n this.__revision++;\n }\n}\n","export type EasingFunction = (progress: number) => number;\n\n// Adapted from\n// https://github.com/ai/easings.net/blob/master/src/easings/easingsFunctions.ts\n\nconst pow = Math.pow;\nconst sqrt = Math.sqrt;\nconst sin = Math.sin;\nconst cos = Math.cos;\nconst PI = Math.PI;\nconst c1 = 1.70158;\nconst c2 = c1 * 1.525;\nconst c3 = c1 + 1;\nconst c4 = (2 * PI) / 3;\nconst c5 = (2 * PI) / 4.5;\n\nexport const bounceOut: EasingFunction = function (x) {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n};\n\nexport type EasingFunctionNames =\n | 'linear'\n | 'easeInQuad'\n | 'easeOutQuad'\n | 'easeInOutQuad'\n | 'easeInCubic'\n | 'easeOutCubic'\n | 'easeInOutCubic'\n | 'easeInQuart'\n | 'easeOutQuart'\n | 'easeInOutQuart'\n | 'easeInQuint'\n | 'easeOutQuint'\n | 'easeInOutQuint'\n | 'easeInSine'\n | 'easeOutSine'\n | 'easeInOutSine'\n | 'easeInExpo'\n | 'easeOutExpo'\n | 'easeInOutExpo'\n | 'easeInCirc'\n | 'easeOutCirc'\n | 'easeInOutCirc'\n | 'easeInBack'\n | 'easeOutBack'\n | 'easeInOutBack'\n | 'easeInElastic'\n | 'easeOutElastic'\n | 'easeInOutElastic'\n | 'easeInBounce'\n | 'easeOutBounce'\n | 'easeInOutBounce';\n\nexport const easingFunctions: { [key in EasingFunctionNames]: EasingFunction } = {\n linear: (x) => x,\n easeInQuad: function (x) {\n return x * x;\n },\n easeOutQuad: function (x) {\n return 1 - (1 - x) * (1 - x);\n },\n easeInOutQuad: function (x) {\n return x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2;\n },\n easeInCubic: function (x) {\n return x * x * x;\n },\n easeOutCubic: function (x) {\n return 1 - pow(1 - x, 3);\n },\n easeInOutCubic: function (x) {\n return x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2;\n },\n easeInQuart: function (x) {\n return x * x * x * x;\n },\n easeOutQuart: function (x) {\n return 1 - pow(1 - x, 4);\n },\n easeInOutQuart: function (x) {\n return x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2;\n },\n easeInQuint: function (x) {\n return x * x * x * x * x;\n },\n easeOutQuint: function (x) {\n return 1 - pow(1 - x, 5);\n },\n easeInOutQuint: function (x) {\n return x < 0.5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2;\n },\n easeInSine: function (x) {\n return 1 - cos((x * PI) / 2);\n },\n easeOutSine: function (x) {\n return sin((x * PI) / 2);\n },\n easeInOutSine: function (x) {\n return -(cos(PI * x) - 1) / 2;\n },\n easeInExpo: function (x) {\n return x === 0 ? 0 : pow(2, 10 * x - 10);\n },\n easeOutExpo: function (x) {\n return x === 1 ? 1 : 1 - pow(2, -10 * x);\n },\n easeInOutExpo: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? pow(2, 20 * x - 10) / 2 : (2 - pow(2, -20 * x + 10)) / 2;\n },\n easeInCirc: function (x) {\n return 1 - sqrt(1 - pow(x, 2));\n },\n easeOutCirc: function (x) {\n return sqrt(1 - pow(x - 1, 2));\n },\n easeInOutCirc: function (x) {\n return x < 0.5 ? (1 - sqrt(1 - pow(2 * x, 2))) / 2 : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2;\n },\n easeInBack: function (x) {\n return c3 * x * x * x - c1 * x * x;\n },\n easeOutBack: function (x) {\n return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2);\n },\n easeInOutBack: function (x) {\n return x < 0.5\n ? (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2\n : (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;\n },\n easeInElastic: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4);\n },\n easeOutElastic: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1;\n },\n easeInOutElastic: function (x) {\n return x === 0\n ? 0\n : x === 1\n ? 1\n : x < 0.5\n ? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2\n : (pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1;\n },\n easeInBounce: function (x) {\n return 1 - bounceOut(1 - x);\n },\n easeOutBounce: bounceOut,\n easeInOutBounce: function (x) {\n return x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2;\n },\n};\n","import { Runtime } from '../../renderer/runtime';\nimport { Position } from '../../types';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { easingFunctions, EasingFunction } from '../../utility/easing-functions';\n\nexport type PendingTransition = {\n from: Strand;\n to: Strand;\n elapsed_time: number;\n total_time: number;\n timingFunction: EasingFunction;\n done: boolean;\n constrain: boolean;\n callback?: () => void;\n};\n\nexport class TransitionManager {\n runtime: Runtime;\n readonly pendingTransition: PendingTransition;\n\n constructor(runtime: Runtime) {\n this.runtime = runtime;\n this.pendingTransition = {\n from: dna(5),\n to: dna(5),\n elapsed_time: 0,\n done: true,\n total_time: 0,\n timingFunction: easingFunctions.easeInOutQuad,\n constrain: false,\n };\n }\n\n hasPending() {\n return !this.pendingTransition.done;\n }\n\n getPendingTransition() {\n return this.pendingTransition;\n }\n\n getPendingFrom() {\n return this.pendingTransition.from;\n }\n\n customTransition(func: (transition: PendingTransition) => void) {\n func(this.pendingTransition);\n }\n\n stopTransition() {\n this.pendingTransition.from = dna(this.runtime.target);\n this.pendingTransition.to = dna(this.runtime.target);\n this.pendingTransition.done = true;\n this.pendingTransition.elapsed_time = 0;\n this.pendingTransition.total_time = 0;\n }\n\n runTransition(target: Strand, delta: number) {\n if (!this.pendingTransition.done) {\n const transition = this.pendingTransition;\n const td = transition.total_time === 0 ? 0 : (transition.elapsed_time + delta) / transition.total_time;\n const step = transition.total_time === 0 ? 1 : td === 0 ? 0 : transition.timingFunction(td);\n\n // Update our target.\n target[1] = transition.from[1] + (transition.to[1] - transition.from[1]) * step;\n target[2] = transition.from[2] + (transition.to[2] - transition.from[2]) * step;\n target[3] = transition.from[3] + (transition.to[3] - transition.from[3]) * step;\n target[4] = transition.from[4] + (transition.to[4] - transition.from[4]) * step;\n\n // Update our transition.\n this.pendingTransition.elapsed_time += delta;\n if (this.pendingTransition.elapsed_time >= this.pendingTransition.total_time) {\n this.pendingTransition.done = true;\n this.pendingTransition.callback?.();\n\n if (this.pendingTransition.constrain) {\n // @todo make this configurable per transition?\n this.constrainBounds({\n transition: {\n duration: this.pendingTransition.total_time === 0 ? 0 : 500,\n easing: easingFunctions.easeOutExpo,\n },\n });\n }\n }\n }\n }\n\n lastZoomTo: {\n factor: number;\n options: any;\n } | null = null;\n\n resumeTransition() {\n if (this.lastZoomTo) {\n this.zoomTo(this.lastZoomTo.factor, this.lastZoomTo.options);\n }\n if (this.isConstraining) {\n this.constrainBounds();\n }\n if (this.lastGoToRegion) {\n this.goToRegion(this.lastGoToRegion.target, this.lastGoToRegion.options);\n }\n }\n\n zoomTo(\n factor: number,\n options: {\n origin?: Position;\n stream?: boolean;\n minZoomFactor?: number;\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}\n ) {\n const {\n origin,\n stream = false,\n transition,\n } = options;\n\n this.lastZoomTo = { factor, options };\n\n const newPoints = this.runtime.getZoomedPosition(factor, { origin });\n\n const dist = Math.abs(1 - factor);\n\n this.applyTransition(\n newPoints,\n transition,\n {\n duration: 2000 * dist,\n easing: easingFunctions.easeOutExpo,\n constrain: true,\n callback: () => {\n this.lastZoomTo = null;\n }\n },\n { stream: false }\n );\n }\n\n isConstraining = false;\n\n constrainBounds({\n transition,\n panPadding = 0,\n }: {\n panPadding?: number;\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}) {\n this.isConstraining = true;\n const [isConstrained, constrained] = this.runtime.constrainBounds(this.runtime.target, { panPadding });\n\n if (isConstrained) {\n this.applyTransition(constrained, transition, {\n duration: 500,\n easing: easingFunctions.easeOutQuart,\n constrain: false,\n callback: () => {\n this.isConstraining = false;\n }\n });\n this.runtime.updateNextFrame();\n }\n }\n\n applyTransition(\n target: Strand,\n transition?: { duration?: number; easing?: EasingFunction; constrain?: boolean },\n defaults?: {\n duration: number;\n easing: EasingFunction;\n constrain?: boolean;\n callback?: () => void;\n },\n {\n stream,\n }: {\n stream?: boolean;\n } = {}\n ) {\n this.pendingTransition.from = dna(this.runtime.target);\n this.pendingTransition.to = target;\n if (!stream) {\n this.pendingTransition.elapsed_time = 0;\n }\n this.pendingTransition.done = false;\n this.pendingTransition.total_time =\n typeof transition?.duration !== 'undefined'\n ? transition.duration\n : typeof defaults?.duration !== 'undefined'\n ? defaults.duration\n : 1000;\n this.pendingTransition.constrain =\n typeof transition?.constrain !== 'undefined'\n ? transition.constrain\n : typeof defaults?.constrain !== 'undefined'\n ? defaults.constrain\n : false;\n this.pendingTransition.timingFunction = transition?.easing || defaults?.easing || easingFunctions.easeInOutSine;\n }\n\n lastGoToRegion: null | { target: any; options: any } = null;\n\n goToRegion(\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n padding?: number;\n },\n {\n transition,\n }: {\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}\n ) {\n this.lastGoToRegion = { target, options: { transition } };\n const clampedRegion = this.runtime.clampRegion(target);\n this.applyTransition(\n DnaFactory.singleBox(clampedRegion.width, clampedRegion.height, clampedRegion.x, clampedRegion.y),\n transition,\n {\n duration: 1000,\n easing: easingFunctions.easeOutExpo,\n constrain: true,\n callback: () => {\n this.lastGoToRegion = null;\n }\n }\n );\n this.runtime.updateNextFrame();\n }\n}\n","import { Projection, RuntimeController, Viewer } from '../types';\nimport { World } from '../world';\nimport {\n DnaFactory,\n mutate,\n scale,\n scaleAtOrigin,\n transform,\n Strand,\n dna,\n translate,\n compose,\n} from '@atlas-viewer/dna';\nimport { Renderer } from './renderer';\nimport { Paint } from '../world-objects/paint';\nimport { TransitionManager } from '../modules/transition-manager/transition-manager';\nimport { nanoid } from 'nanoid';\n\nexport type RuntimeHooks = {\n useFrame: Array<(time: number) => void>;\n useBeforeFrame: Array<(time: number) => void>;\n useAfterFrame: Array<(time: number) => void>;\n useAfterPaint: Array<(paint: Paint) => void>;\n};\n\ntype UnwrapHook<T> = T extends Array<infer R> ? R : never;\ntype UnwrapHookArg<T> = T extends Array<(arg: infer R) => any> ? R : never;\n\nexport type ViewerMode = 'static' | 'explore' | 'sketch';\nconst MIN = Number.MIN_VALUE + 1;\n\nexport type ViewerFilters = {\n grayscale: number;\n contrast: number;\n brightness: number;\n saturate: number;\n hueRotate: number;\n sepia: number;\n invert: number;\n blur: number;\n};\n\nexport type HookOptions = {\n enableFilters?: boolean;\n filters: ViewerFilters;\n};\n\nexport type RuntimeOptions = {\n visibilityRatio: number;\n maxOverZoom: number;\n maxUnderZoom: number;\n};\n\nexport class Runtime {\n id = nanoid();\n ready = false;\n // Helper getters.\n get x(): number {\n return this.target[1];\n }\n\n set x(x: number) {\n this.target[1] = x;\n }\n\n get y(): number {\n return this.target[2];\n }\n\n set y(y: number) {\n this.target[2] = y;\n }\n\n get x2(): number {\n return this.target[3];\n }\n\n set x2(x2: number) {\n this.target[3] = x2;\n }\n\n get y2(): number {\n return this.target[4];\n }\n\n set y2(y2: number) {\n this.target[4] = y2;\n }\n\n get width(): number {\n return this.target[3] - this.target[1];\n }\n\n set width(width: number) {\n this.target[3] = this.target[1] + width;\n }\n\n get height(): number {\n return this.target[4] - this.target[2];\n }\n\n set height(height: number) {\n this.target[4] = this.target[2] = height;\n }\n\n renderer: Renderer;\n world: World;\n target: Strand;\n homePosition: Strand;\n manualHomePosition: boolean;\n manualFocalPosition: boolean;\n focalPosition: Strand;\n // Home padding in CSS pixels to apply when goHome() is used if no padding supplied.\n // Can be a symmetric number or a per-side object { left?, right?, top?, bottom? } (CSS pixels).\n homePaddingPx: number | { left?: number; right?: number; top?: number; bottom?: number } | undefined;\n transitionManager: TransitionManager;\n aggregate: Strand;\n transformBuffer = dna(500);\n lastTarget = dna(5);\n zoomBuffer = dna(5);\n logNextRender = false;\n pendingUpdate = true;\n isCommitting = false;\n firstRender = true;\n lastTime: number;\n stopId?: number;\n mode: ViewerMode = 'explore';\n controllers: RuntimeController[] = [];\n controllersRunning = false;\n controllerStopFunctions: Array<() => void> = [];\n maxScaleFactor = 1;\n _viewerToWorld = { x: 0, y: 0 };\n _lastGoodScale = 1;\n // Track actual canvas dimensions (in CSS pixels) to avoid using target dimensions\n _canvasWidth = 0;\n _canvasHeight = 0;\n hooks: RuntimeHooks = {\n useFrame: [],\n useBeforeFrame: [],\n useAfterPaint: [],\n useAfterFrame: [],\n };\n fpsLimit: number | undefined;\n options: RuntimeOptions;\n hookOptions: HookOptions = {\n filters: {\n grayscale: 0,\n contrast: 0,\n brightness: 0,\n saturate: 0,\n sepia: 0,\n invert: 0,\n hueRotate: 0,\n blur: 0,\n },\n };\n\n constructor(\n renderer: Renderer,\n world: World,\n target: Viewer,\n controllers: RuntimeController[] = [],\n options?: Partial<RuntimeOptions>\n ) {\n this.renderer = renderer;\n this.world = world;\n this.options = {\n maxOverZoom: 1,\n maxUnderZoom: 1,\n visibilityRatio: 1.5,\n ...(options || {}),\n };\n this.target = DnaFactory.projection(target);\n this.manualHomePosition = false;\n this.pendingUpdate = true;\n this.homePosition = DnaFactory.projection(this.world);\n this.manualFocalPosition = false;\n this.focalPosition = this.target; // Follow target by default.\n this.updateFocalPosition();\n this.transitionManager = new TransitionManager(this);\n this.aggregate = scale(1);\n this.world.addLayoutSubscriber((type: string) => {\n if (type === 'repaint') {\n this.pendingUpdate = true;\n }\n if (type === 'recalculate-world-size') {\n if (!this.manualHomePosition) {\n this.setHomePosition();\n this.goHome();\n } else {\n // recalculate world size?\n }\n this.updateFocalPosition();\n }\n });\n this.lastTime = performance.now();\n this.controllers = controllers;\n this.render(this.lastTime);\n this.startControllers();\n\n // default home padding in CSS pixels\n this.homePaddingPx = undefined;\n // Initialize canvas dimensions (will be updated by triggerResize)\n const initialPos = this.getRendererScreenPosition();\n this._canvasWidth = initialPos?.width || 0;\n this._canvasHeight = initialPos?.height || 0;\n }\n\n setHomePosition(position?: Projection) {\n this.homePosition.set(DnaFactory.projection(position ? position : this.world));\n this.pendingUpdate = true;\n }\n\n /**\n * Set the default home padding in CSS pixels. When `goHome()` is invoked without a paddingPx\n * this value will be used and converted to world units internally.\n */\n setHomePaddingPx(px?: number | { left?: number; right?: number; top?: number; bottom?: number }) {\n if (typeof px === 'undefined' || px === null) {\n this.homePaddingPx = undefined;\n } else {\n this.homePaddingPx = px;\n }\n this.pendingUpdate = true;\n }\n\n /**\n * Get the current default home padding in CSS pixels (as set via `setHomePaddingPx`).\n */\n getHomePaddingPx(): number | { left?: number; right?: number; top?: number; bottom?: number } | undefined {\n return this.homePaddingPx;\n }\n\n startControllers() {\n if (this.controllersRunning) {\n return;\n }\n for (const controller of this.controllers) {\n this.controllerStopFunctions.push(controller.start(this));\n }\n this.controllersRunning = true;\n }\n\n stopControllers() {\n if (!this.controllersRunning) {\n return;\n }\n for (const controller of this.controllerStopFunctions) {\n controller();\n }\n this.controllersRunning = false;\n this.controllerStopFunctions = [];\n }\n\n updateControllerPosition() {\n for (const controller of this.controllers) {\n controller.updatePosition(this.x, this.y, this.width, this.height);\n }\n }\n\n triggerResize() {\n if (this.renderer.triggerResize) {\n this.renderer.triggerResize();\n }\n // Update cached canvas dimensions when resize is triggered\n const pos = this.getRendererScreenPosition();\n if (pos) {\n this._canvasWidth = pos.width;\n this._canvasHeight = pos.height;\n }\n this.pendingUpdate = true;\n }\n\n addController(controller: RuntimeController) {\n this.controllers.push(controller);\n if (this.controllersRunning) {\n controller.start(this);\n }\n this.pendingUpdate = true;\n }\n\n cover() {\n return this.goHome({ cover: true });\n }\n\n getRendererScreenPosition() {\n return this.renderer.getRendererScreenPosition();\n }\n\n updateRendererScreenPosition() {\n this.pendingUpdate = true;\n this.renderer.resize();\n }\n\n setOptions(options: Partial<RuntimeOptions>) {\n this.options = { ...this.options, ...options };\n }\n\n getHomeTarget(options: {\n cover?: boolean;\n position?: Strand;\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n } = {}) {\n const rendererPosition = this.getRendererScreenPosition();\n const canvasWidth = rendererPosition?.width || this._canvasWidth || this.width;\n const canvasHeight = rendererPosition?.height || this._canvasHeight || this.height;\n\n if (rendererPosition) {\n this._canvasWidth = rendererPosition.width;\n this._canvasHeight = rendererPosition.height;\n }\n\n const paddingPx = typeof options.paddingPx !== 'undefined' ? options.paddingPx : this.homePaddingPx;\n const padding = {\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n } as { left: number; right: number; top: number; bottom: number };\n\n if (typeof paddingPx === 'number') {\n padding.left = padding.right = padding.top = padding.bottom = paddingPx;\n } else if (paddingPx) {\n padding.left = paddingPx.left || 0;\n padding.right = paddingPx.right || 0;\n padding.top = paddingPx.top || 0;\n padding.bottom = paddingPx.bottom || 0;\n }\n\n const availableWidth = Math.max(1, canvasWidth - padding.left - padding.right);\n const availableHeight = Math.max(1, canvasHeight - padding.top - padding.bottom);\n const viewAspect = availableWidth / availableHeight;\n\n const target = options.position\n ? {\n x: options.position[1],\n y: options.position[2],\n width: options.position[3] - options.position[1],\n height: options.position[4] - options.position[2],\n }\n : {\n x: this.homePosition[1],\n y: this.homePosition[2],\n width: this.homePosition[3] - this.homePosition[1],\n height: this.homePosition[4] - this.homePosition[2],\n };\n\n const targetAspect = target.width / target.height;\n const useWidth = options.cover ? targetAspect < viewAspect : targetAspect > viewAspect;\n\n let viewWidth = target.width;\n let viewHeight = target.height;\n let viewX = target.x;\n let viewY = target.y;\n\n if (useWidth) {\n viewWidth = target.width;\n viewHeight = target.width / viewAspect;\n viewX = target.x;\n viewY = target.y - (viewHeight - target.height) / 2;\n } else {\n viewHeight = target.height;\n viewWidth = target.height * viewAspect;\n viewX = target.x - (viewWidth - target.width) / 2;\n viewY = target.y;\n }\n\n const worldPerPixel = viewWidth / availableWidth;\n const padLeft = padding.left * worldPerPixel;\n const padRight = padding.right * worldPerPixel;\n const padTop = padding.top * worldPerPixel;\n const padBottom = padding.bottom * worldPerPixel;\n\n return {\n x: viewX - padLeft,\n y: viewY - padTop,\n width: viewWidth + padLeft + padRight,\n height: viewHeight + padTop + padBottom,\n };\n }\n\n getHomeTargetStrand(options: {\n cover?: boolean;\n position?: Strand;\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n } = {}) {\n const target = this.getHomeTarget(options);\n return DnaFactory.singleBox(target.width, target.height, target.x, target.y);\n }\n\n goHome(options: { cover?: boolean; position?: Strand; paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number } } = {}) {\n if (this.world.width <= 0 || this.world.height <= 0) return;\n\n const target = this.getHomeTarget(options);\n this.target[1] = Math.round(target.x);\n this.target[2] = Math.round(target.y);\n this.target[3] = Math.round(target.x + target.width);\n this.target[4] = Math.round(target.y + target.height);\n\n const paddingPx = typeof options.paddingPx !== 'undefined' ? options.paddingPx : this.homePaddingPx;\n const constrainOptions = paddingPx ? { ref: true, homePaddingPx: paddingPx } : { ref: true };\n this.constrainBounds(this.target, constrainOptions);\n\n this.updateControllerPosition();\n }\n\n /**\n * Resize world\n *\n * This is generally called when the world is re-sized. This recalculates the current target accordingly. It needs to\n * be improved, tested and planned.\n *\n * @param fromWidth\n * @param toWidth\n * @param fromHeight\n * @param toHeight\n */\n resize(fromWidth: number, toWidth: number, fromHeight: number, toHeight: number) {\n // Step 1. Do we need to calculate a new focal point?\n\n if (this.transitionManager.hasPending()) {\n this.transitionManager.stopTransition();\n }\n\n // @todo figure out if there is some focal point that we can trim, given the resize request.\n // for example if it expand beyond the world, we can crop the focal point.\n this.updateFocalPosition(fromWidth - toWidth, fromHeight - toHeight);\n\n const widthRatio = toWidth / fromWidth;\n const heightRatio = toHeight / fromHeight;\n\n this.target[3] = this.target[1] + (this.target[3] - this.target[1]) * widthRatio;\n this.target[4] = this.target[2] + (this.target[4] - this.target[2]) * heightRatio;\n\n // console.log('resize -> ', toBox(this.target), toBox(this.focalPosition));\n // 1st bad case\n // 1302 738 500 500\n // {x: 0, y: -352.8966979980469, width: 580.4239501953125, height: 1729.7934265136719}\n // {x: 0, y: 0.0000152587890625, width: 1024, height: 1023.9999847412109}\n // 2nd bad case\n // 738 295.9891062144095 500 500\n // {x: 0, y: 0, width: 295.9891052246094, height: 500}\n // {x: 119, y: 0, width: 500, height: 500}\n\n this.goHome({ position: this.focalPosition });\n this.renderer.resize(toWidth, toHeight);\n this.pendingUpdate = true;\n\n this.transitionManager.resumeTransition();\n }\n\n updateFocalPosition(widthDiff?: number, heightDiff?: number) {\n if (!this.manualFocalPosition) {\n const w = this.width;\n const h = this.height;\n const min = Math.min(w, h);\n\n const marginTrimWidth = 0;\n const marginTrimHeight = 0;\n\n // console.log(widthDiff, heightDiff);\n // @todo An way to trim margins - breaks reversible resizing.\n // if (\n // (widthDiff || widthDiff === 0) &&\n // this.x + this.width > this.world.width &&\n // (heightDiff || heightDiff === 0) &&\n // this.y + this.height > this.world.height\n // ) {\n // // const maxMarginW = this.width - this.world.width;\n // // marginTrimWidth = (maxMarginW < widthDiff ? maxMarginW : widthDiff) * 2;\n // // const maxMarginH = this.height - this.world.height;\n // // marginTrimHeight = maxMarginH < heightDiff ? maxMarginH : heightDiff;\n // // console.log('A');\n // }\n\n const baseX = this.x + marginTrimWidth;\n const baseY = this.y + marginTrimHeight;\n\n if (w < h) {\n const diff = this.height - this.width;\n // []\n this.focalPosition = DnaFactory.projection({\n x: baseX,\n y: baseY + diff / 2,\n width: min - marginTrimWidth * 2,\n height: min - marginTrimHeight * 2,\n });\n this.pendingUpdate = true;\n } else {\n const diff = this.width - this.height;\n // [ ]\n this.focalPosition = DnaFactory.projection({\n x: baseX + diff / 2,\n y: baseY,\n width: min - marginTrimWidth * 2,\n height: min - marginTrimHeight * 2,\n });\n this.pendingUpdate = true;\n }\n }\n }\n\n _viewport = { x: 0, y: 0, width: 0, height: 0 };\n\n /**\n * Get Viewport\n *\n * Returns a projection based on the current target.\n *\n * @todo rename to getProjection.\n * @todo evaluate if we actually need this.\n */\n getViewport(): Projection {\n this._viewport.x = this.target[1];\n this._viewport.y = this.target[2];\n this._viewport.width = this.target[3] - this.target[1];\n this._viewport.height = this.target[4] - this.target[2];\n return this._viewport;\n }\n\n /**\n * Set Viewport\n *\n * This is a helper for setting the viewport based on x, y, width and height, opposed to the x1, y1, x2, y2 native\n * co-ordinates of the target.\n *\n * @param data\n */\n setViewport = (data: { x?: number; y?: number; width?: number; height?: number }) => {\n const x = Math.round(typeof data.x === 'undefined' ? this.target[1] : data.x);\n const y = Math.round(typeof data.y === 'undefined' ? this.target[2] : data.y);\n\n if (data.width) {\n this.target[3] = x + data.width;\n } else {\n this.target[3] = this.target[3] - this.target[1] + x;\n }\n if (data.height) {\n this.target[4] = y + data.height;\n } else {\n this.target[4] = this.target[4] - this.target[2] + y;\n }\n\n if (Math.abs(this.target[1] - x) > 0.01) {\n this.target[1] = x;\n }\n if (Math.abs(this.target[2] - y) > 0.01) {\n this.target[2] = y;\n }\n\n this.pendingUpdate = true;\n };\n\n constrainBounds(\n target: Strand,\n {\n panPadding = 0,\n ref = false,\n homePaddingPx,\n }: {\n ref?: boolean;\n panPadding?: number;\n homePaddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n } = {}\n ) {\n const { minX, maxX, minY, maxY } = this.getBounds({ target, padding: panPadding, homePaddingPx });\n\n let isConstrained = false;\n const constrained = ref ? target : dna(target);\n const width = Math.round(target[3] - target[1]);\n const height = Math.round(target[4] - target[2]);\n\n if (minX > target[1]) {\n isConstrained = true;\n constrained[1] = minX;\n constrained[3] = minX + width;\n }\n if (minY > target[2]) {\n isConstrained = true;\n constrained[2] = minY;\n constrained[4] = minY + height;\n }\n if (maxX < target[1]) {\n isConstrained = true;\n constrained[1] = maxX;\n constrained[3] = maxX + width;\n }\n if (maxY < target[2]) {\n isConstrained = true;\n constrained[2] = maxY;\n constrained[4] = maxY + height;\n }\n\n return [isConstrained, constrained] as const;\n }\n\n /**\n * Get bounds\n *\n * Returns the minimum and maximum bounds. This absolutely needs improved. With the addition of zones this is becoming\n * more of an issue. It has to take into account the current layout. There also needs to be a new method for creating\n * a \"home\" view that will fit the content to the view.\n */\n getBounds(options: {\n padding: number;\n target?: Strand;\n homePaddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n }) {\n const target = options.target || this.target;\n const padding = options.padding;\n const visRatio = this.options.visibilityRatio;\n const hiddenRatio = Math.abs(1 - visRatio);\n\n // If homePaddingPx is provided, we need to account for it when calculating bounds.\n // The padding reduces the effective viewport size, so we need to allow a larger target.\n let effectivePaddingLeft = 0;\n let effectivePaddingRight = 0;\n let effectivePaddingTop = 0;\n let effectivePaddingBottom = 0;\n\n if (options.homePaddingPx) {\n const cssScale = this.getScaleFactor(false);\n if (typeof options.homePaddingPx === 'number') {\n const p = options.homePaddingPx / cssScale;\n effectivePaddingLeft = effectivePaddingRight = effectivePaddingTop = effectivePaddingBottom = p;\n } else {\n effectivePaddingLeft = options.homePaddingPx.left ? options.homePaddingPx.left / cssScale : 0;\n effectivePaddingRight = options.homePaddingPx.right ? options.homePaddingPx.right / cssScale : 0;\n effectivePaddingTop = options.homePaddingPx.top ? options.homePaddingPx.top / cssScale : 0;\n effectivePaddingBottom = options.homePaddingPx.bottom ? options.homePaddingPx.bottom / cssScale : 0;\n }\n }\n\n if (this.world.hasActiveZone()) {\n const zone = this.world.getActiveZone();\n\n if (zone) {\n const xCon = target[3] - target[1] < zone.points[3] - zone.points[1];\n const yCon = target[4] - target[2] < zone.points[4] - zone.points[2];\n return {\n minX: xCon\n ? zone.points[1] - padding\n : zone.points[1] + (zone.points[3] - zone.points[1]) / 2 - (target[3] - target[1]) / 2,\n maxX: yCon\n ? zone.points[2] - padding\n : zone.points[2] + (zone.points[4] - zone.points[2]) / 2 - (target[4] - target[2]) / 2,\n minY: xCon\n ? zone.points[3] + padding\n : zone.points[1] + (zone.points[3] - zone.points[1]) / 2 - (target[3] - target[1]) / 2,\n maxY: yCon\n ? zone.points[4] + padding\n : zone.points[2] + (zone.points[4] - zone.points[2]) / 2 - (target[4] - target[2]) / 2,\n };\n }\n }\n\n const wt = target[3] - target[1];\n const ww = this.world.width;\n\n // When we have home padding, the effective world dimensions that need to fit in the viewport\n // are reduced by the padding amount. This allows the viewport to be larger to compensate.\n const effectiveWorldWidth = ww + effectivePaddingLeft + effectivePaddingRight;\n\n // const addConstraintPaddingX = ww / visRatio < wt;\n\n // Add constrain padding = false (zoomed in)\n const xB = -wt * hiddenRatio - effectivePaddingLeft;\n const xD = effectiveWorldWidth - wt - xB;\n\n // ADd constrain padding = true (zoomed out)\n // const xA = ww * visRatio - wt;\n // const xC = ww * visRatio;\n // const xA = -500 / this.getScaleFactor(true);\n // const xC = -200 / this.getScaleFactor(true);\n // const xC = Math.min(-((wt - ww) / 2), ww * hiddenRatio);\n // const xA = Math.max(xC, ww - wt);\n\n // const minX = addConstraintPaddingX ? xA : xB;\n // const maxX = addConstraintPaddingX ? xC : xD;\n\n const ht = target[4] - target[2];\n const hw = this.world.height;\n\n // When we have home padding, the effective world dimensions that need to fit in the viewport\n // are reduced by the padding amount. This allows the viewport to be larger to compensate.\n const effectiveWorldHeight = hw + effectivePaddingTop + effectivePaddingBottom;\n\n // Add constrain padding = false (zoomed in)\n const yB = -ht * hiddenRatio - effectivePaddingTop;\n const yD = effectiveWorldHeight - ht - yB;\n\n // Add constrain padding = true (zoomed out)\n // const yA = hw * visRatio - ht;\n // const yC = hw * visRatio;\n // const yC = Math.min(-((ht - hw) / 2), hw * hiddenRatio);\n // const yA = Math.max(yC, hw * hiddenRatio - ht);\n //\n // const addConstraintPaddingY = hw / visRatio < ht;\n\n // const minY = addConstraintPaddingY ? yA : yB;\n // const maxY = addConstraintPaddingY ? yC : yD;\n\n const maxX = Math.round(Math.max(xB, xD));\n const minX = Math.round(Math.min(xB, xD));\n const maxY = Math.round(Math.max(yB, yD));\n const minY = Math.round(Math.min(yB, yD));\n\n return { minX, maxX, minY, maxY } as const;\n }\n\n getScaleFactor(dpi = false) {\n const scale = this.renderer.getScale(this.target[3] - this.target[1], this.target[4] - this.target[2], dpi);\n if (scale === 0) {\n return this._lastGoodScale;\n }\n this._lastGoodScale = scale;\n return scale;\n }\n\n /**\n * Zoom\n */\n getZoomedPosition(\n factor: number,\n {\n origin,\n fromPos: _fromPos,\n }: {\n origin?: { x: number; y: number };\n fromPos?: Strand;\n }\n ) {\n const fromPos = _fromPos ? { width: _fromPos[3] - _fromPos[1], height: _fromPos[4] - _fromPos[2] } : undefined;\n // Fresh scale factor.\n const scaleFactor = fromPos ? this.renderer.getScale(fromPos.width, fromPos.height) : this.getScaleFactor();\n const w = fromPos ? fromPos.width : this.width;\n const h = fromPos ? fromPos.height : this.height;\n\n const sWidth = this.getRendererScreenPosition()?.width;\n const wWidth = this.world.width;\n const ratio = sWidth ? sWidth / wWidth : 1;\n\n const maxUnderZoom = this.options.maxUnderZoom;\n const maxOverZoom = Math.max(ratio || 1, this.options.maxOverZoom);\n\n const realFactor = 1 / factor;\n const proposedFactor = scaleFactor * realFactor;\n const isZoomingOut = realFactor < 1;\n\n if (isZoomingOut) {\n const width = w * scaleFactor;\n const height = h * scaleFactor;\n\n const widthScale = this.world.width / width;\n const heightScale = this.world.height / height;\n\n if (widthScale > heightScale) {\n // Constrain width\n // If the proposed world display height.\n const proposedWorldDisplayWidth = this.world.width * proposedFactor;\n // Is greater than the display width.\n const displayWidth = ~~(w * scaleFactor);\n const displayWidthAdjusted = displayWidth * maxUnderZoom;\n\n if (proposedWorldDisplayWidth < displayWidthAdjusted) {\n factor = (this.world.width * scaleFactor) / (w * scaleFactor * maxUnderZoom);\n }\n } else {\n // Constrain height.\n // If the proposed world display height.\n const proposedWorldDisplayHeight = this.world.height * proposedFactor;\n // Is greater than the display height.\n const displayHeight = ~~(h * scaleFactor);\n const displayHeightAdjusted = displayHeight * maxUnderZoom;\n\n if (proposedWorldDisplayHeight < displayHeightAdjusted) {\n factor = (this.world.height * scaleFactor) / (h * scaleFactor * maxUnderZoom);\n }\n }\n } else {\n // Zooming in.\n if (proposedFactor > maxOverZoom) {\n factor = scaleFactor / maxOverZoom;\n }\n }\n\n // set the new scale.\n const proposedStrand = transform(\n this.target,\n scaleAtOrigin(\n factor,\n origin ? origin.x : this.target[1] + (this.target[3] - this.target[1]) / 2,\n origin ? origin.y : this.target[2] + (this.target[4] - this.target[2]) / 2\n ),\n this.zoomBuffer\n );\n\n this.constrainBounds(proposedStrand, { ref: true, panPadding: 100 });\n\n return proposedStrand;\n }\n\n clampRegion({\n x,\n y,\n width,\n height,\n padding = 0,\n }: {\n x: number;\n y: number;\n width: number;\n height: number;\n padding?: number;\n }) {\n const w = this.width;\n const h = this.height;\n const matchesHeight = width / w < height / h;\n\n const rx = x - padding;\n const ry = y - padding;\n const rWidth = width + padding * 2;\n const rHeight = height + padding * 2;\n\n if (matchesHeight) {\n // pad on the left and right.\n const actualWidth = (rHeight / h) * w;\n return {\n x: rx - (actualWidth - rWidth) / 2,\n y: ry,\n width: actualWidth,\n height: rHeight,\n };\n }\n // pad on the top and bottom.\n const actualHeight = (rWidth / w) * h;\n return {\n x: rx,\n y: ry - (actualHeight - rHeight) / 2,\n width: rWidth,\n height: actualHeight,\n };\n }\n\n /**\n * Converts units from the viewer to the world.\n *\n * Needs to be tested, as this will become more important with the event system.\n *\n * @param x\n * @param y\n */\n viewerToWorld(x: number, y: number) {\n const scaleFactor = this.getScaleFactor();\n this._viewerToWorld.x = this.target[1] + x / scaleFactor;\n this._viewerToWorld.y = this.target[2] + y / scaleFactor;\n return this._viewerToWorld;\n }\n\n /**\n * Converts units from the viewer to the world.\n *\n * Needs to be tested, as this will become more important with the event system.\n *\n * @param x\n * @param y\n * @param width\n * @param height\n */\n worldToViewer(x: number, y: number, width: number, height: number) {\n const strand = DnaFactory.singleBox(width, height, x, y);\n\n mutate(strand, compose(scale(this.getScaleFactor()), translate(-this.target[1], -this.target[2])));\n\n return {\n // visible: visible[0] !== 0,\n x: strand[1],\n y: strand[2],\n width: strand[3] - strand[1],\n height: strand[4] - strand[2],\n strand,\n };\n }\n\n /**\n * Set scale\n *\n * This will set the scale of the target, with an optional origin.\n *\n * @param scaleFactor\n * @param origin\n */\n setScale(scaleFactor: number, origin?: { x: number; y: number }) {\n mutate(\n this.target,\n scaleAtOrigin(\n scaleFactor,\n origin ? origin.x : this.target[1] + (this.target[3] - this.target[1]) / 2,\n origin ? origin.y : this.target[2] + (this.target[4] - this.target[2]) / 2\n )\n );\n this.pendingUpdate = true;\n }\n\n /**\n * Sync runtime instances\n *\n * Allows a single controller to drive 2 runtime instances, or 2 controllers to both\n * control each other.\n *\n * @param runtime\n */\n syncTo(runtime: Runtime) {\n const oldTarget = this.target;\n this.target = runtime.target;\n this.pendingUpdate = true;\n\n // Return an unsubscribe.\n return () => {\n this.target = oldTarget;\n };\n }\n\n /**\n * Stop the runtime\n *\n * Stops the internal clock, where no more updates will occur. Returns a function to restart it.\n */\n stop(): () => void {\n if (typeof this.stopId !== 'undefined') {\n window.cancelAnimationFrame(this.stopId);\n this.stopId = undefined;\n }\n\n return () => {\n this.render(performance.now());\n };\n }\n\n reset() {\n this.renderer.reset();\n }\n\n selectZone(zone: number | string) {\n this.world.selectZone(zone);\n this.pendingUpdate = true;\n }\n\n deselectZone() {\n this.world.deselectZone();\n this.pendingUpdate = true;\n }\n\n hook<Name extends keyof RuntimeHooks, Arg = UnwrapHookArg<Name>>(name: keyof RuntimeHooks, arg: Arg) {\n const len = this.hooks[name].length;\n if (len !== 0) {\n for (let x = 0; x < len; x++) {\n this.hooks[name][x](arg as any);\n }\n }\n }\n\n registerHook<Name extends keyof RuntimeHooks, Hook = UnwrapHook<Name>>(name: Name, hook: Hook) {\n this.hooks[name].push(hook as any);\n return () => {\n this.hooks[name] = (this.hooks[name] as any[]).filter((e) => e !== (hook as any));\n };\n }\n\n /**\n * Render\n *\n * The hottest path in the runtime, called every 16.7ms, if possible in the future be double-timed on 120hz monitors.\n *\n * @ param t\n */\n render = (t: number) => {\n const delta = t - this.lastTime;\n\n if (this.isCommitting || (this.fpsLimit && delta < 1000 / this.fpsLimit)) {\n this.stopId = window.requestAnimationFrame(this.render);\n return;\n }\n\n this.lastTime = t;\n // First flush\n this.world.flushSubscriptions();\n // Set up our loop.\n this.stopId = window.requestAnimationFrame(this.render);\n\n // Called every frame.\n this.hook('useFrame', delta);\n\n const pendingUpdate = this.pendingUpdate;\n const rendererPendingUpdate = this.renderer.pendingUpdate();\n\n if (this.transitionManager.hasPending()) {\n this.transitionManager.runTransition(this.target, delta);\n\n this.pendingUpdate = true;\n this.updateControllerPosition();\n }\n\n if (\n !this.firstRender &&\n !pendingUpdate &&\n // Check if there was a pending update from the renderer.\n !rendererPendingUpdate &&\n // Then check the points, the first will catch invalidation.\n this.target[0] === this.lastTarget[0] &&\n // The following are x1, y1, x2, y2 points of the target.\n this.target[1] === this.lastTarget[1] &&\n this.target[2] === this.lastTarget[2] &&\n this.target[3] === this.lastTarget[3] &&\n this.target[4] === this.lastTarget[4]\n ) {\n // Nothing to do, target didn't change since last time.\n return;\n }\n\n // Group.\n // console.groupCollapsed(`Previous frame took ${delta} ${delta > 17 ? '<-' : ''} ${delta > 40 ? '<--' : ''}`);\n\n this.hook('useBeforeFrame', delta);\n // Before everything kicks off, add a hook.\n this.renderer.beforeFrame(this.world, delta, this.target, this.hookOptions);\n // Calculate a scale factor by passing in the height and width of the target.\n const scaleFactor = this.getScaleFactor();\n // Get the points to render based on this scale factor and the current x,y,w,h in the target buffer.\n const points = this.renderer.getPointsAt(this.world, this.target, this.aggregate, scaleFactor);\n const pointsLen = points.length;\n for (let p = 0; p < pointsLen; p++) {\n // each point is an array of [SpacialContent, Strand, Strand]\n // The first is used to get real rendering data, like Image URLs etc.\n // The second is the points themselves for the layer. If this is a single\n // image this will be a single set of 5 points, for tiled images, it will be\n // the correct list of tiles, and a much longer list of points.\n const paint = points[p][0];\n const point = points[p][1];\n const transformation = points[p][2];\n\n // This is the position of the points. We apply the transform that came with the points.\n // The points before the transformation are just points relative to their parent (canvas?)\n // When we apply the transform, they become relative to the viewer. Both of these point\n // values are useful, but for rendering, we want the viewer-points.\n // @todo add option in renderer to omit this transform, instead passing it as a param.\n const position = transformation ? transform(point, transformation, this.transformBuffer) : point;\n // Another hook before painting a layer.\n this.renderer.prepareLayer(\n paint,\n paint.__parent && transformation\n ? transform(paint.__parent.crop || paint.__parent.points, transformation)\n : position\n );\n // For loop helps keep this fast, looping through all of the tiles that make up an image.\n // This could be a single point, where len is one.\n const totalTiles = position.length / 5;\n for (let i = 0; i < totalTiles; i++) {\n const key = i * 5;\n // First key position tells us if we should render or not. A 0 will usually\n // indicate that the image is off-screen.\n if (position[key] === 0) {\n continue;\n }\n\n // This is the most expensive call by a long shot, the client implementation.\n // In the reference Canvas implementation, this will grab the URL of the image,\n // load it into an image tag and then paint it onto the canvas at the viewer points.\n this.renderer.paint(\n paint,\n i,\n position[key + 1],\n position[key + 2],\n position[key + 3] - position[key + 1],\n position[key + 4] - position[key + 2]\n );\n this.hook('useAfterPaint', paint);\n }\n\n this.renderer.finishLayer(paint, point);\n }\n // A final hook after the entire frame is complete.\n this.renderer.afterFrame(this.world, delta, this.target, this.hookOptions);\n this.hook('useAfterFrame', delta);\n // Finally at the end, we set up the frame we just rendered.\n this.lastTarget[0] = this.target[0];\n this.lastTarget[1] = this.target[1];\n this.lastTarget[2] = this.target[2];\n this.lastTarget[3] = this.target[3];\n this.lastTarget[4] = this.target[4];\n // We've just finished our first render.\n this.firstRender = false;\n this.pendingUpdate = false;\n this.logNextRender = false;\n if (this.renderer.isReady()) {\n this.ready = true;\n this.world.trigger('ready');\n }\n // Flush world subscriptions.\n this.world.flushSubscriptions();\n const updates = this.world.getScheduledUpdates(this.target, scaleFactor);\n const len = updates.length;\n if (len > 0) {\n for (let i = 0; i < len; i++) {\n const update = updates[len - i - 1]();\n if (update) {\n update.then(() => {\n this.pendingUpdate = true;\n });\n } else {\n this.pendingUpdate = true;\n }\n }\n }\n };\n\n updateNextFrame() {\n this.pendingUpdate = true;\n }\n}\n","import { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\n\nconst borderRegex = /([0-9]+(px|em)\\s+)+(solid)\\s+(.*)/g;\nconst borderRegexCache: any = {};\n\nexport type GeometryProps = {\n id: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n\n open?: boolean;\n points: [number, number][];\n\n className?: string;\n href?: string;\n title?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n // New style.\n style?: GeometryStyle;\n // Deprecated\n backgroundColor?: string;\n border?: string;\n};\n\nexport type GeometryStyle = _GeometryStyle & {\n ':hover'?: _GeometryStyle;\n ':active'?: _GeometryStyle;\n};\n\ntype _GeometryStyle = Partial<{\n // In order\n backgroundColor: string; // colour or gradient function\n opacity: number;\n boxShadow: string; // to parse, splitting /,(?![^\\(]*\\))/\n borderColor: string;\n borderWidth: string;\n borderStyle: string; // 'solid' only\n outlineColor: string;\n outlineWidth: string;\n outlineOffset: string;\n outlineStyle: string; // 'solid' only\n\n // Parsed.\n border: string;\n outline: string;\n background: string;\n\n // transform: string; // scale() rotate() transform() transformX() transformY() - pixels\n // transformOrigin: string; // using translate(x, y); rotate(); translate(-x, -y);\n // backgroundImage: string; // possibly.\n // backgroundRepeat: string; // repeat | repeat-x | repeat-y | no-repeat\n //borderRadius: string; // maybe? Future?\n}>;\n\nconst styleProps: Array<keyof GeometryStyle> = [\n 'backgroundColor',\n 'opacity',\n 'boxShadow',\n 'borderColor',\n 'borderWidth',\n 'borderStyle',\n 'outlineColor',\n 'outlineWidth',\n 'outlineOffset',\n 'outlineStyle',\n];\n\n// const mapping = [\n// // Common\n// ['opacity', 'globalAlpha'],\n// ['transform', ['translate', 'scale', 'rotate']],\n//\n// // Fill rect\n// [\n// 'backgroundColor',\n// ['fillStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['boxShadow', ['shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor']],\n//\n// // Stroke rect\n// ['outline', 'same-as-below'],\n// [\n// 'borderColor',\n// ['strokeStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['borderWidth', 'strokeWidth'],\n// ['borderStyle', ['setLineDash', 'lineDashOffset']],\n// ];\n\nexport class Geometry extends BaseObject<GeometryProps> implements SpacialContent {\n id: string;\n type: 'spacial-content' = 'spacial-content';\n isShape = true;\n points: Strand;\n hoverEvents = false;\n activeEvents = false;\n\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: -1,\n height: -1,\n points: dna(5),\n };\n\n boundingBox: { x: number; y: number; width: number; height: number } | null = null;\n\n _parsed: { border: { id: string | null; match: string[] }; outline: { id: string | null; match: string[] } } = {\n border: { id: null, match: [] },\n outline: { id: null, match: [] },\n };\n\n hovering?: boolean;\n pressing?: boolean;\n props: {\n href?: string;\n hrefTarget?: string;\n title?: string;\n backgroundColor?: string;\n border?: string;\n interactive?: boolean;\n open?: boolean;\n className?: string;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n style?: GeometryStyle;\n hoverStyles?: GeometryStyle;\n pressStyles?: GeometryStyle;\n } = {};\n\n shape: { type: 'none' } | { type: 'polygon'; points: [number, number][]; open?: boolean } = { type: 'none' };\n\n constructor() {\n super();\n this.id = nanoid(12);\n this.points = dna(5);\n this.shape = { type: 'none' };\n }\n\n updateBoundingBox() {\n if (this.shape.type === 'none') return;\n const points = this.shape.points;\n if (this.shape.points.length > 2) {\n const x1 = Math.min(...points.map((p) => p[0]));\n const y1 = Math.min(...points.map((p) => p[1]));\n const x2 = Math.max(0, ...points.map((p) => p[0]));\n const y2 = Math.max(0, ...points.map((p) => p[1]));\n this.boundingBox = {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n };\n\n return;\n }\n this.boundingBox = null;\n }\n\n intersects(pointer?: [number, number] | null): boolean {\n if (!pointer || this.shape.type === 'none') {\n return false;\n }\n // Does the point intersect with the shape?\n const [x, y] = pointer;\n const points = this.shape.points;\n let box = this.boundingBox;\n\n // @todo only enable when all points are NOT selected.\n\n if (!box) {\n this.updateBoundingBox();\n box = this.boundingBox;\n }\n if (!box) {\n return false;\n }\n\n // Outside the bounding box.\n if (x < box.x || x > box.x + box.width || y < box.y || y > box.height + box.y) {\n return false;\n }\n\n // Outside the polygon.\n let inside = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n if (\n points[i][1] > y != points[j][1] > y &&\n x < ((points[j][0] - points[i][0]) * (y - points[i][1])) / (points[j][1] - points[i][1]) + points[i][0]\n ) {\n inside = !inside;\n }\n }\n\n return inside;\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n if (target[3] - target[1] === 1 && target[4] - target[2] === 1) {\n // Clicked on a single point.\n if (this.intersects([target[1], target[2]])) {\n return [[this as any, this.points, aggregate]];\n }\n return [];\n }\n\n // this.points[0] = 1;\n return [[this as any, this.points, aggregate]];\n }\n\n addHover = () => {\n this.hovering = true;\n this.__revision++;\n };\n\n removeHover = () => {\n this.hovering = false;\n this.pressing = false;\n this.__revision++;\n };\n\n addPress = () => {\n this.pressing = true;\n this.__revision++;\n };\n\n removePress = () => {\n this.pressing = false;\n this.__revision++;\n };\n\n applyProps(props: Partial<GeometryProps> = {}) {\n let didUpdate = false;\n\n if (props.points) {\n if (this.shape.type !== 'polygon' || this.shape.points.length !== props.points.length) {\n this.shape = {\n type: 'polygon',\n points: props.points,\n open: props.open,\n };\n this.updateBoundingBox();\n } else {\n let newPoints = false;\n const len = props.points.length;\n for (let i = 0; i < len; i++) {\n if (props.points[i][0] !== this.shape.points[i][0] || props.points[i][1] !== this.shape.points[i][1]) {\n newPoints = true;\n break;\n }\n }\n if (newPoints) {\n this.shape = {\n type: 'polygon',\n points: props.points,\n open: props.open,\n };\n this.updateBoundingBox();\n }\n }\n }\n\n if (props.interactive !== this.props.interactive) {\n didUpdate = true;\n this.props.interactive = props.interactive;\n }\n\n if (props.open || props.open === false) {\n didUpdate = true;\n (this.shape as any).open = props.open;\n }\n\n if (props.style) {\n // pre-process props.\n const borderStyle = props.border || props.style.border;\n if (borderStyle !== this._parsed.border.id) {\n if (!borderStyle) {\n this._parsed.border.id = null;\n this._parsed.border.match = [];\n } else {\n const match = borderRegexCache[borderStyle] || borderRegex.exec(borderStyle) || borderRegex.exec(borderStyle);\n if (match) {\n this._parsed.border.id = borderStyle;\n this._parsed.border.match = borderRegexCache[borderStyle] = match;\n }\n }\n }\n if (this._parsed.border.id) {\n props.style.borderWidth = this._parsed.border.match[1];\n props.style.borderStyle = 'solid'; // only support this.\n props.style.borderColor = this._parsed.border.match[4];\n }\n\n if (props.style.outline !== this._parsed.outline.id) {\n if (!props.style.outline) {\n this._parsed.outline.id = null;\n this._parsed.outline.match = [];\n } else {\n const match =\n borderRegexCache[props.style.outline] ||\n borderRegex.exec(props.style.outline) ||\n borderRegex.exec(props.style.outline);\n\n if (match) {\n this._parsed.outline.id = props.style.outline;\n this._parsed.outline.match = borderRegexCache[props.style.outline] = match;\n }\n }\n }\n if (this._parsed.outline.id) {\n props.style.outlineWidth = this._parsed.outline.match[1];\n props.style.outlineStyle = 'solid'; // only support this.\n props.style.outlineColor = this._parsed.outline.match[4];\n }\n\n this.props.style = props.style;\n // BC fix.\n if (props.backgroundColor && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.backgroundColor;\n didUpdate = true;\n }\n if (props.style.background && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.style.background;\n didUpdate = true;\n }\n\n for (const prop of styleProps) {\n if (this.props.style[prop] !== props.style[prop]) {\n didUpdate = true;\n break;\n }\n }\n\n if (props.style[':hover'] !== this.props.hoverStyles) {\n this.props.hoverStyles = props.style[':hover'];\n if (!this.hoverEvents) {\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n didUpdate = true;\n }\n if (props.style[':active'] !== this.props.pressStyles) {\n this.props.pressStyles = props.style[':active'];\n if (!this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n }\n\n if (props.href !== this.props.href) {\n this.props.href = props.href;\n didUpdate = true;\n }\n\n if (props.hrefTarget !== this.props.hrefTarget) {\n this.props.hrefTarget = props.hrefTarget;\n didUpdate = true;\n }\n\n if (props.title !== this.props.title) {\n this.props.title = props.title;\n didUpdate = true;\n }\n\n if (props.className !== this.props.className) {\n this.props.className = props.className;\n if (props.className && !this.hoverEvents) {\n // Only if class name.\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n if (props.className && !this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n\n if (props.relativeSize !== this.props.relativeSize) {\n this.props.relativeSize = props.relativeSize;\n didUpdate = true;\n }\n if (props.relativeStyle !== this.props.relativeStyle) {\n this.props.relativeStyle = props.relativeStyle;\n didUpdate = true;\n }\n if (props.html !== this.props.html) {\n this.props.html = props.html;\n didUpdate = true;\n }\n\n if (props.target) {\n if (\n props.target.width !== this.display.width ||\n props.target.height !== this.display.height ||\n props.target.x !== this.points[1] ||\n props.target.y !== this.points[2]\n ) {\n didUpdate = true;\n this.points = DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y);\n this.display.points = DnaFactory.singleBox(\n props.target.width,\n props.target.height,\n props.target.x,\n props.target.y\n );\n this.display.width = props.target.width;\n this.display.height = props.target.height;\n }\n }\n\n if (didUpdate) {\n // Bump revision.\n this.__revision++;\n }\n }\n}\n","const perf =\n typeof performance === 'object' &&\n performance &&\n typeof performance.now === 'function'\n ? performance\n : Date\n\nconst hasAbortController = typeof AbortController === 'function'\n\n// minimal backwards-compatibility polyfill\n// this doesn't have nearly all the checks and whatnot that\n// actual AbortController/Signal has, but it's enough for\n// our purposes, and if used properly, behaves the same.\nconst AC = hasAbortController\n ? AbortController\n : class AbortController {\n constructor() {\n this.signal = new AS()\n }\n abort(reason = new Error('This operation was aborted')) {\n this.signal.reason = this.signal.reason || reason\n this.signal.aborted = true\n this.signal.dispatchEvent({\n type: 'abort',\n target: this.signal,\n })\n }\n }\n\nconst hasAbortSignal = typeof AbortSignal === 'function'\n// Some polyfills put this on the AC class, not global\nconst hasACAbortSignal = typeof AC.AbortSignal === 'function'\nconst AS = hasAbortSignal\n ? AbortSignal\n : hasACAbortSignal\n ? AC.AbortController\n : class AbortSignal {\n constructor() {\n this.reason = undefined\n this.aborted = false\n this._listeners = []\n }\n dispatchEvent(e) {\n if (e.type === 'abort') {\n this.aborted = true\n this.onabort(e)\n this._listeners.forEach(f => f(e), this)\n }\n }\n onabort() {}\n addEventListener(ev, fn) {\n if (ev === 'abort') {\n this._listeners.push(fn)\n }\n }\n removeEventListener(ev, fn) {\n if (ev === 'abort') {\n this._listeners = this._listeners.filter(f => f !== fn)\n }\n }\n }\n\nconst warned = new Set()\nconst deprecatedOption = (opt, instead) => {\n const code = `LRU_CACHE_OPTION_${opt}`\n if (shouldWarn(code)) {\n warn(code, `${opt} option`, `options.${instead}`, LRUCache)\n }\n}\nconst deprecatedMethod = (method, instead) => {\n const code = `LRU_CACHE_METHOD_${method}`\n if (shouldWarn(code)) {\n const { prototype } = LRUCache\n const { get } = Object.getOwnPropertyDescriptor(prototype, method)\n warn(code, `${method} method`, `cache.${instead}()`, get)\n }\n}\nconst deprecatedProperty = (field, instead) => {\n const code = `LRU_CACHE_PROPERTY_${field}`\n if (shouldWarn(code)) {\n const { prototype } = LRUCache\n const { get } = Object.getOwnPropertyDescriptor(prototype, field)\n warn(code, `${field} property`, `cache.${instead}`, get)\n }\n}\n\nconst emitWarning = (...a) => {\n typeof process === 'object' &&\n process &&\n typeof process.emitWarning === 'function'\n ? process.emitWarning(...a)\n : console.error(...a)\n}\n\nconst shouldWarn = code => !warned.has(code)\n\nconst warn = (code, what, instead, fn) => {\n warned.add(code)\n const msg = `The ${what} is deprecated. Please use ${instead} instead.`\n emitWarning(msg, 'DeprecationWarning', code, fn)\n}\n\nconst isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n)\n\n/* istanbul ignore next - This is a little bit ridiculous, tbh.\n * The maximum array length is 2^32-1 or thereabouts on most JS impls.\n * And well before that point, you're caching the entire world, I mean,\n * that's ~32GB of just integers for the next/prev links, plus whatever\n * else to hold that many keys and values. Just filling the memory with\n * zeroes at init time is brutal when you get that big.\n * But why not be complete?\n * Maybe in the future, these limits will have expanded. */\nconst getUintArray = max =>\n !isPosInt(max)\n ? null\n : max <= Math.pow(2, 8)\n ? Uint8Array\n : max <= Math.pow(2, 16)\n ? Uint16Array\n : max <= Math.pow(2, 32)\n ? Uint32Array\n : max <= Number.MAX_SAFE_INTEGER\n ? ZeroArray\n : null\n\nclass ZeroArray extends Array {\n constructor(size) {\n super(size)\n this.fill(0)\n }\n}\n\nclass Stack {\n constructor(max) {\n if (max === 0) {\n return []\n }\n const UintArray = getUintArray(max)\n this.heap = new UintArray(max)\n this.length = 0\n }\n push(n) {\n this.heap[this.length++] = n\n }\n pop() {\n return this.heap[--this.length]\n }\n}\n\nclass LRUCache {\n constructor(options = {}) {\n const {\n max = 0,\n ttl,\n ttlResolution = 1,\n ttlAutopurge,\n updateAgeOnGet,\n updateAgeOnHas,\n allowStale,\n dispose,\n disposeAfter,\n noDisposeOnSet,\n noUpdateTTL,\n maxSize = 0,\n maxEntrySize = 0,\n sizeCalculation,\n fetchMethod,\n fetchContext,\n noDeleteOnFetchRejection,\n noDeleteOnStaleGet,\n allowStaleOnFetchRejection,\n allowStaleOnFetchAbort,\n ignoreFetchAbort,\n } = options\n\n // deprecated options, don't trigger a warning for getting them if\n // the thing being passed in is another LRUCache we're copying.\n const { length, maxAge, stale } =\n options instanceof LRUCache ? {} : options\n\n if (max !== 0 && !isPosInt(max)) {\n throw new TypeError('max option must be a nonnegative integer')\n }\n\n const UintArray = max ? getUintArray(max) : Array\n if (!UintArray) {\n throw new Error('invalid max value: ' + max)\n }\n\n this.max = max\n this.maxSize = maxSize\n this.maxEntrySize = maxEntrySize || this.maxSize\n this.sizeCalculation = sizeCalculation || length\n if (this.sizeCalculation) {\n if (!this.maxSize && !this.maxEntrySize) {\n throw new TypeError(\n 'cannot set sizeCalculation without setting maxSize or maxEntrySize'\n )\n }\n if (typeof this.sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation set to non-function')\n }\n }\n\n this.fetchMethod = fetchMethod || null\n if (this.fetchMethod && typeof this.fetchMethod !== 'function') {\n throw new TypeError(\n 'fetchMethod must be a function if specified'\n )\n }\n\n this.fetchContext = fetchContext\n if (!this.fetchMethod && fetchContext !== undefined) {\n throw new TypeError(\n 'cannot set fetchContext without fetchMethod'\n )\n }\n\n this.keyMap = new Map()\n this.keyList = new Array(max).fill(null)\n this.valList = new Array(max).fill(null)\n this.next = new UintArray(max)\n this.prev = new UintArray(max)\n this.head = 0\n this.tail = 0\n this.free = new Stack(max)\n this.initialFill = 1\n this.size = 0\n\n if (typeof dispose === 'function') {\n this.dispose = dispose\n }\n if (typeof disposeAfter === 'function') {\n this.disposeAfter = disposeAfter\n this.disposed = []\n } else {\n this.disposeAfter = null\n this.disposed = null\n }\n this.noDisposeOnSet = !!noDisposeOnSet\n this.noUpdateTTL = !!noUpdateTTL\n this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection\n this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection\n this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort\n this.ignoreFetchAbort = !!ignoreFetchAbort\n\n // NB: maxEntrySize is set to maxSize if it's set\n if (this.maxEntrySize !== 0) {\n if (this.maxSize !== 0) {\n if (!isPosInt(this.maxSize)) {\n throw new TypeError(\n 'maxSize must be a positive integer if specified'\n )\n }\n }\n if (!isPosInt(this.maxEntrySize)) {\n throw new TypeError(\n 'maxEntrySize must be a positive integer if specified'\n )\n }\n this.initializeSizeTracking()\n }\n\n this.allowStale = !!allowStale || !!stale\n this.noDeleteOnStaleGet = !!noDeleteOnStaleGet\n this.updateAgeOnGet = !!updateAgeOnGet\n this.updateAgeOnHas = !!updateAgeOnHas\n this.ttlResolution =\n isPosInt(ttlResolution) || ttlResolution === 0\n ? ttlResolution\n : 1\n this.ttlAutopurge = !!ttlAutopurge\n this.ttl = ttl || maxAge || 0\n if (this.ttl) {\n if (!isPosInt(this.ttl)) {\n throw new TypeError(\n 'ttl must be a positive integer if specified'\n )\n }\n this.initializeTTLTracking()\n }\n\n // do not allow completely unbounded caches\n if (this.max === 0 && this.ttl === 0 && this.maxSize === 0) {\n throw new TypeError(\n 'At least one of max, maxSize, or ttl is required'\n )\n }\n if (!this.ttlAutopurge && !this.max && !this.maxSize) {\n const code = 'LRU_CACHE_UNBOUNDED'\n if (shouldWarn(code)) {\n warned.add(code)\n const msg =\n 'TTL caching without ttlAutopurge, max, or maxSize can ' +\n 'result in unbounded memory consumption.'\n emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)\n }\n }\n\n if (stale) {\n deprecatedOption('stale', 'allowStale')\n }\n if (maxAge) {\n deprecatedOption('maxAge', 'ttl')\n }\n if (length) {\n deprecatedOption('length', 'sizeCalculation')\n }\n }\n\n getRemainingTTL(key) {\n return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0\n }\n\n initializeTTLTracking() {\n this.ttls = new ZeroArray(this.max)\n this.starts = new ZeroArray(this.max)\n\n this.setItemTTL = (index, ttl, start = perf.now()) => {\n this.starts[index] = ttl !== 0 ? start : 0\n this.ttls[index] = ttl\n if (ttl !== 0 && this.ttlAutopurge) {\n const t = setTimeout(() => {\n if (this.isStale(index)) {\n this.delete(this.keyList[index])\n }\n }, ttl + 1)\n /* istanbul ignore else - unref() not supported on all platforms */\n if (t.unref) {\n t.unref()\n }\n }\n }\n\n this.updateItemAge = index => {\n this.starts[index] = this.ttls[index] !== 0 ? perf.now() : 0\n }\n\n this.statusTTL = (status, index) => {\n if (status) {\n status.ttl = this.ttls[index]\n status.start = this.starts[index]\n status.now = cachedNow || getNow()\n status.remainingTTL = status.now + status.ttl - status.start\n }\n }\n\n // debounce calls to perf.now() to 1s so we're not hitting\n // that costly call repeatedly.\n let cachedNow = 0\n const getNow = () => {\n const n = perf.now()\n if (this.ttlResolution > 0) {\n cachedNow = n\n const t = setTimeout(\n () => (cachedNow = 0),\n this.ttlResolution\n )\n /* istanbul ignore else - not available on all platforms */\n if (t.unref) {\n t.unref()\n }\n }\n return n\n }\n\n this.getRemainingTTL = key => {\n const index = this.keyMap.get(key)\n if (index === undefined) {\n return 0\n }\n return this.ttls[index] === 0 || this.starts[index] === 0\n ? Infinity\n : this.starts[index] +\n this.ttls[index] -\n (cachedNow || getNow())\n }\n\n this.isStale = index => {\n return (\n this.ttls[index] !== 0 &&\n this.starts[index] !== 0 &&\n (cachedNow || getNow()) - this.starts[index] >\n this.ttls[index]\n )\n }\n }\n updateItemAge(_index) {}\n statusTTL(_status, _index) {}\n setItemTTL(_index, _ttl, _start) {}\n isStale(_index) {\n return false\n }\n\n initializeSizeTracking() {\n this.calculatedSize = 0\n this.sizes = new ZeroArray(this.max)\n this.removeItemSize = index => {\n this.calculatedSize -= this.sizes[index]\n this.sizes[index] = 0\n }\n this.requireSize = (k, v, size, sizeCalculation) => {\n // provisionally accept background fetches.\n // actual value size will be checked when they return.\n if (this.isBackgroundFetch(v)) {\n return 0\n }\n if (!isPosInt(size)) {\n if (sizeCalculation) {\n if (typeof sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation must be a function')\n }\n size = sizeCalculation(v, k)\n if (!isPosInt(size)) {\n throw new TypeError(\n 'sizeCalculation return invalid (expect positive integer)'\n )\n }\n } else {\n throw new TypeError(\n 'invalid size value (must be positive integer). ' +\n 'When maxSize or maxEntrySize is used, sizeCalculation or size ' +\n 'must be set.'\n )\n }\n }\n return size\n }\n this.addItemSize = (index, size, status) => {\n this.sizes[index] = size\n if (this.maxSize) {\n const maxSize = this.maxSize - this.sizes[index]\n while (this.calculatedSize > maxSize) {\n this.evict(true)\n }\n }\n this.calculatedSize += this.sizes[index]\n if (status) {\n status.entrySize = size\n status.totalCalculatedSize = this.calculatedSize\n }\n }\n }\n removeItemSize(_index) {}\n addItemSize(_index, _size) {}\n requireSize(_k, _v, size, sizeCalculation) {\n if (size || sizeCalculation) {\n throw new TypeError(\n 'cannot set size without setting maxSize or maxEntrySize on cache'\n )\n }\n }\n\n *indexes({ allowStale = this.allowStale } = {}) {\n if (this.size) {\n for (let i = this.tail; true; ) {\n if (!this.isValidIndex(i)) {\n break\n }\n if (allowStale || !this.isStale(i)) {\n yield i\n }\n if (i === this.head) {\n break\n } else {\n i = this.prev[i]\n }\n }\n }\n }\n\n *rindexes({ allowStale = this.allowStale } = {}) {\n if (this.size) {\n for (let i = this.head; true; ) {\n if (!this.isValidIndex(i)) {\n break\n }\n if (allowStale || !this.isStale(i)) {\n yield i\n }\n if (i === this.tail) {\n break\n } else {\n i = this.next[i]\n }\n }\n }\n }\n\n isValidIndex(index) {\n return (\n index !== undefined &&\n this.keyMap.get(this.keyList[index]) === index\n )\n }\n\n *entries() {\n for (const i of this.indexes()) {\n if (\n this.valList[i] !== undefined &&\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield [this.keyList[i], this.valList[i]]\n }\n }\n }\n *rentries() {\n for (const i of this.rindexes()) {\n if (\n this.valList[i] !== undefined &&\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield [this.keyList[i], this.valList[i]]\n }\n }\n }\n\n *keys() {\n for (const i of this.indexes()) {\n if (\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.keyList[i]\n }\n }\n }\n *rkeys() {\n for (const i of this.rindexes()) {\n if (\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.keyList[i]\n }\n }\n }\n\n *values() {\n for (const i of this.indexes()) {\n if (\n this.valList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.valList[i]\n }\n }\n }\n *rvalues() {\n for (const i of this.rindexes()) {\n if (\n this.valList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.valList[i]\n }\n }\n }\n\n [Symbol.iterator]() {\n return this.entries()\n }\n\n find(fn, getOptions) {\n for (const i of this.indexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n if (fn(value, this.keyList[i], this)) {\n return this.get(this.keyList[i], getOptions)\n }\n }\n }\n\n forEach(fn, thisp = this) {\n for (const i of this.indexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n fn.call(thisp, value, this.keyList[i], this)\n }\n }\n\n rforEach(fn, thisp = this) {\n for (const i of this.rindexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n fn.call(thisp, value, this.keyList[i], this)\n }\n }\n\n get prune() {\n deprecatedMethod('prune', 'purgeStale')\n return this.purgeStale\n }\n\n purgeStale() {\n let deleted = false\n for (const i of this.rindexes({ allowStale: true })) {\n if (this.isStale(i)) {\n this.delete(this.keyList[i])\n deleted = true\n }\n }\n return deleted\n }\n\n dump() {\n const arr = []\n for (const i of this.indexes({ allowStale: true })) {\n const key = this.keyList[i]\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n const entry = { value }\n if (this.ttls) {\n entry.ttl = this.ttls[i]\n // always dump the start relative to a portable timestamp\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = perf.now() - this.starts[i]\n entry.start = Math.floor(Date.now() - age)\n }\n if (this.sizes) {\n entry.size = this.sizes[i]\n }\n arr.unshift([key, entry])\n }\n return arr\n }\n\n load(arr) {\n this.clear()\n for (const [key, entry] of arr) {\n if (entry.start) {\n // entry.start is a portable timestamp, but we may be using\n // node's performance.now(), so calculate the offset.\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = Date.now() - entry.start\n entry.start = perf.now() - age\n }\n this.set(key, entry.value, entry)\n }\n }\n\n dispose(_v, _k, _reason) {}\n\n set(\n k,\n v,\n {\n ttl = this.ttl,\n start,\n noDisposeOnSet = this.noDisposeOnSet,\n size = 0,\n sizeCalculation = this.sizeCalculation,\n noUpdateTTL = this.noUpdateTTL,\n status,\n } = {}\n ) {\n size = this.requireSize(k, v, size, sizeCalculation)\n // if the item doesn't fit, don't do anything\n // NB: maxEntrySize set to maxSize by default\n if (this.maxEntrySize && size > this.maxEntrySize) {\n if (status) {\n status.set = 'miss'\n status.maxEntrySizeExceeded = true\n }\n // have to delete, in case a background fetch is there already.\n // in non-async cases, this is a no-op\n this.delete(k)\n return this\n }\n let index = this.size === 0 ? undefined : this.keyMap.get(k)\n if (index === undefined) {\n // addition\n index = this.newIndex()\n this.keyList[index] = k\n this.valList[index] = v\n this.keyMap.set(k, index)\n this.next[this.tail] = index\n this.prev[index] = this.tail\n this.tail = index\n this.size++\n this.addItemSize(index, size, status)\n if (status) {\n status.set = 'add'\n }\n noUpdateTTL = false\n } else {\n // update\n this.moveToTail(index)\n const oldVal = this.valList[index]\n if (v !== oldVal) {\n if (this.isBackgroundFetch(oldVal)) {\n oldVal.__abortController.abort(new Error('replaced'))\n } else {\n if (!noDisposeOnSet) {\n this.dispose(oldVal, k, 'set')\n if (this.disposeAfter) {\n this.disposed.push([oldVal, k, 'set'])\n }\n }\n }\n this.removeItemSize(index)\n this.valList[index] = v\n this.addItemSize(index, size, status)\n if (status) {\n status.set = 'replace'\n const oldValue =\n oldVal && this.isBackgroundFetch(oldVal)\n ? oldVal.__staleWhileFetching\n : oldVal\n if (oldValue !== undefined) status.oldValue = oldValue\n }\n } else if (status) {\n status.set = 'update'\n }\n }\n if (ttl !== 0 && this.ttl === 0 && !this.ttls) {\n this.initializeTTLTracking()\n }\n if (!noUpdateTTL) {\n this.setItemTTL(index, ttl, start)\n }\n this.statusTTL(status, index)\n if (this.disposeAfter) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n return this\n }\n\n newIndex() {\n if (this.size === 0) {\n return this.tail\n }\n if (this.size === this.max && this.max !== 0) {\n return this.evict(false)\n }\n if (this.free.length !== 0) {\n return this.free.pop()\n }\n // initial fill, just keep writing down the list\n return this.initialFill++\n }\n\n pop() {\n if (this.size) {\n const val = this.valList[this.head]\n this.evict(true)\n return val\n }\n }\n\n evict(free) {\n const head = this.head\n const k = this.keyList[head]\n const v = this.valList[head]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('evicted'))\n } else {\n this.dispose(v, k, 'evict')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'evict'])\n }\n }\n this.removeItemSize(head)\n // if we aren't about to use the index, then null these out\n if (free) {\n this.keyList[head] = null\n this.valList[head] = null\n this.free.push(head)\n }\n this.head = this.next[head]\n this.keyMap.delete(k)\n this.size--\n return head\n }\n\n has(k, { updateAgeOnHas = this.updateAgeOnHas, status } = {}) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n if (!this.isStale(index)) {\n if (updateAgeOnHas) {\n this.updateItemAge(index)\n }\n if (status) status.has = 'hit'\n this.statusTTL(status, index)\n return true\n } else if (status) {\n status.has = 'stale'\n this.statusTTL(status, index)\n }\n } else if (status) {\n status.has = 'miss'\n }\n return false\n }\n\n // like get(), but without any LRU updating or TTL expiration\n peek(k, { allowStale = this.allowStale } = {}) {\n const index = this.keyMap.get(k)\n if (index !== undefined && (allowStale || !this.isStale(index))) {\n const v = this.valList[index]\n // either stale and allowed, or forcing a refresh of non-stale value\n return this.isBackgroundFetch(v) ? v.__staleWhileFetching : v\n }\n }\n\n backgroundFetch(k, index, options, context) {\n const v = index === undefined ? undefined : this.valList[index]\n if (this.isBackgroundFetch(v)) {\n return v\n }\n const ac = new AC()\n if (options.signal) {\n options.signal.addEventListener('abort', () =>\n ac.abort(options.signal.reason)\n )\n }\n const fetchOpts = {\n signal: ac.signal,\n options,\n context,\n }\n const cb = (v, updateCache = false) => {\n const { aborted } = ac.signal\n const ignoreAbort = options.ignoreFetchAbort && v !== undefined\n if (options.status) {\n if (aborted && !updateCache) {\n options.status.fetchAborted = true\n options.status.fetchError = ac.signal.reason\n if (ignoreAbort) options.status.fetchAbortIgnored = true\n } else {\n options.status.fetchResolved = true\n }\n }\n if (aborted && !ignoreAbort && !updateCache) {\n return fetchFail(ac.signal.reason)\n }\n // either we didn't abort, and are still here, or we did, and ignored\n if (this.valList[index] === p) {\n if (v === undefined) {\n if (p.__staleWhileFetching) {\n this.valList[index] = p.__staleWhileFetching\n } else {\n this.delete(k)\n }\n } else {\n if (options.status) options.status.fetchUpdated = true\n this.set(k, v, fetchOpts.options)\n }\n }\n return v\n }\n const eb = er => {\n if (options.status) {\n options.status.fetchRejected = true\n options.status.fetchError = er\n }\n return fetchFail(er)\n }\n const fetchFail = er => {\n const { aborted } = ac.signal\n const allowStaleAborted =\n aborted && options.allowStaleOnFetchAbort\n const allowStale =\n allowStaleAborted || options.allowStaleOnFetchRejection\n const noDelete = allowStale || options.noDeleteOnFetchRejection\n if (this.valList[index] === p) {\n // if we allow stale on fetch rejections, then we need to ensure that\n // the stale value is not removed from the cache when the fetch fails.\n const del = !noDelete || p.__staleWhileFetching === undefined\n if (del) {\n this.delete(k)\n } else if (!allowStaleAborted) {\n // still replace the *promise* with the stale value,\n // since we are done with the promise at this point.\n // leave it untouched if we're still waiting for an\n // aborted background fetch that hasn't yet returned.\n this.valList[index] = p.__staleWhileFetching\n }\n }\n if (allowStale) {\n if (options.status && p.__staleWhileFetching !== undefined) {\n options.status.returnedStale = true\n }\n return p.__staleWhileFetching\n } else if (p.__returned === p) {\n throw er\n }\n }\n const pcall = (res, rej) => {\n this.fetchMethod(k, v, fetchOpts).then(v => res(v), rej)\n // ignored, we go until we finish, regardless.\n // defer check until we are actually aborting,\n // so fetchMethod can override.\n ac.signal.addEventListener('abort', () => {\n if (\n !options.ignoreFetchAbort ||\n options.allowStaleOnFetchAbort\n ) {\n res()\n // when it eventually resolves, update the cache.\n if (options.allowStaleOnFetchAbort) {\n res = v => cb(v, true)\n }\n }\n })\n }\n if (options.status) options.status.fetchDispatched = true\n const p = new Promise(pcall).then(cb, eb)\n p.__abortController = ac\n p.__staleWhileFetching = v\n p.__returned = null\n if (index === undefined) {\n // internal, don't expose status.\n this.set(k, p, { ...fetchOpts.options, status: undefined })\n index = this.keyMap.get(k)\n } else {\n this.valList[index] = p\n }\n return p\n }\n\n isBackgroundFetch(p) {\n return (\n p &&\n typeof p === 'object' &&\n typeof p.then === 'function' &&\n Object.prototype.hasOwnProperty.call(\n p,\n '__staleWhileFetching'\n ) &&\n Object.prototype.hasOwnProperty.call(p, '__returned') &&\n (p.__returned === p || p.__returned === null)\n )\n }\n\n // this takes the union of get() and set() opts, because it does both\n async fetch(\n k,\n {\n // get options\n allowStale = this.allowStale,\n updateAgeOnGet = this.updateAgeOnGet,\n noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n // set options\n ttl = this.ttl,\n noDisposeOnSet = this.noDisposeOnSet,\n size = 0,\n sizeCalculation = this.sizeCalculation,\n noUpdateTTL = this.noUpdateTTL,\n // fetch exclusive options\n noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,\n allowStaleOnFetchRejection = this.allowStaleOnFetchRejection,\n ignoreFetchAbort = this.ignoreFetchAbort,\n allowStaleOnFetchAbort = this.allowStaleOnFetchAbort,\n fetchContext = this.fetchContext,\n forceRefresh = false,\n status,\n signal,\n } = {}\n ) {\n if (!this.fetchMethod) {\n if (status) status.fetch = 'get'\n return this.get(k, {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n status,\n })\n }\n\n const options = {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n ttl,\n noDisposeOnSet,\n size,\n sizeCalculation,\n noUpdateTTL,\n noDeleteOnFetchRejection,\n allowStaleOnFetchRejection,\n allowStaleOnFetchAbort,\n ignoreFetchAbort,\n status,\n signal,\n }\n\n let index = this.keyMap.get(k)\n if (index === undefined) {\n if (status) status.fetch = 'miss'\n const p = this.backgroundFetch(k, index, options, fetchContext)\n return (p.__returned = p)\n } else {\n // in cache, maybe already fetching\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n const stale =\n allowStale && v.__staleWhileFetching !== undefined\n if (status) {\n status.fetch = 'inflight'\n if (stale) status.returnedStale = true\n }\n return stale ? v.__staleWhileFetching : (v.__returned = v)\n }\n\n // if we force a refresh, that means do NOT serve the cached value,\n // unless we are already in the process of refreshing the cache.\n const isStale = this.isStale(index)\n if (!forceRefresh && !isStale) {\n if (status) status.fetch = 'hit'\n this.moveToTail(index)\n if (updateAgeOnGet) {\n this.updateItemAge(index)\n }\n this.statusTTL(status, index)\n return v\n }\n\n // ok, it is stale or a forced refresh, and not already fetching.\n // refresh the cache.\n const p = this.backgroundFetch(k, index, options, fetchContext)\n const hasStale = p.__staleWhileFetching !== undefined\n const staleVal = hasStale && allowStale\n if (status) {\n status.fetch = hasStale && isStale ? 'stale' : 'refresh'\n if (staleVal && isStale) status.returnedStale = true\n }\n return staleVal ? p.__staleWhileFetching : (p.__returned = p)\n }\n }\n\n get(\n k,\n {\n allowStale = this.allowStale,\n updateAgeOnGet = this.updateAgeOnGet,\n noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n status,\n } = {}\n ) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n const value = this.valList[index]\n const fetching = this.isBackgroundFetch(value)\n this.statusTTL(status, index)\n if (this.isStale(index)) {\n if (status) status.get = 'stale'\n // delete only if not an in-flight background fetch\n if (!fetching) {\n if (!noDeleteOnStaleGet) {\n this.delete(k)\n }\n if (status) status.returnedStale = allowStale\n return allowStale ? value : undefined\n } else {\n if (status) {\n status.returnedStale =\n allowStale && value.__staleWhileFetching !== undefined\n }\n return allowStale ? value.__staleWhileFetching : undefined\n }\n } else {\n if (status) status.get = 'hit'\n // if we're currently fetching it, we don't actually have it yet\n // it's not stale, which means this isn't a staleWhileRefetching.\n // If it's not stale, and fetching, AND has a __staleWhileFetching\n // value, then that means the user fetched with {forceRefresh:true},\n // so it's safe to return that value.\n if (fetching) {\n return value.__staleWhileFetching\n }\n this.moveToTail(index)\n if (updateAgeOnGet) {\n this.updateItemAge(index)\n }\n return value\n }\n } else if (status) {\n status.get = 'miss'\n }\n }\n\n connect(p, n) {\n this.prev[n] = p\n this.next[p] = n\n }\n\n moveToTail(index) {\n // if tail already, nothing to do\n // if head, move head to next[index]\n // else\n // move next[prev[index]] to next[index] (head has no prev)\n // move prev[next[index]] to prev[index]\n // prev[index] = tail\n // next[tail] = index\n // tail = index\n if (index !== this.tail) {\n if (index === this.head) {\n this.head = this.next[index]\n } else {\n this.connect(this.prev[index], this.next[index])\n }\n this.connect(this.tail, index)\n this.tail = index\n }\n }\n\n get del() {\n deprecatedMethod('del', 'delete')\n return this.delete\n }\n\n delete(k) {\n let deleted = false\n if (this.size !== 0) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n deleted = true\n if (this.size === 1) {\n this.clear()\n } else {\n this.removeItemSize(index)\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'))\n } else {\n this.dispose(v, k, 'delete')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'delete'])\n }\n }\n this.keyMap.delete(k)\n this.keyList[index] = null\n this.valList[index] = null\n if (index === this.tail) {\n this.tail = this.prev[index]\n } else if (index === this.head) {\n this.head = this.next[index]\n } else {\n this.next[this.prev[index]] = this.next[index]\n this.prev[this.next[index]] = this.prev[index]\n }\n this.size--\n this.free.push(index)\n }\n }\n }\n if (this.disposed) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n return deleted\n }\n\n clear() {\n for (const index of this.rindexes({ allowStale: true })) {\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'))\n } else {\n const k = this.keyList[index]\n this.dispose(v, k, 'delete')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'delete'])\n }\n }\n }\n\n this.keyMap.clear()\n this.valList.fill(null)\n this.keyList.fill(null)\n if (this.ttls) {\n this.ttls.fill(0)\n this.starts.fill(0)\n }\n if (this.sizes) {\n this.sizes.fill(0)\n }\n this.head = 0\n this.tail = 0\n this.initialFill = 1\n this.free.length = 0\n this.calculatedSize = 0\n this.size = 0\n if (this.disposed) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n }\n\n get reset() {\n deprecatedMethod('reset', 'clear')\n return this.clear\n }\n\n get length() {\n deprecatedProperty('length', 'size')\n return this.size\n }\n\n static get AbortController() {\n return AC\n }\n static get AbortSignal() {\n return AS\n }\n}\n\nexport default LRUCache\n","import { Strand } from '@atlas-viewer/dna';\nimport { Paint, Paintable, WorldObject } from '../../world-objects';\nimport { PositionPair } from '../../types';\nimport { distance } from '../../utils';\nimport { Text } from '../../objects/text';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { Renderer } from '../../renderer/renderer';\nimport { World } from '../../world';\nimport { Box } from '../../objects/box';\nimport LRUCache from 'lru-cache';\nimport { Geometry } from '../../objects/geometry';\nimport { HookOptions } from '../../standalone';\n\nconst shadowRegex =\n /(-?[0-9]+(px|em)\\s+|0\\s+)(-?[0-9]+(px|em)\\s+|0\\s+)(-?[0-9]+(px|em)\\s+|0\\s+)?(-?[0-9]+(px|em)\\s+|0\\s+)?(.*)/g;\nconst shadowRegexCache: any = {};\nconst isFirefox =\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().includes('firefox');\n\nexport type CanvasRendererOptions = {\n beforeFrame?: (delta: number) => void;\n debug?: boolean;\n htmlContainer?: HTMLDivElement;\n crossOrigin?: boolean;\n dpi?: number;\n box?: boolean;\n polygon?: boolean;\n lruCache?: boolean;\n};\n\nexport type ImageBuffer = {\n canvas: HTMLCanvasElement;\n canvases: string[];\n indices: number[];\n loaded: number[];\n fallback?: ImageBuffer;\n loading: boolean;\n};\n\n// @todo be smarter.\nconst imageCache: { [id: string]: HTMLImageElement } = {};\nconst hostCache: Record<string, any> = {};\n\nexport class CanvasRenderer implements Renderer {\n /**\n * The primary viewing space for the viewer.\n */\n canvas: HTMLCanvasElement;\n\n /**\n * Canvas context for `this.canvas`\n */\n ctx: CanvasRenderingContext2D;\n\n /**\n * Rendering options added in the constructor.\n */\n options: CanvasRendererOptions;\n\n /**\n * Number of images loading.\n */\n imagesPending = 0;\n\n /**\n * Number of completed images, used to calculate pending images.\n */\n imagesLoaded = 0;\n\n /**\n * The ids of the completed images, use to dedupe\n */\n imageIdsLoaded: string[] = [];\n\n /**\n * Can be used to avoid or stop work when frame is or isn't rendering outside of the main loop.\n */\n frameIsRendering = false;\n pendingDrawCall = false;\n firstMeaningfulPaint = false;\n parallelTasks = 8; // @todo configuration.\n frameTasks = 0;\n loadingQueueOrdered = true;\n loadingQueue: Array<{\n id: string;\n scale: number;\n network?: boolean;\n distance: number;\n shifted?: boolean;\n task: () => Promise<any>;\n }> = [];\n currentTask: Promise<any> = Promise.resolve();\n tasksRunning = 0;\n stats?: any;\n averageJobTime = 64; // ms\n lastKnownScale = 1;\n visible: Array<SpacialContent> = [];\n previousVisible: Array<SpacialContent> = [];\n rendererPosition: DOMRect;\n dpi: number;\n drawCalls: Array<() => void> = [];\n lastPaintedObject?: WorldObject;\n hostCache: LRUCache<string, HTMLCanvasElement>;\n invalidated: string[] = [];\n\n constructor(canvas: HTMLCanvasElement, options?: CanvasRendererOptions) {\n this.canvas = canvas;\n this.rendererPosition = canvas.getBoundingClientRect();\n // Not working as expected.\n // this.ctx = canvas.getContext('2d', { alpha: false, desynchronized: true }) as CanvasRenderingContext2D;\n this.ctx = canvas.getContext('2d', { alpha: true }) as CanvasRenderingContext2D;\n this.ctx.imageSmoothingEnabled = true;\n this.options = options || {};\n // Testing fade in.\n // this.canvas.style.opacity = '0';\n this.canvas.style.transition = 'opacity .3s';\n this.dpi = options?.dpi || 1;\n\n this.hostCache = options?.lruCache\n ? new LRUCache<string, HTMLCanvasElement>({\n maxSize: 1024 * 512 * 512, // 250MB total.\n dispose: (value, key, reason) => {\n this.invalidated.push(key);\n value.width = 0;\n value.height = 0;\n },\n sizeCalculation: (value, key) => {\n return value.width * value.height;\n },\n })\n : ({\n store: {},\n get(id: string) {\n return this.store[id];\n },\n set(id: string, value: any) {\n this.store[id] = value;\n },\n } as any);\n\n // if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n // import('stats.js')\n // .then((s) => new s.default())\n // .then((stats) => {\n // this.stats = stats;\n // this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom\n // if (document && document.body) {\n // document.body.appendChild(this.stats.dom);\n // }\n // });\n // }\n }\n\n getCanvasDims() {\n return { width: this.canvas.width / this.dpi, height: this.canvas.height / this.dpi };\n }\n\n resize() {\n this.rendererPosition = this.canvas.getBoundingClientRect();\n }\n\n isReady(): boolean {\n return this.firstMeaningfulPaint;\n }\n\n afterFrame(world: World): void {\n // this.lastPaintedObject = paint.__owner.value;\n this.clearTransform();\n this.lastPaintedObject = undefined;\n // this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2);\n // this.ctx.rotate((90 * Math.PI) / 180);\n // this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);\n this.frameIsRendering = false;\n // After we've rendered, we'll set the pending and loading to correct values.\n this.imagesPending = Math.max(0, this.imagesPending - this.imagesLoaded);\n this.imagesLoaded = 0;\n if (!this.loadingQueueOrdered /*&& this.loadingQueue.length > this.parallelTasks*/) {\n this.loadingQueue = this.loadingQueue.sort((a, b) => {\n if (a.network) {\n if (a.scale === b.scale) {\n return b.distance - a.distance;\n }\n }\n\n return a.scale < b.scale ? -1 : 1;\n });\n this.loadingQueueOrdered = true;\n }\n // Set them.\n this.previousVisible = this.visible;\n this.pendingDrawCall = !!this.drawCalls.length;\n if (this.pendingDrawCall) {\n for (let i = 0; i < this.drawCalls.length; i++) {\n const nextCall = this.drawCalls.shift();\n if (nextCall) nextCall();\n }\n }\n // Some off-screen work might need done, like loading new images in.\n this.doOffscreenWork();\n // Stats\n if (this.options.debug && this.stats) {\n this.stats.end();\n }\n }\n\n doOffscreenWork() {\n this.frameTasks = 0;\n // This is our worker. It is called every 1ms (roughly) and will usually be\n // an async task that can run without blocking the frame. Because of\n // there is a configuration for parallel task count.\n if (this.loadingQueue.length) {\n // First call immediately.\n this._worker();\n if (this.loadingQueue.length /*&& this.tasksRunning < this.parallelTasks*/) {\n // Here's our clock for scheduling tasks, every 1ms it will try to call.\n if (!this._scheduled) {\n this._scheduled = setInterval(this._doWork, 0);\n }\n }\n }\n }\n\n _worker = () => {\n if (\n // First we check if there is work to do.\n this.loadingQueue.length /*&&\n this.tasksRunning < this.parallelTasks &&\n this.frameTasks < this.parallelTasks*/\n ) {\n // Let's pop something off the loading queue.\n const next = this.loadingQueue.pop();\n\n if (next) {\n // @todo removed for now, while a nice optimisation it was breaking the \"renderSmallestFallback\"\n // const outOfBounds = !next.shifted && Math.abs(1 - next.scale / (1 / this.lastKnownScale)) >= 1;\n // if (outOfBounds && !next.shifted) {\n // next.shifted = true;\n // this.loadingQueue.unshift(next);\n // return;\n // }\n // We will increment the task count\n this.tasksRunning++;\n this.frameTasks++;\n // And kick it off. We don't care if it succeeded or not.\n // A task that needs to retry should just add a new task.\n this.currentTask = next\n .task()\n .then(() => {\n this.tasksRunning--;\n })\n .catch(() => {\n this.tasksRunning--;\n });\n }\n }\n };\n _scheduled: any = 0;\n _doWork = () => {\n // Here is the shut down, no more work to do.\n if (this.loadingQueue.length === 0 && this.tasksRunning === 0 && this._scheduled) {\n clearInterval(this._scheduled);\n this._scheduled = 0;\n }\n\n let parallel = this.parallelTasks || 1;\n\n if (!this.firstMeaningfulPaint && this.loadingQueue.length) {\n parallel = this.loadingQueue.length;\n }\n // And here's our working being called. Since JS is blocking, this will complete\n // before the next tick, so its possible that this could be more than 1ms.\n for (let i = 0; i <= parallel; i++) {\n this._worker();\n }\n };\n\n getScale(width: number, height: number, dpi?: boolean): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const canvas = this.getCanvasDims();\n const w = canvas.width / width;\n const h = canvas.height / height;\n const scale = (w < h ? h : w) * (dpi ? this.dpi || 1 : 1);\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n beforeFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n // const scale = this.getScale(target[3] - target[1], target[4] - target[1]);\n // this.ctx.setTransform(scale, 0, 0, scale, -target[1], -target[2]);\n\n if (this.options.debug && this.stats) {\n this.stats.begin();\n }\n this.frameIsRendering = true;\n this.visible = [];\n // User-facing hook for before frame, contains timing information for\n // animations that might be happening, such as pan/drag.\n if (this.options.beforeFrame) {\n this.options.beforeFrame(delta);\n }\n\n const canvas = this.getCanvasDims();\n // But we also need to clear the canvas.\n this.ctx.globalAlpha = 1;\n if (this.canvas.dataset.background === 'transparent') {\n this.ctx.clearRect(0, 0, canvas.width, canvas.height);\n } else {\n this.ctx.fillStyle = this.canvas.dataset.background ?? 'rgb(0, 0, 0)';\n this.ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n // this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2);\n // this.ctx.rotate((-90 * Math.PI) / 180);\n // this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);\n\n if (\n options.enableFilters &&\n (options.filters.brightness ||\n options.filters.contrast ||\n options.filters.grayscale ||\n options.filters.invert ||\n options.filters.sepia ||\n options.filters.saturate ||\n options.filters.hueRotate ||\n options.filters.blur)\n ) {\n let filter = '';\n if (options.filters.brightness) {\n filter += `brightness(${~~(100 + options.filters.brightness * 100)}%) `;\n }\n if (options.filters.contrast) {\n filter += `contrast(${~~(100 + options.filters.contrast * 100)}%) `;\n }\n if (options.filters.grayscale) {\n filter += `grayscale(${~~(options.filters.grayscale * 100)}%) `;\n }\n if (options.filters.invert) {\n filter += `invert(${~~(options.filters.invert * 100)}%) `;\n }\n if (options.filters.sepia) {\n filter += `sepia(${~~(options.filters.sepia * 100)}%) `;\n }\n if (options.filters.saturate) {\n filter += `saturate(${~~(100 + options.filters.saturate * 100)}%) `;\n }\n if (options.filters.hueRotate) {\n filter += `hue-rotate(${options.filters.hueRotate}deg) `;\n }\n if (options.filters.blur) {\n filter += `blur(${options.filters.blur}px) `;\n }\n\n if (this.ctx.filter !== filter) {\n this.ctx.filter = filter;\n }\n } else {\n this.ctx.filter = 'none';\n }\n }\n\n applyTransform(paint: Paintable, x: number, y: number, width: number, height: number) {\n const owner = paint.__owner.value;\n if (owner && owner.rotation) {\n this.ctx.save();\n const moveX = x + width / 2;\n const moveY = y + height / 2;\n\n this.ctx.translate(moveX, moveY);\n this.ctx.rotate((owner.rotation * Math.PI) / 180);\n this.ctx.translate(-moveX, -moveY);\n this.lastPaintedObject = owner;\n }\n }\n clearTransform() {\n // Do something with last object.\n if (this.lastPaintedObject) {\n if (this.lastPaintedObject.rotation) {\n this.ctx.restore();\n }\n this.lastPaintedObject = undefined;\n }\n }\n\n paint(paint: SpacialContent | Text | Box, index: number, x: number, y: number, width: number, height: number): void {\n const ga = this.ctx.globalAlpha;\n\n // Only supporting single and tiled images at the moment.\n if (paint instanceof SingleImage || paint instanceof TiledImage) {\n if (paint.display.rotation) {\n this.ctx.save();\n let moveX = x + width / 2;\n let moveY = y + height / 2;\n if (paint.crop) {\n moveX -= paint.crop[index * 5 + 1];\n moveY -= paint.crop[index * 5 + 2];\n }\n this.ctx.translate(moveX, moveY);\n this.ctx.rotate((paint.display.rotation * Math.PI) / 180);\n this.ctx.translate(-moveX, -moveY);\n }\n\n this.visible.push(paint);\n if (typeof paint.style && (paint.style as any).opacity !== 'undefined') {\n if (!paint.style.opacity) {\n return;\n }\n this.ctx.globalAlpha = paint.style.opacity;\n }\n\n try {\n // 1) Find cached image buffer.\n const imageBuffer: ImageBuffer = paint.__host.canvas;\n const canvas = this.getCanvasDims();\n\n // 2) Schedule paint onto local buffer (async, yay!)\n if (imageBuffer.indices.indexOf(index) === -1 || this.invalidated.indexOf(imageBuffer.canvases[index]) !== -1) {\n // we need to schedule a paint.\n this.schedulePaintToCanvas(\n imageBuffer,\n paint,\n index,\n distance({ x: x + width / 2, y: y + width / 2 }, { x: canvas.width / 2, y: canvas.height / 2 })\n );\n }\n\n // If we've not prepared an initial \"meaningful paint\", then skip the\n // rendering to avoid tiles loading in, breaking the illusion a bit!\n if (!this.firstMeaningfulPaint) {\n return;\n }\n\n const canvasToPaint = this.hostCache.get(imageBuffer.canvases[index]);\n if (canvasToPaint) {\n if (paint.crop && paint.cropData) {\n if (paint.crop[index * 5]) {\n const source = [\n paint.crop[index * 5 + 1] / paint.display.scale - paint.display.points[index * 5 + 1],\n paint.crop[index * 5 + 2] / paint.display.scale - paint.display.points[index * 5 + 2],\n 1 + (paint.crop[index * 5 + 3] - paint.crop[index * 5 + 1]) / paint.display.scale,\n 1 + (paint.crop[index * 5 + 4] - paint.crop[index * 5 + 2]) / paint.display.scale,\n ];\n\n source[0] += paint.cropData.x / paint.display.scale;\n source[1] += paint.cropData.y / paint.display.scale;\n\n const translationDeltaX = paint.x * this.lastKnownScale;\n const translationDeltaY = paint.y * this.lastKnownScale;\n\n const target = [x + translationDeltaX, y + translationDeltaY, width, height];\n\n // What we need?\n target[0] += translationDeltaX;\n target[1] += translationDeltaY;\n\n this.ctx.drawImage(\n canvasToPaint,\n source[0],\n source[1],\n source[2],\n source[3],\n //\n target[0],\n target[1],\n target[2] + 1,\n target[3] + 1\n );\n }\n } else {\n if (isFirefox) {\n this.ctx.drawImage(\n canvasToPaint,\n 0, // paint.display.points[index * 5 + 1],\n 0, // paint.display.points[index * 5 + 2],\n paint.display.points[index * 5 + 3] - paint.display.points[index * 5 + 1],\n paint.display.points[index * 5 + 4] - paint.display.points[index * 5 + 2],\n x,\n y,\n width + 1,\n height + 1\n );\n } else {\n this.ctx.drawImage(\n canvasToPaint,\n 0, // paint.display.points[index * 5 + 1],\n 0, // paint.display.points[index * 5 + 2],\n paint.display.points[index * 5 + 3] - paint.display.points[index * 5 + 1],\n paint.display.points[index * 5 + 4] - paint.display.points[index * 5 + 2],\n x,\n y,\n width + Number.MIN_VALUE + 0.5,\n height + Number.MIN_VALUE + 0.5\n );\n }\n }\n }\n } catch (err) {\n // nothing to do here, likely that the image isn't loaded yet.\n }\n\n if (paint.display.rotation) {\n this.ctx.restore();\n }\n }\n\n const isBox = paint instanceof Box && this.options.box;\n const isGeometry = paint instanceof Geometry && this.options.polygon;\n if ((isBox || isGeometry) && !paint.props.className && !paint.props.html && !paint.props.href) {\n this.visible.push(paint);\n if (paint.props.style) {\n const style = Object.assign(\n //\n {},\n paint.props.style || {},\n paint.hovering ? paint.props.hoverStyles : {},\n paint.pressing ? paint.props.pressStyles : {}\n );\n\n const scale = paint.props.relativeStyle ? 1 : width / paint.width;\n\n if (typeof style.opacity !== 'undefined') {\n this.ctx.globalAlpha = style.opacity;\n }\n\n let bw = 0;\n if (typeof style.borderWidth !== 'undefined') {\n bw = parseInt(style.borderWidth, 10) * scale;\n }\n\n let ow = 0;\n if (typeof style.outlineWidth !== 'undefined') {\n ow = parseInt(style.outlineWidth, 10) * scale;\n }\n\n let oo = 0;\n if (typeof style.outlineOffset !== 'undefined') {\n oo = parseInt(style.outlineOffset, 10) * scale;\n }\n\n if (style.borderColor) {\n this.ctx.strokeStyle = style.borderColor;\n }\n\n // Box shadow\n if (style.boxShadow) {\n const shadows = style.boxShadow.split(/,(?![^(]*\\))/);\n for (const shadow of shadows) {\n const parsed = shadowRegexCache[shadow] || shadowRegex.exec(shadow) || shadowRegex.exec(shadow);\n shadowRegexCache[shadow] = parsed;\n if (parsed) {\n this.ctx.save();\n this.ctx.shadowOffsetX = parseInt(parsed[1]) * this.dpi * scale;\n this.ctx.shadowOffsetY = parseInt(parsed[3]) * this.dpi * scale;\n this.ctx.shadowBlur = parseInt(parsed[5]) * this.dpi * scale;\n this.ctx.shadowColor = parsed[9];\n this.ctx.fillStyle = 'rgba(0,0,0,1)';\n this.ctx.fillRect(x + bw, y + bw, width, height);\n this.ctx.restore();\n }\n }\n }\n\n this.ctx.fillStyle = style.backgroundColor || 'transparent';\n this.ctx.lineWidth = bw;\n\n if (isGeometry) {\n const shape = (paint as any).shape;\n const points = shape.points || [];\n const len = points.length;\n this.ctx.beginPath();\n for (let i = 0; i < len; i++) {\n this.ctx.lineTo(x + points[i][0] * this.lastKnownScale, y + points[i][1] * this.lastKnownScale);\n }\n if (!shape.open) {\n this.ctx.closePath();\n }\n if (bw) {\n this.ctx.stroke();\n }\n if (!shape.open) {\n this.ctx.fill();\n }\n } else {\n if (bw) {\n this.ctx.strokeRect(x + bw / 2, y + bw / 2, width + bw, height + bw);\n }\n this.ctx.fillRect(x + bw, y + bw, width, height);\n }\n\n if (ow) {\n if (style.outlineColor) {\n this.ctx.strokeStyle = style.outlineColor;\n }\n this.ctx.lineWidth = ow;\n // Outline\n this.ctx.strokeRect(\n //\n x - ow / 2 - oo,\n y - ow / 2 - oo,\n width + bw * 2 + ow + oo * 2,\n height + bw * 2 + ow + oo * 2\n );\n }\n }\n\n this.ctx.globalAlpha = ga;\n }\n }\n\n loadImage(url: string, callback: (image: HTMLImageElement) => void, err: (e: any) => void, retry = false): void {\n if (imageCache[url] && imageCache[url].naturalWidth > 0) {\n callback(imageCache[url]);\n return;\n }\n\n try {\n let loaded = false;\n\n if (!retry) {\n setTimeout(() => {\n if (!loaded) {\n this.loadImage(url, callback, err, true);\n }\n }, 3000);\n }\n const image = document.createElement('img');\n image.decoding = 'auto';\n image.onload = function () {\n loaded = true;\n callback(image);\n imageCache[url] = image;\n image.onload = null;\n };\n if (this.options.crossOrigin) {\n image.crossOrigin = 'anonymous';\n }\n image.src = url;\n if (image.complete) {\n image.onload({} as any);\n }\n if (image.width === 0) {\n // no-op, just want to query width. (possibly bug with browsers)\n }\n } catch (e) {\n console.log('image error', e);\n err(e);\n }\n }\n\n schedulePaintToCanvas(imageBuffer: ImageBuffer, paint: SingleImage | TiledImage, index: number, priority: number) {\n // This happens during a frame render, and these are most likely to happen in batches,\n // so it has to be quick.\n // We increment the images pending, so that we continue getting renders.\n this.imagesPending++;\n // We push the index we want to load onto the image buffer.\n imageBuffer.indices.push(index);\n // Unique id for paint.\n const id = `${paint.id}--${paint.display.scale}-${index}`;\n\n const idx = this.invalidated.indexOf(id);\n if (idx !== -1) {\n this.invalidated.splice(idx, 1);\n }\n\n imageBuffer.canvases[index] = id;\n // Mark as loading.\n paint.__host.canvas.loading = true;\n // Set loading queue ordering to false to trigger re-order.\n this.loadingQueueOrdered = false;\n // And we push a \"unit of work\" to perform between frame renders.\n this.loadingQueue.push({\n id,\n scale: paint.display.scale,\n network: true,\n distance: priority,\n task: () =>\n // The only overhead of creating this is the allocation of the lexical scope. So not much, at all.\n new Promise<void>((resolve) => {\n // @todo this is a little slow.\n if (this.visible.indexOf(paint) === -1) {\n this.imagesPending--;\n imageBuffer.indices.splice(imageBuffer.indices.indexOf(index), 1);\n resolve();\n return;\n }\n // When this is task is finally chosen to be done, we\n const url = paint.getImageUrl(index);\n // Load our image.\n this.loadImage(\n url,\n (image) => {\n this.loadingQueue.push({\n id,\n scale: paint.display.scale,\n distance: priority,\n task: () => {\n return new Promise<void>((innerResolve) => {\n if (!this.imageIdsLoaded.includes(id)) {\n this.imagesLoaded++;\n this.imageIdsLoaded.push(id);\n }\n imageBuffer.loaded.push(index);\n if (imageBuffer.loaded.length === imageBuffer.indices.length) {\n imageBuffer.loading = false;\n }\n const points = paint.display.points.slice(index * 5, index * 5 + 5);\n\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;\n canvas.width = points[3] - points[1];\n canvas.height = points[4] - points[2];\n // document.body.append(canvas);\n this.hostCache.set(imageBuffer.canvases[index], canvas);\n this.drawCalls.push(() => {\n ctx.drawImage(image, 0, 0, points[3] - points[1], points[4] - points[2]);\n innerResolve();\n });\n });\n },\n });\n resolve();\n },\n (err) => {\n this.imagesPending--;\n imageBuffer.indices.splice(imageBuffer.indices.indexOf(index), 1);\n resolve();\n }\n );\n }),\n });\n }\n\n afterPaintLayer(paint: SpacialContent, transform: Strand): void {\n // No-op\n }\n\n prepareLayer(paint: SpacialContent, points: Strand): void {\n if (paint.__owner.value) {\n if (paint.cropData) {\n const scale = this.lastKnownScale * (1 / paint.display.scale);\n this.applyTransform(paint, points[1], points[2], points[3] - points[1], points[4] - points[2]);\n // this.applyTransform(\n // paint,\n // points[1] - paint.cropData.x * scale + paint.points[1] * scale,\n // points[2] - paint.cropData.y * scale + paint.points[2] * scale,\n // paint.cropData.width * this.lastKnownScale,\n // paint.cropData.height * this.lastKnownScale\n // );\n } else {\n this.applyTransform(paint, points[1], points[2], points[3] - points[1], points[4] - points[2]);\n }\n }\n\n if (!paint.__host || !paint.__host.canvas) {\n if (paint instanceof SingleImage || paint instanceof TiledImage) {\n // create it if it does not exist.\n this.createImageHost(paint);\n }\n }\n }\n\n finishLayer() {\n if (this.lastPaintedObject) {\n this.clearTransform();\n }\n }\n\n createImageHost(paint: SingleImage | TiledImage) {\n // const canvas = document.createElement('canvas');\n // canvas.width = paint.display.width;\n // canvas.height = paint.display.height;\n // canvas.getContext('2d')?.clearRect(0, 0, paint.display.width, paint.display.height);\n paint.__host = paint.__host ? paint.__host : {};\n paint.__host.canvas = { canvas: undefined, canvases: [], indices: [], loaded: [], loading: false };\n // hostCache[paint.id] = paint.__host;\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n const zone = world.getActiveZone();\n\n if (zone) {\n const xCon = target[3] - target[1] < zone.points[3] - zone.points[1];\n const yCon = target[4] - target[2] < zone.points[4] - zone.points[2];\n return {\n x1: xCon\n ? zone.points[1] - padding\n : zone.points[1] + (zone.points[3] - zone.points[1]) / 2 - (target[3] - target[1]) / 2,\n y1: yCon\n ? zone.points[2] - padding\n : zone.points[2] + (zone.points[4] - zone.points[2]) / 2 - (target[4] - target[2]) / 2,\n x2: xCon\n ? zone.points[3] + padding\n : zone.points[1] + (zone.points[3] - zone.points[1]) / 2 - (target[3] - target[1]) / 2,\n y2: yCon\n ? zone.points[4] + padding\n : zone.points[2] + (zone.points[4] - zone.points[2]) / 2 - (target[4] - target[2]) / 2,\n };\n }\n return null;\n }\n\n pendingUpdate(): boolean {\n const ready =\n !this.pendingDrawCall &&\n this.drawCalls.length === 0 &&\n this.imagesPending === 0 &&\n this.loadingQueue.length === 0 &&\n this.tasksRunning === 0; /*&& this.visible.length > 0*/\n\n if (!ready && this.visible.length === 0) {\n // If its still not ready by 500ms, force it to be.\n setTimeout(() => {\n this.canvas.style.opacity = '1';\n this.firstMeaningfulPaint = true;\n }, 500);\n }\n\n if (!this.firstMeaningfulPaint && ready && this.visible.length) {\n // Fade in the canvas?\n this.canvas.style.opacity = '1';\n // We've not rendered yet, can we render this frame?\n this.firstMeaningfulPaint = ready;\n // We need to return true here to ensure our update is done.\n return true;\n }\n\n if (this.options.debug) {\n return true;\n }\n\n return !ready;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n reset() {\n this.loadingQueue = [];\n this.drawCalls = [];\n }\n}\n","import { Renderer } from '../../renderer/renderer';\nimport { Paint } from '../../world-objects/paint';\nimport { World } from '../../world';\nimport { Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { PositionPair } from '../../types';\nimport { HookOptions } from 'src/standalone';\n\nexport class CompositeRenderer implements Renderer {\n renderers: Renderer[] = [];\n length: number;\n\n constructor(renderers: Array<Renderer | undefined>) {\n for (const renderer of renderers) {\n if (renderer) {\n this.renderers.push(renderer);\n }\n }\n this.length = this.renderers.length;\n }\n\n afterFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].afterFrame(world, delta, target, options);\n }\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].afterPaintLayer(paint, transform);\n }\n }\n\n beforeFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].beforeFrame(world, delta, target, options);\n }\n }\n\n triggerResize() {\n for (let i = 0; i < this.length; i++) {\n const renderer = this.renderers[i];\n if (renderer.triggerResize) {\n renderer.triggerResize();\n }\n }\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return this.renderers[0].getPointsAt(world, target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n return this.renderers[0].getScale(width, height);\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return this.renderers[0].getViewportBounds(world, target, padding);\n }\n\n getRendererScreenPosition() {\n return this.renderers[0].getRendererScreenPosition();\n }\n\n isReady(): boolean {\n for (let i = 0; i < this.length; i++) {\n if (!this.renderers[i].isReady()) {\n return false;\n }\n }\n return true;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].paint(paint, index, x, y, width, height);\n }\n }\n\n pendingUpdate(): boolean {\n for (let i = 0; i < this.length; i++) {\n if (this.renderers[i].pendingUpdate()) {\n return true;\n }\n }\n return false;\n }\n\n prepareLayer(paint: SpacialContent, point: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].prepareLayer(paint, point);\n }\n }\n\n finishLayer(paint: SpacialContent, point: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].finishLayer(paint, point);\n }\n }\n\n resize(width?: number, height?: number): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].resize(width, height);\n }\n }\n\n reset() {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].reset();\n }\n }\n}\n","import { Paint, ZoneInterface } from '../../world-objects';\nimport { World } from '../../world';\nimport { SingleImage, SpacialContent } from '../../spacial-content';\nimport { Renderer } from '../../renderer/renderer';\nimport { PositionPair } from '../../types';\nimport { dna, DnaFactory, scale, Strand } from '@atlas-viewer/dna';\n\nexport class DebugRenderer implements Renderer {\n canvas: HTMLCanvasElement;\n context: CanvasRenderingContext2D;\n heightRatio = 1;\n widthRatio = 1;\n target: Float32Array = new Float32Array(5);\n\n initialWidth: number;\n initialHeight: number;\n bounds: Strand | undefined;\n aggregate: Strand;\n delta = 0;\n renderNextFrame = true;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.initialWidth = canvas.width;\n this.initialHeight = canvas.height;\n this.context = canvas.getContext('2d') as CanvasRenderingContext2D;\n this.context.globalAlpha = 0.5;\n this.aggregate = scale(1);\n\n // const ratio = window.devicePixelRatio || 1;\n // this.canvas.width = canvas.width * ratio;\n // this.canvas.height = canvas.height * ratio;\n // this.canvas.style.width = canvas.width + 'px';\n // this.canvas.style.height = canvas.height + 'px';\n // this.canvas.getContext('2d')?.scale(ratio, ratio);\n }\n\n isReady(): boolean {\n return true;\n }\n\n resize() {\n this.initialWidth = this.canvas.width;\n this.initialHeight = this.canvas.height;\n this.renderNextFrame = true;\n }\n\n afterFrame(world: World, delta: number, target: Float32Array) {\n // Everything in this debugger happens at the end of the render cycle.\n // This debugger is made to be hacked and changed as needed, so some\n // variables are set up as a convenience.\n // First we clear.\n\n if (this.renderNextFrame) {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n // We figure out the size of the debugger in relation to the world.\n const widthRatio = this.initialWidth / world.width;\n const heightRatio = this.initialHeight / world.height;\n\n const ratio = this.widthRatio > this.heightRatio ? widthRatio : heightRatio;\n // this.canvas.height = world.height * ratio;\n // this.canvas.width = world.width * ratio;\n\n // If it needs to be used in other methods, it can be.\n this.target = target;\n\n if (this.bounds) {\n const points = world.getPointsAt(this.bounds, this.aggregate, ratio);\n for (const [paint, point] of points) {\n if (paint instanceof SingleImage) {\n if (paint.__host.canvas) {\n const total = point.length / 5;\n for (let i = 0; i < total; i++) {\n const toPaint = paint.__host.canvas.canvases[i];\n if (toPaint) {\n const toDraw = {\n x1: point[i + 1] * ratio,\n y1: point[i + 2] * ratio,\n width: (point[i + 3] - point[i + 1]) * ratio,\n height: (point[i + 4] - point[i + 2]) * ratio,\n };\n\n // this.context.drawImage(toPaint, toDraw.x1, toDraw.y1, toDraw.width, toDraw.height);\n }\n }\n }\n }\n }\n }\n\n // Get every point on the world, that is laying out the world items, but\n // not the images that make up the world items. (i.e. canvas dimensions and\n // their positions)\n world.getPoints().forEach((v, k, arr) => {\n // Technically not needed, but some might have been hidden.\n // Could make these a different border.\n if (k % 5 === 0 && v) {\n // Descriptive drawing object, doesn't need to be fast.\n // We are not using all of these fields.\n const toDraw = {\n x1: arr[k + 1] * ratio,\n y1: arr[k + 2] * ratio,\n x2: arr[k + 3] * ratio,\n y2: arr[k + 4] * ratio,\n width: (arr[k + 3] - arr[k + 1]) * ratio,\n height: (arr[k + 4] - arr[k + 2]) * ratio,\n };\n\n // World items are red bordered boxes.\n this.context.strokeStyle = 'red';\n this.context.strokeRect(toDraw.x1, toDraw.y1, toDraw.width, toDraw.height);\n }\n });\n\n // If there's a viewport attached, we can render that too\n // There may not be a target, if someone is just debugging a world.\n if (target) {\n // This will be a green box.\n this.context.strokeStyle = 'red';\n this.context.lineWidth = window.devicePixelRatio || 1;\n this.context.strokeRect(\n target[1] * ratio,\n target[2] * ratio,\n (target[3] - target[1]) * ratio,\n (target[4] - target[2]) * ratio\n );\n }\n }\n }\n\n getActiveZone(world: World): ZoneInterface | null {\n return null;\n }\n\n getPointsAt(world: World, target: Float32Array, aggregate: Float32Array, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n return 1;\n }\n\n beforeFrame(world: World, delta: number) {\n // no op.\n this.bounds = DnaFactory.singleBox(world.width, world.height);\n }\n\n drawImage() {\n // no op.\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Float32Array): void {\n // paint.\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n // paint.\n this.renderNextFrame = true;\n }\n\n prepareLayer(paint: SpacialContent): void {\n // prepare\n }\n\n pendingUpdate(): boolean {\n // change this to true if you want to render every frame.\n return false;\n }\n\n hasActiveZone(): boolean {\n return false;\n }\n\n getViewportBounds(world: World, target: Float32Array, padding: number): PositionPair | null {\n return null;\n }\n\n getRendererScreenPosition() {\n return this.canvas.getBoundingClientRect();\n }\n\n finishLayer() {}\n reset() {}\n}\n","import { ViewingDirection } from '@iiif/presentation-3';\nimport { AbstractObject } from '../../world-objects/abstract-object';\nimport { World } from '../../world';\nimport { WorldObject } from '../../world-objects/world-object';\n\nexport class GridBuilder {\n autoWidth = false;\n autoHeight = true;\n width: number;\n height: number;\n\n world: World;\n content: WorldObject[] = [];\n viewingDirection: ViewingDirection = 'left-to-right';\n rows?: number;\n columns?: number = 4;\n spacing = 20;\n reversed = false;\n padding = 20;\n\n constructor() {\n this.world = World.withProps({ width: 0, height: 0, viewingDirection: 'left-to-right' });\n this.width = 0;\n this.height = 0;\n }\n\n setViewingDirection(viewingDirection: ViewingDirection) {\n this.viewingDirection = viewingDirection;\n }\n\n addContent(content: AbstractObject[]) {\n this.content.push(\n ...content.map((item) =>\n this.world.addObjectAt(item, {\n width: 0,\n height: 0,\n x: 0,\n y: 0,\n })\n )\n );\n }\n\n setWidth(width: number) {\n this.width = width;\n }\n\n setHeight(height: number) {\n this.height = height;\n }\n\n setSpacing(spacing: number) {\n this.spacing = spacing;\n }\n\n setPadding(padding: number) {\n this.padding = padding;\n }\n\n setRows(rows?: number) {\n this.autoWidth = true;\n this.rows = rows;\n }\n\n setColumns(columns?: number) {\n this.autoHeight = true;\n this.columns = columns;\n }\n\n recalculate() {\n if (this.height === 0 && this.width === 0) {\n // Nothing to render if its 0 width.\n return;\n }\n\n if (this.rows === 0 || this.columns === 0) {\n // No columns or rows.\n return;\n }\n\n if (this.autoHeight && !this.width) {\n throw new Error('Cannot set auto height without setting a width');\n }\n\n if (this.autoWidth && !this.height) {\n throw new Error('Cannot set auto width without setting a height');\n }\n\n if ((this.viewingDirection === 'left-to-right' || this.viewingDirection === 'top-to-bottom') && this.reversed) {\n this.reversed = false;\n this.content.reverse();\n }\n if ((this.viewingDirection === 'right-to-left' || this.viewingDirection === 'bottom-to-top') && !this.reversed) {\n this.reversed = true;\n this.content.reverse();\n }\n\n const len = this.content.length;\n\n const getColumns = () => {\n if (this.autoWidth && this.rows) {\n const rowsValue = len > this.rows ? this.rows : len;\n return {\n columns: Math.ceil(len / (rowsValue as number)),\n rows: rowsValue,\n };\n }\n\n if (this.autoHeight && this.columns) {\n const columnsValue = len > this.columns ? this.columns : len;\n return {\n columns: columnsValue,\n rows: Math.ceil(len / (columnsValue as number)),\n };\n }\n\n throw new Error('Something went wrong.');\n };\n\n const { columns, rows } = getColumns();\n const contentWidth = this.autoWidth ? -1 : this.width - this.padding * 2;\n // const contentHeight = this.autoHeight ? -1 : this.height - this.padding / 2;\n const itemWidth = this.autoWidth ? -1 : (contentWidth - this.spacing * (columns - 1)) / columns;\n // const itemHeight = this.autoHeight ? -1 : (contentWidth - this.spacing * (columns - 1)) / rows;\n\n // do rows then columns\n if (this.autoHeight && !this.autoWidth) {\n let index = 0;\n let rowHeights = this.padding;\n for (let r = 0; r < rows; r++) {\n if (index === len) {\n break;\n }\n let rowHeight = 0;\n const row = [];\n for (let c = 0; c < columns; c++) {\n const realIndex = this.reversed ? len - index : index;\n if (index === len) {\n break;\n }\n const item = this.content[realIndex];\n const width = item.width;\n const aspectRatio = item.width / item.height;\n const currentRowHeight = itemWidth / aspectRatio;\n row.push([\n index,\n itemWidth, // width\n currentRowHeight, // height\n itemWidth / width, // scale\n ]);\n if (currentRowHeight > rowHeight) {\n rowHeight = currentRowHeight;\n }\n index++;\n }\n // Back through the rows.\n for (let c = 0; c < columns; c++) {\n if (!row[c]) {\n break;\n }\n const worldPoints = this.world.getPoints();\n const currentIndex = row[c][0];\n const width = row[c][1];\n const height = row[c][2];\n const scale = row[c][3];\n const x = this.padding + c * (this.spacing + width);\n const y = rowHeights + (rowHeight - height) / 2;\n const realIndex = this.reversed ? len - currentIndex : currentIndex;\n const prevX = worldPoints[realIndex * 5 + 1];\n const prevY = worldPoints[realIndex * 5 + 2];\n\n this.world.scaleWorldObject(currentIndex, scale);\n if (prevX !== x || prevY !== y) {\n this.world.translateWorldObject(realIndex, x - prevX, y - prevY);\n }\n }\n // Add the current row to the total row heights\n rowHeights += rowHeight + this.spacing;\n }\n this.height = rowHeights + this.padding;\n this.world.resize(this.width, this.height);\n return;\n }\n\n // do columns then rows\n if (this.autoWidth && !this.autoHeight) {\n // @todo\n }\n\n // Fixed height and width, fit content\n if (!this.autoWidth && !this.autoHeight) {\n // @todo\n }\n }\n\n getWorld(): World {\n return this.world;\n }\n}\n","/**\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @providesModule UserAgent_DEPRECATED\n */\n\n/**\n * Provides entirely client-side User Agent and OS detection. You should prefer\n * the non-deprecated UserAgent module when possible, which exposes our\n * authoritative server-side PHP-based detection to the client.\n *\n * Usage is straightforward:\n *\n * if (UserAgent_DEPRECATED.ie()) {\n * // IE\n * }\n *\n * You can also do version checks:\n *\n * if (UserAgent_DEPRECATED.ie() >= 7) {\n * // IE7 or better\n * }\n *\n * The browser functions will return NaN if the browser does not match, so\n * you can also do version compares the other way:\n *\n * if (UserAgent_DEPRECATED.ie() < 7) {\n * // IE6 or worse\n * }\n *\n * Note that the version is a float and may include a minor version number,\n * so you should always use range operators to perform comparisons, not\n * strict equality.\n *\n * **Note:** You should **strongly** prefer capability detection to browser\n * version detection where it's reasonable:\n *\n * http://www.quirksmode.org/js/support.html\n *\n * Further, we have a large number of mature wrapper functions and classes\n * which abstract away many browser irregularities. Check the documentation,\n * grep for things, or ask on javascript@lists.facebook.com before writing yet\n * another copy of \"event || window.event\".\n *\n */\n\nvar _populated = false;\n\n// Browsers\nvar _ie, _firefox, _opera, _webkit, _chrome;\n\n// Actual IE browser for compatibility mode\nvar _ie_real_version;\n\n// Platforms\nvar _osx, _windows, _linux, _android;\n\n// Architectures\nvar _win64;\n\n// Devices\nvar _iphone, _ipad, _native;\n\nvar _mobile;\n\nfunction _populate() {\n if (_populated) {\n return;\n }\n\n _populated = true;\n\n // To work around buggy JS libraries that can't handle multi-digit\n // version numbers, Opera 10's user agent string claims it's Opera\n // 9, then later includes a Version/X.Y field:\n //\n // Opera/9.80 (foo) Presto/2.2.15 Version/10.10\n var uas = navigator.userAgent;\n var agent = /(?:MSIE.(\\d+\\.\\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\\d+\\.\\d+))|(?:Opera(?:.+Version.|.)(\\d+\\.\\d+))|(?:AppleWebKit.(\\d+(?:\\.\\d+)?))|(?:Trident\\/\\d+\\.\\d+.*rv:(\\d+\\.\\d+))/.exec(uas);\n var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas);\n\n _iphone = /\\b(iPhone|iP[ao]d)/.exec(uas);\n _ipad = /\\b(iP[ao]d)/.exec(uas);\n _android = /Android/i.exec(uas);\n _native = /FBAN\\/\\w+;/i.exec(uas);\n _mobile = /Mobile/i.exec(uas);\n\n // Note that the IE team blog would have you believe you should be checking\n // for 'Win64; x64'. But MSDN then reveals that you can actually be coming\n // from either x64 or ia64; so ultimately, you should just check for Win64\n // as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit\n // Windows will send 'WOW64' instead.\n _win64 = !!(/Win64/.exec(uas));\n\n if (agent) {\n _ie = agent[1] ? parseFloat(agent[1]) : (\n agent[5] ? parseFloat(agent[5]) : NaN);\n // IE compatibility mode\n if (_ie && document && document.documentMode) {\n _ie = document.documentMode;\n }\n // grab the \"true\" ie version from the trident token if available\n var trident = /(?:Trident\\/(\\d+.\\d+))/.exec(uas);\n _ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie;\n\n _firefox = agent[2] ? parseFloat(agent[2]) : NaN;\n _opera = agent[3] ? parseFloat(agent[3]) : NaN;\n _webkit = agent[4] ? parseFloat(agent[4]) : NaN;\n if (_webkit) {\n // We do not add the regexp to the above test, because it will always\n // match 'safari' only since 'AppleWebKit' appears before 'Chrome' in\n // the userAgent string.\n agent = /(?:Chrome\\/(\\d+\\.\\d+))/.exec(uas);\n _chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN;\n } else {\n _chrome = NaN;\n }\n } else {\n _ie = _firefox = _opera = _chrome = _webkit = NaN;\n }\n\n if (os) {\n if (os[1]) {\n // Detect OS X version. If no version number matches, set _osx to true.\n // Version examples: 10, 10_6_1, 10.7\n // Parses version number as a float, taking only first two sets of\n // digits. If only one set of digits is found, returns just the major\n // version number.\n var ver = /(?:Mac OS X (\\d+(?:[._]\\d+)?))/.exec(uas);\n\n _osx = ver ? parseFloat(ver[1].replace('_', '.')) : true;\n } else {\n _osx = false;\n }\n _windows = !!os[2];\n _linux = !!os[3];\n } else {\n _osx = _windows = _linux = false;\n }\n}\n\nvar UserAgent_DEPRECATED = {\n\n /**\n * Check if the UA is Internet Explorer.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n ie: function() {\n return _populate() || _ie;\n },\n\n /**\n * Check if we're in Internet Explorer compatibility mode.\n *\n * @return bool true if in compatibility mode, false if\n * not compatibility mode or not ie\n */\n ieCompatibilityMode: function() {\n return _populate() || (_ie_real_version > _ie);\n },\n\n\n /**\n * Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we\n * only need this because Skype can't handle 64-bit IE yet. We need to remove\n * this when we don't need it -- tracked by #601957.\n */\n ie64: function() {\n return UserAgent_DEPRECATED.ie() && _win64;\n },\n\n /**\n * Check if the UA is Firefox.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n firefox: function() {\n return _populate() || _firefox;\n },\n\n\n /**\n * Check if the UA is Opera.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n opera: function() {\n return _populate() || _opera;\n },\n\n\n /**\n * Check if the UA is WebKit.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n webkit: function() {\n return _populate() || _webkit;\n },\n\n /**\n * For Push\n * WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit\n */\n safari: function() {\n return UserAgent_DEPRECATED.webkit();\n },\n\n /**\n * Check if the UA is a Chrome browser.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n chrome : function() {\n return _populate() || _chrome;\n },\n\n\n /**\n * Check if the user is running Windows.\n *\n * @return bool `true' if the user's OS is Windows.\n */\n windows: function() {\n return _populate() || _windows;\n },\n\n\n /**\n * Check if the user is running Mac OS X.\n *\n * @return float|bool Returns a float if a version number is detected,\n * otherwise true/false.\n */\n osx: function() {\n return _populate() || _osx;\n },\n\n /**\n * Check if the user is running Linux.\n *\n * @return bool `true' if the user's OS is some flavor of Linux.\n */\n linux: function() {\n return _populate() || _linux;\n },\n\n /**\n * Check if the user is running on an iPhone or iPod platform.\n *\n * @return bool `true' if the user is running some flavor of the\n * iPhone OS.\n */\n iphone: function() {\n return _populate() || _iphone;\n },\n\n mobile: function() {\n return _populate() || (_iphone || _ipad || _android || _mobile);\n },\n\n nativeApp: function() {\n // webviews inside of the native apps\n return _populate() || _native;\n },\n\n android: function() {\n return _populate() || _android;\n },\n\n ipad: function() {\n return _populate() || _ipad;\n }\n};\n\nmodule.exports = UserAgent_DEPRECATED;\n","/**\n * Copyright (c) 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ExecutionEnvironment\n */\n\n/*jslint evil: true */\n\n'use strict';\n\nvar canUseDOM = !!(\n typeof window !== 'undefined' &&\n window.document &&\n window.document.createElement\n);\n\n/**\n * Simple, lightweight module assisting with the detection and context of\n * Worker. Helps avoid circular dependencies and allows code to reason about\n * whether or not they are in a Worker, even if they never include the main\n * `ReactWorker` dependency.\n */\nvar ExecutionEnvironment = {\n\n canUseDOM: canUseDOM,\n\n canUseWorkers: typeof Worker !== 'undefined',\n\n canUseEventListeners:\n canUseDOM && !!(window.addEventListener || window.attachEvent),\n\n canUseViewport: canUseDOM && !!window.screen,\n\n isInWorker: !canUseDOM // For now, this is true - might change in the future.\n\n};\n\nmodule.exports = ExecutionEnvironment;\n","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isEventSupported\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('./ExecutionEnvironment');\n\nvar useHasFeature;\nif (ExecutionEnvironment.canUseDOM) {\n useHasFeature =\n document.implementation &&\n document.implementation.hasFeature &&\n // always returns true in newer browsers as per the standard.\n // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n document.implementation.hasFeature('', '') !== true;\n}\n\n/**\n * Checks if an event is supported in the current execution environment.\n *\n * NOTE: This will not work correctly for non-generic events such as `change`,\n * `reset`, `load`, `error`, and `select`.\n *\n * Borrows from Modernizr.\n *\n * @param {string} eventNameSuffix Event name, e.g. \"click\".\n * @param {?boolean} capture Check if the capture phase is supported.\n * @return {boolean} True if the event is supported.\n * @internal\n * @license Modernizr 3.0.0pre (Custom Build) | MIT\n */\nfunction isEventSupported(eventNameSuffix, capture) {\n if (!ExecutionEnvironment.canUseDOM ||\n capture && !('addEventListener' in document)) {\n return false;\n }\n\n var eventName = 'on' + eventNameSuffix;\n var isSupported = eventName in document;\n\n if (!isSupported) {\n var element = document.createElement('div');\n element.setAttribute(eventName, 'return;');\n isSupported = typeof element[eventName] === 'function';\n }\n\n if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {\n // This is the only way to test support for the `wheel` event in IE9+.\n isSupported = document.implementation.hasFeature('Events.wheel', '3.0');\n }\n\n return isSupported;\n}\n\nmodule.exports = isEventSupported;\n","/**\n * Copyright (c) 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule normalizeWheel\n * @typechecks\n */\n\n'use strict';\n\nvar UserAgent_DEPRECATED = require('./UserAgent_DEPRECATED');\n\nvar isEventSupported = require('./isEventSupported');\n\n\n// Reasonable defaults\nvar PIXEL_STEP = 10;\nvar LINE_HEIGHT = 40;\nvar PAGE_HEIGHT = 800;\n\n/**\n * Mouse wheel (and 2-finger trackpad) support on the web sucks. It is\n * complicated, thus this doc is long and (hopefully) detailed enough to answer\n * your questions.\n *\n * If you need to react to the mouse wheel in a predictable way, this code is\n * like your bestest friend. * hugs *\n *\n * As of today, there are 4 DOM event types you can listen to:\n *\n * 'wheel' -- Chrome(31+), FF(17+), IE(9+)\n * 'mousewheel' -- Chrome, IE(6+), Opera, Safari\n * 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother!\n * 'DOMMouseScroll' -- FF(0.9.7+) since 2003\n *\n * So what to do? The is the best:\n *\n * normalizeWheel.getEventType();\n *\n * In your event callback, use this code to get sane interpretation of the\n * deltas. This code will return an object with properties:\n *\n * spinX -- normalized spin speed (use for zoom) - x plane\n * spinY -- \" - y plane\n * pixelX -- normalized distance (to pixels) - x plane\n * pixelY -- \" - y plane\n *\n * Wheel values are provided by the browser assuming you are using the wheel to\n * scroll a web page by a number of lines or pixels (or pages). Values can vary\n * significantly on different platforms and browsers, forgetting that you can\n * scroll at different speeds. Some devices (like trackpads) emit more events\n * at smaller increments with fine granularity, and some emit massive jumps with\n * linear speed or acceleration.\n *\n * This code does its best to normalize the deltas for you:\n *\n * - spin is trying to normalize how far the wheel was spun (or trackpad\n * dragged). This is super useful for zoom support where you want to\n * throw away the chunky scroll steps on the PC and make those equal to\n * the slow and smooth tiny steps on the Mac. Key data: This code tries to\n * resolve a single slow step on a wheel to 1.\n *\n * - pixel is normalizing the desired scroll delta in pixel units. You'll\n * get the crazy differences between browsers, but at least it'll be in\n * pixels!\n *\n * - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This\n * should translate to positive value zooming IN, negative zooming OUT.\n * This matches the newer 'wheel' event.\n *\n * Why are there spinX, spinY (or pixels)?\n *\n * - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn\n * with a mouse. It results in side-scrolling in the browser by default.\n *\n * - spinY is what you expect -- it's the classic axis of a mouse wheel.\n *\n * - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and\n * probably is by browsers in conjunction with fancy 3D controllers .. but\n * you know.\n *\n * Implementation info:\n *\n * Examples of 'wheel' event if you scroll slowly (down) by one step with an\n * average mouse:\n *\n * OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120)\n * OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12)\n * OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A)\n * Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120)\n * Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120)\n *\n * On the trackpad:\n *\n * OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6)\n * OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A)\n *\n * On other/older browsers.. it's more complicated as there can be multiple and\n * also missing delta values.\n *\n * The 'wheel' event is more standard:\n *\n * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents\n *\n * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and\n * deltaX, deltaY and deltaZ. Some browsers provide other values to maintain\n * backward compatibility with older events. Those other values help us\n * better normalize spin speed. Example of what the browsers provide:\n *\n * | event.wheelDelta | event.detail\n * ------------------+------------------+--------------\n * Safari v5/OS X | -120 | 0\n * Safari v5/Win7 | -120 | 0\n * Chrome v17/OS X | -120 | 0\n * Chrome v17/Win7 | -120 | 0\n * IE9/Win7 | -120 | undefined\n * Firefox v4/OS X | undefined | 1\n * Firefox v4/Win7 | undefined | 3\n *\n */\nfunction normalizeWheel(/*object*/ event) /*object*/ {\n var sX = 0, sY = 0, // spinX, spinY\n pX = 0, pY = 0; // pixelX, pixelY\n\n // Legacy\n if ('detail' in event) { sY = event.detail; }\n if ('wheelDelta' in event) { sY = -event.wheelDelta / 120; }\n if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; }\n if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; }\n\n // side scrolling on FF with DOMMouseScroll\n if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {\n sX = sY;\n sY = 0;\n }\n\n pX = sX * PIXEL_STEP;\n pY = sY * PIXEL_STEP;\n\n if ('deltaY' in event) { pY = event.deltaY; }\n if ('deltaX' in event) { pX = event.deltaX; }\n\n if ((pX || pY) && event.deltaMode) {\n if (event.deltaMode == 1) { // delta in LINE units\n pX *= LINE_HEIGHT;\n pY *= LINE_HEIGHT;\n } else { // delta in PAGE units\n pX *= PAGE_HEIGHT;\n pY *= PAGE_HEIGHT;\n }\n }\n\n // Fall-back if spin cannot be determined\n if (pX && !sX) { sX = (pX < 1) ? -1 : 1; }\n if (pY && !sY) { sY = (pY < 1) ? -1 : 1; }\n\n return { spinX : sX,\n spinY : sY,\n pixelX : pX,\n pixelY : pY };\n}\n\n\n/**\n * The best combination if you prefer spinX + spinY normalization. It favors\n * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with\n * 'wheel' event, making spin speed determination impossible.\n */\nnormalizeWheel.getEventType = function() /*string*/ {\n return (UserAgent_DEPRECATED.firefox())\n ? 'DOMMouseScroll'\n : (isEventSupported('wheel'))\n ? 'wheel'\n : 'mousewheel';\n};\n\nmodule.exports = normalizeWheel;\n","module.exports = require('./src/normalizeWheel.js');\n","/** @ts-ignore */\nimport normalizeWheel from 'normalize-wheel';\nimport { distance } from '../../utils';\nimport { compose, dna, scale, scaleAtOrigin, transform, translate } from '@atlas-viewer/dna';\nimport { RuntimeController } from '../../types';\nimport { easingFunctions } from '../../utility/easing-functions';\nimport { toBox } from '../../utility/to-box';\n\nconst INTENT_PAN = 'pan';\nconst INTENT_SCROLL = 'scroll';\nconst INTENT_GESTURE = 'gesture';\n\nexport type PopmotionControllerConfig = {\n zoomOutFactor?: number;\n zoomInFactor?: number;\n maxZoomFactor?: number;\n minZoomFactor?: number;\n zoomDuration?: number;\n zoomClamp?: number;\n zoomWheelConstant?: number;\n panBounceStiffness?: number;\n panBounceDamping?: number;\n panTimeConstant?: number;\n panPower?: number;\n nudgeDistance?: number;\n panPadding?: number;\n devicePixelRatio?: number;\n enableWheel?: boolean;\n enableClickToZoom?: boolean;\n ignoreSingleFingerTouch?: boolean;\n enablePanOnWait?: boolean;\n requireMetaKeyForWheelZoom?: boolean;\n panOnWaitDelay?: number;\n parentElement?: HTMLElement | null;\n onPanInSketchMode?: () => void;\n};\n\nexport const defaultConfig: Required<PopmotionControllerConfig> = {\n // Zoom options\n zoomOutFactor: 0.8,\n zoomInFactor: 1.25,\n maxZoomFactor: 1,\n minZoomFactor: 0.05,\n zoomDuration: 300,\n zoomWheelConstant: 20, // 30 = OSD\n // zoomWheelConstant: 15, // 15 = fast\n // zoomWheelConstant: 18,\n zoomClamp: 0.6,\n // Pan options.\n panBounceStiffness: 120,\n panBounceDamping: 15,\n panTimeConstant: 240,\n panPower: 0.1,\n nudgeDistance: 100,\n panPadding: 0,\n devicePixelRatio: 1,\n // Flags\n enableWheel: true,\n enableClickToZoom: true,\n ignoreSingleFingerTouch: false,\n enablePanOnWait: false,\n requireMetaKeyForWheelZoom: false,\n panOnWaitDelay: 40,\n onPanInSketchMode: () => {\n // no-op\n },\n parentElement: null,\n};\n\nexport const popmotionController = (config: PopmotionControllerConfig = {}): RuntimeController => {\n return {\n start: function (runtime) {\n const {\n zoomWheelConstant,\n enableWheel,\n enableClickToZoom,\n ignoreSingleFingerTouch,\n enablePanOnWait,\n panOnWaitDelay,\n parentElement,\n requireMetaKeyForWheelZoom,\n } = {\n ...defaultConfig,\n ...config,\n };\n\n const state = {\n pointerStart: { x: 0, y: 0 },\n isPressing: false,\n mousemoveBuffer: dna(5),\n multiTouch: {\n distance: 0,\n },\n };\n\n runtime.world.activatedEvents.push(\n // List of events we are supporting.\n 'onMouseUp',\n 'onMouseDown',\n 'onMouseMove',\n 'onTouchStart',\n 'onTouchEnd',\n 'onTouchMove',\n 'onContextMenu'\n );\n\n /**\n * Resets the event state after the gesture of behavior has finished\n */\n function resetState() {\n currentDistance = 0;\n intent = '';\n setDataAttribute();\n setDataAttribute(undefined, 'notice');\n touchStartTime = 0;\n }\n\n function onMouseUp() {\n runtime.world.constraintBounds();\n resetState();\n }\n\n function onMouseDown(e: MouseEvent & { atlas: { x: number; y: number } }) {\n if (e.which > 1) {\n state.isPressing = false;\n return;\n }\n if (runtime.mode === 'explore') {\n e.preventDefault();\n state.pointerStart.x = e.atlas.x;\n state.pointerStart.y = e.atlas.y;\n\n runtime.transitionManager.stopTransition();\n\n state.isPressing = true;\n }\n }\n\n function onWindowMouseUp() {\n resetState();\n if (state.isPressing) {\n if (runtime.mode === 'explore') {\n runtime.world.constraintBounds();\n }\n state.isPressing = false;\n }\n }\n\n let currentDistance = 0;\n // the performance.now() time at 'touch-start'\n let touchStartTime = 0;\n // what the user's intent would be for the behavior\n let intent = '';\n function onTouchStart(e: TouchEvent & { atlasTouches: Array<{ id: number; x: number; y: number }> }) {\n if (runtime.mode === 'explore') {\n if (e.atlasTouches.length === 1) {\n touchStartTime = performance.now();\n if (ignoreSingleFingerTouch == false) {\n // this prevents the touch propagation to the window, and thus doesn't drag the page\n e.preventDefault();\n }\n state.pointerStart.x = e.atlasTouches[0].x;\n state.pointerStart.y = e.atlasTouches[0].y;\n }\n if (e.atlasTouches.length === 2) {\n intent = INTENT_GESTURE;\n e.preventDefault();\n const x1 = e.atlasTouches[0].x;\n const x2 = e.atlasTouches[1].x;\n state.pointerStart.x = (x1 + x2) / 2;\n const y1 = e.atlasTouches[0].y;\n const y2 = e.atlasTouches[1].y;\n state.pointerStart.y = (y1 + y2) / 2;\n\n currentDistance = distance(\n { x: e.touches[0].clientX, y: e.touches[0].clientY },\n { x: e.touches[1].clientX, y: e.touches[1].clientY }\n );\n }\n\n runtime.transitionManager.stopTransition();\n\n state.isPressing = true;\n }\n }\n\n /**\n * Sets a data attribute to expose the current intent/behavior/note to the user\n *\n * @param value {string} - the data-attribute value\n * @param dataAttribute {string} - the data-attribute name\n */\n function setDataAttribute(value?: string, dataAttribute = 'intent') {\n if (parentElement) {\n parentElement.dataset[dataAttribute] = value;\n }\n }\n\n function onTouchMove(e: TouchEvent & { atlasTouches: Array<{ id: number; x: number; y: number }> }) {\n let clientX = null;\n let clientY = null;\n let isMulti = false;\n let newDistance = 0;\n if (state.isPressing && e.touches.length === 2) {\n // We have 2?\n const x1 = e.touches[0].clientX;\n const x2 = e.touches[1].clientX;\n clientX = (x1 + x2) / 2;\n const y1 = e.touches[0].clientY;\n const y2 = e.touches[1].clientY;\n clientY = (y1 + y2) / 2;\n\n newDistance = distance(\n { x: e.touches[0].clientX, y: e.touches[0].clientY },\n { x: e.touches[1].clientX, y: e.touches[1].clientY }\n );\n isMulti = true;\n }\n setDataAttribute(intent);\n\n if (state.isPressing && e.touches.length === 1) {\n if (enablePanOnWait) {\n // if there is a delay between the touch-start and the 1st touch-move of < xms, then treat that as a PAN, \n // anything faster is a window scroll\n if (performance.now() - touchStartTime < panOnWaitDelay && intent == '') {\n intent = INTENT_SCROLL;\n }\n if (intent == '') {\n intent = INTENT_PAN;\n }\n }\n setDataAttribute(intent);\n // if we are ignoring a single finger touch, or it's a window-scroll, just 'return'\n if ((intent == '' && ignoreSingleFingerTouch == true) || intent == INTENT_SCROLL) {\n // have CanvasPanel do nothing... scroll the page\n setDataAttribute('require-two-finger', 'notice');\n return;\n }\n const touch = e.touches[0];\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n\n // Translate.\n if (clientX !== null && clientY !== null) {\n const bounds = runtime.getRendererScreenPosition();\n if (bounds) {\n const { x, y } = runtime.viewerToWorld(clientX - bounds.x, clientY - bounds.y);\n\n const deltaDistance = newDistance && currentDistance ? newDistance / currentDistance : 1;\n\n runtime.transitionManager.customTransition((pendingTransition) => {\n pendingTransition.from = dna(runtime.target);\n pendingTransition.to = transform(\n pendingTransition.from,\n compose(\n translate(state.pointerStart.x - x, state.pointerStart.y - y),\n scaleAtOrigin(1 / deltaDistance, x, y)\n ),\n state.mousemoveBuffer\n );\n pendingTransition.elapsed_time = 0;\n pendingTransition.total_time = 0;\n pendingTransition.timingFunction = easingFunctions.easeInOutExpo;\n pendingTransition.done = false;\n });\n }\n currentDistance = newDistance;\n }\n\n if (intent == INTENT_PAN) {\n // if we're panning, prevent default\n // this does the same thing as touchEvents: none; pointerEvents: none;\n e.preventDefault();\n }\n }\n\n function onMouseMove(e: MouseEvent | PointerEvent) {\n if (state.isPressing) {\n const bounds = runtime.getRendererScreenPosition();\n if (bounds) {\n const { x, y } = runtime.viewerToWorld(e.clientX - bounds.x, e.clientY - bounds.y);\n // const atlas = runtime.\n runtime.transitionManager.customTransition((pendingTransition) => {\n pendingTransition.from = dna(runtime.target);\n pendingTransition.to = transform(\n pendingTransition.from,\n translate(state.pointerStart.x - x, state.pointerStart.y - y),\n state.mousemoveBuffer\n );\n pendingTransition.elapsed_time = 0;\n pendingTransition.total_time = 0;\n pendingTransition.timingFunction = easingFunctions.easeInOutExpo;\n pendingTransition.done = false;\n });\n }\n }\n }\n\n function onClick(e: MouseEvent & { atlas: { x: number; y: number } }) {\n if (runtime.mode === 'explore') {\n runtime.world.zoomIn(e.atlas);\n }\n }\n\n function onWheel(e: WheelEvent & { atlas: { x: number; y: number } }) {\n const normalized = normalizeWheel(e);\n const zoomFactor = 1 + normalized.spinY / zoomWheelConstant;\n runtime.world.zoomTo(\n // Generating a zoom from the wheel delta\n zoomFactor,\n e.atlas,\n true\n );\n }\n\n function onWheelGuard(e: WheelEvent) {\n if (requireMetaKeyForWheelZoom && e.metaKey == false) {\n setDataAttribute('meta-required', 'notice');\n e.stopPropagation();\n return false;\n }\n return true;\n }\n\n runtime.world.addEventListener('mouseup', onMouseUp);\n runtime.world.addEventListener('touchend', onMouseUp);\n runtime.world.addEventListener('touchstart', onTouchStart);\n runtime.world.addEventListener('mousedown', onMouseDown);\n\n window.addEventListener('touchend', onWindowMouseUp);\n window.addEventListener('mouseup', onWindowMouseUp);\n\n window.addEventListener('mousemove', onMouseMove);\n\n if (parentElement) {\n // if this is bound to the window, then the entire interaction model goes haywire\n // unclear 100% why\n parentElement.addEventListener('touchmove', onTouchMove as any);\n }\n\n if (enableClickToZoom) {\n runtime.world.activatedEvents.push('onClick');\n runtime.world.addEventListener('click', onClick);\n }\n\n if (enableWheel) {\n runtime.world.activatedEvents.push('onWheel');\n if (requireMetaKeyForWheelZoom) {\n // add an event listener above the world to guard the wheel event if the 'meta' key is pressed\n parentElement?.addEventListener('wheel', onWheelGuard as any, { passive: true, capture: true });\n }\n runtime.world.addEventListener('wheel', onWheel);\n }\n\n // Layout subscriber - move more into here.\n const removeLayout = runtime.world.addLayoutSubscriber((type, data?: any) => {\n if (type === 'zone-changed') {\n runtime.transitionManager.constrainBounds({\n transition: { duration: 0 },\n });\n }\n if (type === 'zoom-to' && data) {\n // zoomTo(data.factor, data.point, data.stream);\n runtime.transitionManager.zoomTo(data.factor, {\n origin: data.point,\n stream: data.stream,\n });\n }\n if (type === 'go-home') {\n const transition = data.immediate ? { duration: 0 } : undefined;\n const paddingPx = typeof data?.paddingPx !== 'undefined' ? data.paddingPx : (runtime as any).homePaddingPx;\n const target = runtime.getHomeTargetStrand({ paddingPx });\n runtime.transitionManager.applyTransition(\n target,\n transition,\n {\n duration: 1000,\n easing: easingFunctions.easeOutExpo,\n constrain: true,\n },\n { stream: false }\n );\n runtime.updateNextFrame();\n }\n if (type === 'goto-region' && data) {\n const transition = data.immediate ? { duration: 0 } : {};\n // If paddingPx is supplied, convert CSS pixels to world units. If it's a number we can pass\n // symmetric padding into goToRegion via the padding parameter. If it's a per-side object, expand\n // the region by the per-side amounts (converted to world units) and pass the expanded region.\n if (typeof data.paddingPx !== 'undefined') {\n const cssScale = runtime.getScaleFactor(false);\n if (typeof data.paddingPx === 'number') {\n const padding = data.paddingPx / cssScale;\n const region = { x: data.x, y: data.y, width: data.width, height: data.height, padding };\n runtime.transitionManager.goToRegion(region, { transition });\n } else {\n // object with left/right/top/bottom\n const left = data.paddingPx.left ? data.paddingPx.left / cssScale : 0;\n const right = data.paddingPx.right ? data.paddingPx.right / cssScale : 0;\n const top = data.paddingPx.top ? data.paddingPx.top / cssScale : 0;\n const bottom = data.paddingPx.bottom ? data.paddingPx.bottom / cssScale : 0;\n const expanded = { x: data.x - left, y: data.y - top, width: data.width + left + right, height: data.height + top + bottom };\n runtime.transitionManager.goToRegion(expanded, { transition });\n }\n } else {\n runtime.transitionManager.goToRegion(data, { transition });\n }\n }\n if (type === 'constrain-bounds') {\n runtime.transitionManager.constrainBounds({\n transition: data?.immediate ? { duration: 0 } : undefined,\n });\n }\n });\n\n return () => {\n runtime.world.removeEventListener('mouseup', onMouseUp);\n runtime.world.removeEventListener('touchend', onMouseUp);\n runtime.world.removeEventListener('touchstart', onTouchStart);\n runtime.world.removeEventListener('mousedown', onMouseDown);\n\n window.removeEventListener('touchend', onWindowMouseUp);\n window.removeEventListener('mouseup', onWindowMouseUp);\n\n runtime.world.removeEventListener('mousemove', onMouseMove);\n if (parentElement) {\n (parentElement as any).removeEventListener('touchmove', onMouseMove);\n (parentElement as any).removeEventListener('wheel', onWheelGuard, { passive: true, capture: true });\n }\n if (enableClickToZoom) {\n runtime.world.removeEventListener('click', onClick);\n }\n\n if (enableWheel) {\n runtime.world.removeEventListener('wheel', onWheel);\n }\n\n removeLayout();\n };\n },\n updatePosition() {\n // no-op\n },\n };\n};\n","import React, { useContext } from 'react';\nimport { ViewerMode } from '../../../renderer/runtime';\n\nexport const ModeContext = React.createContext<ViewerMode>('explore');\nModeContext.displayName = 'Mode';\n\nexport const useMode: () => ViewerMode = () => {\n return useContext(ModeContext);\n};\n\nexport function ModeProvider(props: { mode: ViewerMode; children: React.ReactNode }) {\n return <ModeContext.Provider value={props.mode}>{props.children}</ModeContext.Provider>;\n}\n","import React from 'react';\nimport { Preset } from '../presets/_types';\nimport { RectReadOnly } from 'react-use-measure';\n\nexport const AtlasContext = React.createContext<Preset | null>(null);\nAtlasContext.displayName = 'Atlas';\n\nexport const BoundsContext = React.createContext<RectReadOnly | null>(null);\nBoundsContext.displayName = 'Bounds';\n","let getCurrentTime: () => number;\nconst hasPerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';\n\nif (hasPerformanceNow) {\n const localPerformance = performance;\n getCurrentTime = () => localPerformance.now();\n} else {\n const localDate = Date;\n const initialTime = localDate.now();\n getCurrentTime = () => localDate.now() - initialTime;\n}\n\nexport { getCurrentTime as now };\n","import Reconciler_ from 'react-reconciler';\nimport type { OpaqueHandle } from 'react-reconciler';\nimport { now } from './utility/now';\nimport { Runtime } from '../../renderer/runtime';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { World } from '../../world';\nimport { WorldObject } from '../../world-objects/world-object';\nimport { AtlasObjectModel } from '../../aom';\nimport { BaseObject } from '../../objects/base-object';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { CompositeResource } from '../../spacial-content/composite-resource';\nimport { Text } from '../../objects/text';\nimport { Box } from '../../objects/box';\nimport { supportedEventAttributes, supportedEventMap } from '../../events';\nimport { ImageTexture } from '../../spacial-content/image-texture';\nimport React, { version } from 'react';\nimport { Geometry } from '../../objects/geometry';\n\nconst Reconciler = typeof Reconciler_ === 'function' ? Reconciler_ : null;\n\n// From react-reconciler/constants;\n// import { ContinuousEventPriority, DiscreteEventPriority, DefaultEventPriority } from 'react-reconciler/constants'\nconst ConcurrentRoot = 1;\nconst ContinuousEventPriority = 8;\nconst DefaultEventPriority = 32;\nconst DiscreteEventPriority = 2;\nconst IdleEventPriority = 268435456;\nconst LegacyRoot = 0;\nconst NoEventPriority = 0;\n\nfunction appendChild(parent: AtlasObjectModel<any, any>, child: any) {\n if (parent && parent.appendChild && child) {\n parent.appendChild(child);\n }\n}\n\nfunction removeChild(parent: AtlasObjectModel<any, any>, child: any) {\n if (parent && parent.removeChild && child) {\n parent.removeChild(child);\n }\n}\n\nfunction removeChildFromContainer(parent: Runtime, child: any) {\n return removeChild(parent.world, child);\n}\nfunction insertInContainerBefore(\n container: Runtime,\n child: AtlasObjectModel<any, any>,\n beforeChild: AtlasObjectModel<any, any>\n) {\n return insertBefore(container.world, child, beforeChild);\n}\n\nfunction insertBefore(parent: Runtime | AtlasObjectModel<any, any>, child: any, before: any) {\n if (parent && parent instanceof Runtime) {\n parent = parent.world;\n }\n if (parent && parent.insertBefore) {\n parent.insertBefore(child, before);\n }\n}\n\nexport function applyProps(instance: any, oldProps: any, newProps: any) {\n if (!newProps) {\n return;\n }\n if (instance.applyProps) {\n instance.applyProps(newProps);\n }\n\n if (instance instanceof BaseObject) {\n for (const ev of supportedEventAttributes) {\n const event = ev.slice(2).toLowerCase();\n if (newProps[ev] !== oldProps[ev]) {\n if (oldProps[ev]) {\n instance.removeEventListener(event as any, oldProps[ev]);\n }\n instance.addEventListener(event as any, newProps[ev]);\n }\n }\n }\n}\n\nexport function activateEvents(world: World, props: any) {\n const keys = Object.keys(props);\n let didActivate = false;\n for (const key of keys) {\n if (supportedEventAttributes.indexOf(key as any) !== -1) {\n const ev = (supportedEventMap as any)[key];\n if (ev) {\n if (world.activatedEvents.indexOf(ev) !== -1) continue;\n didActivate = true;\n world.activatedEvents.push(ev);\n }\n }\n }\n if (didActivate) {\n world.triggerEventActivation();\n }\n}\n\nconst roots = new Map<any, any>();\nconst emptyObject = {};\n\nfunction createInstance(\n type: string,\n { args = [], ...props }: any,\n runtime: Runtime,\n hostContext?: any,\n internalInstanceHandle?: Reconciler_.Fiber\n) {\n if (!(runtime instanceof Runtime) && internalInstanceHandle) {\n const fn = (node: Reconciler_.Fiber): Runtime => {\n if (!node.return) return node.stateNode && node.stateNode.containerInfo;\n else return fn(node.return);\n };\n runtime = fn(internalInstanceHandle);\n }\n\n let instance: BaseObject<any, any>;\n let world: World = runtime.world;\n switch (type) {\n case 'world':\n instance = World.withProps({ width: props.width, height: props.height, viewingDirection: 'left-to-right' });\n (instance as World).activatedEvents = world.activatedEvents;\n (instance as World).eventHandlers = world.eventHandlers;\n (instance as World).subscriptions = world.subscriptions;\n (instance as World).triggerEventActivation();\n world = instance as World;\n break;\n case 'box':\n instance = new Box();\n break;\n case 'shape':\n instance = new Geometry();\n break;\n case 'worldObject':\n case 'world-object':\n instance = new WorldObject();\n break;\n case 'worldImage':\n case 'world-image':\n instance = new SingleImage();\n break;\n case 'texture':\n instance = new ImageTexture();\n break;\n case 'compositeImage':\n case 'composite-image':\n // @todo switch to applyProps\n instance = new CompositeResource({\n id: props.id,\n width: props.width,\n height: props.height,\n images: [],\n renderOptions: props.renderOptions,\n });\n break;\n case 'tiledImage':\n case 'tiled-image':\n instance = TiledImage.fromTile(\n props.uri,\n props.display,\n props.tile,\n props.scaleFactor,\n undefined,\n props.format,\n props.useFloorCalc,\n props.version3\n );\n break;\n case 'paragraph':\n instance = new Text();\n (instance as Text).text = props.children;\n break;\n default:\n // throw new Error(`Element <${type} /> not found`);\n return;\n }\n\n activateEvents(world, props);\n applyProps(instance as any, {}, props);\n\n return instance;\n}\n\nfunction appendChildToContainer(runtime: Runtime, world: any) {\n if (world instanceof World) {\n runtime.world = world;\n } else if (world instanceof WorldObject) {\n runtime.world.appendChild(world);\n } else if (world) {\n throw new Error('Invalid root');\n }\n}\n\nlet currentUpdatePriority = NoEventPriority;\n\nconst reconciler = Reconciler\n ? Reconciler<\n any,\n any,\n Runtime,\n unknown, // Instance,\n unknown, // TextInstance,\n unknown, // SuspenseInstance,\n unknown, // HydratableInstance,\n unknown, // PublicInstance,\n unknown, // HostContext,\n unknown, // UpdatePayload,\n unknown, // _ChildSet,\n unknown, // TimeoutHandle,\n unknown // NoTimeout\n >({\n // @ts-ignore\n unstable_now: now,\n // @ts-ignore\n now,\n createInstance,\n removeChild,\n appendChild,\n appendInitialChild: appendChild,\n insertBefore: insertBefore,\n warnsIfNotActing: true,\n supportsMutation: true,\n isPrimaryRenderer: false,\n // @ts-ignore\n scheduleTimeout: typeof setTimeout !== 'undefined' ? setTimeout : undefined,\n // @ts-ignore\n cancelTimeout: typeof clearTimeout !== 'undefined' ? clearTimeout : undefined,\n setTimeout: typeof setTimeout !== 'undefined' ? setTimeout : undefined,\n clearTimeout: typeof clearTimeout !== 'undefined' ? clearTimeout : undefined,\n noTimeout: -1,\n appendChildToContainer,\n removeChildFromContainer: removeChildFromContainer,\n createTextInstance() {\n // no-op\n },\n insertInContainerBefore: insertInContainerBefore,\n prepareUpdate(instance: any, type: any, oldProps: any, newProps: any, runtime: Runtime) {\n activateEvents(runtime.world, newProps);\n return newProps;\n },\n commitUpdate(instance: any, type_: any, prevProps_: any, updatePayload_: any, internalHandle: OpaqueHandle) {\n let type = type_,\n updatePayload = updatePayload_;\n let prevProps = prevProps_;\n if (typeof updatePayload === 'string') {\n // react <= 18\n type = updatePayload_;\n updatePayload = prevProps_;\n }\n\n if (instance.applyProps && updatePayload) {\n applyProps(instance, prevProps, updatePayload);\n }\n },\n\n finalizeInitialChildren(instance: any) {\n // https://github.com/facebook/react/issues/20271\n // Returning true will trigger commitMount\n return instance?.__handlers;\n },\n getChildHostContext() {\n return emptyObject;\n },\n getRootHostContext() {\n return emptyObject;\n },\n prepareForCommit(runtime) {\n runtime.isCommitting = true;\n return null;\n },\n preparePortalMount() {\n // no-op\n },\n hideInstance(instance: BaseObject) {\n if (instance && instance.points) {\n instance.points[0] = 0;\n }\n // @todo these are called when a component is suspended\n },\n unhideInstance(instance: BaseObject, props: any) {\n if (instance && instance.points) {\n instance.points[0] = 1;\n }\n // @todo these are called when a component is suspended\n },\n getPublicInstance(instance: BaseObject) {\n return instance;\n },\n hideTextInstance() {\n throw new Error(\n 'Text is not allowed in the react-three-fibre tree. You may have extraneous whitespace between components.'\n );\n },\n resetAfterCommit(runtime) {\n runtime.isCommitting = false;\n runtime.pendingUpdate = true;\n if (runtime.world) {\n if (runtime.world.needsRecalculate) {\n runtime.world.recalculateWorldSize();\n runtime.world.triggerRepaint();\n }\n }\n },\n shouldSetTextContent() {\n return false;\n },\n clearContainer() {\n return false;\n },\n\n // 0.29.0 and later\n supportsHydration: false,\n supportsPersistence: false,\n\n detachDeletedInstance(node) {\n // no-op?\n // console.log('detachDeletedInstance', node);\n },\n\n afterActiveInstanceBlur() {\n // no-op\n },\n\n beforeActiveInstanceBlur() {\n // no-op\n },\n\n getCurrentEventPriority() {\n // If in the browser, check `window.event` and maybe do something different.\n return DefaultEventPriority;\n },\n\n getInstanceFromNode(node) {\n throw new Error('Not implemented');\n },\n\n getInstanceFromScope(scopeInstance) {\n throw new Error('Not implemented');\n // return nodeToInstanceMap.get(scopeInstance) || null;\n },\n\n prepareScopeUpdate(scopeInstance, instance) {\n throw new Error('Not implemented');\n // nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n logRecoverableError() {\n // noop\n },\n\n requestPostPaintCallback() {\n // noop\n },\n\n rendererPackageName: '@atlas-viewer/atlas',\n rendererVersion: version,\n\n // React 19.\n shouldAttemptEagerTransition: () => false,\n trackSchedulerEvent: () => {},\n resolveEventType: () => null,\n resolveEventTimeStamp: () => -1.1,\n maySuspendCommit: () => false,\n preloadInstance: () => true, // true indicates already loaded\n startSuspendingCommit() {},\n suspendInstance() {},\n waitForCommitToBeReady: () => null,\n NotPendingTransition: null,\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n resolveUpdatePriority() {\n if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;\n\n switch (typeof window !== 'undefined' && window.event?.type) {\n case 'click':\n case 'contextmenu':\n case 'dblclick':\n case 'pointercancel':\n case 'pointerdown':\n case 'pointerup':\n return DiscreteEventPriority;\n case 'pointermove':\n case 'pointerout':\n case 'pointerover':\n case 'pointerenter':\n case 'pointerleave':\n case 'wheel':\n return ContinuousEventPriority;\n default:\n return DefaultEventPriority;\n }\n },\n resetFormInstance() {},\n })\n : null;\n\nif (reconciler) {\n // @ts-ignore DefinitelyTyped is not up to date\n reconciler.injectIntoDevTools();\n}\n\nexport function unmountComponentAtNode(runtime: Runtime, callback?: (runtime: any) => void) {\n const root = roots.get(runtime);\n if (root) {\n if (!reconciler) return;\n reconciler.updateContainer(null, root, null, () => {\n roots.delete(runtime);\n if (callback) callback(runtime);\n });\n }\n}\n\nexport const ReactAtlas = {\n render(whatToRender: any, runtime: any) {\n const root = roots.get(runtime);\n\n if (!reconciler) return;\n\n if (root) {\n reconciler.updateContainer(whatToRender, root, null);\n } else {\n const newRoot = reconciler.createContainer(\n runtime,\n 0,\n null,\n false,\n null,\n '',\n () => {\n // on recoverable error.\n },\n null\n );\n\n reconciler.updateContainer(whatToRender, newRoot, null);\n roots.set(runtime, newRoot);\n }\n },\n unmountComponentAtNode(runtime: Runtime, callback?: (runtime: any) => void) {\n unmountComponentAtNode(runtime, callback);\n },\n};\n","import * as React from 'react';\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' && (window.document?.createElement || window.navigator?.product === 'ReactNative')\n ? React.useLayoutEffect\n : React.useEffect;\n","import React, { ReactNode, useCallback, useEffect, useLayoutEffect, useRef } from 'react';\nimport { ReactAtlas } from '../reconciler';\nimport { ModeContext } from '../hooks/use-mode';\nimport { AtlasContext, BoundsContext } from './AtlasContext';\nimport { ViewerMode } from '../../../renderer/runtime';\nimport { Preset } from '../presets/_types';\nimport { RectReadOnly } from 'react-use-measure';\nimport { useIsomorphicLayoutEffect } from '../utility/react';\n\ntype AtlasWithReconcilerProps = {\n onCreated?: (ctx: Preset) => void | Promise<void>;\n setIsReady: (value: boolean) => void;\n mode?: ViewerMode;\n bounds: RectReadOnly;\n preset: Preset | null;\n children?: ReactNode;\n};\n\nexport const AtlasWithReconciler: React.FC<AtlasWithReconcilerProps> = React.memo(\n ({ children, setIsReady, onCreated, bounds, preset, mode = 'explore' }) => {\n const AtlasRoot = useCallback(\n function AtlasRoot(props: { children: React.ReactElement }): JSX.Element {\n const strictModeDoubleRender = useRef(false);\n\n const activate = () => {\n setIsReady(true);\n };\n\n useEffect(() => {\n if (preset && !strictModeDoubleRender.current) {\n preset.runtime.goHome();\n\n const result = onCreated && onCreated(preset);\n return void (result && result.then ? result.then(activate) : activate());\n }\n return () => {\n // no-op\n };\n }, []);\n\n useEffect(() => {\n strictModeDoubleRender.current = true;\n }, []);\n\n return props.children;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [preset]\n );\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n if (mode !== runtime.mode) {\n runtime.mode = mode;\n }\n\n ReactAtlas.render(\n <React.StrictMode>\n <AtlasRoot>\n <BoundsContext.Provider value={bounds}>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </BoundsContext.Provider>\n </AtlasRoot>\n </React.StrictMode>,\n runtime\n );\n }\n }, [preset, mode, children]);\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n\n return () => {\n ReactAtlas.unmountComponentAtNode(runtime);\n };\n }\n return () => {\n // no-op\n };\n }, [preset]);\n\n return null;\n }\n);\n","import { Renderer } from '../../renderer/renderer';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { Box } from '../../objects/box';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { Strand } from '@atlas-viewer/dna';\nimport { World } from '../../world';\nimport { Paint } from '../../world-objects/paint';\nimport { PositionPair } from '../../types';\nimport { ImageTexture } from '../../spacial-content/image-texture';\n\nexport type WebGLRendererOptions = {\n dpi?: number;\n};\n\nexport class WebGLRenderer implements Renderer {\n canvas: HTMLCanvasElement;\n gl: WebGL2RenderingContext;\n\n program: WebGLProgram;\n fragmentShader: WebGLShader;\n vertexShader: WebGLShader;\n\n rectBuffer: Float32Array;\n\n // language=GLSL\n fragmentShaderSource = `\n precision mediump float;\n\n uniform sampler2D u_image;\n varying vec2 v_texCoord;\n\n void main() {\n gl_FragColor = texture2D(u_image, v_texCoord);\n }\n `;\n\n // language=GLSL\n vertexShaderSource = `\n attribute vec2 a_position;\n uniform vec2 u_resolution;\n varying vec4 v_color;\n uniform sampler2D u_texture;\n\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n\n void main() {\n\n // convert the position from pixels to 0.0 to 1.0\n vec2 zeroToOne = a_position / u_resolution;\n\n // convert from 0->1 to 0->2\n vec2 zeroToTwo = zeroToOne * 2.0;\n\n // convert from 0->2 to -1->+1 (clip space)\n vec2 clipSpace = zeroToTwo - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_texCoord = a_texCoord;\n }\n `;\n\n attributes: {\n position: number;\n texCoord: number;\n };\n uniforms: {\n resolution: WebGLUniformLocation | null;\n texture: WebGLUniformLocation | null;\n };\n buffers: {\n position: WebGLBuffer;\n texCoord: WebGLBuffer;\n };\n rendererPosition: DOMRect;\n dpi: number;\n\n constructor(canvas: HTMLCanvasElement, options?: WebGLRendererOptions) {\n this.canvas = canvas;\n this.rendererPosition = canvas.getBoundingClientRect();\n this.gl = canvas.getContext('webgl2') as WebGL2RenderingContext;\n\n this.fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSource);\n this.vertexShader = this.createShader(this.gl.VERTEX_SHADER, this.vertexShaderSource);\n this.program = this.createProgram(this.vertexShader, this.fragmentShader);\n this.dpi = options?.dpi || 1;\n\n // Shader locations.\n this.attributes = {\n position: this.gl.getAttribLocation(this.program, 'a_position'),\n texCoord: this.gl.getAttribLocation(this.program, 'a_texCoord'),\n };\n this.uniforms = {\n resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),\n texture: this.gl.getUniformLocation(this.program, 'u_texture'),\n };\n\n this.buffers = {\n position: this.createArrayBuffer(),\n texCoord: this.createArrayBuffer(new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0])),\n };\n\n this.rectBuffer = new Float32Array(12);\n\n // Resize step.\n this.resize();\n\n // @todo change.\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.gl.clearColor(0, 0, 0, 0);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n this.gl.useProgram(this.program);\n this.gl.enableVertexAttribArray(this.attributes.position);\n }\n\n resize() {\n this.resizeCanvasToDisplaySize();\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.rendererPosition = this.canvas.getBoundingClientRect();\n }\n\n isReady() {\n return true;\n }\n\n beforeFrame(world: World, delta: number, target: Strand) {\n this.gl.clearColor(0, 0, 0, 0);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n this.gl.vertexAttribPointer(this.attributes.position, 2, this.gl.FLOAT, false, 0, 0);\n this.gl.uniform2f(this.uniforms.resolution, this.gl.canvas.width, this.gl.canvas.height);\n if (this.lastResize > 1000) {\n this.lastResize = 0;\n this.resizeCanvasToDisplaySize();\n }\n this.lastResize += delta;\n }\n\n lastResize = 0;\n\n prepareLayer(paint: SpacialContent) {\n // no-op.\n if (!paint.__host || !paint.__host.webgl) {\n if (paint instanceof SingleImage || paint instanceof TiledImage) {\n // create it if it does not exist.\n this.createImageHost(paint);\n }\n if (paint instanceof ImageTexture) {\n this.createTextureHost(paint);\n }\n // if (paint instanceof Box) {\n // this.createTextureHost(paint);\n // }\n }\n }\n\n createTextureHost(paint: ImageTexture | Box) {\n paint.__host = paint.__host ? paint.__host : {};\n\n const gl = this.gl;\n const texture = this.gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n let lastImage;\n\n if (paint instanceof ImageTexture) {\n const initial = paint.getTexture();\n if (initial.source) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, initial.source);\n }\n lastImage = initial;\n } else {\n // @todo draw box and set webgl.updateTexture function.\n // const data = paint.props.backgroundColor === 'red' ? new Uint8Array([255, 0, 0]) : new Uint8Array([0, 0, 255]);\n // const alignment = 1;\n // gl.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, data);\n }\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\n paint.__host.webgl = {\n height: paint.height,\n width: paint.width,\n texture,\n lastImage,\n };\n }\n\n createImageHost(paint: SingleImage | TiledImage) {\n const textures = [...new Array(paint.points.length / 5)];\n\n paint.__host = paint.__host ? paint.__host : {};\n\n paint.__host.webgl = {\n height: paint.height,\n width: paint.width,\n textures,\n loading: [],\n loaded: [],\n lastLevelRendered: -1,\n onLoad: (index: number, image: any) => {\n const gl = this.gl;\n const texture = this.gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.bindTexture(gl.TEXTURE_2D, null);\n paint.__host.webgl.textures[index] = texture;\n paint.__host.webgl.loaded.push(index);\n },\n };\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n if (paint.type === 'spacial-content') {\n if (paint.__host && paint.__host.webgl) {\n if (paint.getTexture) {\n const newText = paint?.getTexture();\n if (newText && paint.__host.webgl.lastImage !== newText.hash && newText.source && !paint.__host.webgl.error) {\n try {\n const level = 0;\n const internalFormat = this.gl.RGBA;\n const srcFormat = this.gl.RGBA;\n const srcType = this.gl.UNSIGNED_BYTE;\n this.gl.bindTexture(this.gl.TEXTURE_2D, paint.__host.webgl.texture);\n this.gl.texImage2D(this.gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, newText.source);\n paint.__host.webgl.lastImage = newText.hash;\n } catch (e) {\n paint.__host.webgl.error = e;\n }\n }\n }\n\n if (paint.__host.webgl.loading && paint.__host.webgl.loading.indexOf(index) === -1 && paint.getImageUrl) {\n paint.__host.webgl.loading.push(index);\n const image = document.createElement('img');\n image.decoding = 'async';\n image.crossOrigin = 'anonymous';\n image.src = paint.getImageUrl(index);\n image.onload = () => {\n image.onload = null;\n return paint.__host.webgl.onLoad(index, image);\n };\n }\n\n const texture = paint.__host.webgl.texture ? paint.__host.webgl.texture : paint.__host.webgl.textures[index];\n if (texture) {\n this.gl.enableVertexAttribArray(this.attributes.texCoord);\n\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.texCoord);\n this.gl.enableVertexAttribArray(this.attributes.texCoord);\n this.gl.vertexAttribPointer(this.attributes.texCoord, 2, this.gl.FLOAT, false, 0, 0);\n\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.position);\n this.gl.enableVertexAttribArray(this.attributes.position);\n this.gl.vertexAttribPointer(this.attributes.position, 2, this.gl.FLOAT, false, 0, 0);\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n this.gl.uniform1i(this.uniforms.texture, 0);\n this.setRectangle(x, y, width, height);\n this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n }\n }\n }\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand) {\n // no-op\n }\n\n pendingUpdate(): boolean {\n return true;\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n afterFrame() {\n // no-op.\n }\n\n lastKnownScale = 1;\n\n getScale(width: number, height: number, dpi?: boolean): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const canvas = this.getCanvasDims();\n const w = canvas.width / width;\n const h = canvas.height / height;\n const scale = (w < h ? h : w) * (dpi ? this.dpi || 1 : 1);\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n getCanvasDims() {\n return { width: this.canvas.width / this.dpi, height: this.canvas.height / this.dpi };\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n // Helpers.\n createShader(type: number, source: string) {\n const shader = this.gl.createShader(type);\n if (shader) {\n this.gl.shaderSource(shader, source);\n this.gl.compileShader(shader);\n const success = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);\n if (success) {\n return shader;\n }\n\n const info = this.gl.getShaderInfoLog(shader);\n this.gl.deleteShader(shader);\n if (info) {\n throw new Error(info);\n }\n }\n\n throw new Error('Invalid shader');\n }\n\n createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = this.gl.createProgram();\n if (program) {\n this.gl.attachShader(program, vertexShader);\n this.gl.attachShader(program, fragmentShader);\n this.gl.linkProgram(program);\n const success = this.gl.getProgramParameter(program, this.gl.LINK_STATUS);\n if (success) {\n return program;\n }\n\n const info = this.gl.getProgramInfoLog(program);\n this.gl.deleteProgram(program);\n if (info) {\n throw new Error(info);\n }\n }\n throw new Error('Invalid program');\n }\n\n resizeCanvasToDisplaySize() {\n const canvas = this.gl.canvas as HTMLCanvasElement;\n // Lookup the size the browser is displaying the canvas in CSS pixels.\n const displayWidth = canvas.clientWidth;\n const displayHeight = canvas.clientHeight;\n\n // Check if the canvas is not the same size.\n const needResize = canvas.width !== displayWidth || canvas.height !== displayHeight;\n\n if (needResize) {\n // Make the canvas the same size\n canvas.width = displayWidth;\n canvas.height = displayHeight;\n }\n\n return needResize;\n }\n\n createArrayBuffer(data?: Float32Array) {\n const buffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n if (data) {\n this.gl.bufferData(this.gl.ARRAY_BUFFER, data, this.gl.STATIC_DRAW);\n }\n\n if (!buffer) {\n throw new Error('Cannot create buffer');\n }\n return buffer;\n }\n\n setRectangle(x: number, y: number, width: number, height: number) {\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.getRectangle(x, y, width, height), this.gl.STATIC_DRAW);\n }\n\n getRectangle(x: number, y: number, width: number, height: number) {\n const x1 = x;\n const x2 = x + width;\n const y1 = y;\n const y2 = y + height;\n this.rectBuffer.set([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]);\n return this.rectBuffer;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n finishLayer() {}\n reset() {}\n}\n","/**\n * A string hashing function based on Daniel J. Bernstein's popular 'times 33' hash algorithm.\n * @author MatthewBarker <mrjbarker@hotmail.com>\n */\nexport function hash(object: any, str?: boolean): string {\n const text = str ? object : JSON.stringify(object);\n\n let numHash = 5381,\n index = text.length;\n\n while (index) {\n numHash = (numHash * 33) ^ text.charCodeAt(--index);\n }\n\n const num = numHash >>> 0;\n\n const hexString = num.toString(16);\n if (hexString.length % 2) {\n return '0' + hexString;\n }\n return hexString;\n}\n","import { hash } from './hash';\n\nexport class Stylesheet {\n $element: HTMLStyleElement;\n stylesheetClasses: string[];\n activeStylesheetClasses: string[];\n sheetsDidUpdate: boolean;\n sheetPrefix: string;\n stylesheetEntries: Record<string, string>;\n\n constructor(options?: { sheetPrefix?: string }) {\n this.sheetPrefix = options?.sheetPrefix || 'a-';\n this.$element = document.createElement('style');\n this.stylesheetClasses = [];\n this.activeStylesheetClasses = [];\n this.sheetsDidUpdate = false;\n this.stylesheetEntries = {};\n }\n\n getElement() {\n return this.$element;\n }\n\n addStylesheet(_sheet: string) {\n const sheet = _sheet.replace(/\\s\\s+/g, ' ').replace(/: /g, ':').replace(/; /g, ';').trim();\n const className = this.sheetPrefix + hash(sheet, true);\n if (this.stylesheetClasses.indexOf(className) !== -1) {\n return className;\n }\n this.stylesheetClasses.push(className);\n this.activeStylesheetClasses.push(className);\n this.stylesheetEntries[className] = sheet;\n this.sheetsDidUpdate = true;\n return className;\n }\n\n removeStylesheet(obj: any) {\n const className = this.sheetPrefix + hash(obj, true);\n if (this.stylesheetClasses.indexOf(className)) {\n this.stylesheetClasses = this.stylesheetClasses.filter((t) => t !== className);\n }\n this.sheetsDidUpdate = true;\n }\n\n clearClasses() {\n this.activeStylesheetClasses = [];\n }\n\n didUpdateActive() {\n if (this.activeStylesheetClasses.length) {\n for (const sheet of this.activeStylesheetClasses) {\n if (this.stylesheetClasses.indexOf(sheet) === -1) {\n return true;\n }\n }\n for (const sheet of this.stylesheetClasses) {\n if (this.activeStylesheetClasses.indexOf(sheet) === -1) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n updateSheet() {\n if (this.sheetsDidUpdate || this.didUpdateActive()) {\n this.$element.innerText = this.activeStylesheetClasses\n .map((className) => `.${className}{${this.stylesheetEntries[className]}}`)\n .join('');\n this.sheetsDidUpdate = false;\n this.stylesheetClasses = [...this.activeStylesheetClasses];\n }\n }\n}\n","import { Renderer } from '../../renderer/renderer';\nimport { Paint } from '../../world-objects/paint';\nimport { World } from '../../world';\nimport { Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { PositionPair } from '../../types';\nimport { Text } from '../../objects/text';\nimport { Box } from '../../objects/box';\nimport { Stylesheet } from '../../utility/stylesheet';\n\nexport type OverlayRendererOptions = {\n sheetPrefix: string;\n box: boolean;\n text: boolean;\n inlineStyles: boolean;\n triggerResize: () => void;\n background: string;\n};\n\nexport class OverlayRenderer implements Renderer {\n htmlContainer: HTMLDivElement;\n visible: Array<Text | Box | SpacialContent> = [];\n previousVisible: Array<Text | Box | SpacialContent> = [];\n htmlIds: string[] = [];\n firstMeaningfulPaint = false;\n rendererPosition: DOMRect;\n stylesheet: Stylesheet;\n options: OverlayRendererOptions;\n paintTx = 1;\n zIndex = 0;\n classes: {\n hostClassName: string;\n interactive: string;\n nonInteractive: string;\n };\n\n constructor(htmlContainer: HTMLDivElement, options?: Partial<OverlayRendererOptions>) {\n this.htmlContainer = htmlContainer;\n this.htmlContainer.innerHTML = '';\n this.rendererPosition = this.htmlContainer.getBoundingClientRect();\n this.options = {\n triggerResize: () => {},\n box: false,\n text: false,\n sheetPrefix: '',\n inlineStyles: false,\n background: '',\n ...(options || {}),\n };\n this.stylesheet = new Stylesheet({ sheetPrefix: this.options.sheetPrefix });\n if (!this.options.inlineStyles) {\n this.htmlContainer.appendChild(this.stylesheet.getElement());\n }\n\n if (this.options.background) {\n this.htmlContainer.classList.add(\n this.stylesheet.addStylesheet(`\n background: ${this.options.background};\n `)\n );\n }\n\n // Default classes.\n this.classes = {\n hostClassName: this.stylesheet.addStylesheet(`\n position: absolute;\n transform-origin: 0px 0px;\n `),\n interactive: this.stylesheet.addStylesheet(`pointer-events: all`),\n nonInteractive: this.stylesheet.addStylesheet(`pointer-events: none`),\n };\n this.stylesheet.updateSheet();\n }\n\n createHtmlHost(paint: Text | Box) {\n if (this.htmlContainer && (this.options.box || paint.props.className || paint.props.html || paint.props.href)) {\n const div = document.createElement(paint.props.href ? 'a' : 'div');\n if (paint.props.href) {\n div.style.display = 'block';\n (div as HTMLAnchorElement).href = paint.props.href;\n const target = paint.props.hrefTarget || '_blank';\n (div as HTMLAnchorElement).target = target;\n if (target !== '_self') {\n (div as HTMLAnchorElement).rel = 'noopener noreferrer';\n }\n }\n div.title = paint.props.title || '';\n if (this.options.inlineStyles) {\n div.style.display = 'block';\n div.style.position = 'absolute';\n div.style.overflow = 'hidden';\n div.style.transformOrigin = '0px 0px';\n } else {\n div.classList.add(this.classes.hostClassName);\n }\n paint.__host = { element: div, revision: null, relative: false };\n this.updateHtmlHost(paint, paint.width, paint.height);\n if (paint.__onCreate) {\n paint.__onCreate();\n }\n }\n }\n\n triggerResize() {\n this.options.triggerResize();\n }\n\n updateHtmlHost(paint: Text | Box, width?: number, height?: number) {\n if (paint.__revision !== paint.__host.revision) {\n const div = paint.__host.element;\n const classes = [this.classes.hostClassName];\n\n if (paint.props.interactive) {\n if (this.options.inlineStyles) {\n div.style.pointerEvents = 'all';\n } else {\n classes.push(this.classes.interactive);\n }\n } else {\n if (this.options.inlineStyles) {\n div.style.pointerEvents = 'none';\n } else {\n classes.push(this.classes.nonInteractive);\n }\n }\n\n if (paint.props.href) {\n div.style.display = 'block';\n (div as HTMLAnchorElement).href = paint.props.href;\n const target = paint.props.hrefTarget || '_blank';\n (div as HTMLAnchorElement).target = target;\n if (target !== '_self') {\n (div as HTMLAnchorElement).rel = 'noopener noreferrer';\n } else {\n (div as HTMLAnchorElement).rel = '';\n }\n } else if ((div as HTMLAnchorElement).href) {\n (div as HTMLAnchorElement).removeAttribute('href');\n }\n\n if (paint.props.title) {\n div.title = paint.props.title || '';\n }\n\n if (paint.props.className) {\n classes.push(paint.props.className);\n if (paint.hovering) {\n classes.push(`${paint.props.className}--hover`);\n }\n if (paint.pressing) {\n classes.push(`${paint.props.className}--active`);\n }\n }\n\n if (paint.props.relativeStyle) {\n div.style.width = `${width || paint.width}px`;\n div.style.height = `${height || paint.height}px`;\n } else {\n div.style.width = `${paint.width}px`;\n div.style.height = `${paint.height}px`;\n }\n\n const style = (paint.props as any).style;\n if (style) {\n Object.assign(\n div.style,\n (paint.props as any).style || {},\n (paint as any).hovering ? (paint.props as any).hoverStyles || {} : {},\n (paint as any).pressing ? (paint.props as any).pressStyles || {} : {}\n );\n return;\n }\n\n if (this.options.text && paint instanceof Text) {\n if (paint.text) {\n div.innerText = paint.text;\n }\n if (paint.backgroundColor) {\n div.style.backgroundColor = paint.backgroundColor;\n }\n if (paint.color) {\n div.style.color = paint.color;\n }\n if (paint.props.font) {\n div.style.font = paint.props.font;\n }\n if (paint.props.textAlign) {\n div.style.textAlign = paint.props.textAlign;\n }\n paint.__host.revision = paint.__revision;\n const classNames = classes.join(' ');\n div.className = classNames;\n div.part = classNames;\n }\n if (paint instanceof Box && (this.options.box || paint.props.className || paint.props.html)) {\n if (paint.props.backgroundColor) {\n div.style.backgroundColor = paint.props.backgroundColor;\n }\n if (paint.props.border !== div.style.border) {\n div.style.border = paint.props.border;\n }\n }\n\n const classNames = classes.join(' ');\n div.className = classNames;\n div.part = classNames;\n }\n }\n\n afterFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.updateSheet();\n\n for (const prev of this.previousVisible) {\n if (this.visible.indexOf(prev) === -1) {\n if (\n // HTML container\n this.htmlContainer &&\n // Previous ID\n prev.__id &&\n // Is it in the list.\n this.htmlIds.indexOf(prev.__id) !== -1\n ) {\n this.htmlContainer.removeChild(prev.__host.element);\n }\n }\n }\n // Set them.\n this.previousVisible = this.visible;\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {\n // No-op\n }\n\n beforeFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.clearClasses();\n this.paintTx++;\n this.zIndex = 0;\n this.visible = [];\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n const w = this.rendererPosition.width / width;\n const h = this.rendererPosition.height / height;\n return w < h ? h : w;\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n isReady(): boolean {\n return false;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n this.zIndex++;\n\n if (\n ((this.options.text && paint instanceof Text) ||\n (paint instanceof Box && (this.options.box || paint.props.className || paint.props.html))) &&\n paint.__host.tx !== this.paintTx\n ) {\n this.visible.push(paint);\n paint.__host.tx = this.paintTx;\n\n if (this.htmlContainer) {\n this.updateHtmlHost(paint, width, height);\n\n const scale = width / paint.width;\n const element: HTMLDivElement = paint.__host.element;\n element.style.zIndex = `${this.zIndex}`;\n\n if (paint.props.relativeStyle) {\n element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;\n // element.style.transformOrigin = '0px 0px';\n } else {\n // How to rotate overlays.. but don't do it.\n // element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px) translate(${width/2}px, ${height/2}px) rotate(${paint.__owner.value?.rotation || 0}deg) translate(-${width/2}px, -${height/2}px) scale(${scale})`;\n element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px) scale(${scale})`;\n // element.style.transformOrigin = '0px 0px';\n }\n\n if (this.previousVisible.indexOf(paint) === -1) {\n this.htmlContainer.appendChild(element);\n }\n if (this.htmlIds.indexOf(paint.__id) === -1) {\n this.htmlIds.push(paint.__id);\n }\n }\n }\n }\n\n pendingUpdate(): boolean {\n return false;\n }\n\n prepareLayer(paint: SpacialContent): void {\n if (!paint.__host) {\n if (paint instanceof Text || paint instanceof Box) {\n this.createHtmlHost(paint);\n }\n }\n }\n\n resize(width?: number, height?: number): void {\n if (typeof width !== 'undefined' && typeof height !== 'undefined') {\n this.htmlContainer.style.width = `${width}px`;\n this.htmlContainer.style.height = `${height}px`;\n }\n this.rendererPosition = this.htmlContainer.getBoundingClientRect();\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n finishLayer() {}\n\n reset() {}\n}\n","import { Runtime } from '../../renderer/runtime';\nimport { distance } from '../../utils';\nimport { BaseObject } from '../../objects/base-object';\nimport { supportedEventMap } from '../../events';\n\nexport type BrowserEventManagerOptions = {\n /** Default 50ms **/\n simulationRate: number;\n};\n\nexport class BrowserEventManager {\n element: HTMLElement;\n runtime: Runtime;\n unsubscribe: () => any;\n activatedEvents: string[] = [];\n eventHandlers: [string, any][] = [];\n bounds: DOMRect;\n listening: boolean;\n static eventPool = {\n atlas: { x: 0, y: 0 },\n };\n\n // Elements being moused over.\n // lastTouches: { x: number; y: number }[] = [];\n\n // Some state.\n pointerMoveEvent: PointerEvent | undefined = undefined;\n pointerEventState: {\n isClicking: boolean;\n isPressed: boolean;\n isDragging: boolean;\n mousedOver: BaseObject[];\n itemsBeingDragged: BaseObject[];\n mouseDownStart: { x: number; y: number };\n lastTouches: Array<{ id: number; x: number; y: number }>;\n } = {\n isClicking: false,\n isDragging: false,\n isPressed: false,\n mousedOver: [],\n itemsBeingDragged: [],\n mouseDownStart: { x: 0, y: 0 },\n lastTouches: [],\n };\n\n options: BrowserEventManagerOptions;\n\n constructor(element: HTMLElement, runtime: Runtime, options?: Partial<BrowserEventManagerOptions>) {\n this.element = element;\n this.runtime = runtime;\n this.unsubscribe = runtime.world.addLayoutSubscriber(this.layoutSubscriber.bind(this));\n this.bounds = element.getBoundingClientRect();\n this.listening = false;\n this.options = {\n simulationRate: 0,\n ...(options || {}),\n };\n\n let tAcc = 0;\n runtime.registerHook('useFrame', (t: number) => {\n tAcc += t;\n if (tAcc > this.options.simulationRate && this.pointerMoveEvent) {\n tAcc = 0;\n runtime.updateNextFrame();\n }\n });\n\n runtime.registerHook('useBeforeFrame', () => {\n if (this.pointerMoveEvent) {\n this.onPointerMove(this.pointerMoveEvent);\n }\n });\n\n // this is necessary for CavnasPanel to initialize the event listener\n this.activateEvents();\n }\n\n updateBounds() {\n this.bounds = this.element.getBoundingClientRect();\n this.runtime.updateRendererScreenPosition();\n }\n\n layoutSubscriber(type: string) {\n if (type === 'event-activation' && this.listening == false) {\n this.activateEvents();\n }\n }\n\n assignToEvent(e: any, x: number, y: number) {\n BrowserEventManager.eventPool.atlas.x = x;\n BrowserEventManager.eventPool.atlas.y = y;\n e.atlas = BrowserEventManager.eventPool.atlas;\n }\n\n activateEvents() {\n this.listening = true;\n this.element.addEventListener('pointermove', this._realPointerMove);\n this.element.addEventListener('pointerup', this.onPointerUp);\n this.element.addEventListener('pointerdown', this.onPointerDown);\n\n // Normal events.\n this.element.addEventListener('mousedown', this.onPointerEvent);\n this.element.addEventListener('mouseup', this.onPointerEvent);\n this.element.addEventListener('pointercancel', this.onPointerEvent);\n\n // Edge-cases\n this.element.addEventListener('wheel', this.onWheelEvent);\n this.element.addEventListener('contextmenu', this.onContextMenu);\n\n // Touch events.\n this.element.addEventListener('touchstart', this.onTouchEvent);\n this.element.addEventListener('touchcancel', this.onTouchEvent);\n this.element.addEventListener('touchend', this.onTouchEvent);\n this.element.addEventListener('touchmove', this.onTouchEvent);\n }\n\n _realPointerMove = (e: PointerEvent) => {\n this.pointerMoveEvent = e;\n };\n\n onWheelEvent = (e: WheelEvent) => {\n e.preventDefault();\n\n this.onPointerEvent(e);\n };\n \n onContextMenu = (e: MouseEvent) => {\n e.preventDefault();\n const ev = 'onContextMenu';\n if (this.runtime.world.activatedEvents.indexOf(ev) !== -1) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n this.assignToEvent(e, x, y);\n this.runtime.world.propagatePointerEvent(ev as any, e, x, y);\n }\n };\n\n onTouchEvent = (e: TouchEvent) => {\n const type = (supportedEventMap as any)[e.type as any];\n const atlasTouches = [];\n // const atlasTargetTouches = [];\n const len = e.touches.length;\n for (let i = 0; i < len; i++) {\n const touch = e.touches.item(i);\n if (!touch) continue;\n const { x, y } = this.runtime.viewerToWorld(touch.clientX - this.bounds.left, touch.clientY - this.bounds.top);\n\n const atlasTouch = { id: touch.identifier, x, y };\n\n atlasTouches.push(atlasTouch);\n }\n\n if (atlasTouches.length) {\n // Assign the first touch to the main atlas variable\n this.assignToEvent(e, atlasTouches[0].x, atlasTouches[0].y);\n }\n\n if (type !== 'onTouchEnd') {\n this.pointerEventState.lastTouches = atlasTouches;\n (e as any).atlasTouches = atlasTouches;\n this.runtime.world.propagateTouchEvent(type, e as any, atlasTouches);\n } else {\n (e as any).atlasTouches = [];\n this.runtime.world.propagateTouchEvent(type, e as any, this.pointerEventState.lastTouches);\n this.pointerEventState.lastTouches = [];\n }\n };\n\n onPointerEvent = (e: PointerEvent | MouseEvent) => {\n if(e.button === 2){\n return;\n }\n const ev = (supportedEventMap as any)[e.type as any];\n if (ev && this.runtime.world.activatedEvents.indexOf(ev) !== -1) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n this.assignToEvent(e, x, y);\n this.runtime.world.propagatePointerEvent(ev as any, e, x, y);\n }\n };\n\n onPointerDown = (e: PointerEvent | MouseEvent) => {\n if(e.button === 2){\n return;\n }\n this.pointerEventState.isPressed = true;\n this.pointerEventState.isClicking = true;\n this.pointerEventState.mouseDownStart.x = e.clientX;\n this.pointerEventState.mouseDownStart.y = e.clientY;\n setTimeout(() => {\n if (this.runtime) {\n this.pointerEventState.isClicking = false;\n }\n }, 250);\n setTimeout(() => {\n if (this.runtime && this.pointerEventState.isPressed && !this.pointerEventState.isDragging) {\n const dragStart = this.runtime.viewerToWorld(\n this.pointerEventState.mouseDownStart.x - this.bounds.left,\n this.pointerEventState.mouseDownStart.y - this.bounds.top\n );\n this.pointerEventState.isDragging = true;\n this.pointerEventState.itemsBeingDragged = this.runtime.world.propagatePointerEvent(\n 'onDragStart',\n e,\n dragStart.x,\n dragStart.y\n );\n }\n }, 800);\n\n // And then handle as normal pointer event.\n this.onPointerEvent(e);\n };\n\n onPointerUp = (e: PointerEvent | MouseEvent) => {\n if(e.button === 2){\n return;\n }\n if (this.pointerEventState.isClicking) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n\n this.assignToEvent(e, x, y);\n\n this.runtime.world.propagatePointerEvent('onClick', e, x, y);\n }\n\n if (this.pointerEventState.isDragging) {\n for (const item of this.pointerEventState.itemsBeingDragged) {\n item.dispatchEvent('onDragEnd', e);\n }\n this.pointerEventState.isDragging = false;\n }\n this.pointerEventState.isClicking = false;\n this.pointerEventState.isPressed = false;\n this.pointerEventState.itemsBeingDragged = [];\n\n // Then handle as normal pointer event.\n this.onPointerEvent(e);\n };\n\n onPointerMove = (e: PointerEvent | MouseEvent) => {\n this.pointerMoveEvent = undefined;\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n\n if (Number.isNaN(x) || Number.isNaN(y)) {\n return;\n }\n\n this.assignToEvent(e, x, y);\n\n // We have to propagate both, but only get a new list from one.\n this.runtime.world.propagatePointerEvent('onPointerMove', e, x, y);\n const newList = this.runtime.world.propagatePointerEvent('onMouseMove', e, x, y);\n\n // This is where we handle mouse enter and mouse leave events. This could be\n // stored and handled inside of the world.\n const newIds = [];\n const newItems = [];\n for (const item of newList) {\n newIds.push(item.id);\n newItems.push(item);\n if (this.pointerEventState.mousedOver.indexOf(item) === -1) {\n item.dispatchEvent('onMouseEnter', e);\n item.dispatchEvent('onPointerEnter', e);\n\n // @todo the behaviour of these are slightly different.\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseover_event\n item.dispatchEvent('onMouseOver', e);\n item.dispatchEvent('onPointerOver', e);\n }\n }\n for (const oldItem of this.pointerEventState.mousedOver) {\n if (newIds.indexOf(oldItem.id) === -1) {\n oldItem.dispatchEvent('onMouseLeave', e);\n oldItem.dispatchEvent('onPointerLeave', e);\n\n // @todo the behaviour of these are slightly different.\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseout_event\n oldItem.dispatchEvent('onMouseOut', e);\n oldItem.dispatchEvent('onPointerOut', e);\n }\n }\n\n if (this.pointerEventState.isDragging) {\n for (const item of this.pointerEventState.itemsBeingDragged) {\n item.dispatchEvent('onDrag', e);\n }\n // @todo take the results of this and do a drag-over.\n }\n\n if (\n this.pointerEventState.isPressed &&\n !this.pointerEventState.isDragging &&\n distance(this.pointerEventState.mouseDownStart, { x: e.clientX, y: e.clientY }) > 50\n ) {\n const dragStart = this.runtime.viewerToWorld(\n this.pointerEventState.mouseDownStart.x - this.bounds.left,\n this.pointerEventState.mouseDownStart.y - this.bounds.top\n );\n this.pointerEventState.isDragging = true;\n this.pointerEventState.itemsBeingDragged = this.runtime.world.propagatePointerEvent(\n 'onDragStart',\n { ...e, atlas: { x: dragStart.x, y: dragStart.y } },\n dragStart.x,\n dragStart.y\n );\n }\n this.pointerEventState.mousedOver = newItems;\n };\n\n normalizeEventName(event: string) {\n if (event.startsWith('on')) {\n return event.slice(2).toLowerCase();\n }\n return event.toLowerCase();\n }\n\n stop() {\n this.listening = false;\n this.element.removeEventListener('pointermove', this._realPointerMove);\n this.element.removeEventListener('pointerup', this.onPointerUp);\n this.element.removeEventListener('pointerdown', this.onPointerDown);\n\n // Normal events.\n this.element.removeEventListener('mousedown', this.onPointerEvent);\n this.element.removeEventListener('mouseup', this.onPointerEvent);\n this.element.removeEventListener('pointercancel', this.onPointerEvent);\n\n // Edge-cases\n this.element.removeEventListener('wheel', this.onWheelEvent);\n\n // Touch events.\n this.element.removeEventListener('touchstart', this.onTouchEvent);\n this.element.removeEventListener('touchcancel', this.onTouchEvent);\n this.element.removeEventListener('touchend', this.onTouchEvent);\n this.element.removeEventListener('touchmove', this.onTouchEvent);\n\n // Unbind all events.\n this.unsubscribe();\n for (const [event, handler] of this.eventHandlers) {\n this.element.removeEventListener(this.normalizeEventName(event), handler);\n }\n }\n}\n","import { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { CompositeRenderer } from '../../composite-renderer/composite-renderer';\nimport { WebGLRenderer } from '../../webgl-renderer/webgl-renderer';\nimport { CanvasRenderer } from '../../canvas-renderer/canvas-renderer';\nimport { OverlayRenderer } from '../../overlay-renderer/overlay-renderer';\nimport { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { Preset, PresetArgs } from './_types';\nimport { unmountComponentAtNode } from '../reconciler';\nimport { DebugRenderer } from '../../debug-renderer/debug-renderer';\n\nexport type DefaultPresetName = 'default-preset';\n\nexport type DefaultPresetOptions = {\n controllerConfig?: any;\n unstable_webglRenderer?: boolean;\n interactive?: boolean;\n dpi?: number;\n debug?: boolean;\n canvasBox?: boolean;\n polygon?: boolean;\n};\n\nexport function defaultPreset({\n interactive = true,\n viewport,\n forceRefresh,\n canvasElement,\n overlayElement,\n controllerConfig,\n unstable_webglRenderer,\n dpi,\n debug,\n canvasBox = true,\n polygon = true,\n navigatorElement,\n runtimeOptions,\n}: PresetArgs & DefaultPresetOptions): Preset {\n if (!canvasElement) {\n throw new Error('Invalid container');\n }\n\n canvasElement.style.userSelect = 'none';\n\n const controller = interactive\n ? popmotionController({\n minZoomFactor: 0.5,\n maxZoomFactor: 3,\n enableClickToZoom: false,\n parentElement: canvasElement,\n ...(controllerConfig || {}),\n })\n : undefined;\n\n const renderer = new CompositeRenderer([\n unstable_webglRenderer\n ? new WebGLRenderer(canvasElement, { dpi })\n : new CanvasRenderer(canvasElement, { dpi, debug, box: canvasBox, polygon }),\n overlayElement\n ? new OverlayRenderer(overlayElement, {\n box: unstable_webglRenderer || !canvasBox,\n text: true,\n triggerResize: forceRefresh,\n })\n : undefined,\n navigatorElement ? new DebugRenderer(navigatorElement) : undefined,\n ]);\n\n const runtime = new Runtime(\n renderer,\n new World(1024, 1024),\n viewport,\n controller ? [controller] : [],\n runtimeOptions\n );\n\n const em = new BrowserEventManager(canvasElement, runtime);\n\n return {\n name: 'default-preset',\n em,\n runtime,\n renderer,\n controller,\n canvas: canvasElement,\n navigator: navigatorElement,\n unmount() {\n unmountComponentAtNode(runtime);\n runtime.stopControllers();\n runtime.stop();\n runtime.reset();\n if (em) {\n em.stop();\n }\n },\n };\n}\n","import { Renderer } from '../../renderer/renderer';\nimport { World } from '../../world';\nimport { Paint } from '../../world-objects/paint';\nimport { Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { PositionPair } from '../../types';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { Stylesheet } from '../../utility/stylesheet';\n\ntype StaticRendererOptions = {\n imageClass: string;\n addPart: boolean;\n setDraggableFalse: boolean;\n widthStylesheet: boolean;\n sheetPrefix: string;\n background: string;\n};\n\n// @todo make this configurable.\nconst MIN = 1 + Number.MIN_VALUE;\n\nexport class StaticRenderer implements Renderer {\n container: HTMLElement;\n width: number;\n height: number;\n pending = true;\n options: StaticRendererOptions;\n stylesheet: Stylesheet;\n zIndex = 0;\n lastKnownScale = 1;\n rendererPosition: DOMRect;\n\n constructor(container: HTMLElement, options?: Partial<StaticRendererOptions>) {\n this.container = container;\n this.rendererPosition = container.getBoundingClientRect();\n const { width, height } = this.rendererPosition;\n this.width = width;\n this.height = height;\n this.options = {\n addPart: false,\n setDraggableFalse: false,\n imageClass: '',\n widthStylesheet: false,\n sheetPrefix: 'position-',\n background: '#000',\n ...(options || {}),\n };\n this.stylesheet = new Stylesheet({ sheetPrefix: this.options.sheetPrefix });\n this.container.classList.add(\n this.stylesheet.addStylesheet(`\n background: ${this.options.background};\n `)\n );\n if (this.options.widthStylesheet) {\n this.container.appendChild(this.stylesheet.getElement());\n }\n }\n\n isReady(): boolean {\n return true;\n }\n\n resize() {\n this.rendererPosition = this.container.getBoundingClientRect();\n this.width = this.rendererPosition.width;\n this.height = this.rendererPosition.height;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n afterFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.updateSheet();\n\n for (const item of this.previouslyVisible) {\n if (this.currentlyVisible.indexOf(item) === -1) {\n this.container.removeChild(item);\n }\n }\n\n for (const item of this.currentlyVisible) {\n if (this.previouslyVisible.indexOf(item) === -1) {\n this.container.appendChild(item);\n }\n }\n\n this.previouslyVisible = this.currentlyVisible;\n this.currentlyVisible = [];\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {}\n\n beforeFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.clearClasses();\n this.zIndex = 0;\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const w = this.width / width;\n const h = this.height / height;\n const scale = w < h ? h : w;\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n currentlyVisible: HTMLElement[] = [];\n previouslyVisible: HTMLElement[] = [];\n\n createImage() {\n const image = document.createElement('img');\n\n if (this.options.imageClass) {\n image.className = this.options.imageClass;\n if (this.options.addPart) {\n image.setAttribute('part', this.options.imageClass);\n }\n } else {\n image.style.position = 'absolute';\n image.style.pointerEvents = 'none';\n image.style.userSelect = 'none';\n }\n if (this.options.setDraggableFalse) {\n image.setAttribute('draggable', 'false');\n }\n return image;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n // Unsure.\n this.pending = false;\n this.zIndex++;\n\n if (paint instanceof SingleImage) {\n if (!paint.__host) {\n const image = this.createImage();\n image.src = paint.uri;\n paint.__host = image;\n this.container.appendChild(paint.__host);\n }\n\n const element: HTMLImageElement = paint.__host;\n this.currentlyVisible.push(element);\n\n element.style.zIndex = `${this.zIndex}`;\n element.style.opacity = `${paint.style.opacity}`;\n\n if (this.options.widthStylesheet) {\n element.className =\n this.options.imageClass +\n ' ' +\n this.stylesheet.addStylesheet(`width:${(width + MIN).toFixed(2)}px;height:${(height + MIN).toFixed(2)}px;`);\n } else {\n element.style.width = `${width + MIN}px`;\n element.style.height = `${height + MIN}px`;\n }\n element.style.transform = `translate(${x}px, ${y}px)`;\n }\n if (paint instanceof TiledImage) {\n if (!paint.__host) {\n paint.__host = {\n images: [],\n };\n }\n\n if (!paint.__host.images[index]) {\n const url = paint.getImageUrl(index);\n const image = this.createImage();\n image.src = url;\n paint.__host.images[index] = image;\n this.container.appendChild(image);\n }\n const element: HTMLImageElement = paint.__host.images[index];\n element.style.zIndex = `${this.zIndex}`;\n element.style.opacity = `${paint.style.opacity}`;\n\n this.currentlyVisible.push(element);\n\n if (this.options.widthStylesheet) {\n element.className =\n this.options.imageClass +\n ' ' +\n this.stylesheet.addStylesheet(`width:${(width + MIN).toFixed(2)}px;height:${(height + MIN).toFixed(2)}px;`);\n } else {\n element.style.width = `${width + MIN}px`;\n element.style.height = `${height + MIN}px`;\n }\n element.style.transform = `translate(${x}px, ${y}px)`;\n }\n }\n\n pendingUpdate(): boolean {\n return this.pending;\n }\n\n prepareLayer(paint: SpacialContent): void {}\n finishLayer(paint: SpacialContent): void {}\n reset() {}\n}\n","import { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { Preset, PresetArgs } from './_types';\nimport { StaticRenderer } from '../../static-renderer/static-renderer';\nimport { unmountComponentAtNode } from '../reconciler';\nimport { CompositeRenderer } from '../../composite-renderer/composite-renderer';\nimport { OverlayRenderer } from '../../overlay-renderer/overlay-renderer';\n\nexport type StaticPresetName = 'static-preset';\n\nexport type StaticPresetOptions = {\n controllerConfig?: any;\n interactive?: boolean;\n};\n\nexport function staticPreset({\n interactive,\n viewport,\n forceRefresh,\n containerElement,\n overlayElement,\n controllerConfig,\n}: PresetArgs & StaticPresetOptions): Preset {\n if (!containerElement) {\n throw new Error('Invalid container');\n }\n containerElement.style.userSelect = 'none';\n\n const controller = interactive\n ? popmotionController({\n minZoomFactor: 0.5,\n maxZoomFactor: 3,\n enableClickToZoom: false,\n parentElement: containerElement,\n ...(controllerConfig || {}),\n })\n : undefined;\n\n const staticRenderer = new StaticRenderer(containerElement, {\n addPart: false,\n setDraggableFalse: false,\n imageClass: 'atlas-static-image',\n });\n const renderer = overlayElement\n ? new CompositeRenderer([\n staticRenderer,\n new OverlayRenderer(overlayElement, {\n box: true,\n text: true,\n triggerResize: forceRefresh,\n }),\n ])\n : staticRenderer;\n\n const runtime = new Runtime(renderer, new World(1024, 1024), viewport, controller ? [controller] : []);\n\n const em = new BrowserEventManager(containerElement, runtime);\n\n return {\n name: 'static-preset',\n em,\n runtime,\n renderer,\n controller,\n container: containerElement,\n overlay: overlayElement,\n unmount() {\n unmountComponentAtNode(runtime);\n runtime.stopControllers();\n runtime.stop();\n if (em) {\n em.stop();\n }\n },\n };\n}\n","import { defaultPreset, DefaultPresetName, DefaultPresetOptions } from './default-preset';\nimport { staticPreset, StaticPresetName, StaticPresetOptions } from './static-preset';\nimport { Preset } from './_types';\n\nexport const presets: { [key in PresetNames]: (options: any) => Preset } = {\n 'default-preset': defaultPreset,\n 'static-preset': staticPreset,\n};\n\nexport type PresetNames = DefaultPresetName | StaticPresetName;\n\nexport type Presets =\n | readonly [DefaultPresetName, DefaultPresetOptions]\n | readonly [StaticPresetName, StaticPresetOptions];\n","import { PresetNames, Presets, presets } from '../presets';\nimport { Preset, PresetArgs } from '../presets/_types';\nimport { defaultPreset } from '../presets/default-preset';\nimport { useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nconst defaultArgs = {};\n\nexport function usePreset(\n renderPreset: PresetNames | Presets | undefined,\n options: { width: number; height: number; forceRefresh?: any; unstable_webglRenderer?: boolean }\n) {\n const overlayRef = useRef<HTMLDivElement>();\n const canvasRef = useRef<HTMLCanvasElement>();\n const navigatorRef = useRef<HTMLCanvasElement>();\n const containerRef = useRef<HTMLElement>();\n const viewport = useRef<{ width: number; height: number; didUpdate?: boolean }>({\n width: options.width,\n height: options.height,\n didUpdate: true,\n });\n\n const [presetName = 'default-preset', presetArgs = defaultArgs] = Array.isArray(renderPreset)\n ? renderPreset || []\n : [renderPreset];\n\n const [preset, setPreset] = useState<Preset | null>(null);\n\n useLayoutEffect(() => {\n const canvasElement = canvasRef.current;\n const containerElement = containerRef.current;\n const overlayElement = overlayRef.current;\n const navigatorElement = navigatorRef.current;\n const presetFn = ((presets as any)[presetName as any] as (config: PresetArgs) => Preset) || defaultPreset;\n\n const createdPreset = presetFn({\n containerElement,\n canvasElement,\n overlayElement,\n navigatorElement,\n viewport: viewport.current,\n dpi: window.devicePixelRatio || 1,\n forceRefresh: options.forceRefresh,\n unstable_webglRenderer: options.unstable_webglRenderer,\n ...(presetArgs || {}),\n });\n\n setPreset(createdPreset);\n\n return () => {\n if (createdPreset) {\n createdPreset.unmount();\n\n if (canvasElement) {\n canvasElement.height = 0;\n canvasElement.width = 0;\n }\n if (overlayElement) {\n overlayElement.innerHTML = '';\n }\n if (navigatorElement) {\n navigatorElement.height = 0;\n navigatorElement.width = 0;\n }\n }\n };\n }, [presetName, presetArgs]);\n\n const refs = useMemo(\n () => ({\n canvas: canvasRef,\n overlay: overlayRef,\n container: containerRef,\n navigator: navigatorRef,\n }),\n []\n );\n\n return [presetName, preset, viewport, refs] as const;\n}\n","import { hash } from '../../../utility/hash';\nimport { useMemo } from 'react';\n\nexport function useClassname(deps: any[]) {\n return useMemo(() => hash(deps), deps);\n}\n","import React from 'react';\n\nexport const Container = React.forwardRef<HTMLDivElement, any>((props, ref) => {\n // @ts-ignore\n return <div {...props} ref={ref} part={props.className} />;\n});\n","import { useRef } from \"react\";\nimport type { AtlasProps } from \"../Atlas\";\n\nfunction diffProps(\n beforeProps: AtlasProps & {\n width: number;\n height: number;\n },\n afterProps: AtlasProps & {\n width: number;\n height: number;\n }\n) {\n const changes: Record<string, { before: any; after: any }> = {};\n\n // Get all unique keys from both objects\n const allKeys = new Set([...Object.keys(beforeProps), ...Object.keys(afterProps)]);\n\n for (const key of allKeys) {\n const beforeValue = (beforeProps as any)[key];\n const afterValue = (afterProps as any)[key];\n\n // Simple comparison - could be enhanced for deep object comparison if needed\n if (beforeValue !== afterValue) {\n changes[key] = {\n before: beforeValue,\n after: afterValue,\n };\n }\n }\n\n return Object.keys(changes).length > 0 ? changes : null;\n}\n\nexport function useDiffProps(props: any, name = '', enabled = false) {\n const prevProps = useRef(props);\n if (prevProps.current && enabled) {\n console.log('Diff:', name, diffProps(prevProps.current, props));\n prevProps.current = props;\n }\n}\n","import React, { ReactNode, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Runtime, RuntimeOptions, ViewerFilters, ViewerMode } from '../../renderer/runtime';\nimport { PopmotionControllerConfig } from '../popmotion-controller/popmotion-controller';\nimport { ModeContext } from './hooks/use-mode';\nimport useMeasure from 'react-use-measure';\nimport { AtlasContext, BoundsContext } from './components/AtlasContext';\nimport { AtlasWithReconciler } from './components/AtlasWithReconciler';\nimport { PresetNames, Presets } from './presets';\nimport { Preset } from './presets/_types';\nimport { usePreset } from './hooks/use-preset';\nimport { Projection } from '@atlas-viewer/dna';\nimport { useClassname } from './hooks/use-classname';\nimport { Container } from './components/Container';\nimport { useIsomorphicLayoutEffect } from './utility/react';\nimport { useDiffProps } from './hooks/use-diff-props';\n\nexport type AtlasProps = {\n debug?: boolean;\n mode?: ViewerMode;\n onCreated?: (ctx: Preset) => void | Promise<void>;\n resetWorldOnChange?: boolean;\n unstable_webglRenderer?: boolean;\n unstable_noReconciler?: boolean;\n overlayStyle?: any;\n containerStyle?: any;\n containerProps?: any;\n controllerConfig?: PopmotionControllerConfig;\n renderPreset?: PresetNames | Presets;\n hideInlineStyle?: boolean;\n homeCover?: true | false | 'start' | 'end';\n homeOnResize?: boolean;\n homePosition?: Projection;\n /**\n * Home padding in CSS pixels. Can be a number (symmetric) or an object with any of\n * `left`, `right`, `top`, `bottom` for per-side CSS pixel margins.\n */\n homePaddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n className?: string;\n background?: string;\n enableNavigator?: boolean;\n htmlChildren?: ReactNode;\n children: ReactNode;\n runtimeOptions?: Partial<RuntimeOptions>;\n filters?: Partial<ViewerFilters>;\n};\n\nconst filterProperties = [\n 'brightness',\n 'contrast',\n 'grayscale',\n 'hueRotate',\n 'invert',\n 'saturate',\n 'sepia',\n 'blur',\n] as const;\n\nexport const Atlas: React.FC<\n AtlasProps & {\n width: number;\n height: number;\n }\n> = memo(function Atlas(props) {\n let {\n htmlChildren,\n renderPreset: _renderPreset,\n onCreated,\n mode: _mode = 'explore',\n resetWorldOnChange = true,\n // eslint-disable-next-line\n unstable_webglRenderer = false,\n // eslint-disable-next-line\n unstable_noReconciler = false,\n hideInlineStyle = false,\n controllerConfig,\n children,\n overlayStyle,\n containerStyle,\n enableNavigator,\n className,\n containerProps = {},\n homePosition,\n homeOnResize,\n homeCover,\n background,\n runtimeOptions,\n debug,\n filters,\n homePaddingPx,\n ...restProps\n } = props;\n\n useDiffProps(props, 'Atlas.tsx', props.debug);\n\n const [mode, setMode] = useState(_mode);\n // Reference to the current HTML Canvas element\n // Set by React by passing <canvas ref={...} />\n // Used to instantiate the controller and viewer with the correct HTML element.\n const [isReady, setIsReady] = useState(false);\n const strictModeDoubleRender = useRef(false);\n\n const renderPreset = useMemo<PresetNames | Presets>(() => {\n if (typeof _renderPreset === 'string') {\n _renderPreset = [_renderPreset, {}] as Presets;\n }\n if (debug) {\n if (_renderPreset) {\n return [_renderPreset[0], { debug, ...(_renderPreset[1] || {}) }];\n }\n return ['default-preset', { debug }];\n }\n return _renderPreset || 'default-preset';\n }, [_renderPreset, debug]);\n\n // This is an HTML element that sits above the Canvas element that is passed to the controller.\n // Additional non-canvas drawn elements can be placed here and positioned. CSS is applied to this\n // element by this component to absolutely position it. The overlay is updated if the \"bounds\" change\n // on the parent element and matches the size of it.\n\n // This measures the height and width of the Atlas element.\n const [_ref, bounds, forceRefresh] = useMeasure({ scroll: true });\n const outerContainerRef = useRef<HTMLDivElement>();\n const ref = (component: HTMLDivElement) => {\n outerContainerRef.current = component;\n _ref(component);\n };\n\n const [presetName, preset, viewport, refs] = usePreset(renderPreset, {\n width: restProps.width,\n height: restProps.height,\n forceRefresh,\n unstable_webglRenderer,\n });\n\n // This holds the class name for the container. This is changes when the\n // editing mode changes.\n const [containerClassName, setContainerClassName] = useState('');\n\n useEffect(() => {\n setMode(_mode);\n }, [_mode]);\n\n // This changes the mutable state object with the position (top/left/width/height) of the\n // canvas element on the page. This is used in the editing tools such as BoxDraw for comparing\n // positions.\n useEffect(() => {\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n }, [preset, bounds]);\n\n useEffect(() => {\n preset?.runtime.setOptions(runtimeOptions || {});\n }, [runtimeOptions]);\n\n // This changes the mode in the state object when the prop passed in changes. This will\n // be picked up by the renderer on the next method. There is not current way to detect this change.\n // @todo create a mode change event.\n useEffect(() => {\n if (preset && preset.runtime) {\n preset.runtime.mode = mode;\n }\n if (isReady && preset) {\n preset.ready = true;\n }\n }, [preset, isReady, mode]);\n\n useEffect(() => {\n if (preset) {\n // Home cover handled separately.\n if (!homeCover) {\n preset.runtime.manualHomePosition = !!homePosition;\n preset.runtime.setHomePosition(homePosition);\n }\n }\n }, [preset, homeCover, homePosition]);\n\n // Home padding: apply to runtime when preset or prop changes.\n useEffect(() => {\n if (preset) {\n preset.runtime.setHomePaddingPx(homePaddingPx as any);\n }\n }, [preset, homePaddingPx]);\n\n // When the width and height change this will resize the viewer and then reset the view to fit the element.\n // @todo improve or make configurable.\n // @todo resize event.\n useEffect(() => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n viewport.current.didUpdate = true;\n }\n }, [preset, restProps.width, restProps.height, viewport]);\n\n useEffect(() => {\n if (filters && preset) {\n const rt: Runtime = preset.runtime;\n let didUpdate = false;\n rt.hookOptions.enableFilters = true;\n\n for (const property of filterProperties) {\n if (filters[property]) {\n if (filters[property] !== preset.runtime.hookOptions.filters[property]) {\n rt.hookOptions.filters[property] = filters[property] as number;\n didUpdate = true;\n }\n } else if (rt.hookOptions.filters[property]) {\n rt.hookOptions.filters[property] = 0;\n didUpdate = true;\n }\n }\n\n if (didUpdate) {\n rt.updateNextFrame();\n }\n } else {\n if (preset) {\n const rt: Runtime = preset.runtime;\n for (const property of filterProperties) {\n rt.hookOptions.filters[property] = 0;\n }\n rt.hookOptions.enableFilters = false;\n rt.updateNextFrame();\n }\n }\n }, [preset, filters]);\n\n function recalculateHomeCover() {\n if (preset) {\n if (preset.overlay) {\n preset.overlay.style.width = `${bounds.width}px`;\n preset.overlay.style.height = `${bounds.height}px`;\n }\n\n if (preset.container) {\n preset.container.style.width = `${bounds.width}px`;\n preset.container.style.height = `${bounds.height}px`;\n }\n\n if (homeCover) {\n const w = preset.runtime.world.width;\n const h = preset.runtime.world.height;\n const ratio = w / h;\n\n const viewportWidth = viewport.current.width;\n const viewportHeight = viewport.current.height;\n let viewportRatio = viewportWidth / viewportHeight;\n\n if (ratio > viewportRatio) {\n viewportRatio = viewportHeight / viewportWidth;\n // Viewport too tall.\n preset.runtime.manualHomePosition = true;\n let x = (w - h / viewportRatio) / 2;\n if (homeCover === 'start') {\n x = 0;\n }\n if (homeCover === 'end') {\n x = w - h / viewportRatio;\n }\n\n const newHomePosition = {\n x,\n y: 0,\n width: h / viewportRatio,\n height: h,\n };\n\n preset.runtime.setHomePosition(newHomePosition);\n } else {\n let y = (h - w / viewportRatio) / 2;\n if (homeCover === 'start') {\n y = 0;\n }\n if (homeCover === 'end') {\n y = h - w / viewportRatio;\n }\n\n // Viewport too wide. Need to make the home position cover the entire width.\n preset.runtime.manualHomePosition = true;\n\n const newHomePosition = {\n x: 0,\n y,\n width: w,\n height: w / viewportRatio,\n };\n\n preset.runtime.setHomePosition(newHomePosition);\n }\n if (homeOnResize) {\n preset.runtime.goHome({});\n }\n }\n }\n }\n\n // When the bounds of the container change, we need to reflect those changes in the overlay.\n // @todo move to canvas.\n useIsomorphicLayoutEffect(() => {\n recalculateHomeCover();\n }, [preset, props.runtimeOptions?.maxOverZoom, bounds.height, bounds.width, homeCover]);\n\n // When the window resizes we need to recalculate the width.\n // @todo possibly move to controller.\n useIsomorphicLayoutEffect(() => {\n const windowResizeCallback = () => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n if (viewport.current.width !== restProps.width && viewport.current.height !== restProps.height) {\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n viewport.current.didUpdate = true;\n }\n }\n };\n\n window.addEventListener('resize', windowResizeCallback);\n\n return () => window.removeEventListener('resize', windowResizeCallback);\n }, [preset, restProps.height, restProps.width]);\n\n const navigatorOptions = {\n width: 120,\n };\n\n const recalculateNavigatorDimensions = () => {\n if (preset && preset.navigator) {\n const wHeight = preset.runtime.world.height;\n const wWidth = preset.runtime.world.width;\n\n const ratio = window.devicePixelRatio || 1;\n const canvasWidth = navigatorOptions.width;\n const canvasHeight = (navigatorOptions.width / wWidth) * wHeight;\n\n preset.navigator.width = canvasWidth * ratio;\n preset.navigator.height = canvasHeight * ratio;\n preset.navigator.style.width = canvasWidth + 'px';\n preset.navigator.style.height = canvasHeight + 'px';\n }\n };\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n recalculateNavigatorDimensions();\n const rt = preset.runtime;\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'recalculate-world-size') {\n recalculateNavigatorDimensions();\n recalculateHomeCover();\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n }\n });\n }\n return () => {\n // no-op\n };\n }, [preset, restProps.width, restProps.height]);\n\n const Canvas = useCallback(\n function Canvas(props: { children: React.ReactElement }): JSX.Element {\n const activate = () => {\n setIsReady(true);\n };\n\n useEffect(() => {\n if (preset) {\n preset.runtime.goHome();\n\n const result = onCreated && onCreated(preset);\n return void (result && result.then ? result.then(activate) : activate());\n } else {\n throw new Error('Invalid configuration - no runtime found');\n }\n }, []);\n\n return props.children;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [preset]\n );\n\n useEffect(() => {\n if (preset) {\n const rt = preset.runtime;\n if (resetWorldOnChange) {\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'recalculate-world-size') {\n rt.goHome();\n }\n });\n }\n }\n return () => {\n // no-op\n };\n }, [preset, resetWorldOnChange]);\n\n useEffect(() => {\n if (preset) {\n const rt = preset.runtime;\n return rt.registerHook('useBeforeFrame', () => {\n if (viewport.current.didUpdate && preset.canvas) {\n const ratio = window.devicePixelRatio || 1;\n const canvasWidth = viewport.current.width;\n const canvasHeight = viewport.current.height;\n\n preset.canvas.width = canvasWidth * ratio;\n preset.canvas.height = canvasHeight * ratio;\n preset.canvas.style.width = canvasWidth + 'px';\n preset.canvas.style.height = canvasHeight + 'px';\n\n preset.canvas.getContext('2d')?.scale(ratio, ratio);\n\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n\n viewport.current.didUpdate = false;\n }\n });\n }\n return () => {\n // no-op\n };\n }, [preset, resetWorldOnChange]);\n\n // @todo move to controller.\n useEffect(() => {\n const keyupSpace = () => {\n if (preset) {\n setMode('sketch');\n setContainerClassName('mode-sketch');\n }\n window.removeEventListener('keyup', keyupSpace);\n };\n\n const keydownSpace = (e: KeyboardEvent) => {\n if (e.code === 'Space' && preset && preset.runtime.mode === 'sketch') {\n const tagName = (e.target as any)?.tagName?.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea') return;\n // Check if content-editable\n if ((e.target as any)?.isContentEditable) return;\n\n e.preventDefault();\n setMode('explore');\n setContainerClassName('mode-explore');\n window.addEventListener('keyup', keyupSpace);\n }\n };\n\n window.addEventListener('keydown', keydownSpace);\n\n return () => {\n // no-op\n window.removeEventListener('keydown', keydownSpace);\n window.removeEventListener('keyup', keyupSpace);\n };\n }, [preset]);\n\n strictModeDoubleRender.current = true;\n\n const { height: _, width: __, ...canvasProps } = restProps;\n const widthClassName = useClassname([restProps.width, restProps.height]);\n let isInteractive = true;\n // if we have a render preset and that render preset sets interactive to false, then... disable it\n if (\n renderPreset &&\n Array.isArray(renderPreset) &&\n renderPreset.length > 1 &&\n (renderPreset[1] as any).interactive === false\n ) {\n isInteractive = false;\n }\n\n // use css custom prop if set, otherwise background prop, or default\n background = background ?? '#000';\n if (outerContainerRef.current) {\n const computed = getComputedStyle(outerContainerRef.current);\n background = computed.getPropertyValue('--atlas-background') || background;\n }\n\n return (\n <Container\n ref={ref}\n className={[\n 'atlas',\n hideInlineStyle ? '' : `atlas-width-${widthClassName}`,\n containerClassName,\n className,\n `atlas-${presetName}`,\n ]\n .filter(Boolean)\n .join(' ')\n .trim()}\n style={{\n ...containerStyle,\n ...(hideInlineStyle ? {} : { width: restProps.width, height: restProps.height }),\n }}\n >\n {presetName === 'static-preset' ? (\n <Container className=\"atlas-static-container\" ref={refs.container as any} tabIndex={0} {...containerProps} />\n ) : (\n <canvas\n className=\"atlas-canvas\"\n /*@ts-ignore*/\n part=\"atlas-canvas\"\n tabIndex={0}\n {...canvasProps}\n {...containerProps}\n ref={refs.canvas as any}\n data-background={background}\n />\n )}\n\n <Container\n className={['atlas-overlay', isInteractive ? 'atlas-overlay--interactive' : '']\n .filter(Boolean)\n .join(' ')\n .trim()}\n style={{ ...(overlayStyle || {}) }}\n ref={refs.overlay as any}\n >\n {unstable_noReconciler ? (\n <Canvas>\n <BoundsContext.Provider value={bounds}>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </BoundsContext.Provider>\n </Canvas>\n ) : (\n <AtlasWithReconciler\n bounds={bounds}\n preset={preset}\n mode={mode}\n setIsReady={setIsReady}\n onCreated={onCreated}\n >\n {children}\n </AtlasWithReconciler>\n )}\n </Container>\n {enableNavigator ? (\n <Container className=\"atlas-navigator\">\n <canvas\n className=\"atlas-navigator-canvas\"\n /*@ts-ignore*/\n part=\"atlas-navigator-canvas\"\n ref={refs.navigator as any}\n />\n </Container>\n ) : null}\n {hideInlineStyle ? (\n // We still need this, even if inline styles are hidden, this classname is unique to this viewport.\n <style>{`.atlas-width-${widthClassName} { width: ${restProps.width}px; height: ${restProps.height}px; }`}</style>\n ) : (\n <style>{`\n .atlas { position: relative; display: flex; background: ${background}; z-index: var(--atlas-z-index, 10); -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\n .atlas-width-${widthClassName} { width: ${restProps.width}px; height: ${restProps.height}px; }\n .atlas-canvas { flex: 1 1 0px; }\n .atlas-canvas:focus, .atlas-static-container:focus { outline: none }\n .atlas-canvas:focus-visible, .atlas-canvas-container:focus-visible { outline: var(--atlas-focus, 2px solid darkorange) }\n .atlas-static-preset { touch-action: inherit; }\n .atlas-static-container { position: relative; overflow: hidden; flex: 1 1 0px; }\n .atlas-overlay { position: absolute; top: 0; left: 0; none; overflow: hidden; }\n /** setting the pointer events to none means that Atlas will own the touch and mousewheel events **/\n .atlas-overlay--interactive { pointer-events: none; }\n .atlas-static-image { position: absolute; user-select: none; transform-origin: 0px 0px; }\n .atlas-navigator { position: absolute; top: var(--atlas-navigator-top, 10px); right: var(--atlas-navigator-bottom, 10px); left: var(--atlas-navigator-left); bottom: var(--atlas-navigator-bottom); opacity: .8 }\n .atlas-navigator-canvas { width: 100%; }\n `}</style>\n )}\n {htmlChildren}\n </Container>\n );\n});\n","export function toPx(str: string | number) {\n if (Number(str) == str) {\n return `${str}px`;\n }\n\n return str;\n}\n","import { Atlas, AtlasProps } from '../Atlas';\nimport React, { memo, useEffect, useMemo } from 'react';\nimport useMeasure from 'react-use-measure';\nimport { Container } from './Container';\nimport { toPx } from '../utility/to-px';\n\nexport const AtlasAuto: React.FC<\n AtlasProps & {\n height?: number | string;\n width?: number | string;\n resizeHash?: number;\n containerProps?: any;\n aspectRatio?: number;\n }\n> = memo(function AtlasAuto({ resizeHash, aspectRatio, containerProps = {}, htmlChildren, ...props }) {\n const [ref, _bounds, forceRefresh] = useMeasure();\n\n const { height, width, ...restProps } = props as any;\n\n useEffect(() => {\n forceRefresh();\n }, [width, height, resizeHash, forceRefresh]);\n\n const bounds = useMemo(() => {\n if (!aspectRatio) {\n return _bounds;\n }\n\n // Need to find the case where this is not the solution.\n return {\n width: _bounds.width,\n height: _bounds.width * (1 / aspectRatio),\n };\n }, [_bounds, aspectRatio]);\n\n return (\n <Container ref={ref} className=\"atlas-container\" {...containerProps}>\n {bounds.width ? (\n <Atlas width={bounds.width || 100} height={bounds.height || 100} {...restProps}>\n {props.children}\n </Atlas>\n ) : null}\n {props.hideInlineStyle ? null : (\n <style>{`\n .atlas-container {\n display: var(--atlas-container-display, block);\n flex: var(--atlas-container-flex, none);\n width: var(--atlas-container-width, ${width ? `${width}px` : '100%'});\n height: var(--atlas-container-height, ${toPx(height ? height : aspectRatio ? bounds.height : 512)})\n }\n `}</style>\n )}\n {htmlChildren}\n </Container>\n );\n});\n","import { useContext } from 'react';\nimport { AtlasContext } from '../components/AtlasContext';\n\nexport const useAtlas = () => {\n return useContext(AtlasContext);\n};\n","import { useAtlas } from './use-atlas';\n\nexport const useRuntime = () => {\n const atlas = useAtlas();\n return atlas ? atlas.runtime : undefined;\n};\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useAfterFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useAfterFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useAtlas } from './use-atlas';\n\nexport const useCanvas = () => {\n const atlas = useAtlas();\n return atlas && atlas.canvas ? atlas.canvas : undefined;\n};\n","import { useContext } from 'react';\nimport { BoundsContext } from '../components/AtlasContext';\n\nexport function useCanvasPosition() {\n return useContext(BoundsContext);\n}\n","import React, { ReactNode, useEffect, useRef, useState } from 'react';\nimport { useAfterFrame } from '../hooks/use-after-frame';\nimport { useFrame } from '../hooks/use-frame';\nimport { useCanvas } from '../hooks/use-canvas';\nimport { useRuntime } from '../hooks/use-runtime';\nimport { useMode } from '../hooks/use-mode';\nimport { useCanvasPosition } from '../hooks/use-canvas-position';\n\nexport const DrawBox: React.FC<{\n children?: ReactNode;\n onCreate: (bounds: { x: number; y: number; width: number; height: number }) => void;\n}> = ({ onCreate }) => {\n const mousePosition = useRef({ x: 0, y: 0 });\n const canvas = useCanvas();\n const canvasPosition = useCanvasPosition();\n const runtime = useRuntime();\n const [firstCorner, setFirstCorner] = useState<{ x: number; y: number } | undefined>();\n const [secondCorner, setSecondCorner] = useState<{ x: number; y: number } | undefined>();\n const mode = useMode();\n\n useFrame(() => {\n if (runtime && firstCorner && !secondCorner) {\n runtime.pendingUpdate = true;\n }\n }, [firstCorner, secondCorner]);\n\n useAfterFrame(() => {\n if (firstCorner && canvas && runtime) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n const { x, y, width, height } = runtime.worldToViewer(\n firstCorner.x,\n firstCorner.y,\n (secondCorner ? secondCorner.x : mousePosition.current.x) - firstCorner.x,\n (secondCorner ? secondCorner.y : mousePosition.current.y) - firstCorner.y\n );\n\n ctx.lineWidth = secondCorner ? 3 : 1;\n ctx.strokeStyle = '#fff';\n ctx.strokeRect(x, y, width, height);\n\n ctx.lineWidth = secondCorner ? 3 : 1;\n ctx.strokeStyle = '#000';\n ctx.strokeRect(x + 1, y + 1, width - 2, height - 2);\n }\n }\n }, [firstCorner, secondCorner]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (canvasPosition && runtime) {\n const { x, y } = runtime.viewerToWorld(e.clientX - canvasPosition.left, e.clientY - canvasPosition.top);\n mousePosition.current.x = ~~x;\n mousePosition.current.y = ~~y;\n }\n };\n if (canvas) {\n canvas.addEventListener('mousemove', cb);\n return () => canvas.removeEventListener('mousemove', cb);\n }\n return () => {\n // no-op\n };\n }, [canvasPosition, canvas, runtime]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (mode === 'sketch') {\n setFirstCorner({ x: Math.round(mousePosition.current.x), y: Math.round(mousePosition.current.y) });\n setSecondCorner(undefined);\n }\n };\n if (canvas) {\n canvas.addEventListener('mousedown', cb);\n\n return () => canvas.removeEventListener('mousedown', cb);\n }\n return () => {\n // no-op\n };\n }, [canvas, mode]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (firstCorner && !secondCorner) {\n setSecondCorner({ x: Math.round(mousePosition.current.x), y: Math.round(mousePosition.current.y) });\n }\n };\n\n if (canvas) {\n canvas.addEventListener('mouseup', cb);\n\n return () => canvas.removeEventListener('mouseup', cb);\n }\n return () => {\n // no-op\n };\n }, [canvas, firstCorner, secondCorner]);\n\n useEffect(() => {\n if (firstCorner && secondCorner) {\n onCreate({\n x: Math.min(firstCorner.x, secondCorner.x),\n y: Math.min(firstCorner.y, secondCorner.y),\n width: Math.abs(secondCorner.x - firstCorner.x),\n height: Math.abs(secondCorner.y - firstCorner.y),\n });\n }\n }, [firstCorner, onCreate, secondCorner]);\n\n return null;\n};\n","import { MutableRefObject, version } from 'react';\n\nexport async function renderReactDom(html: HTMLElement, toRender: any, root: MutableRefObject<any>) {\n if (version.startsWith('18.') || version.startsWith('19.')) {\n // @ts-ignore\n const module = await import('react-dom/client');\n const createRoot = module.default ? module.default.createRoot : module.createRoot;\n if (!root.current) {\n root.current = createRoot(html);\n }\n root.current.render(toRender);\n } else {\n // @ts-ignore\n if (typeof ReactDOM !== 'undefined') {\n // @ts-ignore\n const { render, unmountComponentAtNode } = ReactDOM;\n render(toRender, html);\n root.current = {\n unmount() {\n unmountComponentAtNode(html);\n },\n };\n } else {\n // Probably only bundlers or\n const module = await import('react-dom');\n const render = module.default ? module.default.render : module.render;\n const unmountComponentAtNode = module.default\n ? module.default.unmountComponentAtNode\n : module.unmountComponentAtNode;\n render(toRender, html);\n root.current = {\n unmount() {\n unmountComponentAtNode(html);\n },\n };\n }\n }\n}\n","import React, { ReactNode, useLayoutEffect, useRef } from 'react';\nimport { Box } from '../../../objects/box';\nimport { useFrame } from '../hooks/use-frame';\nimport { useRuntime } from '../hooks/use-runtime';\nimport { renderReactDom } from '../utility/react-dom';\n\nexport const HTMLPortal: React.FC<\n {\n children?: ReactNode;\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n } & React.RefAttributes<Box>\n> = React.forwardRef<\n Box,\n {\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n style?: any;\n children?: any;\n }\n>(({ children, ...props }, fwdRef) => {\n const ref = useRef<HTMLDivElement>();\n const runtime = useRuntime();\n const lastScale = useRef(0);\n const boxRef = useRef<Box>();\n const root = useRef<any>();\n\n useFrame(() => {\n if (props.relative) {\n const relativeBox = ref.current;\n if (relativeBox && runtime) {\n const scaleFactor = runtime.getScaleFactor();\n if (lastScale.current !== scaleFactor) {\n lastScale.current = scaleFactor;\n relativeBox.style.transformOrigin = '0 0';\n relativeBox.style.transform = `scale(${1 / lastScale.current})`;\n relativeBox.style.width = `${lastScale.current * 100}%`;\n relativeBox.style.height = `${lastScale.current * 100}%`;\n if (ref.current && boxRef.current?.__owner.value?.rotation) {\n relativeBox.style.transform = `scale(${1 / lastScale.current}) translate(50%, 50%) rotate(${\n boxRef.current?.__owner.value?.rotation || 0\n }deg) translate(-50%, -50%)`;\n }\n }\n }\n }\n }, [props.relative]);\n\n useLayoutEffect(() => {\n const box = boxRef.current;\n if (fwdRef && box) {\n if (typeof fwdRef === 'function') {\n fwdRef(box);\n } else {\n fwdRef.current = box;\n }\n }\n async function renderHost() {\n if (box && box.__host) {\n const toRender = props.relative ? <div ref={ref as any}>{children as any}</div> : (children as any);\n\n await renderReactDom(box.__host.element, toRender, root);\n }\n }\n\n if (box && box.__host) {\n renderHost();\n } else if (box) {\n box.__onCreate = renderHost;\n }\n }, [fwdRef, children, boxRef, props.relative]);\n\n useLayoutEffect(() => {\n return () => {\n if (root.current) {\n setTimeout(() => {\n root.current.unmount();\n }, 0);\n }\n };\n }, []);\n\n return <box html {...props} ref={boxRef} />;\n});\n\nHTMLPortal.displayName = 'HTMLPortal';\n","import { supportedEventMap, SupportedEventNames } from '../../../events';\nimport { useEffect } from 'react';\nimport { useRuntime } from './use-runtime';\n\nexport const useWorldEvent = <Name extends SupportedEventNames>(name: Name, cb: (e: any) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n const world = runtime ? runtime.world : undefined;\n\n useEffect(() => {\n if (runtime) {\n const callback = cb;\n const realName = supportedEventMap[name];\n runtime.world.activatedEvents.push(realName);\n const ev = realName.slice(2).toLowerCase();\n runtime.world.addEventListener(ev as any, callback);\n\n return () => {\n runtime.world.removeEventListener(ev as any, callback);\n };\n }\n return () => {\n // no-op\n };\n }, [world, name, ...deps]);\n};\n","export function getRatio(a: number, b: number) {\n if (a === 0) {\n return [0, 1];\n }\n if (b === 0) {\n return [1, 0];\n }\n\n const ratio = Math.abs(a) / Math.abs(b);\n\n return [ratio, 1 - ratio];\n}\n","import { useLayoutEffect, useRef } from 'react';\n\nexport function useModifierKeys() {\n const modifierKeys = useRef({\n ctrl: false,\n shift: false,\n alt: false,\n });\n\n useLayoutEffect(() => {\n function keyDown(e: KeyboardEvent) {\n if (e.key === 'Shift') modifierKeys.current.shift = true;\n if (e.key === 'Control') modifierKeys.current.ctrl = true;\n if (e.key === 'Alt') modifierKeys.current.alt = true;\n }\n function keyUp(e: KeyboardEvent) {\n if (e.key === 'Shift') modifierKeys.current.shift = false;\n if (e.key === 'Control') modifierKeys.current.ctrl = false;\n if (e.key === 'Alt') modifierKeys.current.alt = false;\n }\n\n window.addEventListener('keydown', keyDown);\n window.addEventListener('keyup', keyUp);\n return () => {\n window.removeEventListener('keydown', keyDown);\n window.removeEventListener('keyup', keyUp);\n };\n }, []);\n\n return modifierKeys;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Box } from '../../../objects/box';\nimport { useMode } from './use-mode';\nimport { useWorldEvent } from './use-world-event';\nimport { useRuntime } from './use-runtime';\nimport { useFrame } from './use-frame';\nimport { useCanvasPosition } from './use-canvas-position';\nimport { getRatio } from '../utility/get-ratio';\nimport { useModifierKeys } from './use-modifier-keys';\n\nexport const useResizeWorldItem = (\n props: { x: number; y: number; width: number; height: number; maintainAspectRatio?: boolean; aspectRatio?: number },\n onSave: (item: { x: number; y: number; width: number; height: number }) => void\n) => {\n const mode = useMode();\n const runtime = useRuntime();\n const canvasPosition = useCanvasPosition();\n const resizeMode = useRef<string>();\n const portalRef = useRef<Box | null>(null);\n const mouseStart = useRef<{ x: number; y: number } | undefined>();\n const [isEditing, setIsEditing] = useState(false);\n const isEditingRef = useRef(false);\n\n const cardinalDeltas = useRef({ north: 0, south: 0, east: 0, west: 0 });\n const keys = useModifierKeys();\n\n const mouseEvent = useCallback(\n (direction: string) => (e: any) => {\n isEditingRef.current = true;\n setIsEditing(true);\n if (canvasPosition && runtime) {\n const { top, left } = canvasPosition;\n const current = runtime.viewerToWorld(e.pageX - left, e.pageY - top);\n mouseStart.current = { x: current.x, y: current.y };\n resizeMode.current = direction;\n }\n },\n [canvasPosition, runtime]\n );\n\n const aspectRatio = useMemo(() => {\n // Calculate aspect ratio.\n return props.width / props.height;\n }, [props.width, props.height]);\n\n const constrainToAspectRatio = useCallback(\n (deltas: { north: number; south: number; east: number; west: number }) => {\n const hasDeltas = Math.abs(deltas.north - deltas.south + (deltas.east - deltas.west));\n if (!hasDeltas) return;\n\n const xDelta = -deltas.west + deltas.east;\n const yDelta = -deltas.north + deltas.south;\n\n const originalWidth = props.width + xDelta;\n const originalHeight = props.height + yDelta;\n\n const newAspectRatio = originalWidth / originalHeight;\n\n if (newAspectRatio >= aspectRatio) {\n // too wide\n const width = originalHeight * aspectRatio;\n const margin = originalWidth - width; // reduce by this amount.\n const [eastRatio, westRatio] = getRatio(deltas.east, deltas.west);\n\n deltas.west = deltas.west + margin * westRatio;\n deltas.east = deltas.east - margin * eastRatio;\n } else {\n // too tall\n const height = originalWidth / aspectRatio;\n const margin = originalHeight - height; // reduce by this amount.\n const [northRatio, southRatio] = getRatio(deltas.north, deltas.south);\n\n deltas.north = deltas.north + margin * northRatio;\n deltas.south = deltas.south - margin * southRatio;\n }\n },\n [props.width, props.height, aspectRatio]\n );\n\n useFrame(() => {\n if (mouseStart && runtime) {\n runtime.updateNextFrame();\n }\n });\n\n useEffect(() => {\n if (runtime) {\n runtime.updateNextFrame();\n }\n }, [runtime, isEditing]);\n\n const onPointerMoveCallback = useCallback(\n (e: any) => {\n if (!runtime || !canvasPosition || runtime.mode !== 'sketch') return;\n\n const { top, left } = canvasPosition;\n const position = runtime.viewerToWorld(e.pageX - left, e.pageY - top);\n const box = portalRef.current;\n\n const alt = !props.maintainAspectRatio && keys.current.alt;\n const shift = !alt && keys.current.shift && resizeMode.current?.indexOf('-') !== -1;\n\n // Take co-ordinates, clamp constraints, update\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'east' ||\n resizeMode.current === 'north-east' ||\n resizeMode.current === 'south-east'\n ) {\n cardinalDeltas.current.east = position.x - (mouseStart.current ? mouseStart.current.x : 0);\n if (alt) {\n cardinalDeltas.current.west = -cardinalDeltas.current.east;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'west' ||\n resizeMode.current === 'north-west' ||\n resizeMode.current === 'south-west'\n ) {\n cardinalDeltas.current.west = position.x - (mouseStart.current ? mouseStart.current.x : 0);\n if (alt) {\n cardinalDeltas.current.east = -cardinalDeltas.current.west;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'north' ||\n resizeMode.current === 'north-east' ||\n resizeMode.current === 'north-west'\n ) {\n cardinalDeltas.current.north = position.y - (mouseStart.current ? mouseStart.current.y : 0);\n if (alt) {\n cardinalDeltas.current.south = -cardinalDeltas.current.north;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'south' ||\n resizeMode.current === 'south-west' ||\n resizeMode.current === 'south-east'\n ) {\n cardinalDeltas.current.south = position.y - (mouseStart.current ? mouseStart.current.y : 0);\n if (alt) {\n cardinalDeltas.current.north = -cardinalDeltas.current.south;\n }\n }\n\n if (props.maintainAspectRatio || shift) {\n constrainToAspectRatio(cardinalDeltas.current);\n }\n\n if (box) {\n const dX1 = cardinalDeltas.current.west;\n const dY1 = cardinalDeltas.current.north;\n const dX2 = props.width + cardinalDeltas.current.east;\n const dY2 = props.height + cardinalDeltas.current.south;\n\n box.points[1] = Math.min(dX1, dX2);\n box.points[2] = Math.min(dY1, dY2);\n box.points[3] = Math.max(dX1, dX2);\n box.points[4] = Math.max(dY1, dY2);\n\n runtime.updateNextFrame();\n }\n },\n [runtime, props.width, props.height, props.maintainAspectRatio, canvasPosition]\n );\n\n useWorldEvent('mousemove', onPointerMoveCallback, [props.width, props.height, canvasPosition]);\n useWorldEvent('pointermove', onPointerMoveCallback, [props.width, props.height, canvasPosition]);\n\n const windowPointerUp = useRef<() => void>();\n\n useEffect(() => {\n windowPointerUp.current = () => {\n if (isEditingRef.current) {\n const dX1 = cardinalDeltas.current.west;\n const dY1 = cardinalDeltas.current.north;\n const dX2 = props.width + cardinalDeltas.current.east;\n const dY2 = props.height + cardinalDeltas.current.south;\n\n const x1 = Math.min(dX1, dX2);\n const y1 = Math.min(dY1, dY2);\n const x2 = Math.max(dX1, dX2);\n const y2 = Math.max(dY1, dY2);\n\n const realSize = {\n x: (props.x || 0) + x1,\n y: (props.y || 0) + y1,\n width: x2 - x1 || 1,\n height: y2 - y1 || 1,\n };\n if (props.maintainAspectRatio) {\n // @todo apply aspect ratio here.\n onSave(realSize);\n } else {\n onSave(realSize);\n }\n\n resizeMode.current = undefined;\n mouseStart.current = undefined;\n cardinalDeltas.current.east = 0;\n cardinalDeltas.current.west = 0;\n cardinalDeltas.current.north = 0;\n cardinalDeltas.current.south = 0;\n isEditingRef.current = false;\n setIsEditing(false);\n }\n };\n }, [onSave, props.height, props.width, props.x, props.y]);\n\n useEffect(() => {\n const cb = () => {\n if (windowPointerUp.current) {\n windowPointerUp.current();\n }\n };\n window.addEventListener('pointerup', cb);\n window.addEventListener('touchend', cb);\n return () => {\n window.removeEventListener('pointerup', cb);\n window.removeEventListener('touchend', cb);\n };\n }, []);\n\n return {\n portalRef,\n mode,\n mouseEvent,\n onPointerMoveCallback,\n isEditing,\n };\n};\n","import React, { CSSProperties, ReactNode, useMemo } from 'react';\nimport { useResizeWorldItem } from '../hooks/use-resize-world-item';\nimport { HTMLPortal } from './HTMLPortal';\n\ntype ResizeWorldItemProps = JSX.IntrinsicElements['worldObject'] & {\n handleSize?: number;\n resizable?: boolean;\n rotation?: number;\n onSave: (pos: Partial<{ x: number; y: number; width: number; height: number }>) => void;\n children?: ReactNode;\n maintainAspectRatio?: boolean;\n disableCardinalControls?: boolean;\n};\n\nexport function ResizeWorldItem({\n handleSize: _handleSize,\n resizable,\n onSave,\n children,\n maintainAspectRatio,\n disableCardinalControls,\n ...props\n}: ResizeWorldItemProps) {\n const handleSize = typeof _handleSize === 'undefined' ? (maintainAspectRatio ? 10 : 8) : _handleSize;\n const { portalRef, mode, mouseEvent, isEditing } = useResizeWorldItem(\n { x: props.x || 0, y: props.y || 0, width: props.width, height: props.height, maintainAspectRatio },\n onSave\n );\n const translate = useMemo(() => mouseEvent('translate'), [mouseEvent]);\n const east = useMemo(() => mouseEvent('east'), [mouseEvent]);\n const west = useMemo(() => mouseEvent('west'), [mouseEvent]);\n const south = useMemo(() => mouseEvent('south'), [mouseEvent]);\n const north = useMemo(() => mouseEvent('north'), [mouseEvent]);\n const southEast = useMemo(() => mouseEvent('south-east'), [mouseEvent]);\n const southWest = useMemo(() => mouseEvent('south-west'), [mouseEvent]);\n const northEast = useMemo(() => mouseEvent('north-east'), [mouseEvent]);\n const northWest = useMemo(() => mouseEvent('north-west'), [mouseEvent]);\n\n const inSketchMode = mode === 'sketch';\n const baseStyle: CSSProperties = {\n zIndex: 999,\n boxShadow: '0px 2px 3px 0 rgba(0,0,0,0.2)',\n border: '1px solid rgba(155,155,155,.7)',\n borderRadius: maintainAspectRatio || disableCardinalControls ? '50%' : 2,\n position: 'absolute',\n background: '#fff',\n pointerEvents: isEditing ? 'none' : inSketchMode ? 'initial' : 'none',\n };\n\n return (\n <>\n <world-object {...props}>\n {children}\n\n {inSketchMode && resizable ? (\n <HTMLPortal\n ref={portalRef}\n target={{ x: 0, y: 0, height: props.height, width: props.width }}\n relative={true}\n interactive={false}\n >\n {inSketchMode && resizable ? (\n <>\n <div\n onMouseDown={translate}\n onTouchStart={translate}\n style={{\n display: 'block',\n width: '100%',\n height: '100%',\n position: 'relative',\n border: '1px solid rgba(155,155,155, .7)',\n boxSizing: 'border-box',\n pointerEvents: isEditing ? 'none' : inSketchMode ? 'initial' : 'none',\n }}\n />\n\n {!maintainAspectRatio ? (\n <>\n <div\n title=\"east\"\n onTouchStart={east}\n onMouseDown={east}\n style={{\n ...baseStyle,\n cursor: 'e-resize',\n height: handleSize * 2,\n width: handleSize,\n right: 0,\n top: '50%',\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(${handleSize / 2}px, -${handleSize}px)`,\n }}\n />\n <div\n title=\"west\"\n onMouseDown={west}\n style={{\n ...baseStyle,\n cursor: 'w-resize',\n position: 'absolute',\n height: handleSize * 2,\n width: handleSize,\n left: 0,\n top: '50%',\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize / 2}px, -${handleSize}px)`,\n }}\n />\n\n <div\n title=\"north\"\n onMouseDown={north}\n style={{\n ...baseStyle,\n cursor: 'n-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize * 2,\n left: '50%',\n top: 0,\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize}px, -${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south\"\n onMouseDown={south}\n style={{\n ...baseStyle,\n cursor: 's-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize * 2,\n left: '50%',\n bottom: 0,\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize}px, ${handleSize / 2}px)`,\n }}\n />\n </>\n ) : null}\n\n <div\n title=\"north-east\"\n onMouseDown={northEast}\n style={{\n ...baseStyle,\n cursor: 'ne-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n right: 0,\n top: 0,\n transform: `translate(${handleSize / 2}px, -${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south-east\"\n onMouseDown={southEast}\n style={{\n ...baseStyle,\n cursor: 'se-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n bottom: 0,\n right: 0,\n transform: `translate(${handleSize / 2}px, ${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south-west\"\n onMouseDown={southWest}\n style={{\n ...baseStyle,\n cursor: 'sw-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n bottom: 0,\n left: 0,\n transform: `translate(-${handleSize / 2}px, ${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"north-west\"\n onMouseDown={northWest}\n style={{\n ...baseStyle,\n cursor: 'nw-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n top: 0,\n left: 0,\n transform: `translate(-${handleSize / 2}px, -${handleSize / 2}px)`,\n }}\n />\n </>\n ) : null}\n </HTMLPortal>\n ) : null}\n </world-object>\n </>\n );\n}\n","import React, { ReactNode, useCallback } from 'react';\nimport { ResizeWorldItem } from './ResizeWorldItem';\nimport { BoxStyle } from '../../../objects/box';\n\ntype RegionHighlightType = {\n id: any;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nexport type RegionHighlightProps = {\n id?: string;\n region: RegionHighlightType;\n isEditing: boolean;\n rotation?: number;\n onSave: (annotation: RegionHighlightType) => void;\n onClick: (annotation: RegionHighlightType) => void;\n interactive?: boolean;\n maintainAspectRatio?: boolean;\n disableCardinalControls?: boolean;\n style?: BoxStyle;\n children?: ReactNode;\n};\n\nexport function RegionHighlight({\n interactive,\n region,\n onClick,\n onSave,\n maintainAspectRatio,\n disableCardinalControls,\n isEditing,\n rotation,\n style = { backgroundColor: 'rgba(0,0,0,.5)' },\n}: RegionHighlightProps) {\n const saveCallback = useCallback(\n (bounds: any) => {\n onSave({ id: region.id, x: region.x, y: region.y, height: region.height, width: region.width, ...bounds });\n },\n [onSave, region.id, region.x, region.y, region.height, region.width]\n );\n\n return (\n <ResizeWorldItem\n x={region.x}\n y={region.y}\n rotation={rotation}\n width={region.width}\n height={region.height}\n resizable={isEditing}\n onSave={saveCallback}\n maintainAspectRatio={maintainAspectRatio}\n disableCardinalControls={disableCardinalControls}\n >\n <box\n interactive={interactive}\n onContextMenu={(e) => {\n e.preventDefault();\n }}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick(region);\n }}\n target={{ x: 0, y: 0, width: region.width, height: region.height }}\n style={style}\n />\n </ResizeWorldItem>\n );\n}\n","import React, { ReactNode, useMemo } from 'react';\nimport { GetTile } from '../../iiif/shared';\nimport { CompositeResourceProps } from '../../../spacial-content';\n\nexport const TileSet: React.FC<{\n tiles: GetTile;\n x?: number;\n y?: number;\n width: number;\n height: number;\n rotation?: number;\n crop?: any;\n children?: ReactNode;\n enableThumbnail?: boolean;\n enableSizes?: boolean;\n onClick?: (e: any) => void;\n renderOptions?: CompositeResourceProps;\n}> = (props) => {\n const scale = props.width / (props.crop?.width || props.tiles.width);\n const sizes = props.tiles.imageService.sizes || [];\n const enableThumbnail = props.enableThumbnail;\n const enableSizes = props.enableSizes;\n const canonicalId = useMemo(() => {\n const id = props.tiles.imageService.id || (props.tiles.imageService['@id'] as string);\n if (id && id.endsWith('/info.json')) {\n return id.slice(0, -1 * '/info.json'.length);\n }\n return id;\n }, [props.tiles.imageService.id]);\n\n const tiles = useMemo(() => {\n const tiles = props.tiles.imageService.tiles || [];\n\n if (!tiles.length) {\n const width = props.width;\n let scaleFactors = [1];\n let last = 1;\n while (Math.pow(2, last) < width) {\n last = last * 2;\n scaleFactors.push(last);\n }\n\n return [\n // {\n // width: 256,\n // height: 256,\n // scaleFactors: [1, 2, 4, 8],\n // },\n ];\n }\n\n return tiles;\n }, [props.tiles.imageService]);\n\n const isVersion3 = useMemo(() => {\n const service = props.tiles.imageService;\n const ctx = service ? service['@context']\n ? Array.isArray(service['@context'])\n ? service['@context']\n : [service['@context']]\n : [] : [];\n return ctx.indexOf('http://iiif.io/api/image/3/context.json') !== -1;\n }, [props.tiles.imageService.id]);\n\n return (\n <world-object\n rotation={props.rotation}\n key={props.tiles.imageService.id}\n scale={scale}\n height={props.crop?.height || props.tiles.height}\n width={props.crop?.width || props.tiles.width}\n x={props.x}\n y={props.y}\n onClick={props.onClick}\n >\n <composite-image\n key={props.tiles.imageService.id}\n id={props.tiles.imageService.id}\n width={props.crop?.width || props.tiles.width}\n height={props.crop?.height || props.tiles.height}\n crop={props.crop}\n renderOptions={props.renderOptions}\n >\n {enableThumbnail && props.tiles.thumbnail ? (\n <world-image\n priority\n uri={props.tiles.thumbnail.id}\n target={{ width: props.tiles.width, height: props.tiles.height }}\n display={{ width: props.tiles.thumbnail.width, height: props.tiles.thumbnail.height }}\n crop={props.crop}\n />\n ) : null}\n {enableSizes &&\n sizes.map((size, n) => (\n <world-image\n key={n}\n uri={`${canonicalId}/full/${size.width},${size.height}/0/default.jpg`}\n target={{ width: props.tiles.width, height: props.tiles.height }}\n display={{ width: size.width, height: size.height }}\n crop={props.crop}\n />\n ))}\n {tiles.map((tile: any) =>\n (tile.scaleFactors || []).map((size: number) => {\n return (\n <tiled-image\n key={`${props.tiles.imageService.id}-tile-${size}`}\n uri={props.tiles.imageService.id}\n display={{ width: props.tiles.width, height: props.tiles.height }}\n tile={tile}\n scaleFactor={size}\n crop={props.crop}\n version3={isVersion3}\n />\n );\n })\n )}\n </composite-image>\n </world-object>\n );\n};\n","import { ImageService } from '@iiif/presentation-3';\n\nexport type GetTile = {\n id: string;\n width: number;\n height: number;\n thumbnail?: { id: string; width: number; height: number };\n imageService: ImageService;\n};\n\nexport function getId(entity: any): string {\n return entity.id || entity['@id'];\n}\n","import { ImageServiceLoader } from '@atlas-viewer/iiif-image-api';\nimport { createThumbnailHelper } from '@iiif/helpers/thumbnail';\nimport type { Vault } from '@iiif/helpers/vault';\n\nfunction getGlobal(): any {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n return {};\n}\n\nfunction getGlobalVault() {\n const g = getGlobal();\n\n // Found a vault.\n if (typeof g['IIIF_VAULT'] !== 'undefined') {\n return g['IIIF_VAULT'];\n }\n\n if (typeof g.IIIFVault === 'undefined') {\n throw new Error('Vault not found');\n }\n\n g['IIIF_VAULT'] = new g.IIIFVault.Vault();\n\n return g['IIIF_VAULT'];\n}\n\nconst moduleState: {\n vault: Vault;\n loader: ImageServiceLoader;\n helper: any;\n} = {} as any;\n\nexport function getVaultHelper() {\n if (!moduleState.helper) {\n moduleState.vault = getGlobalVault();\n moduleState.loader = new ImageServiceLoader();\n moduleState.helper = createThumbnailHelper(moduleState.vault as any, { imageServiceLoader: moduleState.loader });\n }\n return moduleState;\n}\n","import { ImageService } from '@iiif/presentation-3';\nimport {\n AnnotationNormalized,\n AnnotationPageNormalized,\n CanvasNormalized,\n ManifestNormalized,\n} from '@iiif/presentation-3-normalized';\nimport { getId, GetTile } from './shared';\nimport { getVaultHelper } from './get-vault-helper';\n\nexport async function getTileFromImageService(infoJsonId: string, width: number, height: number): Promise<GetTile> {\n const { loader } = getVaultHelper();\n const imageService = await loader.loadService({\n id: infoJsonId,\n width: width,\n height: height,\n });\n\n return {\n id: getId(imageService),\n width: width,\n height: height,\n imageService: imageService as ImageService,\n thumbnail: undefined,\n };\n}\n\nexport async function getTileFromCanvas(canvas: CanvasNormalized, thumbnailSize = 512): Promise<GetTile[]> {\n const { vault, loader, helper } = getVaultHelper();\n const tiles = [];\n\n for (const page of canvas.items) {\n for (const anno of vault.get<AnnotationPageNormalized>(page).items) {\n const annotation = vault.get<any>(vault.get<AnnotationNormalized>(anno).body[0]);\n const serviceSnippet = annotation.service[0];\n\n const tile = await getTileFromImageService(serviceSnippet.id, canvas.width, canvas.height);\n\n const { best: thumbnail } = (await (helper.getBestThumbnailAtSize as any)(\n vault,\n loader as any,\n canvas,\n {\n maxHeight: thumbnailSize,\n maxWidth: thumbnailSize,\n },\n true\n )) as any;\n\n if (thumbnail) {\n tile.thumbnail = thumbnail;\n }\n\n tiles.push(tile);\n }\n }\n\n return tiles;\n}\n\nexport async function getTilesFromManifest(manifest: ManifestNormalized) {\n const { vault } = getVaultHelper();\n\n const tiles: any[] = [];\n for (const canvasRef of manifest.items) {\n const canvas = vault.get<CanvasNormalized>(canvasRef);\n tiles.push(...(await getTileFromCanvas(canvas)));\n }\n return tiles;\n}\n\nexport async function getTiles(manifestId: string): Promise<Array<GetTile>> {\n try {\n const { vault } = getVaultHelper();\n const manifest = await vault.loadManifest(manifestId);\n\n if (!manifest) {\n return [];\n }\n\n return getTilesFromManifest(manifest as any);\n } catch (err) {\n console.log('ERR', err);\n return [];\n }\n}\n","import React, { ReactNode, useEffect, useState } from 'react';\nimport { GetTile } from '../../iiif/shared';\nimport { TileSet } from './TileSet';\nimport { getTileFromImageService } from '../../iiif/get-tiles';\nimport { CompositeResourceProps } from '../../../spacial-content';\n\nexport const ImageService: React.FC<{\n id: string;\n width: number;\n height: number;\n x?: number;\n y?: number;\n rotation?: number;\n scale?: number;\n children?: ReactNode;\n crop?: any;\n enableSizes?: boolean;\n enableThumbnail?: boolean;\n renderOptions?: CompositeResourceProps;\n}> = (props) => {\n const [tiles, setTile] = useState<GetTile | undefined>();\n\n useEffect(() => {\n getTileFromImageService(props.id, props.width, props.height).then((s) => {\n setTile(s);\n });\n }, [props.height, props.id, props.width]);\n\n return (\n <world-object x={props.x || 0} y={props.y || 0} width={props.width} height={props.height} scale={props.scale}>\n {tiles ? (\n <TileSet\n tiles={tiles}\n x={props.x}\n y={props.y}\n width={props.crop?.width || props.width}\n height={props.crop?.height || props.height}\n rotation={props.rotation}\n crop={props.crop}\n enableSizes={props.enableSizes}\n enableThumbnail={props.enableThumbnail}\n renderOptions={props.renderOptions}\n >\n {props.children}\n </TileSet>\n ) : null}\n </world-object>\n );\n};\n","import { Paintable } from '../../../world-objects/paint';\nimport { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useAfterPaint = (callback: (paint: Paintable) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useAfterPaint', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { ReactAtlas } from '../reconciler';\nimport { Runtime, ViewerMode } from '../../../renderer/runtime';\nimport { CanvasRenderer } from '../../canvas-renderer/canvas-renderer';\nimport { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { World } from '../../../world';\nimport { AtlasContext } from '../components/AtlasContext';\nimport { ModeContext } from './use-mode';\nimport { Preset } from '../presets/_types';\nimport { usePreset } from './use-preset';\nimport { useIsomorphicLayoutEffect } from '../utility/react';\n\ntype AtlasProps = {\n width: number;\n height: number;\n mode?: ViewerMode;\n onCreated?: (ctx: Preset) => void | Promise<void>;\n containerRef?: { current?: HTMLElement };\n cover?: boolean;\n resetWorldOnChange?: boolean;\n};\n\nexport const useAtlasImage: (\n children: any,\n options: AtlasProps\n) => { uri: string | undefined; loading?: boolean; imageError?: string } = (\n children,\n { onCreated, resetWorldOnChange = true, mode = 'explore', cover, containerRef, ...restProps }\n) => {\n const [ready, setReady] = useState(false);\n const [imageUrl, setImageUrl] = useState<string | undefined>(undefined);\n const [imageError, setError] = useState<string | undefined>(undefined);\n // Reference to the current HTML Canvas element\n // Set by React by passing <canvas ref={...} />\n // Used to instantiate the controller and viewer with the correct HTML element.\n const canvasRef = useRef<HTMLCanvasElement>();\n\n // This is an HTML element that sits above the Canvas element that is passed to the controller.\n // Additional non-canvas drawn elements can be placed here and positioned. CSS is applied to this\n // element by this component to absolutely position it. The overlay is updated if the \"bounds\" change\n // on the parent element and matches the size of it.\n const overlayRef = useRef<HTMLDivElement>();\n\n // This measures the height and width of the Atlas element.\n // const [ref, bounds] = useMeasure({ scroll: true });\n const bounds = useMemo(() => {\n return {\n width: restProps.width,\n height: restProps.height,\n };\n }, [restProps.width, restProps.height]);\n\n // This is a big messy global state of atlas that is updated outside of Reacts lifecycle.\n const [presetName, preset, viewport, refs] = usePreset(undefined, {\n width: restProps.width,\n height: restProps.height,\n });\n\n // Create our in memory canvas.\n useIsomorphicLayoutEffect(() => {\n const $cvs = document.createElement('canvas');\n $cvs.height = bounds.height;\n $cvs.width = bounds.width;\n canvasRef.current = $cvs;\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n const $cvs = canvasRef.current;\n if ($cvs) {\n $cvs.height = bounds.height;\n $cvs.width = bounds.width;\n }\n }, [bounds.width, bounds.height]);\n\n useEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n return runtime.registerHook('useAfterFrame', () => {\n if (canvasRef.current) {\n try {\n setImageUrl(canvasRef.current.toDataURL());\n } catch (e) {\n if (e instanceof Error) {\n setError(e.message);\n }\n }\n }\n });\n }\n return () => {\n // no-op\n };\n }, []);\n\n useEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n return runtime.world.addLayoutSubscriber((type) => {\n if (type === 'ready') {\n setReady(true);\n }\n });\n }\n return () => {\n // no-op\n };\n }, []);\n\n // This changes the mutable state object with the position (top/left/width/height) of the\n // canvas element on the page. This is used in the editing tools such as BoxDraw for comparing\n // positions.\n useEffect(() => {\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n }, [bounds]);\n\n // This changes the mode in the state object when the prop passed in changes. This will\n // be picked up by the renderer on the next method. There is not current way to detect this change.\n // @todo create a mode change event.\n useEffect(() => {\n if (preset) {\n preset.runtime.mode = mode;\n }\n }, [mode]);\n\n // When the width and height change this will resize the viewer and then reset the view to fit the element.\n // @todo improve or make configurable.\n // @todo resize event.\n useEffect(() => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n if (cover) {\n rt.cover();\n } else {\n rt.goHome();\n }\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n }\n }, [restProps.width, restProps.height]);\n\n // When the bounds of the container change, we need to reflect those changes in the overlay.\n // @todo move to canvas.\n useIsomorphicLayoutEffect(() => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n overlay.style.width = `${bounds.width}px`;\n overlay.style.height = `${bounds.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.overflow = 'hidden';\n }, [bounds.height, bounds.width]);\n\n // When the window resizes we need to recalculate the width.\n // @todo possibly move to controller.\n useIsomorphicLayoutEffect(() => {\n const windowResizeCallback = () => {\n if (preset && preset.runtime) {\n const rt: Runtime = preset.runtime;\n\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n }\n };\n\n window.addEventListener('resize', windowResizeCallback);\n\n return () => window.removeEventListener('resize', windowResizeCallback);\n }, [preset, restProps.height, restProps.width]);\n\n const Canvas = useCallback(\n function Canvas(props: { children: React.ReactElement }): JSX.Element {\n const activate = () => {\n if (preset) {\n preset.ready = true;\n }\n };\n\n useEffect(() => {\n if (preset) {\n const result = onCreated && onCreated(preset);\n return void (result && result.then ? result.then(activate) : activate());\n }\n return () => {\n // no-op\n };\n }, []);\n\n return props.children;\n },\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [preset]\n );\n\n useEffect(() => {\n if (preset && preset.runtime) {\n const rt = preset.runtime;\n if (resetWorldOnChange) {\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'recalculate-world-size') {\n rt.goHome({ cover });\n }\n });\n }\n }\n return () => {\n // no-op\n };\n }, [preset, cover, resetWorldOnChange]);\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n ReactAtlas.render(\n <Canvas>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </Canvas>,\n preset.runtime\n );\n }\n }, [preset, mode, children]);\n\n return {\n loading: !imageUrl && ready,\n uri: imageUrl,\n imageError,\n };\n};\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useBeforeFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useBeforeFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useCallback, useState } from 'react';\nimport { nanoid } from 'nanoid';\n\nexport const useControlledAnnotationList = (\n initialList: Array<{ x: number; y: number; width: number; height: number; id: any }> = []\n) => {\n const [annotations, setAnnotations] =\n useState<Array<{ x: number; y: number; width: number; height: number; id: any }>>(initialList);\n const [isEditing, setIsEditing] = useState(false);\n const [selectedAnnotation, setSelectedAnnotation] = useState<string | undefined>();\n\n const addNewAnnotation = useCallback(() => {\n setIsEditing(true);\n setSelectedAnnotation(undefined);\n }, []);\n\n const editAnnotation = useCallback((id: string) => {\n setIsEditing(true);\n setSelectedAnnotation(id);\n }, []);\n\n const onUpdateAnnotation = (newAnno: any) => {\n setAnnotations((val) =>\n val.map((ann) => {\n if (ann.id === newAnno.id) {\n return newAnno;\n }\n return ann;\n })\n );\n };\n\n const onCreateNewAnnotation = useCallback((bounds: { x: number; y: number; width: number; height: number }) => {\n const id = nanoid();\n setAnnotations((a) => [...a, { id, ...bounds }]);\n setIsEditing(false);\n setSelectedAnnotation(undefined);\n }, []);\n\n const onDeselect = useCallback(() => {\n setIsEditing(false);\n setSelectedAnnotation(undefined);\n }, []);\n\n return {\n isEditing,\n onDeselect,\n selectedAnnotation,\n onCreateNewAnnotation,\n annotations,\n onUpdateAnnotation,\n setIsEditing,\n setSelectedAnnotation,\n editAnnotation,\n addNewAnnotation,\n };\n};\n","import { ViewerMode } from '../../../renderer/runtime';\n\nexport function canDrag(ref: { current: ViewerMode }) {\n return ref.current === 'sketch';\n}\n","import { BoxStyle } from '../objects/box';\n\nexport function mergeStyles(defaultStyle?: BoxStyle, style?: BoxStyle): BoxStyle | undefined {\n if (!defaultStyle) {\n return style;\n }\n if (!style) {\n return defaultStyle;\n }\n return {\n ...defaultStyle,\n ...(style || {}),\n ':hover': defaultStyle[':hover']\n ? Object.assign(defaultStyle[':hover'] || {}, style[':hover'] || {})\n : style[':hover'],\n ':active': defaultStyle[':active']\n ? Object.assign(defaultStyle[':active'] || {}, style[':active'] || {})\n : style[':hover'],\n };\n}\n"],"x_google_ignoreList":[1,2,20,25,26,27,28,29],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["AbortController","AbortSignal","v","scopedUrlAlphabet","event: keyof SupportedEvents","listeners","e","borderRegex","borderRegexCache: any","styleProps: Array<keyof BoxStyle>","borderRegexCache","styleProps","borderRegexCache: any","styleProps: Array<keyof GeometryStyle>","scale","clamp","clamp","timeout: ReturnType<typeof setTimeout> | undefined","abort","promise","shadowRegexCache: any","imageCache","LRUCache","scale","nextQueue: QueueTask[]","staleInFlight: string[]","indices: number[]","loaded: number[]","distance","nearestAhead: { image: SingleImage; distance: number } | undefined","nearestBehind: { image: SingleImage; distance: number } | undefined","singleImageLayer: SingleImage | undefined","transform","scale","toPaintIdx: number[]","scale","projected: Array<[number, number]>","points: number[]","tiles: MapTileCoordinate[]","cos","sin","objects: Paintable[]","arr: Paint[]","len","objects: Array<[WorldObject, Paintable[]]>","layers: Paint[]","scale","moduleState: {\n vault: Vault;\n loader: ImageServiceLoader;\n helper: any;\n}","tiles: any[]","adapter: WarpAdapter","hooks: WarpAdapterHooks","DEFAULT_STYLE: NavigatorRendererStyle","bounds: ZoneBounds[]","distance","scale","transform","source: CanvasImageSource | undefined","sourceWidth","sourceHeight","entry: ImageCacheEntry","classNames","scale","element: HTMLDivElement","UserAgent_DEPRECATED","ExecutionEnvironment","isEventSupported","normalizeWheel","bounceOut: EasingFunction","easingFunctions: { [key in EasingFunctionNames]: EasingFunction }","defaultConfig: Required<PopmotionControllerConfig>","panSamples: Array<{ x: number; y: number; t: number }>","lastGestureTarget: any","lastGestureOrigin: { x: number; y: number } | undefined","lastTapPoint: { x: number; y: number } | undefined","currentTapPoint: { x: number; y: number } | undefined","defaultConfig: Required<\n Pick<\n PdfScrollZoneControllerConfig,\n | 'scrollWheelFactor'\n | 'scrollLoadAheadFactor'\n | 'clickDragThresholdPx'\n | 'touchScrollMomentumStrength'\n | 'touchScrollMomentumMinStartPxPerMs'\n >\n>","defaultConfig","mode: ControllerMode","pendingProgrammaticRestoreZoneId: string | undefined","savedScrollViewport: ScrollViewport | undefined","initialHomeAnchorKey: string | undefined","activeTouchId: number | null","lastTouchPoint: WorldPoint | null","scrollBaseViewportCache: ScrollViewport | undefined","panSamples: Array<{ y: number; t: number }>","topZone: ZoneInterface | undefined","nextBaseViewport: ScrollViewport | undefined","touch","atlasTouch","tapPoint","useMode: () => ViewerMode","imageUrl: string | undefined","viewWidth: number","viewHeight: number","viewX: number","viewY: number","scale","defaultConfig: ZoneResolvedConfig","defaultConfig","getCurrentTime: () => number","instance: BaseObject<any, any> | ZoneHostInstance","world: World","now","React","AtlasWithReconciler: React.FC<AtlasWithReconcilerProps>","candidateOrder: string[]","activeCandidateId: string | undefined","selectedRuntimeId: string | undefined","snapshotCache: DevToolsRegistrySnapshot","flattenRenderers","entry: ImageDiagnostic","out: ImageDiagnostic[]","out: Array<SingleImage | TiledImage>","module","unmountComponentAtNode","TABS: DevToolsTab[]","DevTools: React.FC<DevToolsProps>","nodes: InspectorNode[]","DevToolsPanel: React.FC<DevToolsProps>","selectedRuntimeId","rects: Array<{ x: number; y: number; width: number; height: number }>","containerStyle: CSSProperties","buttonStyle: CSSProperties","panelStyle: CSSProperties","sectionStyle: CSSProperties","changes: Record<string, { before: any; after: any }>","fullEvent: AtlasWebGLFallbackEvent","scale","baseRenderer: CanvasRenderer | WebGLRenderer","parityCanvasRenderer: CanvasRenderer | undefined","runtimeRef: { current?: Runtime }","scale","element: HTMLImageElement","presets: { [key in PresetNames]: (options: any) => Preset }","Atlas: React.FC<\n AtlasProps & {\n width: number;\n height: number;\n }\n>","Atlas","presetName: PresetNames","presetOptions: Record<string, unknown>","presetName","injectedNavigatorRendererOptions: Record<string, unknown>","rt: Runtime","scale","Canvas","props","viewport","AtlasAuto: React.FC<\n AtlasProps & {\n height?: number | string;\n width?: number | string;\n resizeHash?: number;\n containerProps?: any;\n aspectRatio?: number;\n }\n>","AtlasAuto","DrawBox: React.FC<{\n children?: ReactNode;\n onCreate: (bounds: { x: number; y: number; width: number; height: number }) => void;\n}>","HTMLPortal: React.FC<\n {\n children?: ReactNode;\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n } & React.RefAttributes<Box>\n>","TileSet: React.FC<{\n tiles: GetTile;\n x?: number;\n y?: number;\n width: number;\n height: number;\n rotation?: number;\n crop?: any;\n children?: ReactNode;\n enableThumbnail?: boolean;\n enableSizes?: boolean;\n onClick?: (e: any) => void;\n renderOptions?: CompositeResourceProps;\n}>","scale","tiles","ImageService: React.FC<{\n id: string;\n width: number;\n height: number;\n x?: number;\n y?: number;\n rotation?: number;\n scale?: number;\n children?: ReactNode;\n crop?: any;\n enableSizes?: boolean;\n enableThumbnail?: boolean;\n renderOptions?: CompositeResourceProps;\n}>","items: ProjectedMapGeoJSONItem[]","all: ProjectedMapGeoJSONItem[]","MapGeoJSON: React.FC<MapGeoJSONProps>","MapObject: React.FC<MapObjectProps>","MapTileLayer: React.FC<MapTileLayerProps>","entries: Array<{\n\t\t\tzoom: number;\n\t\t\tcoverage: ReturnType<typeof estimateFiniteTileGridCoverage>;\n\t\t}>","translate","baseStyle: CSSProperties","useAtlasImage: (\n children: any,\n options: AtlasProps\n) => { uri: string | undefined; loading?: boolean; imageError?: string }","rt: Runtime","Canvas"],"sources":["../src/events.ts","../src/utils.ts","../src/modules/browser-event-manager/browser-event-manager.ts","../node_modules/.pnpm/lru-cache@7.18.3/node_modules/lru-cache/index.mjs","../node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/url-alphabet/index.js","../node_modules/.pnpm/nanoid@5.0.7/node_modules/nanoid/index.browser.js","../src/objects/base-object.ts","../src/objects/box.ts","../src/objects/geometry.ts","../src/spacial-content/single-image.ts","../src/spacial-content/tiled-image.ts","../src/utility/get-zone-constrained-bounds.ts","../src/modules/shared/build-css-filter.ts","../src/modules/shared/image-loading-config.ts","../src/modules/shared/image-request-pool.ts","../src/modules/canvas-renderer/canvas-renderer.ts","../src/modules/composite-renderer/composite-renderer.ts","../src/spacial-content/abstract-content.ts","../src/spacial-content/composite-resource.ts","../src/spacial-content/image-texture.ts","../src/modules/maps/projection.ts","../src/modules/maps/tile-source.ts","../src/spacial-content/map-tiled-image.ts","../src/modules/debug-renderer/debug-renderer.ts","../src/world-objects/world-object.ts","../src/world.ts","../src/modules/grid-builder/grid-builder.ts","../src/modules/iiif/shared.ts","../src/modules/iiif/get-vault-helper.ts","../src/modules/iiif/get-tiles.ts","../src/modules/maps/warped/adapter.ts","../src/modules/navigator-renderer/navigator-renderer.ts","../src/objects/text.ts","../src/utility/hash.ts","../src/utility/stylesheet.ts","../src/modules/overlay-renderer/overlay-renderer.ts","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/UserAgent_DEPRECATED.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/ExecutionEnvironment.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/isEventSupported.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/src/normalizeWheel.js","../node_modules/.pnpm/normalize-wheel@1.0.1/node_modules/normalize-wheel/index.js","../src/utility/easing-functions.ts","../src/modules/popmotion-controller/popmotion-controller.ts","../src/modules/pdf-scroll-zone-controller/pdf-scroll-zone-controller.ts","../src/modules/react-reconciler/components/AtlasContext.tsx","../src/modules/react-reconciler/hooks/use-mode.tsx","../src/modules/transition-manager/transition-manager.ts","../src/renderer/runtime.ts","../src/world-objects/zone.ts","../src/modules/react-reconciler/utility/now.ts","../src/modules/react-reconciler/reconciler.ts","../src/modules/react-reconciler/utility/react.ts","../src/modules/react-reconciler/components/AtlasWithReconciler.tsx","../src/modules/react-reconciler/components/Container.tsx","../src/modules/react-reconciler/hooks/use-atlas.ts","../src/modules/react-reconciler/hooks/use-runtime.ts","../src/modules/react-reconciler/devtools/registry.ts","../src/modules/react-reconciler/devtools/diagnostics.ts","../src/modules/react-reconciler/devtools/actions.ts","../src/modules/react-reconciler/utility/react-dom.ts","../src/modules/react-reconciler/components/DevTools.tsx","../src/modules/react-reconciler/hooks/use-classname.ts","../src/modules/react-reconciler/hooks/use-diff-props.ts","../src/modules/webgl-renderer/webgl-eligibility.ts","../src/modules/webgl-renderer/webgl-renderer.ts","../src/modules/react-reconciler/presets/default-preset.ts","../src/modules/static-renderer/static-renderer.ts","../src/modules/react-reconciler/presets/static-preset.ts","../src/modules/react-reconciler/presets/index.ts","../src/modules/react-reconciler/hooks/use-preset.ts","../src/modules/react-reconciler/Atlas.tsx","../src/modules/react-reconciler/utility/to-px.ts","../src/modules/react-reconciler/components/AtlasAuto.tsx","../src/modules/react-reconciler/hooks/use-after-frame.ts","../src/modules/react-reconciler/hooks/use-frame.ts","../src/modules/react-reconciler/hooks/use-canvas.ts","../src/modules/react-reconciler/hooks/use-canvas-position.ts","../src/modules/react-reconciler/components/BoxDraw.tsx","../src/modules/react-reconciler/components/HTMLPortal.tsx","../src/modules/react-reconciler/components/TileSet.tsx","../src/modules/react-reconciler/components/ImageService.tsx","../src/modules/react-reconciler/hooks/use-map-projection.ts","../src/modules/react-reconciler/hooks/use-map-geojson.ts","../src/modules/react-reconciler/components/MapGeoJSON.tsx","../src/modules/react-reconciler/components/MapObject.tsx","../src/modules/react-reconciler/components/MapTileLayer.tsx","../src/modules/react-reconciler/hooks/use-world-event.ts","../src/modules/react-reconciler/utility/get-ratio.ts","../src/modules/react-reconciler/hooks/use-modifier-keys.ts","../src/modules/react-reconciler/hooks/use-resize-world-item.ts","../src/modules/react-reconciler/components/ResizeWorldItem.tsx","../src/modules/react-reconciler/components/RegionHighlight.tsx","../src/modules/react-reconciler/hooks/use-after-paint.ts","../src/modules/react-reconciler/hooks/use-atlas-image.tsx","../src/modules/react-reconciler/hooks/use-before-frame.ts","../src/modules/react-reconciler/hooks/use-controlled-annotation-list.ts","../src/modules/react-reconciler/hooks/use-zone-runtime-state.ts","../src/modules/react-reconciler/utility/can-drag.ts","../src/utility/merge-styles.ts","../src/world-objects/image.ts"],"sourcesContent":["export const supportedEventAttributes = [\n 'onMouseDown',\n 'onMouseEnter',\n 'onMouseLeave',\n 'onMouseMove',\n 'onMouseOut',\n 'onMouseOver',\n 'onMouseUp',\n 'onTouchCancel',\n 'onTouchEnd',\n 'onTouchMove',\n 'onTouchStart',\n 'onPointerDown',\n 'onPointerMove',\n 'onPointerUp',\n 'onPointerCancel',\n 'onPointerEnter',\n 'onPointerLeave',\n 'onPointerOver',\n 'onPointerOut',\n 'onScroll',\n 'onWheel',\n 'onClick',\n // Drag.\n 'onDragStart',\n 'onDragEnd',\n 'onDragEnter',\n 'onDragExit',\n 'onDrag',\n 'onDragOver',\n 'onContextMenu',\n] as const;\n\nexport function createDefaultEventMap(): SupportedEventMap {\n return supportedEventAttributes.reduce((acc, next) => {\n (acc as any)[next] = [];\n return acc;\n }, {} as SupportedEventMap);\n}\n\nexport const supportedEventMap = supportedEventAttributes.reduce((acc, ev) => {\n (acc as any)[ev.slice(2).toLowerCase()] = ev;\n (acc as any)[ev] = ev;\n return acc;\n}, {} as { [ev in SupportedEventNames]: keyof SupportedEvents });\n\nexport type SupportedEvents = {\n onMouseDown(e: any): void;\n onMouseEnter(e: any): void;\n onMouseLeave(e: any): void;\n onMouseMove(e: any): void;\n onMouseOut(e: any): void;\n onMouseOver(e: any): void;\n onMouseUp(e: any): void;\n onTouchCancel(e: any): void;\n onTouchEnd(e: any): void;\n onTouchMove(e: any): void;\n onTouchStart(e: any): void;\n onPointerDown(e: any): void;\n onPointerMove(e: any): void;\n onPointerUp(e: any): void;\n onPointerCancel(e: any): void;\n onPointerEnter(e: any): void;\n onPointerLeave(e: any): void;\n onPointerOver(e: any): void;\n onPointerOut(e: any): void;\n onScroll(e: any): void;\n onWheel(e: any): void;\n onClick(e: any): void;\n onDragStart(e: any): void;\n onDragEnd(e: any): void;\n onDragEnter(e: any): void;\n onDragExit(e: any): void;\n onDrag(e: any): void;\n onDragOver(e: any): void;\n onContextMenu(e: any): void;\n};\n\nexport type SupportedEventNames =\n | 'mousedown'\n | 'mouseenter'\n | 'mouseleave'\n | 'mousemove'\n | 'mouseout'\n | 'mouseover'\n | 'mouseup'\n | 'touchcancel'\n | 'touchend'\n | 'touchmove'\n | 'touchstart'\n | 'pointerdown'\n | 'pointermove'\n | 'pointerup'\n | 'pointercancel'\n | 'pointerenter'\n | 'pointerleave'\n | 'pointerover'\n | 'pointerout'\n | 'scroll'\n | 'wheel'\n | 'click'\n | 'dragstart'\n | 'dragend'\n | 'dragenter'\n | 'dragexit'\n | 'drag'\n | 'dragover'\n | 'contextmenu';\n\nexport type SupportedEventMap = {\n [Name in keyof SupportedEvents]: Array<SupportedEvents[Name]>;\n};\n","import { SpacialContent } from './spacial-content/spacial-content';\n\nexport function bestResourceAtRatio<T extends SpacialContent>(ratio: number, resources: T[]): T | never {\n const len = resources.length;\n if (len === 0) {\n throw new Error('No resources passed in.');\n }\n\n let best = resources[0];\n let bestDistance = Infinity;\n for (let i = 0; i < len; i++) {\n if (!resources[i] || !resources[i].display) {\n break;\n }\n const distanceScale = distance1D(\n resources[i].display.scale,\n ratio\n );\n\n if (distanceScale < bestDistance) {\n bestDistance = distanceScale;\n best = resources[i];\n }\n }\n return best;\n}\n\nexport function bestResourceIndexAtRatio<T extends SpacialContent>(\n ratio: number,\n resources: T[],\n quality = 1\n): number | never {\n const len = resources.length;\n if (len === 0) {\n throw new Error('No resources passed in.');\n }\n\n let best = 0;\n let bestDistance = Infinity;\n for (let i = 0; i < len; i++) {\n if (!resources[i] || !resources[i].display) {\n break;\n }\n const distanceScale = distance1D(\n resources[i].display.scale,\n ratio / (quality || 1)\n );\n\n if (distanceScale < bestDistance) {\n bestDistance = distanceScale;\n best = i;\n }\n }\n\n return best;\n}\n\nexport function distance1D(a: number, b: number) {\n return Math.abs(a - b);\n}\n\nexport function distance(a: { x: number; y: number }, b: { x: number; y: number }) {\n const xDelta = distance1D(a.x, b.x);\n const yDelta = distance1D(a.y, b.y);\n return Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2));\n}\n\nexport function stripInfoJson(id: string): string {\n const len = id.length;\n if (id.indexOf('/info.json') === len - 10) {\n return id.slice(0, -10);\n }\n return id;\n}\n","import { supportedEventMap } from '../../events';\nimport type { BaseObject } from '../../objects/base-object';\nimport type { Runtime } from '../../renderer/runtime';\nimport { distance } from '../../utils';\n\nexport type BrowserEventManagerOptions = {\n /** Default 50ms **/\n simulationRate: number;\n};\n\nexport class BrowserEventManager {\n element: HTMLElement;\n runtime: Runtime;\n unsubscribe: () => any;\n activatedEvents: string[] = [];\n eventHandlers: [string, any][] = [];\n bounds: DOMRect;\n listening: boolean;\n static eventPool = {\n atlas: { x: 0, y: 0 },\n };\n\n // Elements being moused over.\n // lastTouches: { x: number; y: number }[] = [];\n\n // Some state.\n pointerMoveEvent: PointerEvent | undefined = undefined;\n pointerEventState: {\n isClicking: boolean;\n isPressed: boolean;\n isDragging: boolean;\n mousedOver: BaseObject[];\n itemsBeingDragged: BaseObject[];\n mouseDownStart: { x: number; y: number };\n lastTouches: Array<{ id: number; x: number; y: number }>;\n } = {\n isClicking: false,\n isDragging: false,\n isPressed: false,\n mousedOver: [],\n itemsBeingDragged: [],\n mouseDownStart: { x: 0, y: 0 },\n lastTouches: [],\n };\n\n options: BrowserEventManagerOptions;\n\n constructor(element: HTMLElement, runtime: Runtime, options?: Partial<BrowserEventManagerOptions>) {\n this.element = element;\n this.runtime = runtime;\n this.unsubscribe = runtime.world.addLayoutSubscriber(this.layoutSubscriber.bind(this));\n this.bounds = element.getBoundingClientRect();\n this.listening = false;\n this.options = {\n simulationRate: 0,\n ...(options || {}),\n };\n\n let tAcc = 0;\n runtime.registerHook('useFrame', (t: number) => {\n tAcc += t;\n if (tAcc > this.options.simulationRate && this.pointerMoveEvent) {\n tAcc = 0;\n runtime.updateNextFrame();\n }\n });\n\n runtime.registerHook('useBeforeFrame', () => {\n if (this.pointerMoveEvent) {\n this.onPointerMove(this.pointerMoveEvent);\n }\n });\n\n // this is necessary for CavnasPanel to initialize the event listener\n this.activateEvents();\n }\n\n updateBounds() {\n this.bounds = this.element.getBoundingClientRect();\n this.runtime.updateRendererScreenPosition();\n }\n\n layoutSubscriber(type: string) {\n if (type === 'event-activation' && this.listening == false) {\n this.activateEvents();\n }\n }\n\n assignToEvent(e: any, x: number, y: number) {\n BrowserEventManager.eventPool.atlas.x = x;\n BrowserEventManager.eventPool.atlas.y = y;\n e.atlas = BrowserEventManager.eventPool.atlas;\n }\n\n activateEvents() {\n this.listening = true;\n this.element.addEventListener('pointermove', this._realPointerMove);\n this.element.addEventListener('pointerup', this.onPointerUp);\n this.element.addEventListener('pointerdown', this.onPointerDown);\n\n // Normal events.\n this.element.addEventListener('mousedown', this.onPointerEvent);\n this.element.addEventListener('mouseup', this.onPointerEvent);\n this.element.addEventListener('pointercancel', this.onPointerEvent);\n\n // Edge-cases\n this.element.addEventListener('wheel', this.onWheelEvent);\n this.element.addEventListener('contextmenu', this.onContextMenu);\n\n // Touch events.\n this.element.addEventListener('touchstart', this.onTouchEvent);\n this.element.addEventListener('touchcancel', this.onTouchEvent);\n this.element.addEventListener('touchend', this.onTouchEvent);\n this.element.addEventListener('touchmove', this.onTouchEvent);\n }\n\n _realPointerMove = (e: PointerEvent) => {\n this.pointerMoveEvent = e;\n };\n\n onWheelEvent = (e: WheelEvent) => {\n e.preventDefault();\n\n this.onPointerEvent(e);\n };\n\n onContextMenu = (e: MouseEvent) => {\n e.preventDefault();\n const ev = 'onContextMenu';\n if (this.runtime.world.activatedEvents.indexOf(ev) !== -1) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n this.assignToEvent(e, x, y);\n this.runtime.world.propagatePointerEvent(ev as any, e, x, y);\n }\n };\n\n onTouchEvent = (e: TouchEvent) => {\n const type = (supportedEventMap as any)[e.type as any];\n const atlasTouches = [];\n // const atlasTargetTouches = [];\n const len = e.touches.length;\n for (let i = 0; i < len; i++) {\n const touch = e.touches.item(i);\n if (!touch) continue;\n const { x, y } = this.runtime.viewerToWorld(touch.clientX - this.bounds.left, touch.clientY - this.bounds.top);\n\n const atlasTouch = { id: touch.identifier, x, y };\n\n atlasTouches.push(atlasTouch);\n }\n\n if (atlasTouches.length) {\n // Assign the first touch to the main atlas variable\n this.assignToEvent(e, atlasTouches[0].x, atlasTouches[0].y);\n }\n\n if (type !== 'onTouchEnd' && type !== 'onTouchCancel') {\n this.pointerEventState.lastTouches = atlasTouches;\n (e as any).atlasTouches = atlasTouches;\n this.runtime.world.propagateTouchEvent(type, e as any, atlasTouches);\n } else {\n (e as any).atlasTouches = [];\n this.runtime.world.propagateTouchEvent(type, e as any, this.pointerEventState.lastTouches);\n this.pointerEventState.lastTouches = [];\n }\n };\n\n onPointerEvent = (e: PointerEvent | MouseEvent) => {\n if (e.button === 2) {\n return;\n }\n const ev = (supportedEventMap as any)[e.type as any];\n if (ev && this.runtime.world.activatedEvents.indexOf(ev) !== -1) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n this.assignToEvent(e, x, y);\n this.runtime.world.propagatePointerEvent(ev as any, e, x, y);\n }\n };\n\n onPointerDown = (e: PointerEvent | MouseEvent) => {\n if (e.button === 2) {\n return;\n }\n this.pointerEventState.isPressed = true;\n this.pointerEventState.isClicking = true;\n this.pointerEventState.mouseDownStart.x = e.clientX;\n this.pointerEventState.mouseDownStart.y = e.clientY;\n setTimeout(() => {\n if (this.runtime) {\n this.pointerEventState.isClicking = false;\n }\n }, 250);\n setTimeout(() => {\n if (this.runtime && this.pointerEventState.isPressed && !this.pointerEventState.isDragging) {\n const dragStart = this.runtime.viewerToWorld(\n this.pointerEventState.mouseDownStart.x - this.bounds.left,\n this.pointerEventState.mouseDownStart.y - this.bounds.top\n );\n this.pointerEventState.isDragging = true;\n this.pointerEventState.itemsBeingDragged = this.runtime.world.propagatePointerEvent(\n 'onDragStart',\n e,\n dragStart.x,\n dragStart.y\n );\n }\n }, 800);\n\n // And then handle as normal pointer event.\n this.onPointerEvent(e);\n };\n\n onPointerUp = (e: PointerEvent | MouseEvent) => {\n if (e.button === 2) {\n return;\n }\n if (this.pointerEventState.isClicking) {\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n\n this.assignToEvent(e, x, y);\n\n this.runtime.world.propagatePointerEvent('onClick', e, x, y);\n }\n\n if (this.pointerEventState.isDragging) {\n for (const item of this.pointerEventState.itemsBeingDragged) {\n item.dispatchEvent('onDragEnd', e);\n }\n this.pointerEventState.isDragging = false;\n }\n this.pointerEventState.isClicking = false;\n this.pointerEventState.isPressed = false;\n this.pointerEventState.itemsBeingDragged = [];\n\n // Then handle as normal pointer event.\n this.onPointerEvent(e);\n };\n\n onPointerMove = (e: PointerEvent | MouseEvent) => {\n this.pointerMoveEvent = undefined;\n const { x, y } = this.runtime.viewerToWorld(e.clientX - this.bounds.left, e.clientY - this.bounds.top);\n\n if (Number.isNaN(x) || Number.isNaN(y)) {\n return;\n }\n\n this.assignToEvent(e, x, y);\n\n // We have to propagate both, but only get a new list from one.\n this.runtime.world.propagatePointerEvent('onPointerMove', e, x, y);\n const newList = this.runtime.world.propagatePointerEvent('onMouseMove', e, x, y);\n\n // This is where we handle mouse enter and mouse leave events. This could be\n // stored and handled inside of the world.\n const newIds = [];\n const newItems = [];\n for (const item of newList) {\n newIds.push(item.id);\n newItems.push(item);\n if (this.pointerEventState.mousedOver.indexOf(item) === -1) {\n item.dispatchEvent('onMouseEnter', e);\n item.dispatchEvent('onPointerEnter', e);\n\n // @todo the behaviour of these are slightly different.\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseover_event\n item.dispatchEvent('onMouseOver', e);\n item.dispatchEvent('onPointerOver', e);\n }\n }\n for (const oldItem of this.pointerEventState.mousedOver) {\n if (newIds.indexOf(oldItem.id) === -1) {\n oldItem.dispatchEvent('onMouseLeave', e);\n oldItem.dispatchEvent('onPointerLeave', e);\n\n // @todo the behaviour of these are slightly different.\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseout_event\n oldItem.dispatchEvent('onMouseOut', e);\n oldItem.dispatchEvent('onPointerOut', e);\n }\n }\n\n if (this.pointerEventState.isDragging) {\n for (const item of this.pointerEventState.itemsBeingDragged) {\n item.dispatchEvent('onDrag', e);\n }\n // @todo take the results of this and do a drag-over.\n }\n\n if (\n this.pointerEventState.isPressed &&\n !this.pointerEventState.isDragging &&\n distance(this.pointerEventState.mouseDownStart, {\n x: e.clientX,\n y: e.clientY,\n }) > 50\n ) {\n const dragStart = this.runtime.viewerToWorld(\n this.pointerEventState.mouseDownStart.x - this.bounds.left,\n this.pointerEventState.mouseDownStart.y - this.bounds.top\n );\n this.pointerEventState.isDragging = true;\n this.pointerEventState.itemsBeingDragged = this.runtime.world.propagatePointerEvent(\n 'onDragStart',\n { ...e, atlas: { x: dragStart.x, y: dragStart.y } },\n dragStart.x,\n dragStart.y\n );\n }\n this.pointerEventState.mousedOver = newItems;\n };\n\n normalizeEventName(event: string) {\n if (event.startsWith('on')) {\n return event.slice(2).toLowerCase();\n }\n return event.toLowerCase();\n }\n\n stop() {\n this.listening = false;\n this.element.removeEventListener('pointermove', this._realPointerMove);\n this.element.removeEventListener('pointerup', this.onPointerUp);\n this.element.removeEventListener('pointerdown', this.onPointerDown);\n\n // Normal events.\n this.element.removeEventListener('mousedown', this.onPointerEvent);\n this.element.removeEventListener('mouseup', this.onPointerEvent);\n this.element.removeEventListener('pointercancel', this.onPointerEvent);\n\n // Edge-cases\n this.element.removeEventListener('wheel', this.onWheelEvent);\n\n // Touch events.\n this.element.removeEventListener('touchstart', this.onTouchEvent);\n this.element.removeEventListener('touchcancel', this.onTouchEvent);\n this.element.removeEventListener('touchend', this.onTouchEvent);\n this.element.removeEventListener('touchmove', this.onTouchEvent);\n\n // Unbind all events.\n this.unsubscribe();\n for (const [event, handler] of this.eventHandlers) {\n this.element.removeEventListener(this.normalizeEventName(event), handler);\n }\n }\n}\n","const perf =\n typeof performance === 'object' &&\n performance &&\n typeof performance.now === 'function'\n ? performance\n : Date\n\nconst hasAbortController = typeof AbortController === 'function'\n\n// minimal backwards-compatibility polyfill\n// this doesn't have nearly all the checks and whatnot that\n// actual AbortController/Signal has, but it's enough for\n// our purposes, and if used properly, behaves the same.\nconst AC = hasAbortController\n ? AbortController\n : class AbortController {\n constructor() {\n this.signal = new AS()\n }\n abort(reason = new Error('This operation was aborted')) {\n this.signal.reason = this.signal.reason || reason\n this.signal.aborted = true\n this.signal.dispatchEvent({\n type: 'abort',\n target: this.signal,\n })\n }\n }\n\nconst hasAbortSignal = typeof AbortSignal === 'function'\n// Some polyfills put this on the AC class, not global\nconst hasACAbortSignal = typeof AC.AbortSignal === 'function'\nconst AS = hasAbortSignal\n ? AbortSignal\n : hasACAbortSignal\n ? AC.AbortController\n : class AbortSignal {\n constructor() {\n this.reason = undefined\n this.aborted = false\n this._listeners = []\n }\n dispatchEvent(e) {\n if (e.type === 'abort') {\n this.aborted = true\n this.onabort(e)\n this._listeners.forEach(f => f(e), this)\n }\n }\n onabort() {}\n addEventListener(ev, fn) {\n if (ev === 'abort') {\n this._listeners.push(fn)\n }\n }\n removeEventListener(ev, fn) {\n if (ev === 'abort') {\n this._listeners = this._listeners.filter(f => f !== fn)\n }\n }\n }\n\nconst warned = new Set()\nconst deprecatedOption = (opt, instead) => {\n const code = `LRU_CACHE_OPTION_${opt}`\n if (shouldWarn(code)) {\n warn(code, `${opt} option`, `options.${instead}`, LRUCache)\n }\n}\nconst deprecatedMethod = (method, instead) => {\n const code = `LRU_CACHE_METHOD_${method}`\n if (shouldWarn(code)) {\n const { prototype } = LRUCache\n const { get } = Object.getOwnPropertyDescriptor(prototype, method)\n warn(code, `${method} method`, `cache.${instead}()`, get)\n }\n}\nconst deprecatedProperty = (field, instead) => {\n const code = `LRU_CACHE_PROPERTY_${field}`\n if (shouldWarn(code)) {\n const { prototype } = LRUCache\n const { get } = Object.getOwnPropertyDescriptor(prototype, field)\n warn(code, `${field} property`, `cache.${instead}`, get)\n }\n}\n\nconst emitWarning = (...a) => {\n typeof process === 'object' &&\n process &&\n typeof process.emitWarning === 'function'\n ? process.emitWarning(...a)\n : console.error(...a)\n}\n\nconst shouldWarn = code => !warned.has(code)\n\nconst warn = (code, what, instead, fn) => {\n warned.add(code)\n const msg = `The ${what} is deprecated. Please use ${instead} instead.`\n emitWarning(msg, 'DeprecationWarning', code, fn)\n}\n\nconst isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n)\n\n/* istanbul ignore next - This is a little bit ridiculous, tbh.\n * The maximum array length is 2^32-1 or thereabouts on most JS impls.\n * And well before that point, you're caching the entire world, I mean,\n * that's ~32GB of just integers for the next/prev links, plus whatever\n * else to hold that many keys and values. Just filling the memory with\n * zeroes at init time is brutal when you get that big.\n * But why not be complete?\n * Maybe in the future, these limits will have expanded. */\nconst getUintArray = max =>\n !isPosInt(max)\n ? null\n : max <= Math.pow(2, 8)\n ? Uint8Array\n : max <= Math.pow(2, 16)\n ? Uint16Array\n : max <= Math.pow(2, 32)\n ? Uint32Array\n : max <= Number.MAX_SAFE_INTEGER\n ? ZeroArray\n : null\n\nclass ZeroArray extends Array {\n constructor(size) {\n super(size)\n this.fill(0)\n }\n}\n\nclass Stack {\n constructor(max) {\n if (max === 0) {\n return []\n }\n const UintArray = getUintArray(max)\n this.heap = new UintArray(max)\n this.length = 0\n }\n push(n) {\n this.heap[this.length++] = n\n }\n pop() {\n return this.heap[--this.length]\n }\n}\n\nclass LRUCache {\n constructor(options = {}) {\n const {\n max = 0,\n ttl,\n ttlResolution = 1,\n ttlAutopurge,\n updateAgeOnGet,\n updateAgeOnHas,\n allowStale,\n dispose,\n disposeAfter,\n noDisposeOnSet,\n noUpdateTTL,\n maxSize = 0,\n maxEntrySize = 0,\n sizeCalculation,\n fetchMethod,\n fetchContext,\n noDeleteOnFetchRejection,\n noDeleteOnStaleGet,\n allowStaleOnFetchRejection,\n allowStaleOnFetchAbort,\n ignoreFetchAbort,\n } = options\n\n // deprecated options, don't trigger a warning for getting them if\n // the thing being passed in is another LRUCache we're copying.\n const { length, maxAge, stale } =\n options instanceof LRUCache ? {} : options\n\n if (max !== 0 && !isPosInt(max)) {\n throw new TypeError('max option must be a nonnegative integer')\n }\n\n const UintArray = max ? getUintArray(max) : Array\n if (!UintArray) {\n throw new Error('invalid max value: ' + max)\n }\n\n this.max = max\n this.maxSize = maxSize\n this.maxEntrySize = maxEntrySize || this.maxSize\n this.sizeCalculation = sizeCalculation || length\n if (this.sizeCalculation) {\n if (!this.maxSize && !this.maxEntrySize) {\n throw new TypeError(\n 'cannot set sizeCalculation without setting maxSize or maxEntrySize'\n )\n }\n if (typeof this.sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation set to non-function')\n }\n }\n\n this.fetchMethod = fetchMethod || null\n if (this.fetchMethod && typeof this.fetchMethod !== 'function') {\n throw new TypeError(\n 'fetchMethod must be a function if specified'\n )\n }\n\n this.fetchContext = fetchContext\n if (!this.fetchMethod && fetchContext !== undefined) {\n throw new TypeError(\n 'cannot set fetchContext without fetchMethod'\n )\n }\n\n this.keyMap = new Map()\n this.keyList = new Array(max).fill(null)\n this.valList = new Array(max).fill(null)\n this.next = new UintArray(max)\n this.prev = new UintArray(max)\n this.head = 0\n this.tail = 0\n this.free = new Stack(max)\n this.initialFill = 1\n this.size = 0\n\n if (typeof dispose === 'function') {\n this.dispose = dispose\n }\n if (typeof disposeAfter === 'function') {\n this.disposeAfter = disposeAfter\n this.disposed = []\n } else {\n this.disposeAfter = null\n this.disposed = null\n }\n this.noDisposeOnSet = !!noDisposeOnSet\n this.noUpdateTTL = !!noUpdateTTL\n this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection\n this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection\n this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort\n this.ignoreFetchAbort = !!ignoreFetchAbort\n\n // NB: maxEntrySize is set to maxSize if it's set\n if (this.maxEntrySize !== 0) {\n if (this.maxSize !== 0) {\n if (!isPosInt(this.maxSize)) {\n throw new TypeError(\n 'maxSize must be a positive integer if specified'\n )\n }\n }\n if (!isPosInt(this.maxEntrySize)) {\n throw new TypeError(\n 'maxEntrySize must be a positive integer if specified'\n )\n }\n this.initializeSizeTracking()\n }\n\n this.allowStale = !!allowStale || !!stale\n this.noDeleteOnStaleGet = !!noDeleteOnStaleGet\n this.updateAgeOnGet = !!updateAgeOnGet\n this.updateAgeOnHas = !!updateAgeOnHas\n this.ttlResolution =\n isPosInt(ttlResolution) || ttlResolution === 0\n ? ttlResolution\n : 1\n this.ttlAutopurge = !!ttlAutopurge\n this.ttl = ttl || maxAge || 0\n if (this.ttl) {\n if (!isPosInt(this.ttl)) {\n throw new TypeError(\n 'ttl must be a positive integer if specified'\n )\n }\n this.initializeTTLTracking()\n }\n\n // do not allow completely unbounded caches\n if (this.max === 0 && this.ttl === 0 && this.maxSize === 0) {\n throw new TypeError(\n 'At least one of max, maxSize, or ttl is required'\n )\n }\n if (!this.ttlAutopurge && !this.max && !this.maxSize) {\n const code = 'LRU_CACHE_UNBOUNDED'\n if (shouldWarn(code)) {\n warned.add(code)\n const msg =\n 'TTL caching without ttlAutopurge, max, or maxSize can ' +\n 'result in unbounded memory consumption.'\n emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache)\n }\n }\n\n if (stale) {\n deprecatedOption('stale', 'allowStale')\n }\n if (maxAge) {\n deprecatedOption('maxAge', 'ttl')\n }\n if (length) {\n deprecatedOption('length', 'sizeCalculation')\n }\n }\n\n getRemainingTTL(key) {\n return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0\n }\n\n initializeTTLTracking() {\n this.ttls = new ZeroArray(this.max)\n this.starts = new ZeroArray(this.max)\n\n this.setItemTTL = (index, ttl, start = perf.now()) => {\n this.starts[index] = ttl !== 0 ? start : 0\n this.ttls[index] = ttl\n if (ttl !== 0 && this.ttlAutopurge) {\n const t = setTimeout(() => {\n if (this.isStale(index)) {\n this.delete(this.keyList[index])\n }\n }, ttl + 1)\n /* istanbul ignore else - unref() not supported on all platforms */\n if (t.unref) {\n t.unref()\n }\n }\n }\n\n this.updateItemAge = index => {\n this.starts[index] = this.ttls[index] !== 0 ? perf.now() : 0\n }\n\n this.statusTTL = (status, index) => {\n if (status) {\n status.ttl = this.ttls[index]\n status.start = this.starts[index]\n status.now = cachedNow || getNow()\n status.remainingTTL = status.now + status.ttl - status.start\n }\n }\n\n // debounce calls to perf.now() to 1s so we're not hitting\n // that costly call repeatedly.\n let cachedNow = 0\n const getNow = () => {\n const n = perf.now()\n if (this.ttlResolution > 0) {\n cachedNow = n\n const t = setTimeout(\n () => (cachedNow = 0),\n this.ttlResolution\n )\n /* istanbul ignore else - not available on all platforms */\n if (t.unref) {\n t.unref()\n }\n }\n return n\n }\n\n this.getRemainingTTL = key => {\n const index = this.keyMap.get(key)\n if (index === undefined) {\n return 0\n }\n return this.ttls[index] === 0 || this.starts[index] === 0\n ? Infinity\n : this.starts[index] +\n this.ttls[index] -\n (cachedNow || getNow())\n }\n\n this.isStale = index => {\n return (\n this.ttls[index] !== 0 &&\n this.starts[index] !== 0 &&\n (cachedNow || getNow()) - this.starts[index] >\n this.ttls[index]\n )\n }\n }\n updateItemAge(_index) {}\n statusTTL(_status, _index) {}\n setItemTTL(_index, _ttl, _start) {}\n isStale(_index) {\n return false\n }\n\n initializeSizeTracking() {\n this.calculatedSize = 0\n this.sizes = new ZeroArray(this.max)\n this.removeItemSize = index => {\n this.calculatedSize -= this.sizes[index]\n this.sizes[index] = 0\n }\n this.requireSize = (k, v, size, sizeCalculation) => {\n // provisionally accept background fetches.\n // actual value size will be checked when they return.\n if (this.isBackgroundFetch(v)) {\n return 0\n }\n if (!isPosInt(size)) {\n if (sizeCalculation) {\n if (typeof sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation must be a function')\n }\n size = sizeCalculation(v, k)\n if (!isPosInt(size)) {\n throw new TypeError(\n 'sizeCalculation return invalid (expect positive integer)'\n )\n }\n } else {\n throw new TypeError(\n 'invalid size value (must be positive integer). ' +\n 'When maxSize or maxEntrySize is used, sizeCalculation or size ' +\n 'must be set.'\n )\n }\n }\n return size\n }\n this.addItemSize = (index, size, status) => {\n this.sizes[index] = size\n if (this.maxSize) {\n const maxSize = this.maxSize - this.sizes[index]\n while (this.calculatedSize > maxSize) {\n this.evict(true)\n }\n }\n this.calculatedSize += this.sizes[index]\n if (status) {\n status.entrySize = size\n status.totalCalculatedSize = this.calculatedSize\n }\n }\n }\n removeItemSize(_index) {}\n addItemSize(_index, _size) {}\n requireSize(_k, _v, size, sizeCalculation) {\n if (size || sizeCalculation) {\n throw new TypeError(\n 'cannot set size without setting maxSize or maxEntrySize on cache'\n )\n }\n }\n\n *indexes({ allowStale = this.allowStale } = {}) {\n if (this.size) {\n for (let i = this.tail; true; ) {\n if (!this.isValidIndex(i)) {\n break\n }\n if (allowStale || !this.isStale(i)) {\n yield i\n }\n if (i === this.head) {\n break\n } else {\n i = this.prev[i]\n }\n }\n }\n }\n\n *rindexes({ allowStale = this.allowStale } = {}) {\n if (this.size) {\n for (let i = this.head; true; ) {\n if (!this.isValidIndex(i)) {\n break\n }\n if (allowStale || !this.isStale(i)) {\n yield i\n }\n if (i === this.tail) {\n break\n } else {\n i = this.next[i]\n }\n }\n }\n }\n\n isValidIndex(index) {\n return (\n index !== undefined &&\n this.keyMap.get(this.keyList[index]) === index\n )\n }\n\n *entries() {\n for (const i of this.indexes()) {\n if (\n this.valList[i] !== undefined &&\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield [this.keyList[i], this.valList[i]]\n }\n }\n }\n *rentries() {\n for (const i of this.rindexes()) {\n if (\n this.valList[i] !== undefined &&\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield [this.keyList[i], this.valList[i]]\n }\n }\n }\n\n *keys() {\n for (const i of this.indexes()) {\n if (\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.keyList[i]\n }\n }\n }\n *rkeys() {\n for (const i of this.rindexes()) {\n if (\n this.keyList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.keyList[i]\n }\n }\n }\n\n *values() {\n for (const i of this.indexes()) {\n if (\n this.valList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.valList[i]\n }\n }\n }\n *rvalues() {\n for (const i of this.rindexes()) {\n if (\n this.valList[i] !== undefined &&\n !this.isBackgroundFetch(this.valList[i])\n ) {\n yield this.valList[i]\n }\n }\n }\n\n [Symbol.iterator]() {\n return this.entries()\n }\n\n find(fn, getOptions) {\n for (const i of this.indexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n if (fn(value, this.keyList[i], this)) {\n return this.get(this.keyList[i], getOptions)\n }\n }\n }\n\n forEach(fn, thisp = this) {\n for (const i of this.indexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n fn.call(thisp, value, this.keyList[i], this)\n }\n }\n\n rforEach(fn, thisp = this) {\n for (const i of this.rindexes()) {\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n fn.call(thisp, value, this.keyList[i], this)\n }\n }\n\n get prune() {\n deprecatedMethod('prune', 'purgeStale')\n return this.purgeStale\n }\n\n purgeStale() {\n let deleted = false\n for (const i of this.rindexes({ allowStale: true })) {\n if (this.isStale(i)) {\n this.delete(this.keyList[i])\n deleted = true\n }\n }\n return deleted\n }\n\n dump() {\n const arr = []\n for (const i of this.indexes({ allowStale: true })) {\n const key = this.keyList[i]\n const v = this.valList[i]\n const value = this.isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v\n if (value === undefined) continue\n const entry = { value }\n if (this.ttls) {\n entry.ttl = this.ttls[i]\n // always dump the start relative to a portable timestamp\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = perf.now() - this.starts[i]\n entry.start = Math.floor(Date.now() - age)\n }\n if (this.sizes) {\n entry.size = this.sizes[i]\n }\n arr.unshift([key, entry])\n }\n return arr\n }\n\n load(arr) {\n this.clear()\n for (const [key, entry] of arr) {\n if (entry.start) {\n // entry.start is a portable timestamp, but we may be using\n // node's performance.now(), so calculate the offset.\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = Date.now() - entry.start\n entry.start = perf.now() - age\n }\n this.set(key, entry.value, entry)\n }\n }\n\n dispose(_v, _k, _reason) {}\n\n set(\n k,\n v,\n {\n ttl = this.ttl,\n start,\n noDisposeOnSet = this.noDisposeOnSet,\n size = 0,\n sizeCalculation = this.sizeCalculation,\n noUpdateTTL = this.noUpdateTTL,\n status,\n } = {}\n ) {\n size = this.requireSize(k, v, size, sizeCalculation)\n // if the item doesn't fit, don't do anything\n // NB: maxEntrySize set to maxSize by default\n if (this.maxEntrySize && size > this.maxEntrySize) {\n if (status) {\n status.set = 'miss'\n status.maxEntrySizeExceeded = true\n }\n // have to delete, in case a background fetch is there already.\n // in non-async cases, this is a no-op\n this.delete(k)\n return this\n }\n let index = this.size === 0 ? undefined : this.keyMap.get(k)\n if (index === undefined) {\n // addition\n index = this.newIndex()\n this.keyList[index] = k\n this.valList[index] = v\n this.keyMap.set(k, index)\n this.next[this.tail] = index\n this.prev[index] = this.tail\n this.tail = index\n this.size++\n this.addItemSize(index, size, status)\n if (status) {\n status.set = 'add'\n }\n noUpdateTTL = false\n } else {\n // update\n this.moveToTail(index)\n const oldVal = this.valList[index]\n if (v !== oldVal) {\n if (this.isBackgroundFetch(oldVal)) {\n oldVal.__abortController.abort(new Error('replaced'))\n } else {\n if (!noDisposeOnSet) {\n this.dispose(oldVal, k, 'set')\n if (this.disposeAfter) {\n this.disposed.push([oldVal, k, 'set'])\n }\n }\n }\n this.removeItemSize(index)\n this.valList[index] = v\n this.addItemSize(index, size, status)\n if (status) {\n status.set = 'replace'\n const oldValue =\n oldVal && this.isBackgroundFetch(oldVal)\n ? oldVal.__staleWhileFetching\n : oldVal\n if (oldValue !== undefined) status.oldValue = oldValue\n }\n } else if (status) {\n status.set = 'update'\n }\n }\n if (ttl !== 0 && this.ttl === 0 && !this.ttls) {\n this.initializeTTLTracking()\n }\n if (!noUpdateTTL) {\n this.setItemTTL(index, ttl, start)\n }\n this.statusTTL(status, index)\n if (this.disposeAfter) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n return this\n }\n\n newIndex() {\n if (this.size === 0) {\n return this.tail\n }\n if (this.size === this.max && this.max !== 0) {\n return this.evict(false)\n }\n if (this.free.length !== 0) {\n return this.free.pop()\n }\n // initial fill, just keep writing down the list\n return this.initialFill++\n }\n\n pop() {\n if (this.size) {\n const val = this.valList[this.head]\n this.evict(true)\n return val\n }\n }\n\n evict(free) {\n const head = this.head\n const k = this.keyList[head]\n const v = this.valList[head]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('evicted'))\n } else {\n this.dispose(v, k, 'evict')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'evict'])\n }\n }\n this.removeItemSize(head)\n // if we aren't about to use the index, then null these out\n if (free) {\n this.keyList[head] = null\n this.valList[head] = null\n this.free.push(head)\n }\n this.head = this.next[head]\n this.keyMap.delete(k)\n this.size--\n return head\n }\n\n has(k, { updateAgeOnHas = this.updateAgeOnHas, status } = {}) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n if (!this.isStale(index)) {\n if (updateAgeOnHas) {\n this.updateItemAge(index)\n }\n if (status) status.has = 'hit'\n this.statusTTL(status, index)\n return true\n } else if (status) {\n status.has = 'stale'\n this.statusTTL(status, index)\n }\n } else if (status) {\n status.has = 'miss'\n }\n return false\n }\n\n // like get(), but without any LRU updating or TTL expiration\n peek(k, { allowStale = this.allowStale } = {}) {\n const index = this.keyMap.get(k)\n if (index !== undefined && (allowStale || !this.isStale(index))) {\n const v = this.valList[index]\n // either stale and allowed, or forcing a refresh of non-stale value\n return this.isBackgroundFetch(v) ? v.__staleWhileFetching : v\n }\n }\n\n backgroundFetch(k, index, options, context) {\n const v = index === undefined ? undefined : this.valList[index]\n if (this.isBackgroundFetch(v)) {\n return v\n }\n const ac = new AC()\n if (options.signal) {\n options.signal.addEventListener('abort', () =>\n ac.abort(options.signal.reason)\n )\n }\n const fetchOpts = {\n signal: ac.signal,\n options,\n context,\n }\n const cb = (v, updateCache = false) => {\n const { aborted } = ac.signal\n const ignoreAbort = options.ignoreFetchAbort && v !== undefined\n if (options.status) {\n if (aborted && !updateCache) {\n options.status.fetchAborted = true\n options.status.fetchError = ac.signal.reason\n if (ignoreAbort) options.status.fetchAbortIgnored = true\n } else {\n options.status.fetchResolved = true\n }\n }\n if (aborted && !ignoreAbort && !updateCache) {\n return fetchFail(ac.signal.reason)\n }\n // either we didn't abort, and are still here, or we did, and ignored\n if (this.valList[index] === p) {\n if (v === undefined) {\n if (p.__staleWhileFetching) {\n this.valList[index] = p.__staleWhileFetching\n } else {\n this.delete(k)\n }\n } else {\n if (options.status) options.status.fetchUpdated = true\n this.set(k, v, fetchOpts.options)\n }\n }\n return v\n }\n const eb = er => {\n if (options.status) {\n options.status.fetchRejected = true\n options.status.fetchError = er\n }\n return fetchFail(er)\n }\n const fetchFail = er => {\n const { aborted } = ac.signal\n const allowStaleAborted =\n aborted && options.allowStaleOnFetchAbort\n const allowStale =\n allowStaleAborted || options.allowStaleOnFetchRejection\n const noDelete = allowStale || options.noDeleteOnFetchRejection\n if (this.valList[index] === p) {\n // if we allow stale on fetch rejections, then we need to ensure that\n // the stale value is not removed from the cache when the fetch fails.\n const del = !noDelete || p.__staleWhileFetching === undefined\n if (del) {\n this.delete(k)\n } else if (!allowStaleAborted) {\n // still replace the *promise* with the stale value,\n // since we are done with the promise at this point.\n // leave it untouched if we're still waiting for an\n // aborted background fetch that hasn't yet returned.\n this.valList[index] = p.__staleWhileFetching\n }\n }\n if (allowStale) {\n if (options.status && p.__staleWhileFetching !== undefined) {\n options.status.returnedStale = true\n }\n return p.__staleWhileFetching\n } else if (p.__returned === p) {\n throw er\n }\n }\n const pcall = (res, rej) => {\n this.fetchMethod(k, v, fetchOpts).then(v => res(v), rej)\n // ignored, we go until we finish, regardless.\n // defer check until we are actually aborting,\n // so fetchMethod can override.\n ac.signal.addEventListener('abort', () => {\n if (\n !options.ignoreFetchAbort ||\n options.allowStaleOnFetchAbort\n ) {\n res()\n // when it eventually resolves, update the cache.\n if (options.allowStaleOnFetchAbort) {\n res = v => cb(v, true)\n }\n }\n })\n }\n if (options.status) options.status.fetchDispatched = true\n const p = new Promise(pcall).then(cb, eb)\n p.__abortController = ac\n p.__staleWhileFetching = v\n p.__returned = null\n if (index === undefined) {\n // internal, don't expose status.\n this.set(k, p, { ...fetchOpts.options, status: undefined })\n index = this.keyMap.get(k)\n } else {\n this.valList[index] = p\n }\n return p\n }\n\n isBackgroundFetch(p) {\n return (\n p &&\n typeof p === 'object' &&\n typeof p.then === 'function' &&\n Object.prototype.hasOwnProperty.call(\n p,\n '__staleWhileFetching'\n ) &&\n Object.prototype.hasOwnProperty.call(p, '__returned') &&\n (p.__returned === p || p.__returned === null)\n )\n }\n\n // this takes the union of get() and set() opts, because it does both\n async fetch(\n k,\n {\n // get options\n allowStale = this.allowStale,\n updateAgeOnGet = this.updateAgeOnGet,\n noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n // set options\n ttl = this.ttl,\n noDisposeOnSet = this.noDisposeOnSet,\n size = 0,\n sizeCalculation = this.sizeCalculation,\n noUpdateTTL = this.noUpdateTTL,\n // fetch exclusive options\n noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,\n allowStaleOnFetchRejection = this.allowStaleOnFetchRejection,\n ignoreFetchAbort = this.ignoreFetchAbort,\n allowStaleOnFetchAbort = this.allowStaleOnFetchAbort,\n fetchContext = this.fetchContext,\n forceRefresh = false,\n status,\n signal,\n } = {}\n ) {\n if (!this.fetchMethod) {\n if (status) status.fetch = 'get'\n return this.get(k, {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n status,\n })\n }\n\n const options = {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n ttl,\n noDisposeOnSet,\n size,\n sizeCalculation,\n noUpdateTTL,\n noDeleteOnFetchRejection,\n allowStaleOnFetchRejection,\n allowStaleOnFetchAbort,\n ignoreFetchAbort,\n status,\n signal,\n }\n\n let index = this.keyMap.get(k)\n if (index === undefined) {\n if (status) status.fetch = 'miss'\n const p = this.backgroundFetch(k, index, options, fetchContext)\n return (p.__returned = p)\n } else {\n // in cache, maybe already fetching\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n const stale =\n allowStale && v.__staleWhileFetching !== undefined\n if (status) {\n status.fetch = 'inflight'\n if (stale) status.returnedStale = true\n }\n return stale ? v.__staleWhileFetching : (v.__returned = v)\n }\n\n // if we force a refresh, that means do NOT serve the cached value,\n // unless we are already in the process of refreshing the cache.\n const isStale = this.isStale(index)\n if (!forceRefresh && !isStale) {\n if (status) status.fetch = 'hit'\n this.moveToTail(index)\n if (updateAgeOnGet) {\n this.updateItemAge(index)\n }\n this.statusTTL(status, index)\n return v\n }\n\n // ok, it is stale or a forced refresh, and not already fetching.\n // refresh the cache.\n const p = this.backgroundFetch(k, index, options, fetchContext)\n const hasStale = p.__staleWhileFetching !== undefined\n const staleVal = hasStale && allowStale\n if (status) {\n status.fetch = hasStale && isStale ? 'stale' : 'refresh'\n if (staleVal && isStale) status.returnedStale = true\n }\n return staleVal ? p.__staleWhileFetching : (p.__returned = p)\n }\n }\n\n get(\n k,\n {\n allowStale = this.allowStale,\n updateAgeOnGet = this.updateAgeOnGet,\n noDeleteOnStaleGet = this.noDeleteOnStaleGet,\n status,\n } = {}\n ) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n const value = this.valList[index]\n const fetching = this.isBackgroundFetch(value)\n this.statusTTL(status, index)\n if (this.isStale(index)) {\n if (status) status.get = 'stale'\n // delete only if not an in-flight background fetch\n if (!fetching) {\n if (!noDeleteOnStaleGet) {\n this.delete(k)\n }\n if (status) status.returnedStale = allowStale\n return allowStale ? value : undefined\n } else {\n if (status) {\n status.returnedStale =\n allowStale && value.__staleWhileFetching !== undefined\n }\n return allowStale ? value.__staleWhileFetching : undefined\n }\n } else {\n if (status) status.get = 'hit'\n // if we're currently fetching it, we don't actually have it yet\n // it's not stale, which means this isn't a staleWhileRefetching.\n // If it's not stale, and fetching, AND has a __staleWhileFetching\n // value, then that means the user fetched with {forceRefresh:true},\n // so it's safe to return that value.\n if (fetching) {\n return value.__staleWhileFetching\n }\n this.moveToTail(index)\n if (updateAgeOnGet) {\n this.updateItemAge(index)\n }\n return value\n }\n } else if (status) {\n status.get = 'miss'\n }\n }\n\n connect(p, n) {\n this.prev[n] = p\n this.next[p] = n\n }\n\n moveToTail(index) {\n // if tail already, nothing to do\n // if head, move head to next[index]\n // else\n // move next[prev[index]] to next[index] (head has no prev)\n // move prev[next[index]] to prev[index]\n // prev[index] = tail\n // next[tail] = index\n // tail = index\n if (index !== this.tail) {\n if (index === this.head) {\n this.head = this.next[index]\n } else {\n this.connect(this.prev[index], this.next[index])\n }\n this.connect(this.tail, index)\n this.tail = index\n }\n }\n\n get del() {\n deprecatedMethod('del', 'delete')\n return this.delete\n }\n\n delete(k) {\n let deleted = false\n if (this.size !== 0) {\n const index = this.keyMap.get(k)\n if (index !== undefined) {\n deleted = true\n if (this.size === 1) {\n this.clear()\n } else {\n this.removeItemSize(index)\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'))\n } else {\n this.dispose(v, k, 'delete')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'delete'])\n }\n }\n this.keyMap.delete(k)\n this.keyList[index] = null\n this.valList[index] = null\n if (index === this.tail) {\n this.tail = this.prev[index]\n } else if (index === this.head) {\n this.head = this.next[index]\n } else {\n this.next[this.prev[index]] = this.next[index]\n this.prev[this.next[index]] = this.prev[index]\n }\n this.size--\n this.free.push(index)\n }\n }\n }\n if (this.disposed) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n return deleted\n }\n\n clear() {\n for (const index of this.rindexes({ allowStale: true })) {\n const v = this.valList[index]\n if (this.isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'))\n } else {\n const k = this.keyList[index]\n this.dispose(v, k, 'delete')\n if (this.disposeAfter) {\n this.disposed.push([v, k, 'delete'])\n }\n }\n }\n\n this.keyMap.clear()\n this.valList.fill(null)\n this.keyList.fill(null)\n if (this.ttls) {\n this.ttls.fill(0)\n this.starts.fill(0)\n }\n if (this.sizes) {\n this.sizes.fill(0)\n }\n this.head = 0\n this.tail = 0\n this.initialFill = 1\n this.free.length = 0\n this.calculatedSize = 0\n this.size = 0\n if (this.disposed) {\n while (this.disposed.length) {\n this.disposeAfter(...this.disposed.shift())\n }\n }\n }\n\n get reset() {\n deprecatedMethod('reset', 'clear')\n return this.clear\n }\n\n get length() {\n deprecatedProperty('length', 'size')\n return this.size\n }\n\n static get AbortController() {\n return AC\n }\n static get AbortSignal() {\n return AS\n }\n}\n\nexport default LRUCache\n","export const urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n","import { urlAlphabet as scopedUrlAlphabet } from './url-alphabet/index.js'\nexport { urlAlphabet } from './url-alphabet/index.js'\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1\n let step = -~((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step\n while (j--) {\n id += alphabet[bytes[j] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nexport let nanoid = (size = 21) => {\n let id = ''\n let bytes = crypto.getRandomValues(new Uint8Array(size))\n while (size--) {\n id += scopedUrlAlphabet[bytes[size] & 63]\n }\n return id\n}\n","import { AtlasObjectModel } from '../aom';\nimport { WorldTime } from '../types';\nimport { dna, mutate, scaleAtOrigin, Strand, translate } from '@atlas-viewer/dna';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\nimport { CompositeResource } from '../spacial-content/composite-resource';\nimport {\n createDefaultEventMap,\n SupportedEventMap,\n supportedEventMap,\n SupportedEventNames,\n SupportedEvents,\n} from '../events';\nimport { WorldObject } from '../world-objects';\n\nexport abstract class BaseObject<Props = any, SupportedChildElements = never>\n implements AtlasObjectModel<Props, SupportedChildElements>\n{\n __id: string;\n __revision = 0;\n __host: any;\n __onCreate?: () => void;\n __parent?: CompositeResource;\n __owner: { value: WorldObject | undefined } = { value: undefined };\n __state: any = {};\n // Base properties.\n eventHandlers: SupportedEventMap;\n scale = 1;\n layers: SupportedChildElements[] = [];\n time: WorldTime[] = [];\n\n // crop?: Strand;\n _crop?: Strand;\n cropData?: { x: number; y: number; width: number; height: number };\n\n get crop(): Strand | undefined {\n return this._crop;\n }\n\n set crop(crop: Strand | undefined) {\n this._crop = crop;\n }\n\n // To be set by implementation constructor.\n id: string;\n abstract points: Strand;\n\n getObjectsAt(target: Strand): SupportedChildElements[] | Array<[SupportedChildElements, any[]]> {\n return [];\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand, scale: number): Paint[] {\n return [];\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n return [];\n }\n\n protected constructor() {\n this.id = this.__id = nanoid();\n this.eventHandlers = createDefaultEventMap();\n }\n\n addEventListener = <Name extends SupportedEventNames>(\n name: Name,\n cb: (e: any) => void,\n options?: { capture: boolean; passive: boolean }\n ) => {\n const event: keyof SupportedEvents = supportedEventMap[name];\n if (!this.eventHandlers[event]) {\n throw new Error(`Unknown event ${event}`);\n }\n\n if (this.eventHandlers[event].indexOf(cb) === -1) {\n this.eventHandlers[event].push(cb);\n }\n };\n\n removeEventListener = <Name extends SupportedEventNames>(name: Name, cb: (e: any) => void) => {\n const event = supportedEventMap[name];\n if (!this.eventHandlers[event]) {\n console.warn(`Unknown event ${event}`);\n return;\n }\n if (this.eventHandlers[event].indexOf(cb) !== -1) {\n this.eventHandlers[event] = (this.eventHandlers[event] as any).filter((e: any) => e !== cb);\n }\n };\n\n dispatchEvent<Name extends keyof SupportedEvents>(name: Name, e: any) {\n const listeners = this.eventHandlers[name];\n const len = listeners ? listeners.length : 0;\n let didFire = false;\n if (len) {\n for (let x = 0; x < len; x++) {\n try {\n listeners[x]?.(e);\n didFire = true;\n } catch (e) {\n console.error(name, e);\n }\n }\n }\n return didFire;\n }\n\n get x(): number {\n return this.points[1];\n }\n get y(): number {\n return this.points[2];\n }\n get width(): number {\n return this.points[3] - this.points[1];\n }\n get height(): number {\n return this.points[4] - this.points[2];\n }\n\n translate(x: number, y: number) {\n mutate(this.points, translate(x, y));\n }\n\n atScale(factor: number) {\n mutate(this.points, scaleAtOrigin(factor, this.x, this.y));\n this.scale *= factor;\n }\n\n transform(op: Strand): void {\n mutate(this.points, op);\n }\n\n applyProps(props: Props): void {\n // do nothing.\n this.__revision++;\n }\n appendChild(item: SupportedChildElements): void {\n // do nothing.\n }\n removeChild(item: SupportedChildElements): void {\n // do nothing.\n }\n insertBefore(item: SupportedChildElements, before: SupportedChildElements): void {\n // do nothing.\n }\n hideInstance(): void {\n // do nothing.\n }\n}\n","import { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\n\nconst borderRegex = /([0-9]+(px|em)\\s+)+(solid)\\s+(.*)/g;\nconst borderRegexCache: any = {};\n\nexport type BoxProps = {\n id: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n\n className?: string;\n href?: string;\n title?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n // New style.\n style?: BoxStyle;\n\n // Deprecated\n backgroundColor?: string;\n border?: string;\n};\n\nexport type BoxStyle = _BoxStyle & {\n ':hover'?: _BoxStyle;\n ':active'?: _BoxStyle;\n};\n\ntype _BoxStyle = Partial<{\n // In order\n backgroundColor: string; // colour or gradient function\n opacity: number;\n boxShadow: string; // to parse, splitting /,(?![^\\(]*\\))/\n borderColor: string;\n borderWidth: string;\n borderStyle: string; // 'solid' only\n outlineColor: string;\n outlineWidth: string;\n outlineOffset: string;\n outlineStyle: string; // 'solid' only\n\n // Parsed.\n border: string;\n outline: string;\n background: string;\n\n // transform: string; // scale() rotate() transform() transformX() transformY() - pixels\n // transformOrigin: string; // using translate(x, y); rotate(); translate(-x, -y);\n // backgroundImage: string; // possibly.\n // backgroundRepeat: string; // repeat | repeat-x | repeat-y | no-repeat\n //borderRadius: string; // maybe? Future?\n}>;\n\nconst styleProps: Array<keyof BoxStyle> = [\n 'backgroundColor',\n 'opacity',\n 'boxShadow',\n 'borderColor',\n 'borderWidth',\n 'borderStyle',\n 'outlineColor',\n 'outlineWidth',\n 'outlineOffset',\n 'outlineStyle',\n];\n\n// const mapping = [\n// // Common\n// ['opacity', 'globalAlpha'],\n// ['transform', ['translate', 'scale', 'rotate']],\n//\n// // Fill rect\n// [\n// 'backgroundColor',\n// ['fillStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['boxShadow', ['shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor']],\n//\n// // Stroke rect\n// ['outline', 'same-as-below'],\n// [\n// 'borderColor',\n// ['strokeStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['borderWidth', 'strokeWidth'],\n// ['borderStyle', ['setLineDash', 'lineDashOffset']],\n// ];\n\nexport class Box extends BaseObject<BoxProps> implements SpacialContent {\n id: string;\n type: 'spacial-content' = 'spacial-content';\n points: Strand;\n hoverEvents = false;\n activeEvents = false;\n\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: -1,\n height: -1,\n points: dna(5),\n };\n\n _parsed: { border: { id: string | null; match: string[] }; outline: { id: string | null; match: string[] } } = {\n border: { id: null, match: [] },\n outline: { id: null, match: [] },\n };\n\n hovering?: boolean;\n pressing?: boolean;\n props: {\n href?: string;\n hrefTarget?: string;\n title?: string;\n backgroundColor?: string;\n border?: string;\n interactive?: boolean;\n className?: string;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n style?: BoxStyle;\n hoverStyles?: BoxStyle;\n pressStyles?: BoxStyle;\n } = {};\n\n constructor() {\n super();\n this.id = nanoid(12);\n this.points = dna(5);\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n // this.points[0] = 1;\n return [[this as any, this.points, aggregate]];\n }\n\n addHover = () => {\n this.hovering = true;\n this.__revision++;\n };\n\n removeHover = () => {\n this.hovering = false;\n this.pressing = false;\n this.__revision++;\n };\n\n addPress = () => {\n this.pressing = true;\n this.__revision++;\n };\n\n removePress = () => {\n this.pressing = false;\n this.__revision++;\n };\n\n applyProps(props: Partial<BoxProps> = {}) {\n let didUpdate = false;\n\n if (props.interactive !== this.props.interactive) {\n didUpdate = true;\n this.props.interactive = props.interactive;\n }\n\n if (props.style) {\n // pre-process props.\n const borderStyle = props.border || props.style.border;\n if (borderStyle !== this._parsed.border.id) {\n if (!borderStyle) {\n this._parsed.border.id = null;\n this._parsed.border.match = [];\n } else {\n const match = borderRegexCache[borderStyle] || borderRegex.exec(borderStyle) || borderRegex.exec(borderStyle);\n if (match) {\n this._parsed.border.id = borderStyle;\n this._parsed.border.match = borderRegexCache[borderStyle] = match;\n }\n }\n }\n if (this._parsed.border.id) {\n props.style.borderWidth = this._parsed.border.match[1];\n props.style.borderStyle = 'solid'; // only support this.\n props.style.borderColor = this._parsed.border.match[4];\n }\n\n if (props.style.outline !== this._parsed.outline.id) {\n if (!props.style.outline) {\n this._parsed.outline.id = null;\n this._parsed.outline.match = [];\n } else {\n const match =\n borderRegexCache[props.style.outline] ||\n borderRegex.exec(props.style.outline) ||\n borderRegex.exec(props.style.outline);\n\n if (match) {\n this._parsed.outline.id = props.style.outline;\n this._parsed.outline.match = borderRegexCache[props.style.outline] = match;\n }\n }\n }\n if (this._parsed.outline.id) {\n props.style.outlineWidth = this._parsed.outline.match[1];\n props.style.outlineStyle = 'solid'; // only support this.\n props.style.outlineColor = this._parsed.outline.match[4];\n }\n\n this.props.style = props.style;\n // BC fix.\n if (props.backgroundColor && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.backgroundColor;\n didUpdate = true;\n }\n if (props.style.background && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.style.background;\n didUpdate = true;\n }\n\n for (const prop of styleProps) {\n if (this.props.style[prop] !== props.style[prop]) {\n didUpdate = true;\n break;\n }\n }\n\n if (props.style[':hover'] !== this.props.hoverStyles) {\n this.props.hoverStyles = props.style[':hover'];\n if (!this.hoverEvents) {\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n didUpdate = true;\n }\n if (props.style[':active'] !== this.props.pressStyles) {\n this.props.pressStyles = props.style[':active'];\n if (!this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n }\n\n if (props.href !== this.props.href) {\n this.props.href = props.href;\n didUpdate = true;\n }\n\n if (props.hrefTarget !== this.props.hrefTarget) {\n this.props.hrefTarget = props.hrefTarget;\n didUpdate = true;\n }\n\n if (props.title !== this.props.title) {\n this.props.title = props.title;\n didUpdate = true;\n }\n\n if (props.className !== this.props.className) {\n this.props.className = props.className;\n if (props.className && !this.hoverEvents) {\n // Only if class name.\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n if (props.className && !this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n\n if (props.relativeSize !== this.props.relativeSize) {\n this.props.relativeSize = props.relativeSize;\n didUpdate = true;\n }\n if (props.relativeStyle !== this.props.relativeStyle) {\n this.props.relativeStyle = props.relativeStyle;\n didUpdate = true;\n }\n if (props.html !== this.props.html) {\n this.props.html = props.html;\n didUpdate = true;\n }\n\n if (props.target) {\n if (\n props.target.width !== this.display.width ||\n props.target.height !== this.display.height ||\n props.target.x !== this.points[1] ||\n props.target.y !== this.points[2]\n ) {\n didUpdate = true;\n this.points = DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y);\n this.display.points = DnaFactory.singleBox(\n props.target.width,\n props.target.height,\n props.target.x,\n props.target.y\n );\n this.display.width = props.target.width;\n this.display.height = props.target.height;\n }\n }\n\n if (didUpdate) {\n // Bump revision.\n this.__revision++;\n }\n }\n}\n","import { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\nimport { nanoid } from 'nanoid';\n\nconst borderRegex = /([0-9]+(px|em)\\s+)+(solid)\\s+(.*)/g;\nconst borderRegexCache: any = {};\n\nexport type GeometryProps = {\n id: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n\n open?: boolean;\n points: [number, number][];\n\n className?: string;\n href?: string;\n title?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n // New style.\n style?: GeometryStyle;\n // Deprecated\n backgroundColor?: string;\n border?: string;\n};\n\nexport type GeometryStyle = _GeometryStyle & {\n ':hover'?: _GeometryStyle;\n ':active'?: _GeometryStyle;\n};\n\ntype _GeometryStyle = Partial<{\n // In order\n backgroundColor: string; // colour or gradient function\n opacity: number;\n boxShadow: string; // to parse, splitting /,(?![^\\(]*\\))/\n borderColor: string;\n borderWidth: string;\n borderStyle: string; // 'solid' only\n outlineColor: string;\n outlineWidth: string;\n outlineOffset: string;\n outlineStyle: string; // 'solid' only\n\n // Parsed.\n border: string;\n outline: string;\n background: string;\n\n // transform: string; // scale() rotate() transform() transformX() transformY() - pixels\n // transformOrigin: string; // using translate(x, y); rotate(); translate(-x, -y);\n // backgroundImage: string; // possibly.\n // backgroundRepeat: string; // repeat | repeat-x | repeat-y | no-repeat\n //borderRadius: string; // maybe? Future?\n}>;\n\nconst styleProps: Array<keyof GeometryStyle> = [\n 'backgroundColor',\n 'opacity',\n 'boxShadow',\n 'borderColor',\n 'borderWidth',\n 'borderStyle',\n 'outlineColor',\n 'outlineWidth',\n 'outlineOffset',\n 'outlineStyle',\n];\n\n// const mapping = [\n// // Common\n// ['opacity', 'globalAlpha'],\n// ['transform', ['translate', 'scale', 'rotate']],\n//\n// // Fill rect\n// [\n// 'backgroundColor',\n// ['fillStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['boxShadow', ['shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor']],\n//\n// // Stroke rect\n// ['outline', 'same-as-below'],\n// [\n// 'borderColor',\n// ['strokeStyle', 'createLinearGradient', 'createRadialGradient', 'createConicGradient', 'createPattern'],\n// ],\n// ['borderWidth', 'strokeWidth'],\n// ['borderStyle', ['setLineDash', 'lineDashOffset']],\n// ];\n\nexport class Geometry extends BaseObject<GeometryProps> implements SpacialContent {\n id: string;\n type: 'spacial-content' = 'spacial-content';\n isShape = true;\n points: Strand;\n hoverEvents = false;\n activeEvents = false;\n\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: -1,\n height: -1,\n points: dna(5),\n };\n\n boundingBox: { x: number; y: number; width: number; height: number } | null = null;\n\n _parsed: { border: { id: string | null; match: string[] }; outline: { id: string | null; match: string[] } } = {\n border: { id: null, match: [] },\n outline: { id: null, match: [] },\n };\n\n hovering?: boolean;\n pressing?: boolean;\n props: {\n href?: string;\n hrefTarget?: string;\n title?: string;\n backgroundColor?: string;\n border?: string;\n interactive?: boolean;\n open?: boolean;\n className?: string;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n html?: boolean;\n style?: GeometryStyle;\n hoverStyles?: GeometryStyle;\n pressStyles?: GeometryStyle;\n } = {};\n\n shape: { type: 'none' } | { type: 'polygon'; points: [number, number][]; open?: boolean } = { type: 'none' };\n\n constructor() {\n super();\n this.id = nanoid(12);\n this.points = dna(5);\n this.shape = { type: 'none' };\n }\n\n updateBoundingBox() {\n if (this.shape.type === 'none') return;\n const points = this.shape.points;\n if (this.shape.points.length > 2) {\n const x1 = Math.min(...points.map((p) => p[0]));\n const y1 = Math.min(...points.map((p) => p[1]));\n const x2 = Math.max(0, ...points.map((p) => p[0]));\n const y2 = Math.max(0, ...points.map((p) => p[1]));\n this.boundingBox = {\n x: x1,\n y: y1,\n width: x2 - x1,\n height: y2 - y1,\n };\n\n return;\n }\n this.boundingBox = null;\n }\n\n intersects(pointer?: [number, number] | null): boolean {\n if (!pointer || this.shape.type === 'none') {\n return false;\n }\n // Does the point intersect with the shape?\n const [x, y] = pointer;\n const points = this.shape.points;\n let box = this.boundingBox;\n\n // @todo only enable when all points are NOT selected.\n\n if (!box) {\n this.updateBoundingBox();\n box = this.boundingBox;\n }\n if (!box) {\n return false;\n }\n\n // Outside the bounding box.\n if (x < box.x || x > box.x + box.width || y < box.y || y > box.height + box.y) {\n return false;\n }\n\n // Outside the polygon.\n let inside = false;\n for (let i = 0, j = points.length - 1; i < points.length; j = i++) {\n if (\n points[i][1] > y != points[j][1] > y &&\n x < ((points[j][0] - points[i][0]) * (y - points[i][1])) / (points[j][1] - points[i][1]) + points[i][0]\n ) {\n inside = !inside;\n }\n }\n\n return inside;\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n if (target[3] - target[1] === 1 && target[4] - target[2] === 1) {\n // Clicked on a single point.\n if (this.intersects([target[1], target[2]])) {\n return [[this as any, this.points, aggregate]];\n }\n return [];\n }\n\n // this.points[0] = 1;\n return [[this as any, this.points, aggregate]];\n }\n\n addHover = () => {\n this.hovering = true;\n this.__revision++;\n };\n\n removeHover = () => {\n this.hovering = false;\n this.pressing = false;\n this.__revision++;\n };\n\n addPress = () => {\n this.pressing = true;\n this.__revision++;\n };\n\n removePress = () => {\n this.pressing = false;\n this.__revision++;\n };\n\n applyProps(props: Partial<GeometryProps> = {}) {\n let didUpdate = false;\n\n if (props.points) {\n if (this.shape.type !== 'polygon' || this.shape.points.length !== props.points.length) {\n this.shape = {\n type: 'polygon',\n points: props.points,\n open: props.open,\n };\n this.updateBoundingBox();\n } else {\n let newPoints = false;\n const len = props.points.length;\n for (let i = 0; i < len; i++) {\n if (props.points[i][0] !== this.shape.points[i][0] || props.points[i][1] !== this.shape.points[i][1]) {\n newPoints = true;\n break;\n }\n }\n if (newPoints) {\n this.shape = {\n type: 'polygon',\n points: props.points,\n open: props.open,\n };\n this.updateBoundingBox();\n }\n }\n }\n\n if (props.interactive !== this.props.interactive) {\n didUpdate = true;\n this.props.interactive = props.interactive;\n }\n\n if (props.open || props.open === false) {\n didUpdate = true;\n (this.shape as any).open = props.open;\n }\n\n if (props.style) {\n // pre-process props.\n const borderStyle = props.border || props.style.border;\n if (borderStyle !== this._parsed.border.id) {\n if (!borderStyle) {\n this._parsed.border.id = null;\n this._parsed.border.match = [];\n } else {\n const match = borderRegexCache[borderStyle] || borderRegex.exec(borderStyle) || borderRegex.exec(borderStyle);\n if (match) {\n this._parsed.border.id = borderStyle;\n this._parsed.border.match = borderRegexCache[borderStyle] = match;\n }\n }\n }\n if (this._parsed.border.id) {\n props.style.borderWidth = this._parsed.border.match[1];\n props.style.borderStyle = 'solid'; // only support this.\n props.style.borderColor = this._parsed.border.match[4];\n }\n\n if (props.style.outline !== this._parsed.outline.id) {\n if (!props.style.outline) {\n this._parsed.outline.id = null;\n this._parsed.outline.match = [];\n } else {\n const match =\n borderRegexCache[props.style.outline] ||\n borderRegex.exec(props.style.outline) ||\n borderRegex.exec(props.style.outline);\n\n if (match) {\n this._parsed.outline.id = props.style.outline;\n this._parsed.outline.match = borderRegexCache[props.style.outline] = match;\n }\n }\n }\n if (this._parsed.outline.id) {\n props.style.outlineWidth = this._parsed.outline.match[1];\n props.style.outlineStyle = 'solid'; // only support this.\n props.style.outlineColor = this._parsed.outline.match[4];\n }\n\n this.props.style = props.style;\n // BC fix.\n if (props.backgroundColor && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.backgroundColor;\n didUpdate = true;\n }\n if (props.style.background && !this.props.style.backgroundColor) {\n this.props.style.backgroundColor = props.style.background;\n didUpdate = true;\n }\n\n for (const prop of styleProps) {\n if (this.props.style[prop] !== props.style[prop]) {\n didUpdate = true;\n break;\n }\n }\n\n if (props.style[':hover'] !== this.props.hoverStyles) {\n this.props.hoverStyles = props.style[':hover'];\n if (!this.hoverEvents) {\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n didUpdate = true;\n }\n if (props.style[':active'] !== this.props.pressStyles) {\n this.props.pressStyles = props.style[':active'];\n if (!this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n }\n\n if (props.href !== this.props.href) {\n this.props.href = props.href;\n didUpdate = true;\n }\n\n if (props.hrefTarget !== this.props.hrefTarget) {\n this.props.hrefTarget = props.hrefTarget;\n didUpdate = true;\n }\n\n if (props.title !== this.props.title) {\n this.props.title = props.title;\n didUpdate = true;\n }\n\n if (props.className !== this.props.className) {\n this.props.className = props.className;\n if (props.className && !this.hoverEvents) {\n // Only if class name.\n this.hoverEvents = true;\n this.addEventListener('pointerenter', this.addHover);\n this.addEventListener('pointerleave', this.removeHover);\n }\n if (props.className && !this.activeEvents) {\n this.activeEvents = true;\n this.addEventListener('mousedown', this.addPress);\n this.addEventListener('mouseup', this.removePress);\n }\n didUpdate = true;\n }\n\n if (props.relativeSize !== this.props.relativeSize) {\n this.props.relativeSize = props.relativeSize;\n didUpdate = true;\n }\n if (props.relativeStyle !== this.props.relativeStyle) {\n this.props.relativeStyle = props.relativeStyle;\n didUpdate = true;\n }\n if (props.html !== this.props.html) {\n this.props.html = props.html;\n didUpdate = true;\n }\n\n if (props.target) {\n if (\n props.target.width !== this.display.width ||\n props.target.height !== this.display.height ||\n props.target.x !== this.points[1] ||\n props.target.y !== this.points[2]\n ) {\n didUpdate = true;\n this.points = DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y);\n this.display.points = DnaFactory.singleBox(\n props.target.width,\n props.target.height,\n props.target.x,\n props.target.y\n );\n this.display.width = props.target.width;\n this.display.height = props.target.height;\n }\n }\n\n if (didUpdate) {\n // Bump revision.\n this.__revision++;\n }\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { dna, DnaFactory, mutate, Strand, transform, translate } from '@atlas-viewer/dna';\nimport { DisplayData, SpacialSize } from '../types';\nimport { BaseObject } from '../objects/base-object';\nimport { Paint } from '../world-objects/paint';\n\ntype SingleImageProps = {\n uri: string;\n id?: string;\n display?: { width: number; height: number; rotation?: number };\n target: { width: number; height: number; x?: number; y?: number };\n crop?: { x: number; y: number; width: number; height: number };\n scale?: number;\n priority?: boolean;\n style?: any;\n};\n\nexport class SingleImage extends BaseObject implements SpacialContent {\n readonly type = 'spacial-content';\n\n /**\n * An identifier for this image. Will default to the image URI.\n */\n id: string;\n\n /**\n * The URI of the image being painted.\n */\n uri: string;\n\n /**\n * The real height and width of the image. For example a 1000x1000 painted at 100x100 would contain\n * the display data for 1000x1000 and `this.points` would scale that down to 100x100. This is used to\n * calculate the scale.\n */\n display: DisplayData;\n\n /**\n * Points are relative to the world object.\n * Does not change when viewport moves\n * Does not change if world object position changes.\n * */\n points: Strand;\n\n /**\n * Displayed as priority\n */\n priority?: boolean;\n\n /**\n * Some simple styling options\n */\n style: { opacity: number } = { opacity: 1 };\n\n constructor(data?: {\n id?: string;\n uri: string;\n width: number;\n height: number;\n scale?: number;\n x?: number;\n y?: number;\n rotation?: number;\n }) {\n super();\n if (!data) {\n this.id = '';\n this.uri = '';\n this.display = { x: 0, y: 0, scale: 1, width: 0, height: 0, points: dna(5) };\n this.points = dna(5);\n } else {\n const scale = data.scale || 1;\n this.id = data.id || data.uri;\n this.uri = data.uri;\n this.points = DnaFactory.singleBox(data.width, data.height, data.x, data.y);\n\n this.display = {\n x: 0,\n y: 0,\n scale: scale,\n width: data.width / scale,\n height: data.height / scale,\n points: DnaFactory.singleBox(data.width / scale, data.height / scale),\n rotation: data?.rotation,\n };\n }\n }\n\n applyProps(props: SingleImageProps) {\n const width = props.display ? props.display.width : props.target.width;\n const scale = props.target.width / width;\n\n this.id = props.id || props.uri;\n this.uri = props.uri;\n this.points.set(DnaFactory.singleBox(props.target.width, props.target.height, props.target.x, props.target.y));\n\n if (props.style && typeof props.style.opacity !== 'undefined') {\n this.style.opacity = props.style.opacity;\n }\n\n if (props.crop) {\n this.cropData = props.crop;\n const crop = DnaFactory.singleBox(props.crop.width, props.crop.height, props.crop.x, props.crop.y);\n mutate(crop, translate(-props.crop.x, -props.crop.y));\n if (!this.crop) {\n this.crop = dna(crop);\n } else {\n this.crop.set(crop);\n }\n }\n\n if (props.display) {\n this.display.scale = scale;\n this.display.width = props.display.width;\n this.display.height = props.display.height;\n this.display.rotation = props.display.rotation;\n this.display.points = DnaFactory.singleBox(props.display.width, props.display.height);\n } else {\n this.display.scale = scale;\n this.display.width = props.target.width / scale;\n this.display.height = props.target.height / scale;\n this.display.points = DnaFactory.singleBox(props.target.width / scale, props.target.height / scale);\n }\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.crop || this.points, aggregate]];\n }\n\n // This works, but should be improved.\n // It should create a layered image similar to IIIF with different scale factors of the SVG.\n // And implement its own get points function, to return the right layer.\n // Would also be great if the ID field wasn't the entire SVG.\n static fromSvg(svg: string, target: SpacialSize, display?: SpacialSize, id?: string): SingleImage {\n return SingleImage.fromImage('data:image/svg+xml;base64,' + btoa(svg), target, display, id);\n }\n\n static fromImage(uri: string, target: SpacialSize, display?: SpacialSize, id?: string): SingleImage {\n const instance = new SingleImage();\n\n instance.applyProps({\n uri,\n id,\n display,\n target,\n });\n\n return instance;\n }\n\n getImageUrl() {\n return this.uri;\n }\n}\n","import {\n DnaFactory,\n hidePointsOutsideRegion,\n mutate,\n scale,\n transform,\n Strand,\n dna,\n getIntersection,\n Projection,\n translate,\n} from '@atlas-viewer/dna';\nimport { DisplayData } from '../types';\nimport { Paint } from '../world-objects';\nimport { BaseObject } from '../objects/base-object';\nimport { SpacialContent } from './spacial-content';\nimport { stripInfoJson } from '../utils';\nimport { ImageService } from '@iiif/presentation-3';\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport class TiledImage extends BaseObject implements SpacialContent {\n readonly id: string;\n readonly type = 'spacial-content';\n readonly display: DisplayData;\n tileWidth: number;\n tileHeight: number;\n columns: number;\n rows: number;\n style: { opacity: number } = { opacity: 1 };\n points: Strand;\n service?: ImageService;\n format = 'jpg';\n crop2?: Strand;\n version3?: boolean;\n\n tileUrl: string;\n constructor(data: {\n url: string;\n scaleFactor: number;\n points: Strand;\n displayPoints?: Strand;\n tileWidth: number;\n tileHeight: number;\n width: number;\n height: number;\n columns: number;\n rows: number;\n format?: string;\n id?: string;\n version3?: boolean;\n }) {\n super();\n this.tileUrl = stripInfoJson(data.url);\n this.id = data.id || `${this.tileUrl}--${data.scaleFactor}--${data.tileWidth}x${data.tileHeight}`;\n this.points = data.displayPoints ? data.displayPoints : transform(data.points, scale(data.scaleFactor));\n this.tileWidth = data.tileWidth;\n this.tileHeight = data.tileHeight;\n this.columns = data.columns;\n this.rows = data.rows;\n this.version3 = data.version3;\n this.display = {\n x: 0,\n y: 0,\n width: data.width / data.scaleFactor,\n height: data.height / data.scaleFactor,\n points: data.points,\n scale: data.scaleFactor,\n };\n if (data.format) {\n this.format = data.format;\n }\n }\n\n applyProps(props: any) {\n if (props.style && typeof props.style.opacity !== 'undefined') {\n this.style.opacity = props.style.opacity;\n }\n if (props.service !== this.service) {\n this.service = props.service;\n }\n if (props.format) {\n this.format = props.format;\n } else {\n this.format = 'jpg';\n }\n\n if (typeof props.version3 !== 'undefined') {\n this.version3 = props.version3;\n }\n\n if (props.crop) {\n this.cropData = props.crop;\n\n const crop = dna([...this.points]);\n const len = crop.length / 5;\n\n const minX = props.crop.x || 0;\n const minY = props.crop.y || 0;\n const maxX = props.crop.x + props.crop.width;\n const maxY = props.crop.y + props.crop.height;\n\n for (let i = 0; i < len; i++) {\n const index = i * 5;\n if (\n /* x1 */ crop[index + 1] < maxX && // x1 left - x2 right\n /* x2 */ crop[index + 3] > minX && // x2 right - x1 left\n /* y1 */ crop[index + 2] < maxY && // y1 top - y2 bottom\n /* y2 */ crop[index + 4] > minY // y2 bottom - y1 top\n ) {\n crop[index + 1] = clamp(crop[index + 1], minX, maxX);\n crop[index + 3] = clamp(crop[index + 3], minX, maxX);\n crop[index + 2] = clamp(crop[index + 2], minY, maxY);\n crop[index + 4] = clamp(crop[index + 4], minY, maxY);\n } else {\n crop[index] = 0;\n }\n }\n\n mutate(crop, translate(-props.crop.x, -props.crop.y));\n\n if (!this.crop) {\n this.crop = crop;\n } else {\n this.crop.set(crop);\n }\n }\n }\n\n static fromTile(\n url: string,\n canvas: { width: number; height: number },\n tile: { width: number; height?: number },\n scaleFactor: number,\n service?: ImageService,\n format?: string,\n useFloorCalc?: boolean,\n version3?: boolean\n ): TiledImage {\n const tileHeight = tile.height ? tile.height : tile.width;\n // Dimensions of full image (scaled).\n const fullWidth = useFloorCalc ? Math.floor(canvas.width / scaleFactor) : Math.ceil(canvas.width / scaleFactor);\n const fullHeight = useFloorCalc ? Math.floor(canvas.height / scaleFactor) : Math.ceil(canvas.height / scaleFactor);\n // number of points in the x direction.\n const mWidth = Math.ceil(fullWidth / tile.width);\n // number of points in the y direction\n const mHeight = Math.ceil(fullHeight / tileHeight);\n\n const pointsFactory = DnaFactory.grid(mWidth, mHeight);\n const displayPoints = DnaFactory.grid(mWidth, mHeight);\n\n const ctx = service ? service['@context']\n ? Array.isArray(service['@context'])\n ? service['@context']\n : [service['@context']]\n : [] : [];\n const isV3 = typeof version3 !== 'undefined' ? version3 : ctx.indexOf('http://iiif.io/api/image/3/context.json') !== -1;\n\n // Create matrix\n for (let y = 0; y < mHeight; y++) {\n for (let x = 0; x < mWidth; x++) {\n const rx = x * tile.width;\n const ry = y * tileHeight;\n\n displayPoints.addPoints(\n rx * scaleFactor,\n ry * scaleFactor,\n x === mWidth - 1 ? canvas.width : (rx + tile.width) * scaleFactor,\n y === mHeight - 1 ? canvas.height : (ry + tileHeight) * scaleFactor\n );\n\n pointsFactory.addPoints(\n rx,\n ry,\n x === mWidth - 1 ? fullWidth : rx + tile.width,\n y === mHeight - 1 ? fullHeight : ry + tileHeight\n );\n }\n }\n\n const tiledImage = new TiledImage({\n url,\n scaleFactor,\n points: pointsFactory.build(),\n displayPoints: displayPoints.build(),\n width: canvas.width,\n height: canvas.height,\n tileWidth: tile.width,\n tileHeight,\n columns: mWidth,\n rows: mHeight,\n format,\n version3: isV3,\n });\n\n tiledImage.applyProps({\n service,\n });\n\n return tiledImage;\n }\n\n getImageUrl(index: number): string {\n // Replace this with image service wrapper that recalculates its toString()\n // when SETTING new variables, so that this becomes just a return.\n // We can store these based on the index.\n\n const im = this.points.slice(index * 5, index * 5 + 5);\n const x2 = im[3] - im[1];\n const y2 = im[4] - im[2];\n const w = Math.ceil(x2 / this.display.scale);\n const h = Math.ceil(y2 / this.display.scale);\n\n let widthString = `${w > this.tileWidth ? this.tileWidth : w},`;\n\n if (this.version3) {\n widthString += `${h > this.tileHeight ? this.tileHeight : h}`;\n }\n\n return `${this.tileUrl}/${im[1]},${im[2]},${x2},${y2}/${widthString}/0/default.${this.format || 'jpg'\n }`;\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scaleFactor?: number): Paint[] {\n const points = hidePointsOutsideRegion(this.crop || this.points, target);\n return [[this as any, points, aggregate]];\n }\n\n transform(op: Strand): void {\n mutate(this.points, op);\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => Promise<void>> {\n return [];\n }\n}\n","import type { Strand } from \"@atlas-viewer/dna\";\n\nexport type ZoneConstrainedBounds = {\n\tminX: number;\n\tmaxX: number;\n\tminY: number;\n\tmaxY: number;\n};\n\nexport function getZoneConstrainedBounds(\n\ttarget: Strand,\n\tzonePoints: Strand,\n\tpadding: number,\n): ZoneConstrainedBounds | null {\n\tif (!zonePoints || zonePoints[0] === 0) {\n\t\treturn null;\n\t}\n\n\tconst targetWidth = target[3] - target[1];\n\tconst targetHeight = target[4] - target[2];\n\tconst zoneWidth = zonePoints[3] - zonePoints[1];\n\tconst zoneHeight = zonePoints[4] - zonePoints[2];\n\n\tconst canPanX = targetWidth < zoneWidth;\n\tconst canPanY = targetHeight < zoneHeight;\n\n\tconst centeredX = zonePoints[1] + zoneWidth / 2 - targetWidth / 2;\n\tconst centeredY = zonePoints[2] + zoneHeight / 2 - targetHeight / 2;\n\n\treturn {\n\t\tminX: canPanX ? zonePoints[1] - padding : centeredX,\n\t\tmaxX: canPanX ? zonePoints[3] - targetWidth + padding : centeredX,\n\t\tminY: canPanY ? zonePoints[2] - padding : centeredY,\n\t\tmaxY: canPanY ? zonePoints[4] - targetHeight + padding : centeredY,\n\t};\n}\n","import { HookOptions } from '../../renderer/runtime';\n\nexport function buildCssFilter(options: HookOptions): string {\n if (\n !options.enableFilters ||\n (!options.filters.brightness &&\n !options.filters.contrast &&\n !options.filters.grayscale &&\n !options.filters.invert &&\n !options.filters.sepia &&\n !options.filters.saturate &&\n !options.filters.hueRotate &&\n !options.filters.blur)\n ) {\n return 'none';\n }\n\n let filter = '';\n if (options.filters.brightness) {\n filter += `brightness(${~~(100 + options.filters.brightness * 100)}%) `;\n }\n if (options.filters.contrast) {\n filter += `contrast(${~~(100 + options.filters.contrast * 100)}%) `;\n }\n if (options.filters.grayscale) {\n filter += `grayscale(${~~(options.filters.grayscale * 100)}%) `;\n }\n if (options.filters.invert) {\n filter += `invert(${~~(options.filters.invert * 100)}%) `;\n }\n if (options.filters.sepia) {\n filter += `sepia(${~~(options.filters.sepia * 100)}%) `;\n }\n if (options.filters.saturate) {\n filter += `saturate(${~~(100 + options.filters.saturate * 100)}%) `;\n }\n if (options.filters.hueRotate) {\n filter += `hue-rotate(${options.filters.hueRotate}deg) `;\n }\n if (options.filters.blur) {\n filter += `blur(${options.filters.blur}px) `;\n }\n\n return filter.trim();\n}\n","export type ImageLoadingConfig = {\n maxConcurrentRequests: number;\n maxPrefetchPerFrame: number;\n timeoutMs: number;\n maxAttempts: number;\n baseDelayMs: number;\n maxDelayMs: number;\n jitterRatio: number;\n errorRetryIntervalMs: number;\n revealDelayFrames: number;\n revealBatchWindowFrames: number;\n skipFadeIfLoadedWithinMs: number;\n};\n\nexport type ImageLoadingConfigOverrides = Partial<ImageLoadingConfig>;\n\ntype ConnectionInfo = {\n saveData?: boolean;\n effectiveType?: 'slow-2g' | '2g' | '3g' | '4g' | string;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction getNavigatorConnection(): ConnectionInfo | undefined {\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n\n const nav = navigator as Navigator & {\n connection?: ConnectionInfo;\n mozConnection?: ConnectionInfo;\n webkitConnection?: ConnectionInfo;\n };\n\n return nav.connection || nav.mozConnection || nav.webkitConnection;\n}\n\nfunction getAdaptiveConcurrency(connection?: ConnectionInfo): number {\n let concurrency = 10;\n\n if (typeof navigator !== 'undefined' && typeof navigator.hardwareConcurrency === 'number') {\n concurrency = clamp(Math.round(navigator.hardwareConcurrency * 0.75), 4, 10);\n }\n\n if (connection?.saveData) {\n return 3;\n }\n\n if (connection?.effectiveType === 'slow-2g' || connection?.effectiveType === '2g') {\n return 2;\n }\n\n if (connection?.effectiveType === '3g') {\n return Math.min(concurrency, 4);\n }\n\n return concurrency;\n}\n\nfunction getAdaptivePrefetch(maxConcurrentRequests: number, connection?: ConnectionInfo): number {\n if (connection?.saveData) {\n return 0;\n }\n\n if (connection?.effectiveType === 'slow-2g' || connection?.effectiveType === '2g') {\n return 0;\n }\n\n if (connection?.effectiveType === '3g') {\n return 2;\n }\n\n return Math.min(maxConcurrentRequests + 2, 12);\n}\n\nexport function resolveImageLoadingConfig(overrides: ImageLoadingConfigOverrides = {}): ImageLoadingConfig {\n const connection = getNavigatorConnection();\n const adaptiveConcurrency = getAdaptiveConcurrency(connection);\n\n const maxConcurrentRequests =\n typeof overrides.maxConcurrentRequests === 'number'\n ? Math.max(1, Math.floor(overrides.maxConcurrentRequests))\n : adaptiveConcurrency;\n\n const maxPrefetchPerFrame =\n typeof overrides.maxPrefetchPerFrame === 'number'\n ? Math.max(0, Math.floor(overrides.maxPrefetchPerFrame))\n : getAdaptivePrefetch(maxConcurrentRequests, connection);\n\n return {\n maxConcurrentRequests,\n maxPrefetchPerFrame,\n timeoutMs: typeof overrides.timeoutMs === 'number' ? Math.max(250, Math.floor(overrides.timeoutMs)) : 8000,\n maxAttempts: typeof overrides.maxAttempts === 'number' ? Math.max(1, Math.floor(overrides.maxAttempts)) : 3,\n baseDelayMs: typeof overrides.baseDelayMs === 'number' ? Math.max(0, Math.floor(overrides.baseDelayMs)) : 250,\n maxDelayMs: typeof overrides.maxDelayMs === 'number' ? Math.max(0, Math.floor(overrides.maxDelayMs)) : 3000,\n jitterRatio: typeof overrides.jitterRatio === 'number' ? clamp(overrides.jitterRatio, 0, 1) : 0.2,\n errorRetryIntervalMs:\n typeof overrides.errorRetryIntervalMs === 'number' ? Math.max(0, Math.floor(overrides.errorRetryIntervalMs)) : 30000,\n revealDelayFrames:\n typeof overrides.revealDelayFrames === 'number' ? Math.max(0, Math.floor(overrides.revealDelayFrames)) : 1,\n revealBatchWindowFrames:\n typeof overrides.revealBatchWindowFrames === 'number'\n ? Math.max(0, Math.floor(overrides.revealBatchWindowFrames))\n : 1,\n skipFadeIfLoadedWithinMs:\n typeof overrides.skipFadeIfLoadedWithinMs === 'number'\n ? Math.max(0, Math.floor(overrides.skipFadeIfLoadedWithinMs))\n : 120,\n };\n}\n\nexport function getRetryDelayMs(config: ImageLoadingConfig, attempt: number, random = Math.random): number {\n const normalizedAttempt = Math.max(1, Math.floor(attempt));\n const exponential = config.baseDelayMs * Math.pow(2, normalizedAttempt - 1);\n const capped = Math.min(config.maxDelayMs, exponential);\n const jitterRange = capped * config.jitterRatio;\n if (!jitterRange) {\n return capped;\n }\n\n return Math.max(0, Math.floor(capped + (random() * 2 - 1) * jitterRange));\n}\n","export class ImageRequestCancelledError extends Error {\n silent: boolean;\n\n constructor(message = 'Image request cancelled', silent = true) {\n super(message);\n this.name = 'ImageRequestCancelledError';\n this.silent = silent;\n }\n}\n\nexport function isImageRequestCancelledError(error: unknown): error is ImageRequestCancelledError {\n return error instanceof ImageRequestCancelledError;\n}\n\ntype AcquireResult = {\n requestKey: string;\n promise: Promise<HTMLImageElement>;\n release: (opts?: { silent?: boolean }) => void;\n};\n\ntype RequestEntry = {\n url: string;\n requestKey: string;\n consumers: Set<string>;\n promise: Promise<HTMLImageElement>;\n abortController?: AbortController;\n abortDomImage?: () => void;\n settled: boolean;\n cancelled: boolean;\n silentCancellation: boolean;\n};\n\nexport type ImageRequestPoolOptions = {\n timeoutMs: number;\n crossOrigin?: 'anonymous' | 'use-credentials';\n useFetch?: boolean;\n cache?: Map<string, HTMLImageElement>;\n};\n\nlet requestCounter = 0;\n\nfunction nextRequestKey(url: string): string {\n requestCounter += 1;\n return `${requestCounter}:${url}`;\n}\n\nfunction createTimeoutError(url: string): Error {\n return new Error(`Image load timeout: ${url}`);\n}\n\nfunction loadDomImage(url: string, options: { timeoutMs: number; crossOrigin?: 'anonymous' | 'use-credentials' }) {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const image = document.createElement('img');\n image.decoding = 'async';\n if (options.crossOrigin) {\n image.crossOrigin = options.crossOrigin;\n }\n\n let settled = false;\n\n const promise = new Promise<HTMLImageElement>((resolve, reject) => {\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n }\n image.onload = null;\n image.onerror = null;\n };\n\n image.onload = () => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n resolve(image);\n };\n\n image.onerror = (error) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n reject(error);\n };\n\n timeout = setTimeout(() => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n reject(createTimeoutError(url));\n }, options.timeoutMs);\n\n image.src = url;\n\n if (image.complete && image.naturalWidth > 0) {\n settled = true;\n cleanup();\n resolve(image);\n }\n });\n\n const abort = () => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeout) {\n clearTimeout(timeout);\n }\n image.onload = null;\n image.onerror = null;\n image.src = '';\n };\n\n return { promise, abort };\n}\n\nexport class ImageRequestPool {\n private readonly timeoutMs: number;\n private readonly crossOrigin?: 'anonymous' | 'use-credentials';\n private readonly useFetch: boolean;\n private readonly cache: Map<string, HTMLImageElement>;\n private readonly inFlight = new Map<string, RequestEntry>();\n private readonly knownConsumers = new Map<string, Set<string>>();\n\n constructor(options: ImageRequestPoolOptions) {\n this.timeoutMs = options.timeoutMs;\n this.crossOrigin = options.crossOrigin;\n this.useFetch = !!options.useFetch && typeof fetch !== 'undefined' && typeof AbortController !== 'undefined';\n this.cache = options.cache || new Map<string, HTMLImageElement>();\n }\n\n acquire(url: string, consumerId: string): AcquireResult {\n const cached = this.cache.get(url);\n if (cached && cached.naturalWidth > 0) {\n return {\n requestKey: `cached:${url}`,\n promise: Promise.resolve(cached),\n release: () => {\n // No-op, fulfilled from cache.\n },\n };\n }\n\n let entry = this.inFlight.get(url);\n\n if (!entry) {\n const requestKey = nextRequestKey(url);\n entry = {\n url,\n requestKey,\n consumers: new Set<string>(),\n promise: Promise.resolve(document.createElement('img')),\n settled: false,\n cancelled: false,\n silentCancellation: true,\n };\n\n entry.promise = this.createRequest(entry)\n .then((image) => {\n entry!.settled = true;\n this.cache.set(url, image);\n return image;\n })\n .catch((error) => {\n entry!.settled = true;\n if (entry!.cancelled) {\n throw new ImageRequestCancelledError('Image request cancelled', entry!.silentCancellation);\n }\n throw error;\n })\n .finally(() => {\n if (entry && entry.consumers.size === 0) {\n this.inFlight.delete(url);\n }\n });\n\n this.inFlight.set(url, entry);\n }\n\n entry.consumers.add(consumerId);\n const tracked = this.knownConsumers.get(consumerId) || new Set<string>();\n tracked.add(url);\n this.knownConsumers.set(consumerId, tracked);\n\n return {\n requestKey: entry.requestKey,\n promise: entry.promise,\n release: (opts) => {\n this.release(url, consumerId, opts);\n },\n };\n }\n\n release(url: string, consumerId: string, opts: { silent?: boolean } = {}) {\n const tracked = this.knownConsumers.get(consumerId);\n if (tracked) {\n tracked.delete(url);\n if (tracked.size === 0) {\n this.knownConsumers.delete(consumerId);\n }\n }\n\n const entry = this.inFlight.get(url);\n if (!entry) {\n return;\n }\n\n entry.consumers.delete(consumerId);\n if (opts.silent === false) {\n entry.silentCancellation = false;\n }\n\n if (entry.consumers.size > 0) {\n return;\n }\n\n if (!entry.settled) {\n entry.cancelled = true;\n if (entry.abortController) {\n entry.abortController.abort();\n }\n if (entry.abortDomImage) {\n entry.abortDomImage();\n }\n return;\n }\n\n this.inFlight.delete(url);\n }\n\n releaseConsumer(consumerId: string, opts: { silent?: boolean } = {}) {\n const tracked = this.knownConsumers.get(consumerId);\n if (!tracked) {\n return;\n }\n\n for (const url of [...tracked]) {\n this.release(url, consumerId, opts);\n }\n }\n\n cancelAll(opts: { silent?: boolean } = {}) {\n const consumers = [...this.knownConsumers.keys()];\n for (const consumerId of consumers) {\n this.releaseConsumer(consumerId, opts);\n }\n }\n\n private async createRequest(entry: RequestEntry): Promise<HTMLImageElement> {\n if (this.useFetch) {\n const abortController = new AbortController();\n entry.abortController = abortController;\n const timeout = setTimeout(() => {\n abortController.abort(createTimeoutError(entry.url));\n }, this.timeoutMs);\n try {\n const credentials = this.crossOrigin === 'use-credentials' ? 'include' : 'same-origin';\n const response = await fetch(entry.url, {\n signal: abortController.signal,\n credentials,\n });\n if (!response.ok) {\n throw new Error(`Image request failed (${response.status}): ${entry.url}`);\n }\n\n const blob = await response.blob();\n const objectUrl = URL.createObjectURL(blob);\n try {\n const { promise, abort } = loadDomImage(objectUrl, {\n timeoutMs: this.timeoutMs,\n crossOrigin: undefined,\n });\n entry.abortDomImage = abort;\n return await promise;\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n\n const { promise, abort } = loadDomImage(entry.url, {\n timeoutMs: this.timeoutMs,\n crossOrigin: this.crossOrigin,\n });\n entry.abortDomImage = abort;\n return promise;\n }\n}\n","import type { Strand } from '@atlas-viewer/dna';\nimport LRUCache from 'lru-cache';\nimport { Box } from '../../objects/box';\nimport { Geometry } from '../../objects/geometry';\nimport type { Text } from '../../objects/text';\nimport type { Renderer } from '../../renderer/renderer';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport type { SpacialContent } from '../../spacial-content/spacial-content';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport type { HookOptions } from '../../standalone';\nimport type { PositionPair } from '../../types';\nimport { getZoneConstrainedBounds } from '../../utility/get-zone-constrained-bounds';\nimport { distance } from '../../utils';\nimport type { World } from '../../world';\nimport type { Paint, Paintable, WorldObject } from '../../world-objects';\nimport { buildCssFilter } from '../shared/build-css-filter';\nimport type { AtlasImageLoadErrorEvent } from '../shared/image-load-events';\nimport { getRetryDelayMs, type ImageLoadingConfig, resolveImageLoadingConfig } from '../shared/image-loading-config';\nimport { ImageRequestPool, isImageRequestCancelledError } from '../shared/image-request-pool';\n\nconst shadowRegex =\n /(-?[0-9]+(px|em)\\s+|0\\s+)(-?[0-9]+(px|em)\\s+|0\\s+)(-?[0-9]+(px|em)\\s+|0\\s+)?(-?[0-9]+(px|em)\\s+|0\\s+)?(.*)/g;\nconst shadowRegexCache: any = {};\nconst isFirefox =\n typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().includes('firefox');\n\nexport type CanvasRendererOptions = {\n beforeFrame?: (delta: number) => void;\n debug?: boolean;\n htmlContainer?: HTMLDivElement;\n crossOrigin?: boolean;\n dpi?: number;\n box?: boolean;\n polygon?: boolean;\n lruCache?: boolean;\n paintImages?: boolean;\n shouldPaintImage?: (paint: SingleImage | TiledImage, index: number) => boolean;\n readiness?: 'first-meaningful-paint' | 'immediate';\n imageLoading?: Partial<ImageLoadingConfig>;\n onImageError?: (event: AtlasImageLoadErrorEvent) => void;\n};\n\nexport type ImageBuffer = {\n canvas?: HTMLCanvasElement;\n canvases: string[];\n tiles?: Record<number, TileLoadingState>;\n indices: number[];\n loaded: number[];\n fallback?: ImageBuffer;\n loading: boolean;\n};\n\nexport type TileLoadingState = {\n state: 'idle' | 'queued' | 'loading' | 'decoded' | 'error';\n requestedAt?: number;\n loadedAt?: number;\n lastUsedAt?: number;\n url?: string;\n error?: unknown;\n attempts?: number;\n nextRetryAt?: number;\n lastRequestKey?: string;\n cancelledAt?: number;\n skipFade?: boolean;\n};\n\ntype QueueTask = {\n id: string;\n scale: number;\n kind: 'network' | 'decode';\n tileKey?: string;\n requestKey?: string;\n network?: boolean;\n distance: number;\n shifted?: boolean;\n paint?: SingleImage | TiledImage;\n index?: number;\n prefetch?: boolean;\n task: () => Promise<any>;\n};\n\ntype InFlightTileLoad = {\n tileKey: string;\n requestKey: string;\n url: string;\n consumerId: string;\n paint: SingleImage | TiledImage;\n imageBuffer: ImageBuffer;\n index: number;\n release: (opts?: { silent?: boolean }) => void;\n};\n\nconst imageCache = new Map<string, HTMLImageElement>();\nconst hostCache: Record<string, any> = {};\n\nexport class CanvasRenderer implements Renderer {\n /**\n * The primary viewing space for the viewer.\n */\n canvas: HTMLCanvasElement;\n\n /**\n * Canvas context for `this.canvas`\n */\n ctx: CanvasRenderingContext2D;\n\n /**\n * Rendering options added in the constructor.\n */\n options: CanvasRendererOptions;\n\n /**\n * Number of images loading.\n */\n imagesPending = 0;\n\n /**\n * Number of completed images, used to calculate pending images.\n */\n imagesLoaded = 0;\n\n /**\n * The ids of the completed images, use to dedupe\n */\n imageIdsLoaded: string[] = [];\n\n /**\n * Can be used to avoid or stop work when frame is or isn't rendering outside of the main loop.\n */\n frameIsRendering = false;\n pendingDrawCall = false;\n firstMeaningfulPaint = false;\n parallelTasks = 6;\n maxPrefetchPerFrame = 8;\n imageLoadingConfig: ImageLoadingConfig;\n imageRequestPool: ImageRequestPool;\n frameTasks = 0;\n loadingQueueOrdered = true;\n loadingQueue: QueueTask[] = [];\n currentTask: Promise<any> = Promise.resolve();\n tasksRunning = 0;\n inFlightImageLoads = new Map<string, InFlightTileLoad>();\n requiredTileKeys = new Set<string>();\n requiredPrefetchTileKeys = new Set<string>();\n requestGeneration = 0;\n frameCounter = 0;\n pendingTileReveals = new Map<\n string,\n {\n imageBuffer: ImageBuffer;\n index: number;\n queuedFrame: number;\n }\n >();\n stats?: any;\n averageJobTime = 64; // ms\n lastKnownScale = 1;\n visible: Array<SpacialContent> = [];\n previousVisible: Array<SpacialContent> = [];\n rendererPosition: DOMRect;\n dpi: number;\n drawCalls: Array<() => void> = [];\n lastPaintedObject?: WorldObject;\n hostCache: LRUCache<string, HTMLCanvasElement>;\n invalidated: string[] = [];\n fallbackRevealTimeout: ReturnType<typeof setTimeout> | null = null;\n framePrefetchCount = 0;\n hasTilesFading = false;\n hasActiveLayerClip = false;\n\n constructor(canvas: HTMLCanvasElement, options?: CanvasRendererOptions) {\n this.canvas = canvas;\n this.rendererPosition = canvas.getBoundingClientRect();\n // Not working as expected.\n // this.ctx = canvas.getContext('2d', { alpha: false, desynchronized: true }) as CanvasRenderingContext2D;\n this.ctx = canvas.getContext('2d', {\n alpha: true,\n }) as CanvasRenderingContext2D;\n this.ctx.imageSmoothingEnabled = true;\n this.options = options || {};\n this.imageLoadingConfig = resolveImageLoadingConfig(this.options.imageLoading);\n this.parallelTasks = this.imageLoadingConfig.maxConcurrentRequests;\n this.maxPrefetchPerFrame = this.imageLoadingConfig.maxPrefetchPerFrame;\n this.imageRequestPool = new ImageRequestPool({\n timeoutMs: this.imageLoadingConfig.timeoutMs,\n crossOrigin: this.options.crossOrigin ? 'anonymous' : undefined,\n useFetch: !!this.options.crossOrigin,\n cache: imageCache,\n });\n // Testing fade in.\n // this.canvas.style.opacity = '0';\n this.canvas.style.transition = 'opacity .3s';\n this.dpi = options?.dpi || 1;\n if (this.options.readiness === 'immediate') {\n this.firstMeaningfulPaint = true;\n this.canvas.style.opacity = '1';\n }\n\n this.hostCache = options?.lruCache\n ? new LRUCache<string, HTMLCanvasElement>({\n maxSize: 1024 * 512 * 512, // 250MB total.\n dispose: (value, key, reason) => {\n this.invalidated.push(key);\n value.width = 0;\n value.height = 0;\n },\n sizeCalculation: (value, key) => {\n return value.width * value.height;\n },\n })\n : ({\n store: {},\n get(id: string) {\n return this.store[id];\n },\n set(id: string, value: any) {\n this.store[id] = value;\n },\n } as any);\n\n // if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n // import('stats.js')\n // .then((s) => new s.default())\n // .then((stats) => {\n // this.stats = stats;\n // this.stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom\n // if (document && document.body) {\n // document.body.appendChild(this.stats.dom);\n // }\n // });\n // }\n }\n\n getCanvasDims() {\n return {\n width: this.canvas.width / this.dpi,\n height: this.canvas.height / this.dpi,\n };\n }\n\n resize() {\n this.rendererPosition = this.canvas.getBoundingClientRect();\n }\n\n private getCompositeOwner(paint?: SingleImage | TiledImage): unknown {\n const parent = paint?.__parent as any;\n return parent && parent.renderOptions ? parent : undefined;\n }\n\n private compareCompositeLoadPriority(\n aPaint?: SingleImage | TiledImage,\n bPaint?: SingleImage | TiledImage\n ): number {\n const aOwner = this.getCompositeOwner(aPaint);\n const bOwner = this.getCompositeOwner(bPaint);\n if (!aOwner || aOwner !== bOwner) {\n return 0;\n }\n\n const aScale = aPaint?.display.scale || 0;\n const bScale = bPaint?.display.scale || 0;\n return aScale - bScale;\n }\n\n isReady(): boolean {\n return this.firstMeaningfulPaint;\n }\n\n afterFrame(world: World): void {\n // this.lastPaintedObject = paint.__owner.value;\n this.clearTransform();\n this.lastPaintedObject = undefined;\n // this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2);\n // this.ctx.rotate((90 * Math.PI) / 180);\n // this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);\n this.frameIsRendering = false;\n this.imagesPending =\n this.loadingQueue.length + this.tasksRunning + this.inFlightImageLoads.size + this.pendingTileReveals.size;\n this.imagesLoaded = 0;\n if (!this.loadingQueueOrdered /*&& this.loadingQueue.length > this.parallelTasks*/) {\n this.loadingQueue = this.loadingQueue.sort((a, b) => {\n const compositePriority = this.compareCompositeLoadPriority(a.paint, b.paint);\n if (compositePriority !== 0) {\n return compositePriority;\n }\n if (a.network && b.network && a.scale === b.scale) {\n return b.distance - a.distance;\n }\n return a.scale - b.scale;\n });\n this.loadingQueueOrdered = true;\n }\n this.scheduleSingleImageLookahead(world);\n // Set them.\n this.previousVisible = this.visible;\n this.pruneStaleTileWork();\n this.pendingDrawCall = !!this.drawCalls.length;\n if (this.pendingDrawCall) {\n for (let i = 0; i < this.drawCalls.length; i++) {\n const nextCall = this.drawCalls.shift();\n if (nextCall) nextCall();\n }\n }\n // Some off-screen work might need done, like loading new images in.\n this.doOffscreenWork();\n // Stats\n if (this.options.debug && this.stats) {\n this.stats.end();\n }\n }\n\n doOffscreenWork() {\n this.frameTasks = 0;\n // This is our worker. It is called every 1ms (roughly) and will usually be\n // an async task that can run without blocking the frame. Because of\n // there is a configuration for parallel task count.\n if (this.loadingQueue.length) {\n // First call immediately.\n this._worker();\n if (this.loadingQueue.length && this.tasksRunning < this.parallelTasks) {\n // Here's our clock for scheduling tasks, every 1ms it will try to call.\n if (!this._scheduled) {\n this._scheduled = setInterval(this._doWork, 0);\n }\n }\n }\n }\n\n _worker = () => {\n if (\n // First we check if there is work to do.\n this.loadingQueue.length &&\n this.tasksRunning < this.parallelTasks &&\n this.frameTasks < this.parallelTasks\n ) {\n // Let's pop something off the loading queue.\n const next = this.loadingQueue.pop();\n\n if (next) {\n // @todo removed for now, while a nice optimisation it was breaking the \"renderSmallestFallback\"\n // const outOfBounds = !next.shifted && Math.abs(1 - next.scale / (1 / this.lastKnownScale)) >= 1;\n // if (outOfBounds && !next.shifted) {\n // next.shifted = true;\n // this.loadingQueue.unshift(next);\n // return;\n // }\n // We will increment the task count\n this.tasksRunning++;\n this.frameTasks++;\n // And kick it off. We don't care if it succeeded or not.\n // A task that needs to retry should just add a new task.\n this.currentTask = next\n .task()\n .then(() => {\n this.tasksRunning--;\n })\n .catch(() => {\n this.tasksRunning--;\n });\n }\n }\n };\n _scheduled: any = 0;\n _doWork = () => {\n // Here is the shut down, no more work to do.\n if (this.loadingQueue.length === 0 && this.tasksRunning === 0 && this._scheduled) {\n clearInterval(this._scheduled);\n this._scheduled = 0;\n }\n\n let parallel = this.parallelTasks || 1;\n\n if (!this.firstMeaningfulPaint && this.loadingQueue.length) {\n parallel = this.loadingQueue.length;\n }\n // And here's our working being called. Since JS is blocking, this will complete\n // before the next tick, so its possible that this could be more than 1ms.\n for (let i = 0; i < parallel; i++) {\n this._worker();\n }\n };\n\n getScale(width: number, height: number, dpi?: boolean): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const canvas = this.getCanvasDims();\n const w = canvas.width / width;\n const h = canvas.height / height;\n const scale = (w < h ? h : w) * (dpi ? this.dpi || 1 : 1);\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n beforeFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n // const scale = this.getScale(target[3] - target[1], target[4] - target[1]);\n // this.ctx.setTransform(scale, 0, 0, scale, -target[1], -target[2]);\n\n if (this.options.debug && this.stats) {\n this.stats.begin();\n }\n this.frameIsRendering = true;\n this.frameCounter += 1;\n this.visible = [];\n this.framePrefetchCount = 0;\n this.hasTilesFading = false;\n this.requiredTileKeys.clear();\n this.requiredPrefetchTileKeys.clear();\n this.flushTileRevealBatch();\n // User-facing hook for before frame, contains timing information for\n // animations that might be happening, such as pan/drag.\n if (this.options.beforeFrame) {\n this.options.beforeFrame(delta);\n }\n\n const canvas = this.getCanvasDims();\n // But we also need to clear the canvas.\n this.ctx.globalAlpha = 1;\n if (this.canvas.dataset.background === 'transparent') {\n this.ctx.clearRect(0, 0, canvas.width, canvas.height);\n } else {\n this.ctx.fillStyle = this.canvas.dataset.background ?? 'rgb(0, 0, 0)';\n this.ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n // this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2);\n // this.ctx.rotate((-90 * Math.PI) / 180);\n // this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);\n\n const filter = buildCssFilter(options);\n if (this.ctx.filter !== filter) {\n this.ctx.filter = filter;\n }\n }\n\n applyTransform(paint: Paintable, x: number, y: number, width: number, height: number) {\n const owner = paint.__owner.value;\n if (owner && owner.rotation) {\n this.ctx.save();\n const moveX = x + width / 2;\n const moveY = y + height / 2;\n\n this.ctx.translate(moveX, moveY);\n this.ctx.rotate((owner.rotation * Math.PI) / 180);\n this.ctx.translate(-moveX, -moveY);\n this.lastPaintedObject = owner;\n }\n }\n clearTransform() {\n // Do something with last object.\n if (this.lastPaintedObject) {\n if (this.lastPaintedObject.rotation) {\n this.ctx.restore();\n }\n this.lastPaintedObject = undefined;\n }\n }\n\n private getTileKey(paint: SingleImage | TiledImage, index: number): string {\n return `${paint.id}::${paint.display.scale}::${index}`;\n }\n\n private nextRequestKey(tileKey: string): string {\n this.requestGeneration += 1;\n return `${tileKey}::${this.requestGeneration}`;\n }\n\n private markTileRequired(tileKey: string, prefetch: boolean) {\n if (prefetch) {\n this.requiredPrefetchTileKeys.add(tileKey);\n return;\n }\n this.requiredTileKeys.add(tileKey);\n }\n\n private isTileRequired(tileKey: string): boolean {\n return this.requiredTileKeys.has(tileKey) || this.requiredPrefetchTileKeys.has(tileKey);\n }\n\n private shouldSkipFade(tileState: TileLoadingState | undefined, now = performance.now()): boolean {\n if (!tileState?.requestedAt) {\n return false;\n }\n return now - tileState.requestedAt <= this.imageLoadingConfig.skipFadeIfLoadedWithinMs;\n }\n\n private enqueueTileReveal(tileKey: string, imageBuffer: ImageBuffer, index: number) {\n const now = performance.now();\n if (this.imageLoadingConfig.revealDelayFrames === 0 && this.imageLoadingConfig.revealBatchWindowFrames === 0) {\n const state = this.getTileState(imageBuffer, index);\n this.setTileState(imageBuffer, index, {\n ...state,\n loadedAt: now,\n skipFade: this.shouldSkipFade(state, now),\n });\n return;\n }\n\n this.pendingTileReveals.set(tileKey, {\n imageBuffer,\n index,\n queuedFrame: this.frameCounter,\n });\n }\n\n private flushTileRevealBatch() {\n if (this.pendingTileReveals.size === 0) {\n return;\n }\n\n const delay = this.imageLoadingConfig.revealDelayFrames;\n const windowFrames = this.imageLoadingConfig.revealBatchWindowFrames;\n const now = performance.now();\n\n const entries = [...this.pendingTileReveals.entries()].sort((a, b) => a[1].queuedFrame - b[1].queuedFrame);\n let cursor = 0;\n\n while (cursor < entries.length) {\n const first = entries[cursor];\n if (this.frameCounter - first[1].queuedFrame < delay) {\n break;\n }\n\n const cutoffFrame = first[1].queuedFrame + windowFrames;\n while (cursor < entries.length && entries[cursor][1].queuedFrame <= cutoffFrame) {\n const [tileKey, pending] = entries[cursor];\n const state = this.getTileState(pending.imageBuffer, pending.index);\n if (state.state === 'decoded' && !state.loadedAt) {\n this.setTileState(pending.imageBuffer, pending.index, {\n ...state,\n loadedAt: now,\n skipFade: this.shouldSkipFade(state, now),\n });\n }\n this.pendingTileReveals.delete(tileKey);\n cursor += 1;\n }\n }\n }\n\n private emitImageError(event: Omit<AtlasImageLoadErrorEvent, 'renderer'>) {\n if (this.options.onImageError) {\n this.options.onImageError({\n renderer: 'canvas',\n ...event,\n });\n }\n }\n\n private releaseInFlightTileLoad(tileKey: string, opts: { silent?: boolean } = {}) {\n const inFlight = this.inFlightImageLoads.get(tileKey);\n if (!inFlight) {\n return;\n }\n\n inFlight.release(opts);\n this.inFlightImageLoads.delete(tileKey);\n }\n\n private pruneStaleTileWork() {\n const nextQueue: QueueTask[] = [];\n for (const task of this.loadingQueue) {\n if (!task.tileKey || this.isTileRequired(task.tileKey)) {\n nextQueue.push(task);\n continue;\n }\n\n if (task.paint && typeof task.index === 'number') {\n const imageBuffer = this.ensureImageBuffer(task.paint);\n const state = this.getTileState(imageBuffer, task.index);\n if (state.lastRequestKey === task.requestKey && (state.state === 'queued' || state.state === 'loading')) {\n this.setTileState(imageBuffer, task.index, {\n ...state,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n }\n if (task.tileKey) {\n this.pendingTileReveals.delete(task.tileKey);\n }\n }\n this.loadingQueue = nextQueue;\n\n const staleInFlight: string[] = [];\n for (const [tileKey, inFlight] of this.inFlightImageLoads.entries()) {\n if (this.isTileRequired(tileKey)) {\n continue;\n }\n staleInFlight.push(tileKey);\n const state = this.getTileState(inFlight.imageBuffer, inFlight.index);\n if (state.lastRequestKey === inFlight.requestKey && state.state === 'loading') {\n this.setTileState(inFlight.imageBuffer, inFlight.index, {\n ...state,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n this.pendingTileReveals.delete(tileKey);\n }\n\n for (const tileKey of staleInFlight) {\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n }\n }\n\n private ensureImageBuffer(paint: SingleImage | TiledImage): ImageBuffer {\n if (!paint.__host || !paint.__host.canvas) {\n this.createImageHost(paint);\n }\n\n const imageBuffer = paint.__host.canvas as ImageBuffer;\n if (!imageBuffer.tiles) {\n imageBuffer.tiles = {};\n }\n if (!imageBuffer.indices) {\n imageBuffer.indices = [];\n }\n if (!imageBuffer.loaded) {\n imageBuffer.loaded = [];\n }\n if (!imageBuffer.canvases) {\n imageBuffer.canvases = [];\n }\n\n return imageBuffer;\n }\n\n private getTileState(imageBuffer: ImageBuffer, index: number): TileLoadingState {\n if (!imageBuffer.tiles) {\n imageBuffer.tiles = {};\n }\n if (!imageBuffer.tiles[index]) {\n imageBuffer.tiles[index] = { state: 'idle' };\n this.syncBufferState(imageBuffer);\n }\n return imageBuffer.tiles[index];\n }\n\n private setTileState(imageBuffer: ImageBuffer, index: number, state: TileLoadingState) {\n if (!imageBuffer.tiles) {\n imageBuffer.tiles = {};\n }\n imageBuffer.tiles[index] = state;\n this.syncBufferState(imageBuffer);\n }\n\n private syncBufferState(imageBuffer: ImageBuffer) {\n const indices: number[] = [];\n const loaded: number[] = [];\n const tiles = imageBuffer.tiles || {};\n const keys = Object.keys(tiles);\n for (let i = 0; i < keys.length; i++) {\n const index = parseInt(keys[i], 10);\n const state = tiles[index].state;\n if (state === 'queued' || state === 'loading') {\n indices.push(index);\n }\n if (state === 'decoded') {\n loaded.push(index);\n }\n }\n imageBuffer.indices = indices;\n imageBuffer.loaded = loaded;\n imageBuffer.loading = indices.length > 0;\n }\n\n private getCompositeRenderOptions(paint: SingleImage | TiledImage) {\n return paint.__parent?.renderOptions;\n }\n\n private shouldClipLayerToBounds(paint: SpacialContent): boolean {\n if (!(paint instanceof SingleImage || paint instanceof TiledImage)) {\n return false;\n }\n return !!this.getCompositeRenderOptions(paint)?.clipToBounds;\n }\n\n private getBoundsFromPoints(points: Strand): { x: number; y: number; width: number; height: number } | undefined {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < points.length; i += 5) {\n if (!points[i]) {\n continue;\n }\n minX = Math.min(minX, points[i + 1]);\n minY = Math.min(minY, points[i + 2]);\n maxX = Math.max(maxX, points[i + 3]);\n maxY = Math.max(maxY, points[i + 4]);\n }\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {\n return undefined;\n }\n if (maxX <= minX || maxY <= minY) {\n return undefined;\n }\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n }\n\n private getLayerPolicy(paint: SingleImage | TiledImage) {\n return this.getCompositeRenderOptions(paint)?.layerPolicy || 'fallback-only';\n }\n\n private isLayerActive(paint: SingleImage | TiledImage): boolean {\n const parent = paint.__parent as any;\n if (!parent) {\n return true;\n }\n const policy = this.getLayerPolicy(paint);\n if (policy === 'always-blend') {\n return true;\n }\n if (typeof parent.isImageActive === 'function') {\n return !!parent.isImageActive(paint);\n }\n return true;\n }\n\n private getPrefetchRadius(paint: SingleImage | TiledImage): number {\n const options = this.getCompositeRenderOptions(paint);\n if (!options) {\n return 0;\n }\n if (typeof options.prefetchRadius === 'number') {\n return Math.max(0, options.prefetchRadius);\n }\n if (options.loadingBias === 'speed') {\n return 2;\n }\n if (options.loadingBias === 'data') {\n return 0;\n }\n return 1;\n }\n\n private getFadeAlpha(\n paint: SingleImage | TiledImage,\n tileState: TileLoadingState | undefined,\n isActiveLayer: boolean\n ): number {\n if (tileState?.skipFade) {\n return 1;\n }\n\n const isRevealDeferred =\n tileState?.state === 'decoded' &&\n !tileState.loadedAt &&\n (this.imageLoadingConfig.revealDelayFrames > 0 || this.imageLoadingConfig.revealBatchWindowFrames > 0);\n if (isRevealDeferred) {\n return 0;\n }\n\n const options = this.getCompositeRenderOptions(paint);\n if (!options || !options.fadeInMs || options.fadeInMs <= 0) {\n return 1;\n }\n\n const now = performance.now();\n let fadeAlpha = 1;\n\n if (isActiveLayer && options.fadeOnLayerChange && options.layerPolicy !== 'active-only') {\n const parent = paint.__parent as any;\n if (parent && typeof parent.getImageActivatedAt === 'function') {\n const activatedAt = parent.getImageActivatedAt(paint);\n if (typeof activatedAt === 'number') {\n fadeAlpha = Math.min(fadeAlpha, Math.max(0, Math.min(1, (now - activatedAt) / options.fadeInMs)));\n }\n }\n }\n\n if (tileState?.loadedAt && (isActiveLayer || options.fadeFallbackTiles)) {\n fadeAlpha = Math.min(fadeAlpha, Math.max(0, Math.min(1, (now - tileState.loadedAt) / options.fadeInMs)));\n }\n\n return fadeAlpha;\n }\n\n private schedulePrefetchNeighbours(\n imageBuffer: ImageBuffer,\n paint: SingleImage | TiledImage,\n index: number,\n priority: number\n ) {\n if (!(paint instanceof TiledImage)) {\n return;\n }\n if (this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n return;\n }\n\n const options = this.getCompositeRenderOptions(paint);\n if (options?.loadingBias === 'data') {\n return;\n }\n\n const radius = this.getPrefetchRadius(paint);\n if (radius <= 0) {\n return;\n }\n\n const columns = paint.columns;\n const rows = paint.rows;\n if (!columns || !rows) {\n return;\n }\n\n const x = index % columns;\n const y = Math.floor(index / columns);\n\n for (let distance = 1; distance <= radius; distance++) {\n for (let dy = -distance; dy <= distance; dy++) {\n for (let dx = -distance; dx <= distance; dx++) {\n if (Math.max(Math.abs(dx), Math.abs(dy)) !== distance) {\n continue;\n }\n const nx = x + dx;\n const ny = y + dy;\n if (nx < 0 || ny < 0 || nx >= columns || ny >= rows) {\n continue;\n }\n\n const neighbourIndex = ny * columns + nx;\n const neighbourTileKey = this.getTileKey(paint, neighbourIndex);\n this.markTileRequired(neighbourTileKey, true);\n if (this.schedulePaintToCanvas(imageBuffer, paint, neighbourIndex, priority + distance * 1000, true)) {\n this.framePrefetchCount++;\n if (this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n return;\n }\n }\n }\n }\n }\n }\n\n private scheduleSingleImageLookahead(world: World) {\n if (this.maxPrefetchPerFrame <= 0 || this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n return;\n }\n if (world.hasActiveZone()) {\n return;\n }\n\n let viewportTop = Number.POSITIVE_INFINITY;\n let viewportBottom = Number.NEGATIVE_INFINITY;\n const visibleOwners = new Set<WorldObject>();\n for (let i = 0; i < this.visible.length; i++) {\n const owner = this.visible[i].__owner?.value;\n if (!owner || owner.type !== 'world-object' || owner.points[0] === 0) {\n continue;\n }\n visibleOwners.add(owner as WorldObject);\n viewportTop = Math.min(viewportTop, owner.points[2]);\n viewportBottom = Math.max(viewportBottom, owner.points[4]);\n }\n\n if (!Number.isFinite(viewportTop) || !Number.isFinite(viewportBottom)) {\n return;\n }\n const viewportHeight = viewportBottom - viewportTop;\n if (viewportHeight <= 0) {\n return;\n }\n\n const lookaheadDistance = viewportHeight * 1.5;\n const aheadLimit = viewportBottom + lookaheadDistance;\n const behindLimit = viewportTop - lookaheadDistance;\n\n let nearestAhead: { image: SingleImage; distance: number } | undefined;\n let nearestBehind: { image: SingleImage; distance: number } | undefined;\n\n const objects = world.getObjects() as Array<WorldObject | undefined>;\n for (let i = 0; i < objects.length; i++) {\n const object = objects[i];\n if (!object || object.type !== 'world-object' || object.points[0] === 0) {\n continue;\n }\n if (visibleOwners.has(object)) {\n continue;\n }\n\n const objectTop = object.points[2];\n const objectBottom = object.points[4];\n\n const isAhead = objectTop >= viewportBottom && objectTop <= aheadLimit;\n const isBehind = objectBottom <= viewportTop && objectBottom >= behindLimit;\n\n if (!isAhead && !isBehind) {\n continue;\n }\n\n let singleImageLayer: SingleImage | undefined;\n for (let j = 0; j < object.layers.length; j++) {\n const layer = object.layers[j];\n if (layer instanceof SingleImage) {\n singleImageLayer = layer;\n break;\n }\n }\n\n if (!singleImageLayer) {\n continue;\n }\n\n if (isAhead) {\n const distance = objectTop - viewportBottom;\n if (!nearestAhead || distance < nearestAhead.distance) {\n nearestAhead = { image: singleImageLayer, distance };\n }\n }\n if (isBehind) {\n const distance = viewportTop - objectBottom;\n if (!nearestBehind || distance < nearestBehind.distance) {\n nearestBehind = { image: singleImageLayer, distance };\n }\n }\n }\n\n const prefetchCandidates = [nearestAhead, nearestBehind].filter(Boolean) as Array<{\n image: SingleImage;\n distance: number;\n }>;\n\n for (const candidate of prefetchCandidates) {\n if (this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n break;\n }\n const imageBuffer = this.ensureImageBuffer(candidate.image);\n if (this.schedulePaintToCanvas(imageBuffer, candidate.image, 0, 10000 + candidate.distance, true)) {\n this.framePrefetchCount++;\n }\n }\n }\n\n paint(paint: SpacialContent | Text | Box, index: number, x: number, y: number, width: number, height: number): void {\n const ga = this.ctx.globalAlpha;\n const zoneVisibilityAlpha =\n typeof (paint as any).__zoneVisibilityAlpha === 'number' ? (paint as any).__zoneVisibilityAlpha : 1;\n\n // Only supporting single and tiled images at the moment.\n if (paint instanceof SingleImage || paint instanceof TiledImage) {\n const rotation = paint.display.rotation || 0;\n const didRotate = rotation !== 0;\n\n try {\n if (didRotate) {\n this.ctx.save();\n let moveX = x + width / 2;\n let moveY = y + height / 2;\n if (paint.crop) {\n moveX -= paint.crop[index * 5 + 1];\n moveY -= paint.crop[index * 5 + 2];\n }\n this.ctx.translate(moveX, moveY);\n this.ctx.rotate((rotation * Math.PI) / 180);\n this.ctx.translate(-moveX, -moveY);\n }\n\n const shouldPaintImages = this.options.paintImages !== false;\n const shouldPaintImage = this.options.shouldPaintImage ? this.options.shouldPaintImage(paint, index) : true;\n if (!shouldPaintImages || !shouldPaintImage) {\n return;\n }\n\n this.visible.push(paint);\n\n const baseOpacity =\n (typeof paint.style?.opacity !== 'undefined' ? paint.style.opacity : 1) * zoneVisibilityAlpha;\n if (!baseOpacity) {\n return;\n }\n this.ctx.globalAlpha = ga * baseOpacity;\n\n const imageBuffer = this.ensureImageBuffer(paint);\n const tileState = this.getTileState(imageBuffer, index);\n tileState.lastUsedAt = performance.now();\n this.setTileState(imageBuffer, index, tileState);\n const tileKey = this.getTileKey(paint, index);\n this.markTileRequired(tileKey, false);\n\n const isActiveLayer = this.isLayerActive(paint);\n const canvas = this.getCanvasDims();\n const priority = distance(\n { x: x + width / 2, y: y + height / 2 },\n { x: canvas.width / 2, y: canvas.height / 2 }\n );\n const isInvalidated = this.invalidated.indexOf(imageBuffer.canvases[index]) !== -1;\n const canvasToPaint = this.hostCache.get(imageBuffer.canvases[index]);\n const hasImage = !!canvasToPaint && !isInvalidated;\n\n if (isInvalidated) {\n this.setTileState(imageBuffer, index, {\n ...tileState,\n state: 'idle',\n });\n }\n\n if (\n (isInvalidated || !hasImage || tileState.state === 'idle' || tileState.state === 'error') &&\n isActiveLayer\n ) {\n this.schedulePaintToCanvas(imageBuffer, paint, index, priority, false);\n this.schedulePrefetchNeighbours(imageBuffer, paint, index, priority);\n }\n\n // If we've not prepared an initial \"meaningful paint\", then skip the\n // rendering to avoid tiles loading in, breaking the illusion a bit.\n if (!this.firstMeaningfulPaint) {\n return;\n }\n\n if (canvasToPaint && !isInvalidated) {\n const fadeAlpha = this.getFadeAlpha(paint, tileState, isActiveLayer);\n if (fadeAlpha < 1) {\n this.hasTilesFading = true;\n }\n this.ctx.globalAlpha = ga * baseOpacity * fadeAlpha;\n\n if (paint.crop && paint.cropData) {\n if (paint.crop[index * 5]) {\n const source = [\n paint.crop[index * 5 + 1] / paint.display.scale - paint.display.points[index * 5 + 1],\n paint.crop[index * 5 + 2] / paint.display.scale - paint.display.points[index * 5 + 2],\n 1 + (paint.crop[index * 5 + 3] - paint.crop[index * 5 + 1]) / paint.display.scale,\n 1 + (paint.crop[index * 5 + 4] - paint.crop[index * 5 + 2]) / paint.display.scale,\n ];\n\n source[0] += paint.cropData.x / paint.display.scale;\n source[1] += paint.cropData.y / paint.display.scale;\n\n const translationDeltaX = paint.x * this.lastKnownScale;\n const translationDeltaY = paint.y * this.lastKnownScale;\n\n const target = [x + translationDeltaX, y + translationDeltaY, width, height];\n target[0] += translationDeltaX;\n target[1] += translationDeltaY;\n\n this.ctx.drawImage(\n canvasToPaint,\n source[0],\n source[1],\n source[2],\n source[3],\n target[0],\n target[1],\n target[2] + 1,\n target[3] + 1\n );\n }\n } else {\n if (isFirefox) {\n this.ctx.drawImage(\n canvasToPaint,\n 0,\n 0,\n paint.display.points[index * 5 + 3] - paint.display.points[index * 5 + 1],\n paint.display.points[index * 5 + 4] - paint.display.points[index * 5 + 2],\n x,\n y,\n width + 1,\n height + 1\n );\n } else {\n this.ctx.drawImage(\n canvasToPaint,\n 0,\n 0,\n paint.display.points[index * 5 + 3] - paint.display.points[index * 5 + 1],\n paint.display.points[index * 5 + 4] - paint.display.points[index * 5 + 2],\n x,\n y,\n width + Number.MIN_VALUE + 0.5,\n height + Number.MIN_VALUE + 0.5\n );\n }\n }\n }\n } catch (err) {\n // nothing to do here, likely that the image isn't loaded yet.\n } finally {\n if (didRotate) {\n this.ctx.restore();\n }\n this.ctx.globalAlpha = ga;\n }\n }\n\n const isBox = paint instanceof Box && this.options.box;\n const isGeometry = paint instanceof Geometry && this.options.polygon;\n if ((isBox || isGeometry) && !paint.props.className && !paint.props.html && !paint.props.href) {\n this.visible.push(paint);\n if (paint.props.style) {\n const style = Object.assign(\n //\n {},\n paint.props.style || {},\n paint.hovering ? paint.props.hoverStyles : {},\n paint.pressing ? paint.props.pressStyles : {}\n );\n\n const scale = paint.props.relativeStyle ? 1 : width / paint.width;\n const styleOpacity = typeof style.opacity !== 'undefined' ? style.opacity : 1;\n this.ctx.globalAlpha = ga * styleOpacity * zoneVisibilityAlpha;\n\n let bw = 0;\n if (typeof style.borderWidth !== 'undefined') {\n bw = parseInt(style.borderWidth, 10) * scale;\n }\n\n let ow = 0;\n if (typeof style.outlineWidth !== 'undefined') {\n ow = parseInt(style.outlineWidth, 10) * scale;\n }\n\n let oo = 0;\n if (typeof style.outlineOffset !== 'undefined') {\n oo = parseInt(style.outlineOffset, 10) * scale;\n }\n\n if (style.borderColor) {\n this.ctx.strokeStyle = style.borderColor;\n }\n\n // Box shadow\n if (style.boxShadow) {\n const shadows = style.boxShadow.split(/,(?![^(]*\\))/);\n for (const shadow of shadows) {\n const parsed = shadowRegexCache[shadow] || shadowRegex.exec(shadow) || shadowRegex.exec(shadow);\n shadowRegexCache[shadow] = parsed;\n if (parsed) {\n this.ctx.save();\n this.ctx.shadowOffsetX = parseInt(parsed[1]) * this.dpi * scale;\n this.ctx.shadowOffsetY = parseInt(parsed[3]) * this.dpi * scale;\n this.ctx.shadowBlur = parseInt(parsed[5]) * this.dpi * scale;\n this.ctx.shadowColor = parsed[9];\n this.ctx.fillStyle = 'rgba(0,0,0,1)';\n this.ctx.fillRect(x + bw, y + bw, width, height);\n this.ctx.restore();\n }\n }\n }\n\n this.ctx.fillStyle = style.backgroundColor || 'transparent';\n this.ctx.lineWidth = bw;\n\n if (isGeometry) {\n const shape = (paint as any).shape;\n const points = shape.points || [];\n const len = points.length;\n this.ctx.beginPath();\n for (let i = 0; i < len; i++) {\n this.ctx.lineTo(x + points[i][0] * this.lastKnownScale, y + points[i][1] * this.lastKnownScale);\n }\n if (!shape.open) {\n this.ctx.closePath();\n }\n if (bw) {\n this.ctx.stroke();\n }\n if (!shape.open) {\n this.ctx.fill();\n }\n } else {\n if (bw) {\n this.ctx.strokeRect(x + bw / 2, y + bw / 2, width + bw, height + bw);\n }\n this.ctx.fillRect(x + bw, y + bw, width, height);\n }\n\n if (ow) {\n if (style.outlineColor) {\n this.ctx.strokeStyle = style.outlineColor;\n }\n this.ctx.lineWidth = ow;\n // Outline\n this.ctx.strokeRect(\n //\n x - ow / 2 - oo,\n y - ow / 2 - oo,\n width + bw * 2 + ow + oo * 2,\n height + bw * 2 + ow + oo * 2\n );\n }\n }\n\n this.ctx.globalAlpha = ga;\n }\n }\n\n schedulePaintToCanvas(\n imageBuffer: ImageBuffer,\n paint: SingleImage | TiledImage,\n index: number,\n priority: number,\n prefetch = false\n ): boolean {\n const tileState = this.getTileState(imageBuffer, index);\n const now = performance.now();\n const tileKey = this.getTileKey(paint, index);\n this.markTileRequired(tileKey, prefetch);\n this.pendingTileReveals.delete(tileKey);\n\n if (tileState.nextRetryAt && tileState.nextRetryAt > now) {\n return false;\n }\n\n if (tileState.state === 'queued' || tileState.state === 'loading' || tileState.state === 'decoded') {\n return false;\n }\n\n const id = `${paint.id}--${paint.display.scale}-${index}`;\n const requestKey = this.nextRequestKey(tileKey);\n imageBuffer.canvases[index] = id;\n const idx = this.invalidated.indexOf(id);\n if (idx !== -1) {\n this.invalidated.splice(idx, 1);\n }\n\n this.setTileState(imageBuffer, index, {\n ...tileState,\n state: 'queued',\n requestedAt: now,\n error: undefined,\n lastRequestKey: requestKey,\n cancelledAt: undefined,\n skipFade: false,\n });\n\n this.loadingQueueOrdered = false;\n this.loadingQueue.push({\n id,\n scale: paint.display.scale,\n kind: 'network',\n tileKey,\n requestKey,\n network: true,\n distance: priority,\n paint,\n index,\n prefetch,\n task: async () => {\n const state = this.getTileState(imageBuffer, index);\n if (state.lastRequestKey !== requestKey) {\n return;\n }\n if (state.state !== 'queued' && state.state !== 'loading') {\n return;\n }\n const isCurrentlyVisible = this.visible.indexOf(paint) !== -1;\n const wasVisibleLastFrame = this.previousVisible.indexOf(paint) !== -1;\n if (!prefetch && !isCurrentlyVisible && !wasVisibleLastFrame) {\n this.setTileState(imageBuffer, index, {\n ...state,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n this.pendingTileReveals.delete(tileKey);\n return;\n }\n\n const url = paint.getImageUrl(index);\n this.setTileState(imageBuffer, index, {\n ...state,\n state: 'loading',\n url,\n requestedAt: state.requestedAt || performance.now(),\n error: undefined,\n });\n\n try {\n const consumerId = `${tileKey}::${requestKey}`;\n const acquired = this.imageRequestPool.acquire(url, consumerId);\n this.inFlightImageLoads.set(tileKey, {\n tileKey,\n requestKey,\n url,\n consumerId,\n paint,\n imageBuffer,\n index,\n release: acquired.release,\n });\n const image = await acquired.promise;\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n const currentState = this.getTileState(imageBuffer, index);\n if (currentState.lastRequestKey !== requestKey || currentState.state !== 'loading') {\n return;\n }\n this.loadingQueueOrdered = false;\n this.loadingQueue.push({\n id: `${id}--decode`,\n scale: paint.display.scale,\n kind: 'decode',\n tileKey,\n requestKey,\n distance: priority,\n paint,\n index,\n prefetch,\n task: () =>\n new Promise<void>((resolve) => {\n const stateBeforeDecode = this.getTileState(imageBuffer, index);\n if (stateBeforeDecode.lastRequestKey !== requestKey || stateBeforeDecode.state !== 'loading') {\n resolve();\n return;\n }\n const points = paint.display.points.slice(index * 5, index * 5 + 5);\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;\n canvas.width = points[3] - points[1];\n canvas.height = points[4] - points[2];\n this.hostCache.set(imageBuffer.canvases[index], canvas);\n this.drawCalls.push(() => {\n const commitState = this.getTileState(imageBuffer, index);\n if (commitState.lastRequestKey !== requestKey || commitState.state !== 'loading') {\n resolve();\n return;\n }\n ctx.drawImage(image, 0, 0, points[3] - points[1], points[4] - points[2]);\n const finalState = this.getTileState(imageBuffer, index);\n this.setTileState(imageBuffer, index, {\n ...finalState,\n state: 'decoded',\n loadedAt: undefined,\n error: undefined,\n attempts: 0,\n nextRetryAt: undefined,\n });\n this.enqueueTileReveal(tileKey, imageBuffer, index);\n this.imagesLoaded++;\n resolve();\n });\n }),\n });\n } catch (error) {\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n if (isImageRequestCancelledError(error)) {\n const cancelledState = this.getTileState(imageBuffer, index);\n if (cancelledState.lastRequestKey === requestKey) {\n this.setTileState(imageBuffer, index, {\n ...cancelledState,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n this.pendingTileReveals.delete(tileKey);\n return;\n }\n\n const failedState = this.getTileState(imageBuffer, index);\n if (failedState.lastRequestKey !== requestKey) {\n return;\n }\n\n const attempts = (failedState.attempts || 0) + 1;\n const willRetry = attempts < this.imageLoadingConfig.maxAttempts;\n const nextRetryAt = willRetry\n ? performance.now() + getRetryDelayMs(this.imageLoadingConfig, attempts)\n : performance.now() + this.imageLoadingConfig.errorRetryIntervalMs;\n\n this.setTileState(imageBuffer, index, {\n ...failedState,\n state: willRetry ? 'idle' : 'error',\n error,\n attempts,\n nextRetryAt,\n });\n this.pendingTileReveals.delete(tileKey);\n\n this.emitImageError({\n severity: 'recoverable',\n imageUrl: url,\n contentId: paint.id,\n tileIndex: index,\n attempt: attempts,\n maxAttempts: this.imageLoadingConfig.maxAttempts,\n willRetry,\n nextRetryAt,\n error,\n });\n }\n },\n });\n return true;\n }\n\n afterPaintLayer(paint: SpacialContent, transform: Strand): void {\n // No-op\n }\n\n prepareLayer(paint: SpacialContent, points: Strand): void {\n this.hasActiveLayerClip = false;\n\n if (paint.__owner.value) {\n if (paint.cropData) {\n const scale = this.lastKnownScale * (1 / paint.display.scale);\n this.applyTransform(paint, points[1], points[2], points[3] - points[1], points[4] - points[2]);\n // this.applyTransform(\n // paint,\n // points[1] - paint.cropData.x * scale + paint.points[1] * scale,\n // points[2] - paint.cropData.y * scale + paint.points[2] * scale,\n // paint.cropData.width * this.lastKnownScale,\n // paint.cropData.height * this.lastKnownScale\n // );\n } else {\n this.applyTransform(paint, points[1], points[2], points[3] - points[1], points[4] - points[2]);\n }\n }\n\n if (this.shouldClipLayerToBounds(paint)) {\n const bounds = this.getBoundsFromPoints(points);\n if (bounds) {\n this.ctx.save();\n this.ctx.beginPath();\n this.ctx.rect(bounds.x, bounds.y, bounds.width, bounds.height);\n this.ctx.clip();\n this.hasActiveLayerClip = true;\n }\n }\n\n if (!paint.__host || !paint.__host.canvas) {\n if (paint instanceof SingleImage || paint instanceof TiledImage) {\n // create it if it does not exist.\n this.createImageHost(paint);\n }\n }\n }\n\n finishLayer() {\n if (this.hasActiveLayerClip) {\n this.ctx.restore();\n this.hasActiveLayerClip = false;\n }\n if (this.lastPaintedObject) {\n this.clearTransform();\n }\n }\n\n createImageHost(paint: SingleImage | TiledImage) {\n // const canvas = document.createElement('canvas');\n // canvas.width = paint.display.width;\n // canvas.height = paint.display.height;\n // canvas.getContext('2d')?.clearRect(0, 0, paint.display.width, paint.display.height);\n paint.__host = paint.__host ? paint.__host : {};\n paint.__host.canvas = {\n canvas: undefined,\n canvases: [],\n tiles: {},\n indices: [],\n loaded: [],\n loading: false,\n };\n // hostCache[paint.id] = paint.__host;\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n const zone = world.getActiveZone();\n\n if (zone) {\n zone.recalculateBounds();\n const bounds = getZoneConstrainedBounds(target, zone.points, padding);\n if (bounds) {\n const width = target[3] - target[1];\n const height = target[4] - target[2];\n return {\n x1: bounds.minX,\n y1: bounds.minY,\n x2: bounds.maxX + width,\n y2: bounds.maxY + height,\n };\n }\n }\n return null;\n }\n\n pendingUpdate(): boolean {\n this.imagesPending =\n this.loadingQueue.length + this.tasksRunning + this.inFlightImageLoads.size + this.pendingTileReveals.size;\n const ready =\n !this.pendingDrawCall &&\n this.drawCalls.length === 0 &&\n this.loadingQueue.length === 0 &&\n this.tasksRunning === 0 &&\n this.inFlightImageLoads.size === 0 &&\n this.pendingTileReveals.size === 0;\n\n if (\n !ready &&\n this.visible.length === 0 &&\n this.options.readiness !== 'immediate' &&\n this.fallbackRevealTimeout === null\n ) {\n // If its still not ready by 500ms, force it to be.\n this.fallbackRevealTimeout = setTimeout(() => {\n this.canvas.style.opacity = '1';\n this.firstMeaningfulPaint = true;\n this.fallbackRevealTimeout = null;\n }, 500);\n }\n\n if (!this.firstMeaningfulPaint && ready && (this.visible.length || this.options.readiness === 'immediate')) {\n // Fade in the canvas?\n this.canvas.style.opacity = '1';\n // We've not rendered yet, can we render this frame?\n this.firstMeaningfulPaint = ready;\n // We need to return true here to ensure our update is done.\n return true;\n }\n\n if (this.options.debug) {\n return true;\n }\n\n if (this.hasTilesFading) {\n return true;\n }\n\n return !ready;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n resetReadyState() {\n if (this.options.readiness === 'immediate') {\n return;\n }\n this.firstMeaningfulPaint = false;\n if (this.fallbackRevealTimeout) {\n clearTimeout(this.fallbackRevealTimeout);\n this.fallbackRevealTimeout = null;\n }\n }\n\n reset() {\n this.loadingQueue = [];\n this.drawCalls = [];\n if (this._scheduled) {\n clearInterval(this._scheduled);\n this._scheduled = 0;\n }\n for (const tileKey of [...this.inFlightImageLoads.keys()]) {\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n }\n this.imageRequestPool.cancelAll({ silent: true });\n this.inFlightImageLoads.clear();\n this.requiredTileKeys.clear();\n this.requiredPrefetchTileKeys.clear();\n this.pendingTileReveals.clear();\n this.requestGeneration += 1;\n this.frameCounter = 0;\n if (this.fallbackRevealTimeout) {\n clearTimeout(this.fallbackRevealTimeout);\n this.fallbackRevealTimeout = null;\n }\n this.imagesPending = 0;\n this.imagesLoaded = 0;\n this.hasTilesFading = false;\n }\n}\n","import { Renderer } from '../../renderer/renderer';\nimport { Paint } from '../../world-objects/paint';\nimport { World } from '../../world';\nimport { Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { PositionPair } from '../../types';\nimport { HookOptions } from 'src/standalone';\n\nexport class CompositeRenderer implements Renderer {\n renderers: Renderer[] = [];\n length: number;\n\n constructor(renderers: Array<Renderer | undefined>) {\n for (const renderer of renderers) {\n if (renderer) {\n this.renderers.push(renderer);\n }\n }\n this.length = this.renderers.length;\n }\n\n afterFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].afterFrame(world, delta, target, options);\n }\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].afterPaintLayer(paint, transform);\n }\n }\n\n beforeFrame(world: World, delta: number, target: Strand, options: HookOptions): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].beforeFrame(world, delta, target, options);\n }\n }\n\n triggerResize() {\n for (let i = 0; i < this.length; i++) {\n const renderer = this.renderers[i];\n if (renderer.triggerResize) {\n renderer.triggerResize();\n }\n }\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return this.renderers[0].getPointsAt(world, target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n return this.renderers[0].getScale(width, height);\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return this.renderers[0].getViewportBounds(world, target, padding);\n }\n\n getRendererScreenPosition() {\n return this.renderers[0].getRendererScreenPosition();\n }\n\n isReady(): boolean {\n for (let i = 0; i < this.length; i++) {\n if (!this.renderers[i].isReady()) {\n return false;\n }\n }\n return true;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].paint(paint, index, x, y, width, height);\n }\n }\n\n pendingUpdate(): boolean {\n for (let i = 0; i < this.length; i++) {\n if (this.renderers[i].pendingUpdate()) {\n return true;\n }\n }\n return false;\n }\n\n prepareLayer(paint: SpacialContent, point: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].prepareLayer(paint, point);\n }\n }\n\n finishLayer(paint: SpacialContent, point: Strand): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].finishLayer(paint, point);\n }\n }\n\n resize(width?: number, height?: number): void {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].resize(width, height);\n }\n }\n\n reset() {\n for (let i = 0; i < this.length; i++) {\n this.renderers[i].reset();\n }\n }\n\n resetReadyState() {\n for (let i = 0; i < this.length; i++) {\n if (this.renderers[i].resetReadyState) {\n this.renderers[i].resetReadyState();\n }\n }\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { DisplayData } from '../types';\nimport { Paint } from '../world-objects';\nimport { Strand } from '@atlas-viewer/dna';\nimport { BaseObject } from '../objects/base-object';\n\n/**\n * @deprecated\n */\nexport abstract class AbstractContent<Props = any, SupportedLayers = never>\n extends BaseObject<Props, SupportedLayers>\n implements SpacialContent\n{\n abstract readonly id: string;\n readonly type: 'spacial-content' = 'spacial-content';\n abstract points: Strand;\n abstract readonly display: DisplayData;\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n}\n","import { compose, DnaFactory, dna, type Strand, translate } from '@atlas-viewer/dna';\nimport type { AtlasObjectModel } from '../aom';\nimport type { DisplayData } from '../types';\nimport { bestResourceIndexAtRatio } from '../utils';\nimport type { Paint } from '../world-objects';\nimport { AbstractContent } from './abstract-content';\nimport { SingleImage } from './single-image';\nimport type { SpacialContent } from './spacial-content';\n\ntype RenderOptions = {\n renderSmallestFallback: boolean;\n renderLayers: number;\n minSize: number;\n maxImageSize: number;\n quality: number;\n useDevicePixelRatio: boolean;\n layerPolicy: 'fallback-only' | 'always-blend' | 'active-only';\n loadingBias: 'balanced' | 'speed' | 'data';\n prefetchRadius?: number;\n fadeInMs: number;\n fadeFallbackTiles: boolean;\n fadeOnLayerChange: boolean;\n clipToBounds: boolean;\n};\n\nexport type CompositeResourceProps = Partial<RenderOptions>;\n\nexport class CompositeResource\n extends AbstractContent\n implements SpacialContent, AtlasObjectModel<CompositeResourceProps, SpacialContent>\n{\n readonly id: string;\n readonly display: DisplayData;\n points: Strand;\n images: SpacialContent[] = [];\n allImages: SpacialContent[] = [];\n scaleFactors: number[] = [];\n aggregateBuffer = dna(9);\n lazyLoader?: () => Promise<SpacialContent[]>;\n isFullyLoaded = false;\n isLoadingFullResource = false;\n maxScaleFactor = 0;\n private layerSelection = new WeakMap<SpacialContent, { active: boolean; frame: number; activatedAt?: number }>();\n private layerSelectionFrame = 0;\n\n renderOptions: RenderOptions;\n\n constructor(data: {\n id: string;\n width: number;\n height: number;\n images: SpacialContent[];\n loadFullImages?: () => Promise<SpacialContent[]>;\n renderOptions?: CompositeResourceProps;\n }) {\n super();\n this.id = data.id;\n this.points = DnaFactory.singleBox(data.width, data.height);\n this.lazyLoader = data.loadFullImages;\n if (!data.loadFullImages) {\n this.isFullyLoaded = true;\n }\n this.display = {\n x: 0,\n y: 0,\n points: DnaFactory.singleBox(data.width, data.height),\n height: data.height,\n width: data.width,\n scale: 1,\n };\n this.renderOptions = {\n renderSmallestFallback: true,\n renderLayers: 2,\n minSize: 255,\n maxImageSize: 2048,\n quality: 1.3,\n useDevicePixelRatio: true,\n layerPolicy: 'always-blend',\n loadingBias: 'balanced',\n prefetchRadius: 1,\n fadeInMs: 300,\n fadeFallbackTiles: false,\n fadeOnLayerChange: false,\n clipToBounds: false,\n ...(data.renderOptions || {}),\n };\n\n this.addImages(data.images);\n }\n\n applyProps(props: CompositeResourceProps) {\n let shouldResort = false;\n if (\n typeof props.renderSmallestFallback !== 'undefined' &&\n props.renderSmallestFallback !== this.renderOptions.renderSmallestFallback\n ) {\n this.renderOptions.renderSmallestFallback = props.renderSmallestFallback;\n }\n if (typeof props.renderLayers !== 'undefined' && props.renderLayers !== this.renderOptions.renderLayers) {\n this.renderOptions.renderLayers = props.renderLayers;\n }\n if (typeof props.minSize !== 'undefined' && props.minSize !== this.renderOptions.minSize) {\n this.renderOptions.minSize = props.minSize;\n shouldResort = true;\n }\n if (typeof props.maxImageSize !== 'undefined' && props.maxImageSize !== this.renderOptions.maxImageSize) {\n this.renderOptions.maxImageSize = props.maxImageSize;\n shouldResort = true;\n }\n if (typeof props.quality !== 'undefined' && props.quality !== this.renderOptions.quality) {\n this.renderOptions.quality = props.quality;\n }\n if (\n typeof props.useDevicePixelRatio !== 'undefined' &&\n props.useDevicePixelRatio !== this.renderOptions.useDevicePixelRatio\n ) {\n this.renderOptions.useDevicePixelRatio = props.useDevicePixelRatio;\n }\n if (typeof props.layerPolicy !== 'undefined' && props.layerPolicy !== this.renderOptions.layerPolicy) {\n this.renderOptions.layerPolicy = props.layerPolicy;\n }\n if (typeof props.loadingBias !== 'undefined' && props.loadingBias !== this.renderOptions.loadingBias) {\n this.renderOptions.loadingBias = props.loadingBias;\n }\n if (typeof props.prefetchRadius !== 'undefined' && props.prefetchRadius !== this.renderOptions.prefetchRadius) {\n this.renderOptions.prefetchRadius = props.prefetchRadius;\n }\n if (typeof props.fadeInMs !== 'undefined' && props.fadeInMs !== this.renderOptions.fadeInMs) {\n this.renderOptions.fadeInMs = props.fadeInMs;\n }\n if (\n typeof props.fadeFallbackTiles !== 'undefined' &&\n props.fadeFallbackTiles !== this.renderOptions.fadeFallbackTiles\n ) {\n this.renderOptions.fadeFallbackTiles = props.fadeFallbackTiles;\n }\n if (\n typeof props.fadeOnLayerChange !== 'undefined' &&\n props.fadeOnLayerChange !== this.renderOptions.fadeOnLayerChange\n ) {\n this.renderOptions.fadeOnLayerChange = props.fadeOnLayerChange;\n }\n if (typeof props.clipToBounds !== 'undefined' && props.clipToBounds !== this.renderOptions.clipToBounds) {\n this.renderOptions.clipToBounds = props.clipToBounds;\n }\n\n if (shouldResort) {\n this.sortByScales();\n }\n }\n\n appendChild(item: SpacialContent) {\n this.addImages([item]);\n }\n\n removeChild(item: SpacialContent) {\n if (this.images.indexOf(item) === -1 && this.allImages.indexOf(item) === -1) {\n return;\n }\n\n const key = this.getImageDedupeKey(item);\n this.images = this.images.filter((image) => image !== item && this.getImageDedupeKey(image) !== key);\n this.allImages = this.allImages.filter((image) => image !== item && this.getImageDedupeKey(image) !== key);\n this.sortByScales();\n }\n\n insertBefore(item: SpacialContent, before: SpacialContent) {\n // @todo this is pre-sorted by size. We could change this, but this\n // drives other behaviours.\n this.addImages([item]);\n }\n\n hideInstance() {\n // @todo not yet implemented. this.points[0] = 0 ???\n }\n\n addImages(images: SpacialContent[]) {\n const existingObjects = new Set(this.allImages);\n const existingKeys = new Set(this.allImages.map((image) => this.getImageDedupeKey(image)));\n for (const image of images) {\n if (!image || existingObjects.has(image)) {\n continue;\n }\n const key = this.getImageDedupeKey(image);\n if (existingKeys.has(key)) {\n continue;\n }\n image.__parent = this;\n image.__owner = this.__owner;\n this.allImages.push(image);\n existingObjects.add(image);\n existingKeys.add(key);\n }\n this.sortByScales();\n }\n\n private getImageDedupeKey(image: SpacialContent) {\n return `${image.id}::${image.display.scale}`;\n }\n\n sortByScales() {\n this._scheduleSortByScales = true;\n }\n\n _scheduleSortByScales = false;\n _sortByScales = () => {\n this._scheduleSortByScales = false;\n this.allImages.sort((a: SpacialContent, b: SpacialContent) => b.display.width - a.display.width);\n this.images = [];\n let lastScale = 0.1;\n for (const image of this.allImages) {\n if (\n image.display.width < this.renderOptions.minSize &&\n image.display.height < this.renderOptions.minSize &&\n !image.priority\n ) {\n continue;\n }\n\n if (\n image instanceof SingleImage &&\n (image.display.width > this.renderOptions.maxImageSize ||\n image.display.height > this.renderOptions.maxImageSize) &&\n !image.priority\n ) {\n continue;\n }\n\n const diff = Math.abs(image.display.scale - lastScale);\n if (diff < 0.25 || image.priority) {\n const otherImage = this.images.pop();\n if (otherImage && (otherImage instanceof SingleImage || otherImage.priority)) {\n if (image.priority) {\n this.images.push(image);\n }\n this.images.push(otherImage);\n } else {\n if (image) {\n this.images.push(image);\n }\n }\n } else {\n if (image) {\n this.images.push(image);\n }\n }\n\n lastScale = image.display.scale;\n }\n\n if (this.images.length === 0) {\n // Workaround for bad filtering.\n this.images = [...this.allImages];\n }\n\n this.scaleFactors = this.images.map((singleImage) => singleImage.display.scale);\n this.maxScaleFactor = this.scaleFactors.length ? Math.max(...this.scaleFactors) : 0;\n };\n\n loadFullResource = async () => {\n if (this.isFullyLoaded || this.isLoadingFullResource) {\n return;\n }\n if (this.lazyLoader) {\n this.isLoadingFullResource = true;\n try {\n const newImages = await this.lazyLoader();\n this.addImages(newImages || []);\n this.isFullyLoaded = true;\n } finally {\n this.isLoadingFullResource = false;\n }\n }\n };\n\n fallback = [this.loadFullResource];\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => Promise<void>> {\n if (this._scheduleSortByScales) {\n return [this._sortByScales] as any[];\n }\n if (this.isFullyLoaded) {\n return [];\n }\n if (scaleFactor > 1 / this.maxScaleFactor) {\n return this.fallback;\n }\n return [];\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n if (this.images.length === 0) {\n return [];\n }\n\n const devicePixelRatio =\n this.renderOptions.useDevicePixelRatio && typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n const bestIndex = bestResourceIndexAtRatio(\n 1 / (scale || 1) / devicePixelRatio,\n this.images,\n this.renderOptions.quality\n );\n\n const len = this.images.length;\n const newAggregate = aggregate ? compose(aggregate, translate(this.x, this.y)) : translate(this.x, this.y);\n\n let toPaintIdx: number[] = [bestIndex];\n if (bestIndex !== this.images.length - 1 && this.images[bestIndex + 1]) {\n toPaintIdx = [];\n for (let i = len - 1; i >= bestIndex; i--) {\n toPaintIdx.push(i);\n }\n const smallestIdx = toPaintIdx[0];\n if (this.renderOptions.renderLayers) {\n toPaintIdx = toPaintIdx.slice(-Math.min(toPaintIdx.length, this.renderOptions.renderLayers));\n }\n\n if (this.renderOptions.renderSmallestFallback && toPaintIdx.indexOf(smallestIdx) === -1) {\n toPaintIdx.unshift(smallestIdx);\n }\n }\n\n toPaintIdx.sort((a, b) => {\n const aImage = this.images[a];\n const bImage = this.images[b];\n const aScale = aImage ? aImage.display.scale : 0;\n const bScale = bImage ? bImage.display.scale : 0;\n // Larger display scale is lower quality, and should paint/load first as fallback.\n return bScale - aScale;\n });\n\n const active = new Set<number>();\n switch (this.renderOptions.layerPolicy) {\n case 'always-blend':\n for (const idx of toPaintIdx) {\n active.add(idx);\n }\n break;\n case 'active-only':\n active.add(bestIndex);\n toPaintIdx = [bestIndex];\n break;\n case 'fallback-only':\n default:\n active.add(bestIndex);\n if (this.renderOptions.renderSmallestFallback && toPaintIdx.length) {\n active.add(toPaintIdx[0]);\n }\n break;\n }\n\n const activeImages = new Set<SpacialContent>();\n for (const idx of active) {\n const image = this.images[idx];\n if (image) {\n activeImages.add(image);\n }\n }\n\n this.layerSelectionFrame += 1;\n const now = this.getNow();\n const initialActivatedAt = now - Math.max(0, this.renderOptions.fadeInMs);\n for (const image of this.allImages) {\n const previous = this.layerSelection.get(image);\n const isActive = activeImages.has(image);\n if (!isActive) {\n this.layerSelection.set(image, {\n active: false,\n frame: this.layerSelectionFrame,\n });\n continue;\n }\n\n const hadPreviousFrame = !!previous && previous.frame === this.layerSelectionFrame - 1;\n const wasActive = hadPreviousFrame && previous.active;\n this.layerSelection.set(image, {\n active: true,\n frame: this.layerSelectionFrame,\n activatedAt:\n wasActive && typeof previous.activatedAt === 'number'\n ? previous.activatedAt\n : hadPreviousFrame\n ? now\n : initialActivatedAt,\n });\n }\n\n const toPaint = [];\n for (let i = 0; i < toPaintIdx.length; i++) {\n const idx = toPaintIdx[i];\n const image = this.images[idx];\n toPaint.push(...image.getAllPointsAt(target, newAggregate, scale));\n }\n\n return toPaint;\n }\n\n isImageActive(image: SpacialContent): boolean {\n const selected = this.layerSelection.get(image);\n return !!selected && selected.frame === this.layerSelectionFrame && selected.active;\n }\n\n getImageActivatedAt(image: SpacialContent): number | undefined {\n const selected = this.layerSelection.get(image);\n if (!selected || selected.frame !== this.layerSelectionFrame || !selected.active) {\n return undefined;\n }\n return selected.activatedAt;\n }\n\n private getNow(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n }\n}\n","import { SpacialContent } from './spacial-content';\nimport { DisplayData } from '../types';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { Paint } from '../world-objects/paint';\nimport { BaseObject } from '../objects/base-object';\n\nexport type UpdateTextureFunction = () => { source: TexImageSource | undefined; hash: any };\n\nexport type ImageTextureProps = {\n id: string;\n display?: { width: number; height: number };\n target: { width: number; height: number };\n scale?: number;\n getTexture: UpdateTextureFunction;\n};\n\nexport class ImageTexture extends BaseObject implements SpacialContent {\n readonly type = 'spacial-content';\n id: string;\n uri: string;\n display: DisplayData;\n points: Strand;\n getTexture: UpdateTextureFunction;\n\n constructor(data?: { id?: string; uri: string; width: number; height: number; scale?: number }) {\n super();\n\n this.getTexture = () => {\n // no-op\n return { source: undefined, hash: -1 };\n };\n\n if (!data) {\n this.id = '';\n this.uri = '';\n this.display = { x: 0, y: 0, scale: 1, width: 0, height: 0, points: dna(5) };\n this.points = dna(5);\n } else {\n const scale = data.scale || 1;\n this.id = data.id || data.uri;\n this.uri = data.uri;\n this.points = DnaFactory.singleBox(data.width, data.height);\n\n this.display = {\n x: 0,\n y: 0,\n scale: scale,\n width: data.width / scale,\n height: data.height / scale,\n points: scale !== 1 ? DnaFactory.singleBox(data.width / scale, data.height / scale) : this.points,\n };\n }\n }\n\n applyProps(props: ImageTextureProps) {\n const width = props.display ? props.display.width : props.target.width;\n const scale = props.target.width / width;\n\n this.id = props.id;\n this.points.set(DnaFactory.singleBox(props.target.width, props.target.height));\n\n this.display.scale = scale;\n this.display.width = props.target.width / scale;\n this.display.height = props.target.height / scale;\n this.getTexture = props.getTexture;\n this.display.points =\n scale !== 1 ? DnaFactory.singleBox(props.target.width / scale, props.target.height / scale) : this.points;\n }\n\n getAllPointsAt(target: Strand, aggregate?: Strand, scale?: number): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n}\n","import type { LngLatPoint, MapBounds, MapProjection, WorldPoint, WorldRect } from './types';\n\nexport const MAX_MERCATOR_LATITUDE = 85.05112878;\n\nfunction assertFiniteNumber(value: number, label: string): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${label} must be a finite number`);\n }\n}\n\nfunction assertPositiveNumber(value: number, label: string): void {\n assertFiniteNumber(value, label);\n if (value <= 0) {\n throw new Error(`${label} must be greater than 0`);\n }\n}\n\nexport function clampMercatorLatitude(lat: number): number {\n if (!Number.isFinite(lat)) {\n throw new Error('Latitude must be a finite number');\n }\n if (lat > MAX_MERCATOR_LATITUDE) {\n return MAX_MERCATOR_LATITUDE;\n }\n if (lat < -MAX_MERCATOR_LATITUDE) {\n return -MAX_MERCATOR_LATITUDE;\n }\n return lat;\n}\n\nexport function validateMapBounds(bounds: MapBounds): MapBounds {\n assertFiniteNumber(bounds.west, 'Map bounds west');\n assertFiniteNumber(bounds.south, 'Map bounds south');\n assertFiniteNumber(bounds.east, 'Map bounds east');\n assertFiniteNumber(bounds.north, 'Map bounds north');\n\n if (bounds.west < -180 || bounds.west > 180) {\n throw new Error('Map bounds west must be within [-180, 180]');\n }\n if (bounds.east < -180 || bounds.east > 180) {\n throw new Error('Map bounds east must be within [-180, 180]');\n }\n if (bounds.south < -90 || bounds.south > 90) {\n throw new Error('Map bounds south must be within [-90, 90]');\n }\n if (bounds.north < -90 || bounds.north > 90) {\n throw new Error('Map bounds north must be within [-90, 90]');\n }\n\n if (bounds.west >= bounds.east) {\n throw new Error('Map bounds must satisfy west < east (antimeridian crossing is not supported)');\n }\n\n if (bounds.south >= bounds.north) {\n throw new Error('Map bounds must satisfy south < north');\n }\n\n return bounds;\n}\n\nexport function longitudeToMercatorX(lng: number): number {\n if (!Number.isFinite(lng)) {\n throw new Error('Longitude must be a finite number');\n }\n return (lng + 180) / 360;\n}\n\nexport function latitudeToMercatorY(lat: number): number {\n const clamped = clampMercatorLatitude(lat);\n const radians = (clamped * Math.PI) / 180;\n return (1 - Math.log(Math.tan(radians) + 1 / Math.cos(radians)) / Math.PI) / 2;\n}\n\nexport function mercatorXToLongitude(x: number): number {\n if (!Number.isFinite(x)) {\n throw new Error('Mercator X must be a finite number');\n }\n return x * 360 - 180;\n}\n\nexport function mercatorYToLatitude(y: number): number {\n if (!Number.isFinite(y)) {\n throw new Error('Mercator Y must be a finite number');\n }\n const n = Math.PI * (1 - 2 * y);\n return (180 / Math.PI) * Math.atan(Math.sinh(n));\n}\n\nexport function lngToTileX(lng: number, zoom: number): number {\n return longitudeToMercatorX(lng) * Math.pow(2, zoom);\n}\n\nexport function latToTileY(lat: number, zoom: number): number {\n return latitudeToMercatorY(lat) * Math.pow(2, zoom);\n}\n\nexport function tileXToLng(tileX: number, zoom: number): number {\n return mercatorXToLongitude(tileX / Math.pow(2, zoom));\n}\n\nexport function tileYToLat(tileY: number, zoom: number): number {\n return mercatorYToLatitude(tileY / Math.pow(2, zoom));\n}\n\nexport function createMapProjection(config: { bounds: MapBounds; width: number; height: number }): MapProjection {\n const bounds = validateMapBounds(config.bounds);\n assertPositiveNumber(config.width, 'Map world width');\n assertPositiveNumber(config.height, 'Map world height');\n\n const westX = longitudeToMercatorX(bounds.west);\n const eastX = longitudeToMercatorX(bounds.east);\n const northY = latitudeToMercatorY(bounds.north);\n const southY = latitudeToMercatorY(bounds.south);\n\n const widthMercator = eastX - westX;\n const heightMercator = southY - northY;\n\n if (!(widthMercator > 0)) {\n throw new Error('Map bounds produce an invalid mercator X span');\n }\n if (!(heightMercator > 0)) {\n throw new Error('Map bounds produce an invalid mercator Y span');\n }\n\n const lngLatToWorld = (lng: number, lat: number): WorldPoint => {\n const xNorm = longitudeToMercatorX(lng);\n const yNorm = latitudeToMercatorY(lat);\n return {\n x: ((xNorm - westX) / widthMercator) * config.width,\n y: ((yNorm - northY) / heightMercator) * config.height,\n };\n };\n\n const worldToLngLat = (x: number, y: number): LngLatPoint => {\n assertFiniteNumber(x, 'World x');\n assertFiniteNumber(y, 'World y');\n\n const xNorm = westX + (x / config.width) * widthMercator;\n const yNorm = northY + (y / config.height) * heightMercator;\n\n return {\n lng: mercatorXToLongitude(xNorm),\n lat: mercatorYToLatitude(yNorm),\n };\n };\n\n const lngLatBoundsToWorldRect = (boundsToProject: MapBounds): WorldRect => {\n validateMapBounds(boundsToProject);\n\n const northWest = lngLatToWorld(boundsToProject.west, boundsToProject.north);\n const southEast = lngLatToWorld(boundsToProject.east, boundsToProject.south);\n\n return {\n x: northWest.x,\n y: northWest.y,\n width: southEast.x - northWest.x,\n height: southEast.y - northWest.y,\n };\n };\n\n const worldRectToLngLatBounds = (rect: WorldRect): MapBounds => {\n assertFiniteNumber(rect.x, 'World rect x');\n assertFiniteNumber(rect.y, 'World rect y');\n assertFiniteNumber(rect.width, 'World rect width');\n assertFiniteNumber(rect.height, 'World rect height');\n\n const northWest = worldToLngLat(rect.x, rect.y);\n const southEast = worldToLngLat(rect.x + rect.width, rect.y + rect.height);\n\n return {\n west: northWest.lng,\n south: southEast.lat,\n east: southEast.lng,\n north: northWest.lat,\n };\n };\n\n const projectRing = (ring: Array<[number, number]>): Array<[number, number]> => {\n const projected: Array<[number, number]> = [];\n for (const [lng, lat] of ring) {\n const world = lngLatToWorld(lng, lat);\n projected.push([world.x, world.y]);\n }\n return projected;\n };\n\n return {\n lngLatToWorld,\n worldToLngLat,\n lngLatBoundsToWorldRect,\n worldRectToLngLatBounds,\n projectRing,\n };\n}\n","import type { MapTileSource, MapTileUrlContext } from './types';\n\nexport const DEFAULT_OSM_TILE_TEMPLATE = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';\n\nexport function getSubdomainForTile(ctx: MapTileUrlContext): string | undefined {\n if (ctx.s) {\n return ctx.s;\n }\n\n const subdomains = ctx.subdomains || [];\n if (subdomains.length === 0) {\n return undefined;\n }\n\n const index = Math.abs(ctx.x + ctx.y + ctx.z) % subdomains.length;\n return subdomains[index];\n}\n\nexport function resolveTileTemplate(template: string, ctx: MapTileUrlContext): string {\n const subdomain = getSubdomainForTile(ctx) || '';\n\n return template\n .replace(/\\{z\\}/g, `${ctx.z}`)\n .replace(/\\{x\\}/g, `${ctx.x}`)\n .replace(/\\{y\\}/g, `${ctx.y}`)\n .replace(/\\{s\\}/g, subdomain);\n}\n\nexport function resolveTileUrl(source: MapTileSource | undefined, ctx: MapTileUrlContext): string {\n const resolvedSource = source || DEFAULT_OSM_TILE_TEMPLATE;\n if (typeof resolvedSource === 'function') {\n return resolvedSource(ctx);\n }\n return resolveTileTemplate(resolvedSource, ctx);\n}\n","import { dna, type Strand } from '@atlas-viewer/dna';\nimport {\n createMapProjection,\n latToTileY,\n lngToTileX,\n tileXToLng,\n tileYToLat,\n validateMapBounds,\n} from '../modules/maps/projection';\nimport { DEFAULT_OSM_TILE_TEMPLATE, resolveTileUrl } from '../modules/maps/tile-source';\nimport type { MapBounds, MapTileSource } from '../modules/maps/types';\nimport { TiledImage } from './tiled-image';\n\nexport type MapTileCoordinate = {\n x: number;\n y: number;\n z: number;\n};\n\nexport type MapTileGrid = {\n points: Strand;\n tiles: MapTileCoordinate[];\n columns: number;\n rows: number;\n count: number;\n minTileX: number;\n maxTileX: number;\n minTileY: number;\n maxTileY: number;\n};\n\nexport type MapTileGridCoverage = Omit<MapTileGrid, 'points' | 'tiles'> & {\n westTile: number;\n eastTile: number;\n northTile: number;\n southTile: number;\n tileSpanX: number;\n tileSpanY: number;\n};\n\nexport type MapTiledImageProps = {\n id?: string;\n bounds: MapBounds;\n worldWidth: number;\n worldHeight: number;\n zoom: number;\n tileSize?: number;\n scaleFactor?: number;\n tileSource?: MapTileSource;\n tileUrlTemplate?: string;\n subdomains?: string[];\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function estimateFiniteTileGridCoverage(config: { bounds: MapBounds; zoom: number }): MapTileGridCoverage {\n validateMapBounds(config.bounds);\n\n const zoom = Math.max(0, Math.floor(config.zoom));\n const zoomSize = 2 ** zoom;\n const maxTileIndex = zoomSize - 1;\n\n const westTileFloat = lngToTileX(config.bounds.west, zoom);\n const eastTileFloat = lngToTileX(config.bounds.east, zoom);\n const northTileFloat = latToTileY(config.bounds.north, zoom);\n const southTileFloat = latToTileY(config.bounds.south, zoom);\n\n const westTile = clamp(westTileFloat, 0, zoomSize);\n const eastTile = clamp(eastTileFloat, 0, zoomSize);\n const northTile = clamp(northTileFloat, 0, zoomSize);\n const southTile = clamp(southTileFloat, 0, zoomSize);\n\n // Fractional span represents true source-pixel coverage for the target bounds.\n const tileSpanX = Math.max(1e-9, eastTile - westTile);\n const tileSpanY = Math.max(1e-9, southTile - northTile);\n\n const minTileX = clamp(Math.floor(westTileFloat), 0, maxTileIndex);\n const maxTileX = clamp(Math.ceil(eastTileFloat) - 1, 0, maxTileIndex);\n const minTileY = clamp(Math.floor(northTileFloat), 0, maxTileIndex);\n const maxTileY = clamp(Math.ceil(southTileFloat) - 1, 0, maxTileIndex);\n\n const columns = Math.max(1, maxTileX - minTileX + 1);\n const rows = Math.max(1, maxTileY - minTileY + 1);\n return {\n columns,\n rows,\n count: columns * rows,\n minTileX,\n maxTileX,\n minTileY,\n maxTileY,\n westTile,\n eastTile,\n northTile,\n southTile,\n tileSpanX,\n tileSpanY,\n };\n}\n\nexport function createFiniteTileGrid(config: {\n bounds: MapBounds;\n zoom: number;\n worldWidth: number;\n worldHeight: number;\n maxTiles?: number;\n}): MapTileGrid {\n validateMapBounds(config.bounds);\n\n const zoom = Math.max(0, Math.floor(config.zoom));\n const projection = createMapProjection({\n bounds: config.bounds,\n width: config.worldWidth,\n height: config.worldHeight,\n });\n\n const coverage = estimateFiniteTileGridCoverage({\n bounds: config.bounds,\n zoom,\n });\n const maxTiles = typeof config.maxTiles === 'number' ? config.maxTiles : Number.POSITIVE_INFINITY;\n if (coverage.count > maxTiles) {\n throw new Error(\n `Map tile grid too large at zoom ${zoom}: ${coverage.count} tiles exceeds the configured max (${maxTiles})`\n );\n }\n\n const points: number[] = [];\n const tiles: MapTileCoordinate[] = [];\n\n for (let tileY = coverage.minTileY; tileY <= coverage.maxTileY; tileY++) {\n for (let tileX = coverage.minTileX; tileX <= coverage.maxTileX; tileX++) {\n const tileWestLng = tileXToLng(tileX, zoom);\n const tileEastLng = tileXToLng(tileX + 1, zoom);\n const tileNorthLat = tileYToLat(tileY, zoom);\n const tileSouthLat = tileYToLat(tileY + 1, zoom);\n\n const northWest = projection.lngLatToWorld(tileWestLng, tileNorthLat);\n const southEast = projection.lngLatToWorld(tileEastLng, tileSouthLat);\n\n points.push(1, northWest.x, northWest.y, southEast.x, southEast.y);\n tiles.push({ x: tileX, y: tileY, z: zoom });\n }\n }\n\n return {\n points: dna(points.length ? points : [0]),\n tiles,\n columns: coverage.columns,\n rows: coverage.rows,\n count: coverage.count,\n minTileX: coverage.minTileX,\n maxTileX: coverage.maxTileX,\n minTileY: coverage.minTileY,\n maxTileY: coverage.maxTileY,\n };\n}\n\nexport class MapTiledImage extends TiledImage {\n readonly zoom: number;\n readonly bounds: MapBounds;\n readonly worldWidth: number;\n readonly worldHeight: number;\n readonly tileSize: number;\n readonly tileSource: MapTileSource;\n readonly subdomains: string[];\n readonly tileCoordinates: MapTileCoordinate[];\n readonly minTileX: number;\n readonly maxTileX: number;\n readonly minTileY: number;\n readonly maxTileY: number;\n\n constructor(props: MapTiledImageProps) {\n const scaleFactor = props.scaleFactor || 1;\n const tileSize = props.tileSize || 256;\n const tileSource = props.tileSource || props.tileUrlTemplate || DEFAULT_OSM_TILE_TEMPLATE;\n const grid = createFiniteTileGrid({\n bounds: props.bounds,\n zoom: props.zoom,\n worldWidth: props.worldWidth,\n worldHeight: props.worldHeight,\n });\n\n const id =\n props.id ||\n `map-tiled-image-z${props.zoom}-${props.worldWidth}x${props.worldHeight}-${grid.minTileX}:${grid.maxTileX}-${grid.minTileY}:${grid.maxTileY}`;\n\n super({\n id,\n url: 'map://tile-source',\n scaleFactor,\n points: grid.points,\n displayPoints: grid.points,\n tileWidth: tileSize,\n tileHeight: tileSize,\n width: props.worldWidth,\n height: props.worldHeight,\n columns: grid.columns,\n rows: grid.rows,\n format: 'png',\n version3: false,\n });\n\n this.zoom = Math.max(0, Math.floor(props.zoom));\n this.bounds = { ...props.bounds };\n this.worldWidth = props.worldWidth;\n this.worldHeight = props.worldHeight;\n this.tileSize = tileSize;\n this.tileSource = tileSource;\n this.subdomains = [...(props.subdomains || [])];\n this.tileCoordinates = grid.tiles;\n this.minTileX = grid.minTileX;\n this.maxTileX = grid.maxTileX;\n this.minTileY = grid.minTileY;\n this.maxTileY = grid.maxTileY;\n }\n\n getImageUrl(index: number): string {\n const tile = this.tileCoordinates[index];\n if (!tile) {\n return '';\n }\n\n return resolveTileUrl(this.tileSource, {\n z: tile.z,\n x: tile.x,\n y: tile.y,\n tileSize: this.tileSize,\n subdomains: this.subdomains,\n });\n }\n}\n","import { Paint, ZoneInterface } from '../../world-objects';\nimport { World } from '../../world';\nimport { SingleImage, SpacialContent } from '../../spacial-content';\nimport { Renderer } from '../../renderer/renderer';\nimport { PositionPair } from '../../types';\nimport { dna, DnaFactory, scale, Strand } from '@atlas-viewer/dna';\n\nexport class DebugRenderer implements Renderer {\n canvas: HTMLCanvasElement;\n context: CanvasRenderingContext2D;\n heightRatio = 1;\n widthRatio = 1;\n target: Float32Array = new Float32Array(5);\n\n initialWidth: number;\n initialHeight: number;\n bounds: Strand | undefined;\n aggregate: Strand;\n delta = 0;\n renderNextFrame = true;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n this.initialWidth = canvas.width;\n this.initialHeight = canvas.height;\n this.context = canvas.getContext('2d') as CanvasRenderingContext2D;\n this.context.globalAlpha = 0.5;\n this.aggregate = scale(1);\n\n // const ratio = window.devicePixelRatio || 1;\n // this.canvas.width = canvas.width * ratio;\n // this.canvas.height = canvas.height * ratio;\n // this.canvas.style.width = canvas.width + 'px';\n // this.canvas.style.height = canvas.height + 'px';\n // this.canvas.getContext('2d')?.scale(ratio, ratio);\n }\n\n isReady(): boolean {\n return true;\n }\n\n resize() {\n this.initialWidth = this.canvas.width;\n this.initialHeight = this.canvas.height;\n this.renderNextFrame = true;\n }\n\n afterFrame(world: World, delta: number, target: Float32Array) {\n // Everything in this debugger happens at the end of the render cycle.\n // This debugger is made to be hacked and changed as needed, so some\n // variables are set up as a convenience.\n // First we clear.\n\n if (this.renderNextFrame) {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n // We figure out the size of the debugger in relation to the world.\n const widthRatio = this.initialWidth / world.width;\n const heightRatio = this.initialHeight / world.height;\n\n const ratio = this.widthRatio > this.heightRatio ? widthRatio : heightRatio;\n // this.canvas.height = world.height * ratio;\n // this.canvas.width = world.width * ratio;\n\n // If it needs to be used in other methods, it can be.\n this.target = target;\n\n if (this.bounds) {\n const points = world.getPointsAt(this.bounds, this.aggregate, ratio);\n for (const [paint, point] of points) {\n if (paint instanceof SingleImage) {\n if (paint.__host.canvas) {\n const total = point.length / 5;\n for (let i = 0; i < total; i++) {\n const toPaint = paint.__host.canvas.canvases[i];\n if (toPaint) {\n const toDraw = {\n x1: point[i + 1] * ratio,\n y1: point[i + 2] * ratio,\n width: (point[i + 3] - point[i + 1]) * ratio,\n height: (point[i + 4] - point[i + 2]) * ratio,\n };\n\n // this.context.drawImage(toPaint, toDraw.x1, toDraw.y1, toDraw.width, toDraw.height);\n }\n }\n }\n }\n }\n }\n\n // Get every point on the world, that is laying out the world items, but\n // not the images that make up the world items. (i.e. canvas dimensions and\n // their positions)\n world.getPoints().forEach((v, k, arr) => {\n // Technically not needed, but some might have been hidden.\n // Could make these a different border.\n if (k % 5 === 0 && v) {\n // Descriptive drawing object, doesn't need to be fast.\n // We are not using all of these fields.\n const toDraw = {\n x1: arr[k + 1] * ratio,\n y1: arr[k + 2] * ratio,\n x2: arr[k + 3] * ratio,\n y2: arr[k + 4] * ratio,\n width: (arr[k + 3] - arr[k + 1]) * ratio,\n height: (arr[k + 4] - arr[k + 2]) * ratio,\n };\n\n // World items are red bordered boxes.\n this.context.strokeStyle = 'red';\n this.context.strokeRect(toDraw.x1, toDraw.y1, toDraw.width, toDraw.height);\n }\n });\n\n // If there's a viewport attached, we can render that too\n // There may not be a target, if someone is just debugging a world.\n if (target) {\n // This will be a green box.\n this.context.strokeStyle = 'red';\n this.context.lineWidth = window.devicePixelRatio || 1;\n this.context.strokeRect(\n target[1] * ratio,\n target[2] * ratio,\n (target[3] - target[1]) * ratio,\n (target[4] - target[2]) * ratio\n );\n }\n }\n }\n\n getActiveZone(world: World): ZoneInterface | null {\n return null;\n }\n\n getPointsAt(world: World, target: Float32Array, aggregate: Float32Array, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n return 1;\n }\n\n beforeFrame(world: World, delta: number) {\n // no op.\n this.bounds = DnaFactory.singleBox(world.width, world.height);\n }\n\n drawImage() {\n // no op.\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Float32Array): void {\n // paint.\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n // paint.\n this.renderNextFrame = true;\n }\n\n prepareLayer(paint: SpacialContent): void {\n // prepare\n }\n\n pendingUpdate(): boolean {\n // change this to true if you want to render every frame.\n return false;\n }\n\n hasActiveZone(): boolean {\n return false;\n }\n\n getViewportBounds(world: World, target: Float32Array, padding: number): PositionPair | null {\n return null;\n }\n\n getRendererScreenPosition() {\n return this.canvas.getBoundingClientRect();\n }\n\n finishLayer() {}\n reset() {}\n}\n","import { Paint, Paintable } from './paint';\nimport { AbstractObject } from './abstract-object';\nimport {\n Strand,\n dna,\n compose,\n getIntersection,\n scale,\n transform,\n translate,\n hidePointsOutsideRegion,\n} from '@atlas-viewer/dna';\nimport { BaseObject } from '../objects/base-object';\nimport { SpacialContent } from '../spacial-content';\nimport { Geometry } from '../objects/geometry';\n\nfunction rotate(cx: number, cy: number, x: number, y: number, angle: number) {\n const radians = (Math.PI / 180) * angle,\n cos = Math.cos(radians),\n sin = Math.sin(radians),\n nx = cos * (x - cx) + sin * (y - cy) + cx,\n ny = cos * (y - cy) - sin * (x - cx) + cy;\n return [nx, ny];\n}\n\ntype WorldObjectProps = {\n id: string;\n width: number;\n height: number;\n scale?: number;\n x?: number;\n y?: number;\n rotation?: number;\n};\n\nexport class WorldObject extends BaseObject<WorldObjectProps, Paintable> {\n id: string;\n type = 'world-object';\n scale: number;\n layers: Paintable[];\n\n /**\n * This position in the world local to the scale of the object.\n * So a 1000x1000 drawn at 0.1 scale at x=5, y=10 on the world would have world points 50,100,1000,1000\n *\n * To get it's world-relative position you need to multiple the scale out.\n */\n points: Strand;\n\n /**\n * These are relative to where to object is in the world at the scale of the world.\n * So a 1000x1000 drawn at 0.1 scale at x=5, y=10 on the world would have world points 0,0,100,100\n */\n worldPoints: Strand;\n\n intersectionBuffer = dna(5);\n aggregateBuffer = dna(9);\n invertedBuffer = dna(9);\n rotation = 0;\n filteredPointsBuffer: Strand;\n _updatedList: any[] = [];\n geometry?: any;\n\n constructor(props?: AbstractObject, position?: { x: number; y: number }) {\n super();\n const { x = 0, y = 0 } = position || {};\n\n if (!props) {\n this.id = '';\n this.scale = 1;\n this.layers = [];\n this.points = dna(5);\n this.worldPoints = dna(5);\n this.filteredPointsBuffer = dna(5);\n } else {\n // @deprecated.\n this.id = props.id || '';\n this.scale = 1;\n this.layers = props.layers;\n\n this.points = dna([1, x, y, x + props.width, y + props.height]);\n this.worldPoints = dna([1, x, y, x + props.width, y + props.height]);\n this.filteredPointsBuffer = dna(props.layers.length * 5);\n }\n }\n\n static createWithProps(props: WorldObjectProps) {\n const instance = new WorldObject();\n instance.applyProps(props);\n return instance;\n }\n\n applyProps(props: WorldObjectProps) {\n const x = props.x || 0;\n const y = props.y || 0;\n\n if (typeof props.id !== 'undefined') {\n this.id = props.id;\n }\n const s = typeof props.scale !== 'undefined' ? props.scale : this.scale;\n\n this.points[0] = 1;\n this.points[1] = x;\n this.points[2] = y;\n this.points[3] = x + props.width;\n this.points[4] = y + props.height;\n this.rotation = props.rotation || 0;\n\n this.worldPoints[3] = this.worldPoints[1] + props.width;\n this.worldPoints[4] = this.worldPoints[2] + props.height;\n\n if (props.scale && props.scale !== 1) {\n this.atScale(s);\n }\n\n this.scale = s;\n\n // @todo this will be a bit tricky as we have to use the translate\n // function to update the props. It will be a case of checking\n // the props, and applying the difference. x = 2 => 3 = (x + 1)\n // For the reconciler, we could also give access to the bare transforms\n // Although that might be painful as the props would be out of sync.\n }\n\n appendChild(item: Paintable) {\n // Not set manually.\n if (item.points[0] === 0) {\n item.points.set(this.points);\n }\n item.__owner.value = this;\n\n this.addLayers([item]);\n }\n\n removeChild(item: Paintable) {\n this.layers = this.layers.filter((layer) => layer !== item);\n this.filteredPointsBuffer = dna(this.layers.length * 5);\n }\n\n insertBefore(item: Paintable, before: Paintable) {\n const index = this.layers.indexOf(before);\n if (index === -1) {\n return;\n }\n if (this.layers.indexOf(item) !== -1) {\n return;\n }\n\n // const beforeLayers = this.layers.slice(0, index - 1);\n const beforeLayers = this.layers.slice(0, index);\n const afterLayers = this.layers.slice(index);\n\n this.layers = [...beforeLayers, item, ...afterLayers];\n }\n\n hideInstance() {\n console.warn('hideInstance: not yet implemented');\n }\n\n getObjectsAt(target: Strand, all?: boolean): Paintable[] {\n if (this.rotation) {\n target = this.applyRotation(target);\n }\n\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n if (filteredPoints[0] === 0) {\n return [];\n }\n\n const len = this.layers.length;\n const objects: Paintable[] = [];\n for (let index = 0; index < len; index++) {\n const layer = this.layers[index] as SpacialContent | WorldObject;\n\n if (all && (layer as Geometry).isShape) {\n const t = transform(layer.points, translate(this.x, this.y));\n const int = (layer as Geometry).intersects([target[1] - t[1], target[2] - t[2]]);\n if (!int) continue;\n }\n\n const filter = hidePointsOutsideRegion(\n transform(layer.points, translate(this.x, this.y)),\n target,\n this.filteredPointsBuffer\n );\n\n if (filter[0] !== 0) {\n objects.push(layer as SpacialContent);\n }\n\n if (all) {\n const object = layer as WorldObject;\n objects.push(...object.getObjectsAt(target, all));\n }\n }\n return objects;\n }\n\n applyRotation(target: Strand) {\n if (this.rotation) {\n const a = { x: target[1], y: target[2] };\n const b = { x: target[1], y: target[4] };\n const c = { x: target[3], y: target[2] };\n const d = { x: target[3], y: target[4] };\n\n const x = this.points[1] + (this.points[3] - this.points[1]) / 2;\n const y = this.points[2] + (this.points[4] - this.points[2]) / 2;\n\n const [x1, y1] = rotate(x, y, a.x, a.y, this.rotation);\n const [x2, y2] = rotate(x, y, b.x, b.y, this.rotation);\n const [x3, y3] = rotate(x, y, c.x, c.y, this.rotation);\n const [x4, y4] = rotate(x, y, d.x, d.y, this.rotation);\n\n const rx1 = Math.min(x1, x2, x3, x4);\n const rx2 = Math.max(x1, x2, x3, x4);\n const ry1 = Math.min(y1, y2, y3, y4);\n const ry2 = Math.max(y1, y2, y3, y4);\n\n return dna([target[0], rx1, ry1, rx2, ry2]);\n }\n return target;\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n const transformer = compose(translate(this.x, this.y), scale(this.scale), this.aggregateBuffer);\n\n if (this.rotation) {\n target = this.applyRotation(target);\n }\n\n const inter = getIntersection(target, this.points, this.intersectionBuffer);\n const len = this.layers.length;\n const arr: Paint[] = [];\n\n const t = transform(inter, compose(scale(1 / this.scale), translate(-this.x, -this.y), this.invertedBuffer));\n const agg = aggregate ? compose(aggregate, transformer, this.aggregateBuffer) : transformer;\n const s = scaleFactor * this.scale;\n\n for (let i = 0; i < len; i++) {\n // Crop intersection.\n arr.push(...this.layers[i].getAllPointsAt(t, agg, s));\n }\n return arr;\n }\n\n addLayers(paintables: Paintable[]) {\n const paintablesToAdd = [];\n for (const paintable of paintables) {\n if (this.layers.indexOf(paintable) !== -1) {\n continue;\n }\n paintablesToAdd.push(paintable);\n // Check for crop.\n if (\n paintable.points.length === 5 &&\n // Paint.x < 0\n (paintable.points[1] < this.worldPoints[1] / this.scale ||\n // Paint.y < 0\n paintable.points[2] < this.worldPoints[2] / this.scale ||\n // Paint.width > this.width\n paintable.points[3] > this.worldPoints[3] / this.scale ||\n // Paint.height > this.height\n paintable.points[4] > this.worldPoints[4] / this.scale)\n ) {\n // @todo support for tiled crops.\n paintable.crop =\n paintable.crop ||\n dna([\n 1,\n Math.max(this.worldPoints[1] / this.scale, paintable.points[1]),\n Math.max(this.worldPoints[2] / this.scale, paintable.points[2]),\n Math.min(this.worldPoints[3] / this.scale, paintable.points[3]),\n Math.min(this.worldPoints[4] / this.scale, paintable.points[4]),\n ]);\n }\n }\n\n this.layers = this.layers.concat(paintablesToAdd);\n\n this.filteredPointsBuffer = dna(this.layers.length * 5);\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n const len = this.layers.length;\n this._updatedList = [];\n const s = scaleFactor * this.scale;\n for (let i = 0; i < len; i++) {\n const updates = this.layers[i].getScheduledUpdates(target, s);\n if (updates) {\n this._updatedList.push(...updates);\n }\n }\n return this._updatedList;\n }\n}\n","import {\n compose,\n DnaFactory,\n dna,\n dnaLength,\n hidePointsOutsideRegion,\n mutate,\n type Strand,\n scale,\n scaleAtOrigin,\n translate,\n} from '@atlas-viewer/dna';\nimport type { SupportedEvents } from './events';\nimport type { WorldDebugEvent } from './modules/react-reconciler/devtools/types';\nimport { BaseObject } from './objects/base-object';\nimport { Geometry } from './objects/geometry';\nimport type { SpacialContent } from './spacial-content/spacial-content';\nimport type { Viewer, ViewingDirection } from './types';\nimport type { AbstractObject } from './world-objects/abstract-object';\nimport type { Paint, Paintable } from './world-objects/paint';\nimport { WorldObject } from './world-objects/world-object';\nimport type { ZoneInterface } from './world-objects/zone';\n\ntype WorldTarget = { x: number; y: number; width?: number; height?: number };\n\ntype WorldProps = {\n width: number;\n height: number;\n viewingDirection: ViewingDirection;\n};\n\nexport class World extends BaseObject<WorldProps, WorldObject> {\n id = 'world';\n _width: number;\n _height: number;\n aspectRatio: number;\n viewingDirection: ViewingDirection;\n aggregateBuffer = dna(9);\n isDirty = false;\n zones: ZoneInterface[] = [];\n filteredPointsBuffer: Strand;\n selectedZone?: number;\n triggerQueue: Array<[string, any]> = [];\n activatedEvents: string[] = [];\n _updatedList: any[] = [];\n translationBuffer = dna(9);\n needsRecalculate = true;\n emptyPaintables = [];\n renderOrder: number[] = [];\n debugSubscribers = new Set<(event: WorldDebugEvent) => void>();\n zoneVisibilityFadeDurationMs = 220;\n zoneOutsideOpacity = 0.2;\n zoneVisibilityFade?: {\n zoneId: string;\n startedAt: number;\n };\n\n get x(): number {\n return 0;\n }\n get y(): number {\n return 0;\n }\n get width(): number {\n return this._width;\n }\n get height(): number {\n return this._height;\n }\n\n points: Strand;\n\n // These should be the same size.\n private objects: Array<WorldObject | null> = [];\n subscriptions: Array<(type: string, changes?: unknown) => void> = [];\n\n constructor(width = 0, height = 0, worldObjectCount = 100, viewingDirection: ViewingDirection = 'left-to-right') {\n super();\n this._width = width;\n this._height = height;\n this.aspectRatio = Number.isNaN(width / height) ? 1 : width / height;\n this.viewingDirection = viewingDirection;\n this.points = dna(worldObjectCount * 5);\n this.filteredPointsBuffer = dna(worldObjectCount * 5);\n }\n\n static withProps(props: WorldProps) {\n const instance = new World();\n instance.applyProps(props);\n return instance;\n }\n\n applyProps(props: WorldProps) {\n if (\n typeof props.width !== 'undefined' &&\n typeof props.height !== 'undefined' &&\n (props.width !== this._width || props.height !== this._height)\n ) {\n this.resize(props.width, props.height);\n }\n if (props.viewingDirection !== this.viewingDirection) {\n this.viewingDirection = props.viewingDirection;\n this.triggerRepaint();\n }\n }\n\n propagateTouchEvent(eventName: string, e: TouchEvent, touchTargets: Array<{ x: number; y: number }>) {\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n\n const targets = [];\n for (const touch of touchTargets) {\n if (touch.x && touch.y) {\n const point = DnaFactory.singleBox(1, 1, touch.x, touch.y);\n targets.push(this.getObjectsAt(point, true).reverse());\n }\n }\n\n this.emitDebug({\n type: 'touch',\n at: performance.now(),\n event: eventName,\n touches: touchTargets.length,\n });\n\n return targets.map((target) =>\n this.propagateEvent(eventName, e, target, {\n bubbles: true,\n cancelable: true,\n })\n );\n }\n\n propagatePointerEvent<Name extends keyof SupportedEvents>(\n eventName: Name,\n e: any,\n x: number,\n y: number,\n opts: { bubbles?: boolean; cancelable?: boolean } = {}\n ) {\n // @todo re-add activated events, but smarter.\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n const point = DnaFactory.singleBox(1, 1, x, y);\n const worldObjects = this.getObjectsAt(point, true).reverse();\n\n // Here there is more we can handle.\n // - When a move move event is detected:\n // - Handle mouse enter / leave\n // - Handle drag / drag start / drag end / drag-over\n // - When a mouse leave\n // - Reset mouse over items\n // - When a mouse down event is detected:\n // - Store click / clickStart / drag items\n\n const result = this.propagateEvent(eventName, e, worldObjects, opts);\n this.emitDebug({\n type: 'pointer',\n at: performance.now(),\n event: eventName,\n x,\n y,\n targets: result.length,\n });\n\n return result;\n }\n\n _propagateEventTargets: any[] = [];\n propagateEvent(\n eventName: string,\n e: any,\n worldObjects: [WorldObject, SpacialContent[]][],\n { bubbles = false, cancelable = false }: { bubbles?: boolean; cancelable?: boolean } = {}\n ) {\n // @todo re-add activated events, but smarter.\n // if (this.activatedEvents.indexOf(eventName) === -1) return [];\n // Modify event if we need to.\n e.atlasTarget = this;\n\n // Store the stack of targets.\n this._propagateEventTargets.length = 1;\n this._propagateEventTargets[0] = this;\n\n // Set up a stop propagation\n let stopped = false;\n e.stopPropagation = () => {\n stopped = true;\n };\n\n const woLen = worldObjects.length;\n for (let w = woLen - 1; w >= 0; w--) {\n // @todo unsure why this was here.\n // if (w === 1) break;\n this._propagateEventTargets.unshift(worldObjects[w][0]);\n const len = worldObjects[w][1].length;\n if (len) {\n for (let i = 0; i < len; i++) {\n this._propagateEventTargets.unshift(worldObjects[w][1][i]);\n }\n }\n }\n\n const len = this._propagateEventTargets.length;\n let didFire = false;\n for (let i = 0; i < len; i++) {\n e.atlasTarget = this._propagateEventTargets[i];\n e.atlasWorld = this;\n didFire = this._propagateEventTargets[i].dispatchEvent(eventName as any, e) || didFire;\n if (stopped) break;\n }\n\n if (didFire) {\n this.triggerRepaint();\n }\n return this._propagateEventTargets;\n }\n\n appendChild(item: WorldObject) {\n const idx = this.appendWorldObject(item);\n this.renderOrder.push(idx / 5);\n }\n\n removeChild(item: WorldObject) {\n const index = this.objects.indexOf(item);\n\n if (index === -1) {\n for (const obj of this.objects) {\n if (obj && obj.id === item.id) {\n this.removeChild(obj);\n return;\n }\n }\n return;\n }\n\n this.objects[index] = null;\n this.renderOrder = this.renderOrder.filter((t) => t !== index);\n this.points[index * 5] = 0;\n for (const zone of this.zones) {\n const zoneIndex = zone.objects.indexOf(item);\n if (zoneIndex !== -1) {\n zone.objects.splice(zoneIndex, 1);\n zone.recalculateBounds();\n }\n }\n this.triggerRepaint();\n this.needsRecalculate = true;\n }\n\n insertBefore(item: WorldObject, before: WorldObject) {\n const beforeIndex = this.objects.indexOf(before);\n if (beforeIndex === -1) {\n return;\n }\n\n const idx = this.appendWorldObject(item);\n this.renderOrder.splice(beforeIndex - 1, 0, idx / 5);\n }\n\n hideInstance() {\n // not yet implemented.\n // console.warn('hideInstance: Not yet implemented');\n }\n\n asWorldObject(): WorldObject | null {\n // @todo.\n return null;\n }\n\n addZone(zone: ZoneInterface) {\n this.zones.push(zone);\n }\n\n removeZone(zone: ZoneInterface) {\n const index = this.zones.indexOf(zone);\n if (index === -1) {\n return;\n }\n this.zones.splice(index, 1);\n if (typeof this.selectedZone === 'undefined') {\n return;\n }\n if (this.selectedZone === index) {\n this.selectedZone = undefined;\n this.trigger('zone-changed');\n return;\n }\n if (this.selectedZone > index) {\n this.selectedZone -= 1;\n }\n }\n\n getZoneById(id: string): ZoneInterface | undefined {\n for (const zone of this.zones) {\n if (zone.id === id) {\n return zone;\n }\n }\n return undefined;\n }\n\n hasZone(id: string): boolean {\n return typeof this.getZoneById(id) !== 'undefined';\n }\n\n selectZone(id: string | number) {\n if (typeof id === 'string') {\n const zone = this.getZoneById(id);\n if (zone) {\n this.selectedZone = this.zones.indexOf(zone);\n this.zoneVisibilityFade = {\n zoneId: zone.id,\n startedAt: performance.now(),\n };\n this.trigger('zone-changed');\n }\n } else {\n if (this.zones[id]) {\n this.selectedZone = id;\n this.zoneVisibilityFade = {\n zoneId: this.zones[id].id,\n startedAt: performance.now(),\n };\n this.trigger('zone-changed');\n }\n }\n }\n\n deselectZone() {\n this.selectedZone = undefined;\n this.zoneVisibilityFade = undefined;\n this.trigger('zone-changed');\n }\n\n getActiveZone(): ZoneInterface | undefined {\n if (typeof this.selectedZone !== 'undefined') {\n return this.zones[this.selectedZone];\n }\n return undefined;\n }\n\n hasActiveZone(): boolean {\n return typeof this.selectedZone !== 'undefined';\n }\n\n private checkResizeInternalBuffer() {\n if (dnaLength(this.points) === this.objects.length) {\n // resize, doubles each time, @todo change.\n const points = this.points;\n const newPoints = dna(this.points.length * 2);\n newPoints.set(points, 0);\n this.points = newPoints;\n }\n }\n\n appendWorldObject(object: WorldObject) {\n this.checkResizeInternalBuffer();\n\n const index = this.objects.length * 5;\n const pointValues = object.points;\n object.points = this.points.subarray(this.objects.length * 5, this.objects.length * 5 + 5);\n object.points[1] = pointValues[1];\n object.points[2] = pointValues[2];\n object.points[3] = pointValues[3];\n object.points[4] = pointValues[4];\n\n this.objects.push(object);\n this.filteredPointsBuffer = dna(this.objects.length * 5);\n this.needsRecalculate = true;\n\n this.triggerRepaint();\n\n return index;\n }\n\n recalculateWorldSize() {\n let didChange = false;\n if (this.needsRecalculate) {\n const wBuffer = new Int32Array(this.objects.length);\n const hBuffer = new Int32Array(this.objects.length);\n const len = this.renderOrder.length;\n for (let _index = 0; _index < len; _index++) {\n const index = this.renderOrder[_index];\n const object = this.objects[index];\n if (object) {\n wBuffer[_index] = this.points[index * 5 + 3];\n hBuffer[_index] = this.points[index * 5 + 4];\n }\n }\n const newWidth = Math.max(...wBuffer);\n if (newWidth !== this._width) {\n this._width = newWidth;\n didChange = true;\n }\n const newHeight = Math.max(...hBuffer);\n if (newHeight !== this._height) {\n this._height = newHeight;\n didChange = true;\n }\n if (didChange) {\n this.trigger('recalculate-world-size', {\n width: newWidth,\n height: newHeight,\n });\n }\n this.needsRecalculate = false;\n }\n\n return didChange;\n }\n\n /**\n * @deprecated\n */\n addObjectAt(object: AbstractObject, target: WorldTarget): WorldObject {\n // @todo make target optional, default layout management\n // to be applied that will simply line up all of the\n // images in a row. The target is mainly to be used\n // by a builder. Also support adding a world object\n // here, which is itself an abstract object.\n\n if (target.width && !target.height) {\n target.height = (target.width / object.width) * object.height;\n } else if (target.height && !target.width) {\n target.width = (target.height / object.height) * object.width;\n }\n if (!target || !target.width || !target.height) {\n target.width = object.width;\n target.height = object.height;\n }\n\n const { width, x, y } = target;\n\n const scaleFactor = width / object.width;\n\n this.checkResizeInternalBuffer();\n\n // @todo integrity to ensure these remain.\n this.points.set(DnaFactory.singleBox(object.width, object.height, 0, 0), this.objects.length * 5);\n\n const worldObject = new WorldObject(object);\n\n worldObject.points = this.points.subarray(this.objects.length * 5, this.objects.length * 5 + 5);\n // worldObject.atScale(scaleFactor);\n // worldObject.translate(x, y);\n this.objects.push(worldObject);\n this.scaleWorldObject(this.objects.length - 1, scaleFactor);\n this.translateWorldObject(this.objects.length - 1, x, y);\n this.filteredPointsBuffer = dna(this.points.length * 2);\n\n this.triggerRepaint();\n this.needsRecalculate = true;\n\n return worldObject;\n }\n\n scaleWorldObject(index: number, factor: number) {\n mutate(\n this.points.subarray(index * 5, index * 5 + 5),\n scaleAtOrigin(factor, this.points[index * 5 + 1], this.points[index * 5 + 2])\n );\n const obj = this.objects[index];\n if (obj) {\n obj.atScale(factor);\n this.triggerRepaint();\n }\n }\n\n translateWorldObject(index: number, x: number, y: number) {\n mutate(this.points.subarray(index * 5, index * 5 + 5), translate(x, y));\n const obj = this.objects[index];\n if (obj) {\n obj.translate(x, y);\n this.triggerRepaint();\n }\n }\n\n resize(width: number, height: number) {\n this._width = width;\n this._height = height;\n\n this.aspectRatio = width / height;\n\n // @todo what happens when projections are out of bounds?\n // @todo what happens when objects are out of bounds?\n this.triggerRepaint();\n\n return this;\n }\n\n getObjects() {\n return this.objects;\n }\n\n getPoints() {\n return this.points;\n }\n\n getPointsFromViewer(target: Viewer, aggregate?: Strand) {\n const targetPoints = DnaFactory.singleBox(target.width, target.height, target.x, target.y);\n return this.getPointsAt(targetPoints, aggregate, target.scale);\n }\n\n addLayoutSubscriber(subscription: (type: string, data: unknown) => void) {\n this.subscriptions.push(subscription);\n\n return () => {\n this.subscriptions.splice(this.subscriptions.indexOf(subscription), 1);\n };\n }\n\n getScheduledUpdates(target: Strand, scaleFactor: number): Array<() => void | Promise<void>> {\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n\n const len = this.objects.length;\n this._updatedList = [];\n\n for (let index = 0; index < len; index++) {\n if (filteredPoints[index * 5] !== 0) {\n if (!this.objects[index]) continue;\n this._updatedList.push(...(this.objects[index] as WorldObject).getScheduledUpdates(target, scaleFactor));\n }\n }\n return this._updatedList;\n }\n\n private isZoneOutsideVisibilityFading(zone: ZoneInterface): boolean {\n return !!(\n this.zoneVisibilityFade &&\n this.zoneVisibilityFade.zoneId === zone.id &&\n performance.now() - this.zoneVisibilityFade.startedAt < this.zoneVisibilityFadeDurationMs\n );\n }\n\n private getZoneOutsideVisibility(zone: ZoneInterface): number {\n const dimmedOpacity = this.zoneOutsideOpacity;\n if (!this.zoneVisibilityFade || this.zoneVisibilityFade.zoneId !== zone.id) {\n return dimmedOpacity;\n }\n const elapsed = performance.now() - this.zoneVisibilityFade.startedAt;\n if (elapsed >= this.zoneVisibilityFadeDurationMs) {\n return dimmedOpacity;\n }\n const progress = Math.max(0, Math.min(1, elapsed / this.zoneVisibilityFadeDurationMs));\n return 1 - progress * (1 - dimmedOpacity);\n }\n\n getObjectsAt(target: Strand, all = false, includeZoneFade = false): Array<[WorldObject, Paintable[]]> {\n const zone = this.getActiveZone();\n const includeOutsideObjects = zone && includeZoneFade ? this.getZoneOutsideVisibility(zone) > 0 : false;\n const filteredPoints = hidePointsOutsideRegion(this.points, target, this.filteredPointsBuffer);\n\n const len = this.renderOrder.length;\n const objects: Array<[WorldObject, Paintable[]]> = [];\n\n for (let _index = 0; _index < len; _index++) {\n const index = this.renderOrder[_index];\n if (filteredPoints[index * 5] !== 0) {\n const object = this.objects[index];\n const inZone = !zone || zone.objects.indexOf(object) !== -1;\n if (!object || (!inZone && !includeOutsideObjects)) {\n continue;\n }\n if (object.type !== 'world-object') {\n objects.push([object, [object]] as any);\n continue;\n }\n if (all) {\n objects.push([object, object.getObjectsAt(target, all)]);\n } else {\n objects.push([object, this.emptyPaintables]);\n }\n }\n }\n\n return objects;\n }\n\n getPointsAt(target: Strand, aggregate?: Strand, scaleFactor = 1): Paint[] {\n const zone = this.getActiveZone();\n const outsideVisibility = zone ? this.getZoneOutsideVisibility(zone) : 0;\n const objects = this.getObjectsAt(target, false, true);\n const translation = compose(scale(scaleFactor), translate(-target[1], -target[2]), this.translationBuffer);\n const transformer = aggregate ? compose(aggregate, translation, this.aggregateBuffer) : translation;\n const len = objects.length;\n\n const layers: Paint[] = [];\n for (let index = 0; index < len; index++) {\n if (objects[index]) {\n const worldObject = objects[index][0];\n const paints = worldObject.getAllPointsAt(target, transformer, scaleFactor);\n const inZone = !zone || zone.objects.indexOf(worldObject) !== -1;\n const zoneVisibilityAlpha = inZone ? 1 : outsideVisibility;\n for (let i = 0; i < paints.length; i++) {\n (paints[i][0] as any).__zoneVisibilityAlpha = zoneVisibilityAlpha;\n }\n layers.push(...paints);\n }\n }\n if (zone && this.isZoneOutsideVisibilityFading(zone)) {\n this.triggerRepaint();\n }\n return layers;\n }\n\n _alreadyFlushed: any = [];\n flushSubscriptions() {\n if (this.triggerQueue.length) {\n this._alreadyFlushed = [];\n const queueLen = this.triggerQueue.length;\n for (let x = 0; x < queueLen; x++) {\n if (this._alreadyFlushed.indexOf(this.triggerQueue[x][0]) !== -1) {\n continue;\n }\n if (typeof this.triggerQueue[x][1] === 'undefined') {\n this._alreadyFlushed.push(this.triggerQueue[x][0]);\n }\n const len = this.subscriptions.length;\n for (let i = 0; i < len; i++) {\n // eslint-disable-next-line prefer-spread\n (this.subscriptions[i] as any).apply(null, this.triggerQueue[x]);\n }\n }\n this.triggerQueue = [];\n }\n }\n\n trigger<T>(type: string, data?: T) {\n this.emitDebug({\n type: 'trigger',\n at: performance.now(),\n event: type,\n data,\n });\n this.triggerQueue.push([type, data]);\n }\n\n triggerEventActivation() {\n this.trigger('event-activation');\n }\n\n triggerRepaint() {\n this.trigger('repaint');\n }\n\n gotoRegion(data: {\n x: number;\n y: number;\n height: number;\n width: number;\n padding?: number;\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n nudge?: boolean;\n immediate?: boolean;\n }) {\n this.trigger('goto-region', data);\n }\n\n goHome(immediate = false, paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number }) {\n this.trigger('go-home', {\n immediate,\n paddingPx,\n });\n }\n\n zoomTo(factor: number, point?: { x: number; y: number }, stream?: boolean) {\n this.trigger('zoom-to', {\n point,\n factor,\n stream,\n });\n }\n\n zoomIn(point?: { x: number; y: number }) {\n this.trigger('zoom-to', {\n point,\n factor: 0.5,\n });\n }\n\n zoomOut(point?: { x: number; y: number }) {\n this.trigger('zoom-to', {\n point,\n factor: 2,\n });\n }\n\n constraintBounds(immediate?: boolean) {\n this.trigger('constrain-bounds', { immediate });\n }\n\n hasPendingAnimation() {\n return !!(\n this.zoneVisibilityFade &&\n performance.now() - this.zoneVisibilityFade.startedAt < this.zoneVisibilityFadeDurationMs\n );\n }\n\n addDebugSubscriber(callback: (event: WorldDebugEvent) => void) {\n this.debugSubscribers.add(callback);\n return () => {\n this.removeDebugSubscriber(callback);\n };\n }\n\n removeDebugSubscriber(callback: (event: WorldDebugEvent) => void) {\n this.debugSubscribers.delete(callback);\n }\n\n private emitDebug(event: WorldDebugEvent) {\n if (this.debugSubscribers.size === 0) {\n return;\n }\n for (const callback of this.debugSubscribers) {\n callback(event);\n }\n }\n}\n","import { ViewingDirection } from '@iiif/presentation-3';\nimport { AbstractObject } from '../../world-objects/abstract-object';\nimport { World } from '../../world';\nimport { WorldObject } from '../../world-objects/world-object';\n\nexport class GridBuilder {\n autoWidth = false;\n autoHeight = true;\n width: number;\n height: number;\n\n world: World;\n content: WorldObject[] = [];\n viewingDirection: ViewingDirection = 'left-to-right';\n rows?: number;\n columns?: number = 4;\n spacing = 20;\n reversed = false;\n padding = 20;\n\n constructor() {\n this.world = World.withProps({ width: 0, height: 0, viewingDirection: 'left-to-right' });\n this.width = 0;\n this.height = 0;\n }\n\n setViewingDirection(viewingDirection: ViewingDirection) {\n this.viewingDirection = viewingDirection;\n }\n\n addContent(content: AbstractObject[]) {\n this.content.push(\n ...content.map((item) =>\n this.world.addObjectAt(item, {\n width: 0,\n height: 0,\n x: 0,\n y: 0,\n })\n )\n );\n }\n\n setWidth(width: number) {\n this.width = width;\n }\n\n setHeight(height: number) {\n this.height = height;\n }\n\n setSpacing(spacing: number) {\n this.spacing = spacing;\n }\n\n setPadding(padding: number) {\n this.padding = padding;\n }\n\n setRows(rows?: number) {\n this.autoWidth = true;\n this.rows = rows;\n }\n\n setColumns(columns?: number) {\n this.autoHeight = true;\n this.columns = columns;\n }\n\n recalculate() {\n if (this.height === 0 && this.width === 0) {\n // Nothing to render if its 0 width.\n return;\n }\n\n if (this.rows === 0 || this.columns === 0) {\n // No columns or rows.\n return;\n }\n\n if (this.autoHeight && !this.width) {\n throw new Error('Cannot set auto height without setting a width');\n }\n\n if (this.autoWidth && !this.height) {\n throw new Error('Cannot set auto width without setting a height');\n }\n\n if ((this.viewingDirection === 'left-to-right' || this.viewingDirection === 'top-to-bottom') && this.reversed) {\n this.reversed = false;\n this.content.reverse();\n }\n if ((this.viewingDirection === 'right-to-left' || this.viewingDirection === 'bottom-to-top') && !this.reversed) {\n this.reversed = true;\n this.content.reverse();\n }\n\n const len = this.content.length;\n\n const getColumns = () => {\n if (this.autoWidth && this.rows) {\n const rowsValue = len > this.rows ? this.rows : len;\n return {\n columns: Math.ceil(len / (rowsValue as number)),\n rows: rowsValue,\n };\n }\n\n if (this.autoHeight && this.columns) {\n const columnsValue = len > this.columns ? this.columns : len;\n return {\n columns: columnsValue,\n rows: Math.ceil(len / (columnsValue as number)),\n };\n }\n\n throw new Error('Something went wrong.');\n };\n\n const { columns, rows } = getColumns();\n const contentWidth = this.autoWidth ? -1 : this.width - this.padding * 2;\n // const contentHeight = this.autoHeight ? -1 : this.height - this.padding / 2;\n const itemWidth = this.autoWidth ? -1 : (contentWidth - this.spacing * (columns - 1)) / columns;\n // const itemHeight = this.autoHeight ? -1 : (contentWidth - this.spacing * (columns - 1)) / rows;\n\n // do rows then columns\n if (this.autoHeight && !this.autoWidth) {\n let index = 0;\n let rowHeights = this.padding;\n for (let r = 0; r < rows; r++) {\n if (index === len) {\n break;\n }\n let rowHeight = 0;\n const row = [];\n for (let c = 0; c < columns; c++) {\n const realIndex = this.reversed ? len - index : index;\n if (index === len) {\n break;\n }\n const item = this.content[realIndex];\n const width = item.width;\n const aspectRatio = item.width / item.height;\n const currentRowHeight = itemWidth / aspectRatio;\n row.push([\n index,\n itemWidth, // width\n currentRowHeight, // height\n itemWidth / width, // scale\n ]);\n if (currentRowHeight > rowHeight) {\n rowHeight = currentRowHeight;\n }\n index++;\n }\n // Back through the rows.\n for (let c = 0; c < columns; c++) {\n if (!row[c]) {\n break;\n }\n const worldPoints = this.world.getPoints();\n const currentIndex = row[c][0];\n const width = row[c][1];\n const height = row[c][2];\n const scale = row[c][3];\n const x = this.padding + c * (this.spacing + width);\n const y = rowHeights + (rowHeight - height) / 2;\n const realIndex = this.reversed ? len - currentIndex : currentIndex;\n const prevX = worldPoints[realIndex * 5 + 1];\n const prevY = worldPoints[realIndex * 5 + 2];\n\n this.world.scaleWorldObject(currentIndex, scale);\n if (prevX !== x || prevY !== y) {\n this.world.translateWorldObject(realIndex, x - prevX, y - prevY);\n }\n }\n // Add the current row to the total row heights\n rowHeights += rowHeight + this.spacing;\n }\n this.height = rowHeights + this.padding;\n this.world.resize(this.width, this.height);\n return;\n }\n\n // do columns then rows\n if (this.autoWidth && !this.autoHeight) {\n // @todo\n }\n\n // Fixed height and width, fit content\n if (!this.autoWidth && !this.autoHeight) {\n // @todo\n }\n }\n\n getWorld(): World {\n return this.world;\n }\n}\n","import { ImageService } from '@iiif/presentation-3';\n\nexport type GetTile = {\n id: string;\n width: number;\n height: number;\n thumbnail?: { id: string; width: number; height: number };\n imageService: ImageService;\n};\n\nexport function getId(entity: any): string {\n return entity.id || entity['@id'];\n}\n","import { ImageServiceLoader } from '@atlas-viewer/iiif-image-api';\nimport { createThumbnailHelper } from '@iiif/helpers/thumbnail';\nimport type { Vault } from '@iiif/helpers/vault';\n\nfunction getGlobal(): any {\n if (typeof self !== 'undefined') {\n return self;\n }\n if (typeof window !== 'undefined') {\n return window;\n }\n if (typeof global !== 'undefined') {\n return global;\n }\n return {};\n}\n\nfunction getGlobalVault() {\n const g = getGlobal();\n\n // Found a vault.\n if (typeof g['IIIF_VAULT'] !== 'undefined') {\n return g['IIIF_VAULT'];\n }\n\n if (typeof g.IIIFVault === 'undefined') {\n throw new Error('Vault not found');\n }\n\n g['IIIF_VAULT'] = new g.IIIFVault.Vault();\n\n return g['IIIF_VAULT'];\n}\n\nconst moduleState: {\n vault: Vault;\n loader: ImageServiceLoader;\n helper: any;\n} = {} as any;\n\nexport function getVaultHelper() {\n if (!moduleState.helper) {\n moduleState.vault = getGlobalVault();\n moduleState.loader = new ImageServiceLoader();\n moduleState.helper = createThumbnailHelper(moduleState.vault as any, { imageServiceLoader: moduleState.loader });\n }\n return moduleState;\n}\n","import { ImageService } from '@iiif/presentation-3';\nimport {\n AnnotationNormalized,\n AnnotationPageNormalized,\n CanvasNormalized,\n ManifestNormalized,\n} from '@iiif/presentation-3-normalized';\nimport { getId, GetTile } from './shared';\nimport { getVaultHelper } from './get-vault-helper';\n\nexport async function getTileFromImageService(infoJsonId: string, width: number, height: number): Promise<GetTile> {\n const { loader } = getVaultHelper();\n const imageService = await loader.loadService({\n id: infoJsonId,\n width: width,\n height: height,\n });\n\n return {\n id: getId(imageService),\n width: width,\n height: height,\n imageService: imageService as ImageService,\n thumbnail: undefined,\n };\n}\n\nexport async function getTileFromCanvas(canvas: CanvasNormalized, thumbnailSize = 512): Promise<GetTile[]> {\n const { vault, loader, helper } = getVaultHelper();\n const tiles = [];\n\n for (const page of canvas.items) {\n for (const anno of vault.get<AnnotationPageNormalized>(page).items) {\n const annotation = vault.get<any>(vault.get<AnnotationNormalized>(anno).body[0]);\n const serviceSnippet = annotation.service[0];\n\n const tile = await getTileFromImageService(serviceSnippet.id, canvas.width, canvas.height);\n\n const { best: thumbnail } = (await (helper.getBestThumbnailAtSize as any)(\n vault,\n loader as any,\n canvas,\n {\n maxHeight: thumbnailSize,\n maxWidth: thumbnailSize,\n },\n true\n )) as any;\n\n if (thumbnail) {\n tile.thumbnail = thumbnail;\n }\n\n tiles.push(tile);\n }\n }\n\n return tiles;\n}\n\nexport async function getTilesFromManifest(manifest: ManifestNormalized) {\n const { vault } = getVaultHelper();\n\n const tiles: any[] = [];\n for (const canvasRef of manifest.items) {\n const canvas = vault.get<CanvasNormalized>(canvasRef);\n tiles.push(...(await getTileFromCanvas(canvas)));\n }\n return tiles;\n}\n\nexport async function getTiles(manifestId: string): Promise<Array<GetTile>> {\n try {\n const { vault } = getVaultHelper();\n const manifest = await vault.loadManifest(manifestId);\n\n if (!manifest) {\n return [];\n }\n\n return getTilesFromManifest(manifest as any);\n } catch (err) {\n console.log('ERR', err);\n return [];\n }\n}\n","import type { WarpAdapter, WarpAdapterHooks, WarpControlPoint, WarpTransformationType, WarpUpdateReason } from './types';\n\nexport class WarpAdapterController {\n private controlPoints: WarpControlPoint[] = [];\n private transformationType: WarpTransformationType = 'projective';\n\n constructor(\n private readonly adapter: WarpAdapter,\n private readonly hooks: WarpAdapterHooks = {}\n ) {}\n\n getState() {\n return {\n controlPoints: [...this.controlPoints],\n transformationType: this.transformationType,\n };\n }\n\n setControlPoints(controlPoints: WarpControlPoint[]): void {\n this.controlPoints = [...controlPoints];\n this.adapter.setMapGcps(this.controlPoints);\n if (this.hooks.onControlPointsChange) {\n this.hooks.onControlPointsChange(this.controlPoints);\n }\n this.update('gcps');\n }\n\n setTransformationType(type: WarpTransformationType): void {\n this.transformationType = type;\n this.adapter.setMapTransformationType(type);\n if (this.hooks.onTransformationTypeChange) {\n this.hooks.onTransformationTypeChange(type);\n }\n this.update('transformation');\n }\n\n update(reason: WarpUpdateReason = 'manual'): void {\n this.adapter.update(reason);\n if (this.hooks.onUpdate) {\n this.hooks.onUpdate(reason);\n }\n }\n}\n\nexport function createWarpAdapterController(adapter: WarpAdapter, hooks?: WarpAdapterHooks): WarpAdapterController {\n return new WarpAdapterController(adapter, hooks);\n}\n","import { DnaFactory, type Strand, transform } from '@atlas-viewer/dna';\nimport { Box } from '../../objects/box';\nimport { Geometry } from '../../objects/geometry';\nimport { ImageTexture } from '../../spacial-content/image-texture';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport type { World } from '../../world';\nimport type { ZoneInterface } from '../../world-objects/zone';\nimport { DebugRenderer } from '../debug-renderer/debug-renderer';\n\nexport type NavigatorTransform = {\n scale: number;\n offsetX: number;\n offsetY: number;\n worldX: number;\n worldY: number;\n worldWidth: number;\n worldHeight: number;\n};\n\nexport type NavigatorWorldRegion = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nexport type NavigatorRendererStyle = {\n background: string;\n objectFill: string;\n objectStroke: string;\n viewportFill: string;\n viewportStroke: string;\n viewportLineWidth: number;\n};\n\ntype SharedCanvasTileState = {\n state?: 'idle' | 'queued' | 'loading' | 'decoded' | 'error';\n};\n\ntype SharedCanvasImageBuffer = {\n canvases?: string[];\n tiles?: Record<number, SharedCanvasTileState>;\n};\n\ntype SharedCanvasRenderer = {\n hostCache?: {\n get(id: string): HTMLCanvasElement | undefined;\n };\n invalidated?: string[];\n schedulePaintToCanvas?: (\n imageBuffer: SharedCanvasImageBuffer,\n paint: SingleImage | TiledImage,\n index: number,\n priority: number,\n prefetch?: boolean\n ) => boolean;\n createImageHost?: (paint: SingleImage | TiledImage) => void;\n};\n\nexport type NavigatorRendererOptions = {\n style?: Partial<NavigatorRendererStyle>;\n maxRects?: number;\n minVisibleRectSize?: number;\n drawFallbackBoxes?: boolean;\n zoneWindow?: NavigatorZoneWindowOptions;\n sharedCanvasRenderer?: SharedCanvasRenderer;\n onRequestRender?: () => void;\n onDebugEvent?: (event: NavigatorDebugEvent) => void;\n};\n\nexport type NavigatorDebugEvent =\n | {\n type: 'preview-image-requested';\n imageUrl: string;\n }\n | {\n type: 'preview-image-loaded';\n imageUrl: string;\n cached: boolean;\n }\n | {\n type: 'preview-image-error';\n imageUrl: string;\n }\n | {\n type: 'world-layer-invalidated';\n reason: string;\n }\n | {\n type: 'frame-skipped-zero-size-canvas';\n canvasWidth: number;\n canvasHeight: number;\n baseCanvasWidth: number;\n baseCanvasHeight: number;\n }\n | {\n type: 'world-layer-render-start';\n region: NavigatorWorldRegion;\n }\n | {\n type: 'world-layer-render-end';\n region: NavigatorWorldRegion;\n }\n | {\n type: 'render-request-forwarded';\n reason: string;\n };\n\nexport type NavigatorZoneWindowOptions = {\n total?: number;\n before?: number;\n after?: number;\n};\n\nexport type NavigatorWorldRegionOptions = {\n target?: Strand | { x: number; y: number; width: number; height: number };\n zoneWindow?: NavigatorZoneWindowOptions;\n};\n\nconst DEFAULT_STYLE: NavigatorRendererStyle = {\n background: 'rgba(15, 23, 42, 0.7)',\n objectFill: 'rgba(56, 189, 248, 0.22)',\n objectStroke: 'rgba(56, 189, 248, 0.62)',\n viewportFill: 'rgba(251, 191, 36, 0.22)',\n viewportStroke: 'rgba(250, 204, 21, 1)',\n viewportLineWidth: 2,\n};\n\ntype ImageCacheEntry = {\n image: HTMLImageElement;\n status: 'loading' | 'loaded' | 'error';\n};\n\ntype ZoneBounds = {\n zone: ZoneInterface;\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n};\n\ntype ResolvedZoneWindow = {\n total: number;\n before: number;\n after: number;\n};\n\nfunction toInt(value: number | undefined): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return undefined;\n }\n return Math.floor(value);\n}\n\nfunction resolveZoneWindow(\n zoneWindow: NavigatorZoneWindowOptions | undefined,\n zoneCount: number\n): ResolvedZoneWindow | null {\n if (!zoneWindow || zoneCount <= 1) {\n return null;\n }\n\n const requestedTotal = toInt(zoneWindow.total);\n const requestedBefore = toInt(zoneWindow.before);\n const requestedAfter = toInt(zoneWindow.after);\n\n let total =\n typeof requestedTotal !== 'undefined'\n ? Math.max(1, requestedTotal)\n : typeof requestedBefore !== 'undefined' || typeof requestedAfter !== 'undefined'\n ? Math.max(1, Math.max(0, requestedBefore || 0) + Math.max(0, requestedAfter || 0) + 1)\n : 9;\n let before = typeof requestedBefore !== 'undefined' ? Math.max(0, requestedBefore) : undefined;\n let after = typeof requestedAfter !== 'undefined' ? Math.max(0, requestedAfter) : undefined;\n\n if (typeof before === 'undefined' && typeof after === 'undefined') {\n before = Math.floor((total - 1) / 2);\n after = total - before - 1;\n } else if (typeof before === 'undefined') {\n before = Math.max(0, total - (after || 0) - 1);\n } else if (typeof after === 'undefined') {\n after = Math.max(0, total - before - 1);\n }\n\n const expectedTotal = before + after + 1;\n if (expectedTotal !== total) {\n total = expectedTotal;\n }\n\n total = Math.max(1, Math.min(zoneCount, total));\n before = Math.min(before, total - 1);\n after = total - before - 1;\n\n return { total, before, after };\n}\n\nfunction getZoneBounds(world: World): ZoneBounds[] {\n const bounds: ZoneBounds[] = [];\n for (let i = 0; i < world.zones.length; i++) {\n const zone = world.zones[i];\n zone.recalculateBounds();\n if (zone.points[0] === 0) {\n continue;\n }\n bounds.push({\n zone,\n minX: zone.points[1],\n minY: zone.points[2],\n maxX: zone.points[3],\n maxY: zone.points[4],\n });\n }\n bounds.sort((a, b) => {\n if (a.minY !== b.minY) {\n return a.minY - b.minY;\n }\n if (a.minX !== b.minX) {\n return a.minX - b.minX;\n }\n return (a.zone?.id || '').localeCompare(b.zone?.id || '');\n });\n return bounds;\n}\n\nfunction getWindowedZoneBounds(world: World, options: NavigatorWorldRegionOptions): ZoneBounds[] | null {\n const resolvedWindow = resolveZoneWindow(options.zoneWindow, world.zones.length);\n if (!resolvedWindow) {\n return null;\n }\n\n const bounds = getZoneBounds(world);\n if (bounds.length <= resolvedWindow.total) {\n return bounds;\n }\n\n const anchorIndex = getAnchorZoneIndex(bounds, options.target);\n let start = anchorIndex - resolvedWindow.before;\n let end = start + resolvedWindow.total - 1;\n\n if (start < 0) {\n start = 0;\n end = resolvedWindow.total - 1;\n }\n\n if (end >= bounds.length) {\n end = bounds.length - 1;\n start = Math.max(0, end - resolvedWindow.total + 1);\n }\n\n return bounds.slice(start, end + 1);\n}\n\nfunction getViewportCenter(target: NavigatorWorldRegionOptions['target']): { x: number; y: number } | null {\n if (!target) {\n return null;\n }\n if (Array.isArray(target) || ArrayBuffer.isView(target)) {\n const strand = target as Strand;\n if (strand[0] === 0) {\n return null;\n }\n return {\n x: (strand[1] + strand[3]) / 2,\n y: (strand[2] + strand[4]) / 2,\n };\n }\n return {\n x: target.x + target.width / 2,\n y: target.y + target.height / 2,\n };\n}\n\nfunction getAnchorZoneIndex(zoneBounds: ZoneBounds[], target: NavigatorWorldRegionOptions['target']): number {\n if (zoneBounds.length === 0) {\n return 0;\n }\n\n const center = getViewportCenter(target);\n if (!center) {\n return 0;\n }\n\n for (let i = 0; i < zoneBounds.length; i++) {\n const zone = zoneBounds[i];\n if (center.x >= zone.minX && center.x <= zone.maxX && center.y >= zone.minY && center.y <= zone.maxY) {\n return i;\n }\n }\n\n let closestIndex = 0;\n let closestDistance = Number.POSITIVE_INFINITY;\n for (let i = 0; i < zoneBounds.length; i++) {\n const zone = zoneBounds[i];\n const zoneCenterY = (zone.minY + zone.maxY) / 2;\n const distance = Math.abs(center.y - zoneCenterY);\n if (distance < closestDistance) {\n closestDistance = distance;\n closestIndex = i;\n }\n }\n return closestIndex;\n}\n\nfunction toRegion(zoneBounds: ZoneBounds[]): NavigatorWorldRegion | null {\n if (zoneBounds.length === 0) {\n return null;\n }\n\n let minX = zoneBounds[0].minX;\n let minY = zoneBounds[0].minY;\n let maxX = zoneBounds[0].maxX;\n let maxY = zoneBounds[0].maxY;\n\n for (let i = 1; i < zoneBounds.length; i++) {\n const zone = zoneBounds[i];\n minX = Math.min(minX, zone.minX);\n minY = Math.min(minY, zone.minY);\n maxX = Math.max(maxX, zone.maxX);\n maxY = Math.max(maxY, zone.maxY);\n }\n\n return {\n x: minX,\n y: minY,\n width: Math.max(1, maxX - minX),\n height: Math.max(1, maxY - minY),\n };\n}\n\nexport function getNavigatorWorldTransform(\n worldWidth: number,\n worldHeight: number,\n navigatorWidth: number,\n navigatorHeight: number,\n worldX = 0,\n worldY = 0\n): NavigatorTransform {\n const safeWorldWidth = Math.max(1, worldWidth);\n const safeWorldHeight = Math.max(1, worldHeight);\n const scale = Math.min(navigatorWidth / safeWorldWidth, navigatorHeight / safeWorldHeight);\n\n const drawnWidth = safeWorldWidth * scale;\n const drawnHeight = safeWorldHeight * scale;\n\n return {\n scale,\n offsetX: (navigatorWidth - drawnWidth) / 2,\n offsetY: (navigatorHeight - drawnHeight) / 2,\n worldX,\n worldY,\n worldWidth: safeWorldWidth,\n worldHeight: safeWorldHeight,\n };\n}\n\nexport function getNavigatorWorldRegion(world: World, options: NavigatorWorldRegionOptions = {}): NavigatorWorldRegion {\n const activeZone = world.getActiveZone();\n if (activeZone) {\n activeZone.recalculateBounds();\n if (activeZone.points[0] !== 0) {\n return {\n x: activeZone.points[1],\n y: activeZone.points[2],\n width: Math.max(1, activeZone.points[3] - activeZone.points[1]),\n height: Math.max(1, activeZone.points[4] - activeZone.points[2]),\n };\n }\n }\n\n const windowedBounds = getWindowedZoneBounds(world, options);\n if (windowedBounds && windowedBounds.length > 0) {\n const region = toRegion(windowedBounds);\n if (region) {\n return region;\n }\n }\n\n return {\n x: 0,\n y: 0,\n width: Math.max(1, world.width),\n height: Math.max(1, world.height),\n };\n}\n\nexport function getNavigatorVisibleZoneIdSet(\n world: World,\n options: NavigatorWorldRegionOptions = {}\n): Set<string> | null {\n const activeZone = world.getActiveZone();\n if (activeZone) {\n activeZone.recalculateBounds();\n if (activeZone.points[0] !== 0) {\n return new Set([activeZone.id]);\n }\n return new Set();\n }\n\n const windowedBounds = getWindowedZoneBounds(world, options);\n if (!windowedBounds) {\n return null;\n }\n\n const visibleZoneIds = new Set<string>();\n for (const bounds of windowedBounds) {\n visibleZoneIds.add(bounds.zone.id);\n }\n return visibleZoneIds;\n}\n\nexport function navigatorToWorldPoint(transform: NavigatorTransform, x: number, y: number): { x: number; y: number } {\n if (!transform.scale || !Number.isFinite(transform.scale)) {\n return { x: transform.worldX, y: transform.worldY };\n }\n\n const worldX = transform.worldX + (x - transform.offsetX) / transform.scale;\n const worldY = transform.worldY + (y - transform.offsetY) / transform.scale;\n\n return {\n x: Math.max(transform.worldX, Math.min(transform.worldX + transform.worldWidth, worldX)),\n y: Math.max(transform.worldY, Math.min(transform.worldY + transform.worldHeight, worldY)),\n };\n}\n\nexport class NavigatorRenderer extends DebugRenderer {\n private readonly style: NavigatorRendererStyle;\n private readonly maxRects: number;\n private readonly minVisibleRectSize: number;\n private readonly drawFallbackBoxes: boolean;\n private readonly zoneWindow?: NavigatorZoneWindowOptions;\n private readonly sharedCanvasRenderer?: SharedCanvasRenderer;\n private readonly onRequestRender?: () => void;\n private readonly onDebugEvent?: (event: NavigatorDebugEvent) => void;\n private readonly baseCanvas: HTMLCanvasElement;\n private readonly baseContext: CanvasRenderingContext2D;\n private readonly worldTarget: Strand = DnaFactory.singleBox(1, 1, 0, 0);\n private readonly previewImageCache = new Map<string, ImageCacheEntry>();\n\n private worldLayerDirty = true;\n private lastWorldWidth = 0;\n private lastWorldHeight = 0;\n private lastTargetX = Number.NaN;\n private lastTargetY = Number.NaN;\n private lastTargetX2 = Number.NaN;\n private lastTargetY2 = Number.NaN;\n private lastRegionX = Number.NaN;\n private lastRegionY = Number.NaN;\n private lastRegionWidth = Number.NaN;\n private lastRegionHeight = Number.NaN;\n private worldLayerInvalidationVersion = 0;\n private sharedCanvasResourcesPending = false;\n\n constructor(canvas: HTMLCanvasElement, options: NavigatorRendererOptions = {}) {\n super(canvas);\n this.style = { ...DEFAULT_STYLE, ...(options.style || {}) };\n this.maxRects = Math.max(100, options.maxRects || 5000);\n this.minVisibleRectSize = Math.max(1, options.minVisibleRectSize || 1);\n this.drawFallbackBoxes = options.drawFallbackBoxes !== false;\n this.zoneWindow = options.zoneWindow;\n this.sharedCanvasRenderer = options.sharedCanvasRenderer;\n this.onRequestRender = options.onRequestRender;\n this.onDebugEvent = options.onDebugEvent;\n this.context.globalAlpha = 1;\n this.context.imageSmoothingEnabled = false;\n\n this.baseCanvas = document.createElement('canvas');\n this.baseContext = this.baseCanvas.getContext('2d') as CanvasRenderingContext2D;\n this.baseContext.imageSmoothingEnabled = true;\n\n this.syncBaseLayerCanvas();\n }\n\n private emitDebugEvent(event: NavigatorDebugEvent) {\n if (this.onDebugEvent) {\n this.onDebugEvent(event);\n }\n }\n\n private requestRender(reason: string) {\n if (this.onRequestRender) {\n this.emitDebugEvent({\n type: 'render-request-forwarded',\n reason,\n });\n this.onRequestRender();\n }\n }\n\n invalidateWorldLayer(reason = 'manual') {\n this.worldLayerInvalidationVersion++;\n this.worldLayerDirty = true;\n this.renderNextFrame = true;\n this.emitDebugEvent({\n type: 'world-layer-invalidated',\n reason,\n });\n this.requestRender(reason);\n }\n\n resize() {\n super.resize();\n this.syncBaseLayerCanvas();\n this.invalidateWorldLayer('resize');\n }\n\n beforeFrame(world: World) {\n if (world.width !== this.lastWorldWidth || world.height !== this.lastWorldHeight) {\n this.lastWorldWidth = world.width;\n this.lastWorldHeight = world.height;\n this.invalidateWorldLayer('world-size-changed');\n }\n }\n\n paint() {\n this.renderNextFrame = true;\n }\n\n pendingUpdate(): boolean {\n return this.renderNextFrame || this.worldLayerDirty;\n }\n\n afterFrame(world: World, _delta: number, target: Strand) {\n const frameInvalidationVersion = this.worldLayerInvalidationVersion;\n if (this.canvas.width <= 0 || this.canvas.height <= 0) {\n this.emitDebugEvent({\n type: 'frame-skipped-zero-size-canvas',\n canvasWidth: this.canvas.width,\n canvasHeight: this.canvas.height,\n baseCanvasWidth: this.baseCanvas.width,\n baseCanvasHeight: this.baseCanvas.height,\n });\n this.renderNextFrame = true;\n return;\n }\n\n const region = getNavigatorWorldRegion(world, {\n target,\n zoneWindow: this.zoneWindow,\n });\n const regionChanged = this.hasRegionChanged(region);\n if (regionChanged) {\n this.worldLayerDirty = true;\n }\n const viewportChanged = this.hasViewportChanged(target);\n const shouldRender = this.renderNextFrame || this.worldLayerDirty || viewportChanged;\n\n if (!shouldRender) {\n return;\n }\n\n if (this.baseCanvas.width !== this.canvas.width || this.baseCanvas.height !== this.canvas.height) {\n this.syncBaseLayerCanvas();\n this.worldLayerDirty = true;\n }\n\n if (this.baseCanvas.width <= 0 || this.baseCanvas.height <= 0) {\n this.emitDebugEvent({\n type: 'frame-skipped-zero-size-canvas',\n canvasWidth: this.canvas.width,\n canvasHeight: this.canvas.height,\n baseCanvasWidth: this.baseCanvas.width,\n baseCanvasHeight: this.baseCanvas.height,\n });\n this.renderNextFrame = true;\n return;\n }\n\n if (this.worldLayerDirty) {\n const worldLayerRenderInvalidationVersion = this.worldLayerInvalidationVersion;\n this.sharedCanvasResourcesPending = false;\n this.emitDebugEvent({\n type: 'world-layer-render-start',\n region,\n });\n try {\n this.renderWorldLayer(world, region);\n } finally {\n this.emitDebugEvent({\n type: 'world-layer-render-end',\n region,\n });\n }\n this.worldLayerDirty =\n this.sharedCanvasResourcesPending ||\n worldLayerRenderInvalidationVersion !== this.worldLayerInvalidationVersion;\n }\n\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.drawImage(this.baseCanvas, 0, 0);\n this.renderViewportBox(target, region);\n\n this.lastTargetX = target[1];\n this.lastTargetY = target[2];\n this.lastTargetX2 = target[3];\n this.lastTargetY2 = target[4];\n this.lastRegionX = region.x;\n this.lastRegionY = region.y;\n this.lastRegionWidth = region.width;\n this.lastRegionHeight = region.height;\n this.renderNextFrame =\n this.sharedCanvasResourcesPending || frameInvalidationVersion !== this.worldLayerInvalidationVersion;\n }\n\n private hasViewportChanged(target: Strand) {\n return (\n this.lastTargetX !== target[1] ||\n this.lastTargetY !== target[2] ||\n this.lastTargetX2 !== target[3] ||\n this.lastTargetY2 !== target[4]\n );\n }\n\n private hasRegionChanged(region: NavigatorWorldRegion) {\n return (\n this.lastRegionX !== region.x ||\n this.lastRegionY !== region.y ||\n this.lastRegionWidth !== region.width ||\n this.lastRegionHeight !== region.height\n );\n }\n\n private syncBaseLayerCanvas() {\n this.baseCanvas.width = this.canvas.width;\n this.baseCanvas.height = this.canvas.height;\n }\n\n private shouldClipImagePaintToBounds(paint: unknown): boolean {\n if (!(paint instanceof SingleImage || paint instanceof TiledImage)) {\n return false;\n }\n return !!(paint as any).__parent?.renderOptions?.clipToBounds;\n }\n\n private getBoundsFromPoints(points: Strand): { x: number; y: number; width: number; height: number } | undefined {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < points.length; i += 5) {\n if (!points[i]) {\n continue;\n }\n minX = Math.min(minX, points[i + 1]);\n minY = Math.min(minY, points[i + 2]);\n maxX = Math.max(maxX, points[i + 3]);\n maxY = Math.max(maxY, points[i + 4]);\n }\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {\n return undefined;\n }\n if (maxX <= minX || maxY <= minY) {\n return undefined;\n }\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n }\n\n private getLayerClipBounds(\n paint: unknown,\n transformation: Strand | undefined,\n navigatorTransform: NavigatorTransform\n ): { x: number; y: number; width: number; height: number } | undefined {\n if (!this.shouldClipImagePaintToBounds(paint)) {\n return undefined;\n }\n\n const parent = (paint as any).__parent;\n const parentPoints = parent?.crop || parent?.points;\n if (!parentPoints) {\n return undefined;\n }\n\n const transformedParentPoints = transformation ? transform(parentPoints, transformation) : parentPoints;\n const bounds = this.getBoundsFromPoints(transformedParentPoints);\n if (!bounds) {\n return undefined;\n }\n\n return {\n x: bounds.x + navigatorTransform.offsetX,\n y: bounds.y + navigatorTransform.offsetY,\n width: bounds.width,\n height: bounds.height,\n };\n }\n\n private renderWorldLayer(world: World, region: NavigatorWorldRegion) {\n const ctx = this.baseContext;\n ctx.clearRect(0, 0, this.baseCanvas.width, this.baseCanvas.height);\n ctx.fillStyle = this.style.background;\n ctx.fillRect(0, 0, this.baseCanvas.width, this.baseCanvas.height);\n\n const activeZone = world.getActiveZone();\n const navigatorTransform = getNavigatorWorldTransform(\n region.width,\n region.height,\n this.baseCanvas.width,\n this.baseCanvas.height,\n region.x,\n region.y\n );\n\n this.worldTarget[1] = region.x;\n this.worldTarget[2] = region.y;\n this.worldTarget[3] = region.x + region.width;\n this.worldTarget[4] = region.y + region.height;\n\n const points = world.getPointsAt(this.worldTarget, this.aggregate, navigatorTransform.scale);\n let drawn = 0;\n\n for (let p = 0; p < points.length; p++) {\n if (drawn >= this.maxRects) {\n break;\n }\n\n const paint = points[p][0] as any;\n const point = points[p][1];\n const transformation = points[p][2];\n const position = transformation ? transform(point, transformation) : point;\n const total = position.length / 5;\n const layerClipBounds = this.getLayerClipBounds(paint, transformation, navigatorTransform);\n\n if (layerClipBounds) {\n ctx.save();\n ctx.beginPath();\n ctx.rect(layerClipBounds.x, layerClipBounds.y, layerClipBounds.width, layerClipBounds.height);\n ctx.clip();\n }\n\n try {\n for (let i = 0; i < total; i++) {\n if (drawn >= this.maxRects) {\n break;\n }\n\n const key = i * 5;\n if (position[key] === 0) {\n continue;\n }\n if (activeZone) {\n const owner = (paint as any)?.__owner?.value;\n if (!owner || activeZone.objects.indexOf(owner) === -1) {\n continue;\n }\n }\n\n const x = position[key + 1] + navigatorTransform.offsetX;\n const y = position[key + 2] + navigatorTransform.offsetY;\n const width = Math.max(this.minVisibleRectSize, position[key + 3] - position[key + 1]);\n const height = Math.max(this.minVisibleRectSize, position[key + 4] - position[key + 2]);\n\n if (paint instanceof Geometry) {\n this.renderGeometry(ctx, paint, x, y, navigatorTransform.scale);\n } else if (paint instanceof Box) {\n this.renderBox(ctx, paint, x, y, width, height, navigatorTransform.scale);\n } else if (!this.renderImagePaint(ctx, paint, i, x, y, width, height)) {\n if (this.drawFallbackBoxes) {\n this.renderFallbackBox(ctx, x, y, width, height);\n }\n }\n\n drawn++;\n }\n } finally {\n if (layerClipBounds) {\n ctx.restore();\n }\n }\n }\n }\n\n private renderFallbackBox(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number) {\n const px = Math.round(x);\n const py = Math.round(y);\n const pw = Math.max(1, Math.round(width));\n const ph = Math.max(1, Math.round(height));\n\n ctx.fillStyle = this.style.objectFill;\n ctx.strokeStyle = this.style.objectStroke;\n ctx.lineWidth = 1;\n ctx.fillRect(px, py, pw, ph);\n if (pw > 2 && ph > 2) {\n ctx.strokeRect(px + 0.5, py + 0.5, pw - 1, ph - 1);\n }\n }\n\n private renderImagePaint(\n ctx: CanvasRenderingContext2D,\n paint: unknown,\n index: number,\n x: number,\n y: number,\n width: number,\n height: number\n ): boolean {\n if (width <= 0 || height <= 0) {\n return false;\n }\n\n let source: CanvasImageSource | undefined;\n\n if (paint instanceof ImageTexture) {\n source = paint.getTexture()?.source as CanvasImageSource | undefined;\n } else if (paint instanceof SingleImage || paint instanceof TiledImage) {\n const renderedFromSharedCanvas = this.renderSharedCanvasImage(ctx, paint, index, x, y, width, height);\n if (renderedFromSharedCanvas !== null) {\n return renderedFromSharedCanvas;\n }\n if (typeof paint.getImageUrl !== 'function') {\n return false;\n }\n const imageUrl = paint.getImageUrl(index);\n source = this.getLoadedPreviewImage(imageUrl);\n }\n\n if (!source) {\n return false;\n }\n\n const dw = Math.max(1, Math.round(width));\n const dh = Math.max(1, Math.round(height));\n ctx.drawImage(source, Math.round(x), Math.round(y), dw, dh);\n return true;\n }\n\n private ensureSharedCanvasImageBuffer(paint: SingleImage | TiledImage): SharedCanvasImageBuffer {\n if (!paint.__host?.canvas) {\n this.sharedCanvasRenderer?.createImageHost?.(paint);\n }\n if (!paint.__host) {\n paint.__host = {};\n }\n if (!paint.__host.canvas) {\n paint.__host.canvas = {\n canvases: [],\n tiles: {},\n };\n }\n if (!paint.__host.canvas.canvases) {\n paint.__host.canvas.canvases = [];\n }\n if (!paint.__host.canvas.tiles) {\n paint.__host.canvas.tiles = {};\n }\n return paint.__host.canvas as SharedCanvasImageBuffer;\n }\n\n private drawSharedCanvasTile(\n ctx: CanvasRenderingContext2D,\n paint: SingleImage | TiledImage,\n index: number,\n sharedTileCanvas: HTMLCanvasElement,\n x: number,\n y: number,\n width: number,\n height: number\n ): boolean {\n const dw = Math.max(1, Math.round(width));\n const dh = Math.max(1, Math.round(height));\n\n if (paint.crop && paint.cropData) {\n const cropIndex = index * 5;\n if (!paint.crop[cropIndex]) {\n return false;\n }\n\n const sourceX =\n paint.crop[cropIndex + 1] / paint.display.scale -\n paint.display.points[cropIndex + 1] +\n paint.cropData.x / paint.display.scale;\n const sourceY =\n paint.crop[cropIndex + 2] / paint.display.scale -\n paint.display.points[cropIndex + 2] +\n paint.cropData.y / paint.display.scale;\n const sourceWidth = 1 + (paint.crop[cropIndex + 3] - paint.crop[cropIndex + 1]) / paint.display.scale;\n const sourceHeight = 1 + (paint.crop[cropIndex + 4] - paint.crop[cropIndex + 2]) / paint.display.scale;\n\n ctx.drawImage(\n sharedTileCanvas,\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n Math.round(x),\n Math.round(y),\n dw,\n dh\n );\n return true;\n }\n\n const pointIndex = index * 5;\n const sourceWidth = paint.display.points[pointIndex + 3] - paint.display.points[pointIndex + 1];\n const sourceHeight = paint.display.points[pointIndex + 4] - paint.display.points[pointIndex + 2];\n ctx.drawImage(sharedTileCanvas, 0, 0, sourceWidth, sourceHeight, Math.round(x), Math.round(y), dw, dh);\n return true;\n }\n\n private renderSharedCanvasImage(\n ctx: CanvasRenderingContext2D,\n paint: SingleImage | TiledImage,\n index: number,\n x: number,\n y: number,\n width: number,\n height: number\n ): boolean | null {\n const sharedCanvasRenderer = this.sharedCanvasRenderer;\n if (!sharedCanvasRenderer?.hostCache) {\n return null;\n }\n\n const imageBuffer = this.ensureSharedCanvasImageBuffer(paint);\n const canvasId = imageBuffer.canvases?.[index];\n const isInvalidated = !!canvasId && !!sharedCanvasRenderer.invalidated?.includes(canvasId);\n const sharedTileCanvas = canvasId && !isInvalidated ? sharedCanvasRenderer.hostCache.get(canvasId) : undefined;\n\n if (sharedTileCanvas) {\n return this.drawSharedCanvasTile(ctx, paint, index, sharedTileCanvas, x, y, width, height);\n }\n\n const tileState = imageBuffer.tiles?.[index];\n const priority = Math.hypot(x + width / 2 - this.baseCanvas.width / 2, y + height / 2 - this.baseCanvas.height / 2);\n const scheduled = sharedCanvasRenderer.schedulePaintToCanvas?.(imageBuffer, paint, index, priority, false) || false;\n\n if (scheduled || tileState?.state === 'queued' || tileState?.state === 'loading' || tileState?.state === 'decoded') {\n this.sharedCanvasResourcesPending = true;\n }\n\n return false;\n }\n\n private getLoadedPreviewImage(imageUrl: string): HTMLImageElement | undefined {\n const cached = this.previewImageCache.get(imageUrl);\n if (cached) {\n if (cached.status === 'loading' && cached.image.complete) {\n if (cached.image.naturalWidth > 0 && cached.image.naturalHeight > 0) {\n cached.status = 'loaded';\n this.emitDebugEvent({\n type: 'preview-image-loaded',\n imageUrl,\n cached: true,\n });\n this.invalidateWorldLayer('preview-image-loaded');\n return cached.image;\n }\n cached.status = 'error';\n this.emitDebugEvent({\n type: 'preview-image-error',\n imageUrl,\n });\n return undefined;\n }\n return cached.status === 'loaded' ? cached.image : undefined;\n }\n\n const image = new Image();\n const entry: ImageCacheEntry = {\n image,\n status: 'loading',\n };\n this.previewImageCache.set(imageUrl, entry);\n this.emitDebugEvent({\n type: 'preview-image-requested',\n imageUrl,\n });\n\n image.onload = () => {\n if (entry.status !== 'loading') {\n return;\n }\n entry.status = 'loaded';\n this.emitDebugEvent({\n type: 'preview-image-loaded',\n imageUrl,\n cached: false,\n });\n this.invalidateWorldLayer('preview-image-loaded');\n };\n\n image.onerror = () => {\n if (entry.status !== 'loading') {\n return;\n }\n entry.status = 'error';\n this.emitDebugEvent({\n type: 'preview-image-error',\n imageUrl,\n });\n };\n\n image.src = imageUrl;\n\n if (image.complete) {\n if (image.naturalWidth > 0 && image.naturalHeight > 0) {\n entry.status = 'loaded';\n this.emitDebugEvent({\n type: 'preview-image-loaded',\n imageUrl,\n cached: true,\n });\n this.invalidateWorldLayer('preview-image-loaded');\n } else {\n entry.status = 'error';\n this.emitDebugEvent({\n type: 'preview-image-error',\n imageUrl,\n });\n }\n }\n\n return entry.status === 'loaded' ? image : undefined;\n }\n\n private renderBox(\n ctx: CanvasRenderingContext2D,\n paint: Box,\n x: number,\n y: number,\n width: number,\n height: number,\n worldScale: number\n ) {\n const style = paint.props?.style;\n\n if (!style) {\n this.renderFallbackBox(ctx, x, y, width, height);\n return;\n }\n\n const fill = style.backgroundColor || this.style.objectFill;\n const stroke = style.borderColor || this.style.objectStroke;\n const borderWidthRaw = style.borderWidth ? parseInt(style.borderWidth, 10) : 0;\n const borderWidth = Math.max(0, borderWidthRaw * (paint.props?.relativeStyle ? 1 : worldScale));\n\n ctx.globalAlpha = typeof style.opacity === 'number' ? style.opacity : 1;\n ctx.fillStyle = fill;\n ctx.fillRect(Math.round(x), Math.round(y), Math.max(1, Math.round(width)), Math.max(1, Math.round(height)));\n\n if (borderWidth > 0) {\n ctx.strokeStyle = stroke;\n ctx.lineWidth = Math.max(1, borderWidth);\n ctx.strokeRect(\n Math.round(x) + ctx.lineWidth / 2,\n Math.round(y) + ctx.lineWidth / 2,\n Math.max(1, Math.round(width)) - ctx.lineWidth,\n Math.max(1, Math.round(height)) - ctx.lineWidth\n );\n }\n\n ctx.globalAlpha = 1;\n }\n\n private renderGeometry(ctx: CanvasRenderingContext2D, paint: Geometry, x: number, y: number, worldScale: number) {\n const shape = paint.shape;\n if (shape.type !== 'polygon' || shape.points.length === 0) {\n return;\n }\n\n const style = paint.props?.style || {};\n const fill = style.backgroundColor || this.style.objectFill;\n const stroke = style.borderColor || this.style.objectStroke;\n const borderWidthRaw = style.borderWidth ? parseInt(style.borderWidth, 10) : 0;\n const borderWidth = Math.max(0, borderWidthRaw * (paint.props?.relativeStyle ? 1 : worldScale));\n\n ctx.globalAlpha = typeof style.opacity === 'number' ? style.opacity : 1;\n ctx.beginPath();\n\n for (let i = 0; i < shape.points.length; i++) {\n const px = x + shape.points[i][0] * worldScale;\n const py = y + shape.points[i][1] * worldScale;\n if (i === 0) {\n ctx.moveTo(px, py);\n } else {\n ctx.lineTo(px, py);\n }\n }\n\n if (!shape.open) {\n ctx.closePath();\n ctx.fillStyle = fill;\n ctx.fill();\n }\n\n if (borderWidth > 0 || shape.open) {\n ctx.strokeStyle = stroke;\n ctx.lineWidth = Math.max(1, borderWidth || 1);\n ctx.stroke();\n }\n\n ctx.globalAlpha = 1;\n }\n\n private renderViewportBox(target: Strand, region: NavigatorWorldRegion) {\n const transform = getNavigatorWorldTransform(\n region.width,\n region.height,\n this.canvas.width,\n this.canvas.height,\n region.x,\n region.y\n );\n\n const x = (target[1] - transform.worldX) * transform.scale + transform.offsetX;\n const y = (target[2] - transform.worldY) * transform.scale + transform.offsetY;\n const width = (target[3] - target[1]) * transform.scale;\n const height = (target[4] - target[2]) * transform.scale;\n\n const px = Math.round(x);\n const py = Math.round(y);\n const pw = Math.max(1, Math.round(width));\n const ph = Math.max(1, Math.round(height));\n\n this.context.fillStyle = this.style.viewportFill;\n this.context.fillRect(px, py, pw, ph);\n\n this.context.strokeStyle = this.style.viewportStroke;\n this.context.lineWidth = Math.max(1, this.style.viewportLineWidth);\n this.context.strokeRect(px + 0.5, py + 0.5, Math.max(1, pw - 1), Math.max(1, ph - 1));\n }\n}\n","import { TextWrapperOptions } from '../types';\nimport { BaseObject } from './base-object';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../spacial-content/spacial-content';\nimport { Paint } from '../world-objects/paint';\n\nexport type TextProps = TextWrapperOptions & {\n id: string;\n text: string;\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n color: string;\n backgroundColor: string;\n fontSize: number;\n fontFamily: string;\n interactive?: boolean;\n};\n\nexport class Text extends BaseObject<TextProps> implements SpacialContent {\n type: 'spacial-content' = 'spacial-content';\n id: string;\n points: Strand;\n color = '#000';\n backgroundColor?: string;\n hovering?: boolean;\n pressing?: boolean;\n text = '';\n display = {\n x: 0,\n y: 0,\n scale: 1,\n width: 100,\n height: 100,\n points: dna(5),\n };\n className?: string;\n html?: boolean;\n interactive = false;\n props: TextWrapperOptions & {\n title?: string;\n href?: string;\n hrefTarget?: string;\n interactive?: boolean;\n relativeSize?: boolean;\n relativeStyle?: boolean;\n className?: string;\n html?: boolean;\n } = {\n font: '18px Arial, sans-serif',\n lineHeight: 1,\n textAlign: 'left',\n verticalAlign: 'top',\n paddingX: 0,\n paddingY: 0,\n fitParent: false,\n lineBreak: 'auto',\n strokeText: false,\n sizeToFill: false,\n maxFontSizeToFill: undefined,\n allowNewLine: true,\n justifyLines: false,\n renderHDPI: false,\n textDecoration: 'none',\n interactive: false,\n relativeSize: false,\n };\n\n constructor() {\n super();\n this.id = '';\n this.points = dna(5);\n }\n\n getAllPointsAt(target: Strand, aggregate: Strand): Paint[] {\n return [[this as any, this.points, aggregate]];\n }\n\n applyProps({\n id,\n target,\n text,\n color,\n backgroundColor,\n fontSize = 18,\n interactive,\n fontFamily = 'Arial, sans-serif',\n ...props\n }: Partial<TextProps>) {\n props.font = `${fontSize}px ${fontFamily}`;\n\n this.interactive = interactive || false;\n\n if (typeof text !== 'undefined') {\n this.text = text || '';\n }\n if (color) {\n this.color = color;\n }\n if (backgroundColor) {\n this.backgroundColor = backgroundColor;\n }\n if (id) {\n this.id = id;\n }\n if (target) {\n this.points = DnaFactory.singleBox(target.width, target.height, target.x, target.y);\n this.display.points = this.points;\n this.display.width = target.width;\n this.display.height = target.height;\n }\n this.props = { ...this.props, ...props };\n // Bump revision.\n this.__revision++;\n }\n}\n","/**\n * A string hashing function based on Daniel J. Bernstein's popular 'times 33' hash algorithm.\n * @author MatthewBarker <mrjbarker@hotmail.com>\n */\nexport function hash(object: any, str?: boolean): string {\n const text = str ? object : JSON.stringify(object);\n\n let numHash = 5381,\n index = text.length;\n\n while (index) {\n numHash = (numHash * 33) ^ text.charCodeAt(--index);\n }\n\n const num = numHash >>> 0;\n\n const hexString = num.toString(16);\n if (hexString.length % 2) {\n return '0' + hexString;\n }\n return hexString;\n}\n","import { hash } from './hash';\n\nexport class Stylesheet {\n $element: HTMLStyleElement;\n stylesheetClasses: string[];\n activeStylesheetClasses: string[];\n sheetsDidUpdate: boolean;\n sheetPrefix: string;\n stylesheetEntries: Record<string, string>;\n\n constructor(options?: { sheetPrefix?: string }) {\n this.sheetPrefix = options?.sheetPrefix || 'a-';\n this.$element = document.createElement('style');\n this.stylesheetClasses = [];\n this.activeStylesheetClasses = [];\n this.sheetsDidUpdate = false;\n this.stylesheetEntries = {};\n }\n\n getElement() {\n return this.$element;\n }\n\n addStylesheet(_sheet: string) {\n const sheet = _sheet.replace(/\\s\\s+/g, ' ').replace(/: /g, ':').replace(/; /g, ';').trim();\n const className = this.sheetPrefix + hash(sheet, true);\n if (this.stylesheetClasses.indexOf(className) !== -1) {\n return className;\n }\n this.stylesheetClasses.push(className);\n this.activeStylesheetClasses.push(className);\n this.stylesheetEntries[className] = sheet;\n this.sheetsDidUpdate = true;\n return className;\n }\n\n removeStylesheet(obj: any) {\n const className = this.sheetPrefix + hash(obj, true);\n if (this.stylesheetClasses.indexOf(className)) {\n this.stylesheetClasses = this.stylesheetClasses.filter((t) => t !== className);\n }\n this.sheetsDidUpdate = true;\n }\n\n clearClasses() {\n this.activeStylesheetClasses = [];\n }\n\n didUpdateActive() {\n if (this.activeStylesheetClasses.length) {\n for (const sheet of this.activeStylesheetClasses) {\n if (this.stylesheetClasses.indexOf(sheet) === -1) {\n return true;\n }\n }\n for (const sheet of this.stylesheetClasses) {\n if (this.activeStylesheetClasses.indexOf(sheet) === -1) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n updateSheet() {\n if (this.sheetsDidUpdate || this.didUpdateActive()) {\n this.$element.innerText = this.activeStylesheetClasses\n .map((className) => `.${className}{${this.stylesheetEntries[className]}}`)\n .join('');\n this.sheetsDidUpdate = false;\n this.stylesheetClasses = [...this.activeStylesheetClasses];\n }\n }\n}\n","import type { Strand } from '@atlas-viewer/dna';\nimport { Box } from '../../objects/box';\nimport { Text } from '../../objects/text';\nimport type { Renderer } from '../../renderer/renderer';\nimport type { SpacialContent } from '../../spacial-content/spacial-content';\nimport type { PositionPair } from '../../types';\nimport { Stylesheet } from '../../utility/stylesheet';\nimport type { World } from '../../world';\nimport type { Paint } from '../../world-objects/paint';\n\nexport type OverlayRendererOptions = {\n sheetPrefix: string;\n box: boolean;\n text: boolean;\n inlineStyles: boolean;\n triggerResize: () => void;\n background: string;\n};\n\nexport class OverlayRenderer implements Renderer {\n htmlContainer: HTMLDivElement;\n visible: Array<Text | Box | SpacialContent> = [];\n previousVisible: Array<Text | Box | SpacialContent> = [];\n htmlIds: string[] = [];\n firstMeaningfulPaint = false;\n rendererPosition: DOMRect;\n stylesheet: Stylesheet;\n options: OverlayRendererOptions;\n paintTx = 1;\n zIndex = 0;\n classes: {\n hostClassName: string;\n interactive: string;\n nonInteractive: string;\n };\n\n constructor(htmlContainer: HTMLDivElement, options?: Partial<OverlayRendererOptions>) {\n this.htmlContainer = htmlContainer;\n this.htmlContainer.innerHTML = '';\n this.rendererPosition = this.htmlContainer.getBoundingClientRect();\n this.options = {\n triggerResize: () => {},\n box: false,\n text: false,\n sheetPrefix: '',\n inlineStyles: false,\n background: '',\n ...(options || {}),\n };\n this.stylesheet = new Stylesheet({ sheetPrefix: this.options.sheetPrefix });\n if (!this.options.inlineStyles) {\n this.htmlContainer.appendChild(this.stylesheet.getElement());\n }\n\n if (this.options.background) {\n this.htmlContainer.classList.add(\n this.stylesheet.addStylesheet(`\n background: ${this.options.background};\n `)\n );\n }\n\n // Default classes.\n this.classes = {\n hostClassName: this.stylesheet.addStylesheet(`\n position: absolute;\n transform-origin: 0px 0px;\n `),\n interactive: this.stylesheet.addStylesheet(`pointer-events: all`),\n nonInteractive: this.stylesheet.addStylesheet(`pointer-events: none`),\n };\n this.stylesheet.updateSheet();\n }\n\n createHtmlHost(paint: Text | Box) {\n if (\n this.htmlContainer &&\n ((paint instanceof Text && this.options.text) ||\n this.options.box ||\n paint.props.className ||\n paint.props.html ||\n paint.props.href)\n ) {\n const div = document.createElement(paint.props.href ? 'a' : 'div');\n if (paint.props.href) {\n div.style.display = 'block';\n (div as HTMLAnchorElement).href = paint.props.href;\n const target = paint.props.hrefTarget || '_blank';\n (div as HTMLAnchorElement).target = target;\n if (target !== '_self') {\n (div as HTMLAnchorElement).rel = 'noopener noreferrer';\n }\n }\n div.title = paint.props.title || '';\n if (this.options.inlineStyles) {\n div.style.display = 'block';\n div.style.position = 'absolute';\n div.style.overflow = 'hidden';\n div.style.transformOrigin = '0px 0px';\n } else {\n div.classList.add(this.classes.hostClassName);\n }\n paint.__host = { element: div, revision: null, relative: false };\n this.updateHtmlHost(paint, paint.width, paint.height);\n if (paint.__onCreate) {\n paint.__onCreate();\n }\n }\n }\n\n triggerResize() {\n this.options.triggerResize();\n }\n\n updateHtmlHost(paint: Text | Box, width?: number, height?: number) {\n if (paint.__revision !== paint.__host.revision) {\n const div = paint.__host.element;\n const classes = [this.classes.hostClassName];\n\n if (paint.props.interactive) {\n if (this.options.inlineStyles) {\n div.style.pointerEvents = 'all';\n } else {\n classes.push(this.classes.interactive);\n }\n } else {\n if (this.options.inlineStyles) {\n div.style.pointerEvents = 'none';\n } else {\n classes.push(this.classes.nonInteractive);\n }\n }\n\n if (paint.props.href) {\n div.style.display = 'block';\n (div as HTMLAnchorElement).href = paint.props.href;\n const target = paint.props.hrefTarget || '_blank';\n (div as HTMLAnchorElement).target = target;\n if (target !== '_self') {\n (div as HTMLAnchorElement).rel = 'noopener noreferrer';\n } else {\n (div as HTMLAnchorElement).rel = '';\n }\n } else if ((div as HTMLAnchorElement).href) {\n (div as HTMLAnchorElement).removeAttribute('href');\n }\n\n if (paint.props.title) {\n div.title = paint.props.title || '';\n }\n\n if (paint.props.className) {\n classes.push(paint.props.className);\n if (paint.hovering) {\n classes.push(`${paint.props.className}--hover`);\n }\n if (paint.pressing) {\n classes.push(`${paint.props.className}--active`);\n }\n }\n\n if (paint.props.relativeStyle) {\n div.style.width = `${width || paint.width}px`;\n div.style.height = `${height || paint.height}px`;\n } else {\n div.style.width = `${paint.width}px`;\n div.style.height = `${paint.height}px`;\n }\n\n const style = (paint.props as any).style;\n if (style) {\n Object.assign(\n div.style,\n (paint.props as any).style || {},\n (paint as any).hovering ? (paint.props as any).hoverStyles || {} : {},\n (paint as any).pressing ? (paint.props as any).pressStyles || {} : {}\n );\n return;\n }\n\n if (this.options.text && paint instanceof Text) {\n if (paint.text) {\n div.innerText = paint.text;\n }\n if (paint.backgroundColor) {\n div.style.backgroundColor = paint.backgroundColor;\n }\n if (paint.color) {\n div.style.color = paint.color;\n }\n if (paint.props.font) {\n div.style.font = paint.props.font;\n }\n if (paint.props.textAlign) {\n div.style.textAlign = paint.props.textAlign;\n }\n paint.__host.revision = paint.__revision;\n const classNames = classes.join(' ');\n div.className = classNames;\n div.part = classNames;\n }\n if (paint instanceof Box && (this.options.box || paint.props.className || paint.props.html)) {\n if (paint.props.backgroundColor) {\n div.style.backgroundColor = paint.props.backgroundColor;\n }\n if (paint.props.border !== div.style.border) {\n div.style.border = paint.props.border;\n }\n }\n\n const classNames = classes.join(' ');\n div.className = classNames;\n div.part = classNames;\n }\n }\n\n afterFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.updateSheet();\n\n for (const prev of this.previousVisible) {\n if (this.visible.indexOf(prev) === -1) {\n if (\n // HTML container\n this.htmlContainer &&\n // Previous ID\n prev.__id &&\n // Is it in the list.\n this.htmlIds.indexOf(prev.__id) !== -1\n ) {\n this.htmlContainer.removeChild(prev.__host.element);\n }\n }\n }\n // Set them.\n this.previousVisible = this.visible;\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {\n // No-op\n }\n\n beforeFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.clearClasses();\n this.paintTx++;\n this.zIndex = 0;\n this.visible = [];\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n const w = this.rendererPosition.width / width;\n const h = this.rendererPosition.height / height;\n return w < h ? h : w;\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n isReady(): boolean {\n return true;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n this.zIndex++;\n\n if (\n ((this.options.text && paint instanceof Text) ||\n (paint instanceof Box && (this.options.box || paint.props.className || paint.props.html))) &&\n paint.__host &&\n paint.__host.tx !== this.paintTx\n ) {\n this.visible.push(paint);\n paint.__host.tx = this.paintTx;\n\n if (this.htmlContainer) {\n this.updateHtmlHost(paint, width, height);\n\n const scale = width / paint.width;\n const element: HTMLDivElement = paint.__host.element;\n element.style.zIndex = `${this.zIndex}`;\n\n if (paint.props.relativeStyle) {\n element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;\n // element.style.transformOrigin = '0px 0px';\n } else {\n // How to rotate overlays.. but don't do it.\n // element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px) translate(${width/2}px, ${height/2}px) rotate(${paint.__owner.value?.rotation || 0}deg) translate(-${width/2}px, -${height/2}px) scale(${scale})`;\n element.style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px) scale(${scale})`;\n // element.style.transformOrigin = '0px 0px';\n }\n\n if (this.previousVisible.indexOf(paint) === -1) {\n this.htmlContainer.appendChild(element);\n }\n if (this.htmlIds.indexOf(paint.__id) === -1) {\n this.htmlIds.push(paint.__id);\n }\n }\n }\n }\n\n pendingUpdate(): boolean {\n return false;\n }\n\n prepareLayer(paint: SpacialContent): void {\n if (!paint.__host) {\n if (paint instanceof Text || paint instanceof Box) {\n this.createHtmlHost(paint);\n }\n }\n }\n\n resize(width?: number, height?: number): void {\n if (typeof width !== 'undefined' && typeof height !== 'undefined') {\n this.htmlContainer.style.width = `${width}px`;\n this.htmlContainer.style.height = `${height}px`;\n }\n this.rendererPosition = this.htmlContainer.getBoundingClientRect();\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n finishLayer() {}\n\n reset() {}\n}\n","/**\n * Copyright 2004-present Facebook. All Rights Reserved.\n *\n * @providesModule UserAgent_DEPRECATED\n */\n\n/**\n * Provides entirely client-side User Agent and OS detection. You should prefer\n * the non-deprecated UserAgent module when possible, which exposes our\n * authoritative server-side PHP-based detection to the client.\n *\n * Usage is straightforward:\n *\n * if (UserAgent_DEPRECATED.ie()) {\n * // IE\n * }\n *\n * You can also do version checks:\n *\n * if (UserAgent_DEPRECATED.ie() >= 7) {\n * // IE7 or better\n * }\n *\n * The browser functions will return NaN if the browser does not match, so\n * you can also do version compares the other way:\n *\n * if (UserAgent_DEPRECATED.ie() < 7) {\n * // IE6 or worse\n * }\n *\n * Note that the version is a float and may include a minor version number,\n * so you should always use range operators to perform comparisons, not\n * strict equality.\n *\n * **Note:** You should **strongly** prefer capability detection to browser\n * version detection where it's reasonable:\n *\n * http://www.quirksmode.org/js/support.html\n *\n * Further, we have a large number of mature wrapper functions and classes\n * which abstract away many browser irregularities. Check the documentation,\n * grep for things, or ask on javascript@lists.facebook.com before writing yet\n * another copy of \"event || window.event\".\n *\n */\n\nvar _populated = false;\n\n// Browsers\nvar _ie, _firefox, _opera, _webkit, _chrome;\n\n// Actual IE browser for compatibility mode\nvar _ie_real_version;\n\n// Platforms\nvar _osx, _windows, _linux, _android;\n\n// Architectures\nvar _win64;\n\n// Devices\nvar _iphone, _ipad, _native;\n\nvar _mobile;\n\nfunction _populate() {\n if (_populated) {\n return;\n }\n\n _populated = true;\n\n // To work around buggy JS libraries that can't handle multi-digit\n // version numbers, Opera 10's user agent string claims it's Opera\n // 9, then later includes a Version/X.Y field:\n //\n // Opera/9.80 (foo) Presto/2.2.15 Version/10.10\n var uas = navigator.userAgent;\n var agent = /(?:MSIE.(\\d+\\.\\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\\d+\\.\\d+))|(?:Opera(?:.+Version.|.)(\\d+\\.\\d+))|(?:AppleWebKit.(\\d+(?:\\.\\d+)?))|(?:Trident\\/\\d+\\.\\d+.*rv:(\\d+\\.\\d+))/.exec(uas);\n var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas);\n\n _iphone = /\\b(iPhone|iP[ao]d)/.exec(uas);\n _ipad = /\\b(iP[ao]d)/.exec(uas);\n _android = /Android/i.exec(uas);\n _native = /FBAN\\/\\w+;/i.exec(uas);\n _mobile = /Mobile/i.exec(uas);\n\n // Note that the IE team blog would have you believe you should be checking\n // for 'Win64; x64'. But MSDN then reveals that you can actually be coming\n // from either x64 or ia64; so ultimately, you should just check for Win64\n // as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit\n // Windows will send 'WOW64' instead.\n _win64 = !!(/Win64/.exec(uas));\n\n if (agent) {\n _ie = agent[1] ? parseFloat(agent[1]) : (\n agent[5] ? parseFloat(agent[5]) : NaN);\n // IE compatibility mode\n if (_ie && document && document.documentMode) {\n _ie = document.documentMode;\n }\n // grab the \"true\" ie version from the trident token if available\n var trident = /(?:Trident\\/(\\d+.\\d+))/.exec(uas);\n _ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie;\n\n _firefox = agent[2] ? parseFloat(agent[2]) : NaN;\n _opera = agent[3] ? parseFloat(agent[3]) : NaN;\n _webkit = agent[4] ? parseFloat(agent[4]) : NaN;\n if (_webkit) {\n // We do not add the regexp to the above test, because it will always\n // match 'safari' only since 'AppleWebKit' appears before 'Chrome' in\n // the userAgent string.\n agent = /(?:Chrome\\/(\\d+\\.\\d+))/.exec(uas);\n _chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN;\n } else {\n _chrome = NaN;\n }\n } else {\n _ie = _firefox = _opera = _chrome = _webkit = NaN;\n }\n\n if (os) {\n if (os[1]) {\n // Detect OS X version. If no version number matches, set _osx to true.\n // Version examples: 10, 10_6_1, 10.7\n // Parses version number as a float, taking only first two sets of\n // digits. If only one set of digits is found, returns just the major\n // version number.\n var ver = /(?:Mac OS X (\\d+(?:[._]\\d+)?))/.exec(uas);\n\n _osx = ver ? parseFloat(ver[1].replace('_', '.')) : true;\n } else {\n _osx = false;\n }\n _windows = !!os[2];\n _linux = !!os[3];\n } else {\n _osx = _windows = _linux = false;\n }\n}\n\nvar UserAgent_DEPRECATED = {\n\n /**\n * Check if the UA is Internet Explorer.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n ie: function() {\n return _populate() || _ie;\n },\n\n /**\n * Check if we're in Internet Explorer compatibility mode.\n *\n * @return bool true if in compatibility mode, false if\n * not compatibility mode or not ie\n */\n ieCompatibilityMode: function() {\n return _populate() || (_ie_real_version > _ie);\n },\n\n\n /**\n * Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we\n * only need this because Skype can't handle 64-bit IE yet. We need to remove\n * this when we don't need it -- tracked by #601957.\n */\n ie64: function() {\n return UserAgent_DEPRECATED.ie() && _win64;\n },\n\n /**\n * Check if the UA is Firefox.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n firefox: function() {\n return _populate() || _firefox;\n },\n\n\n /**\n * Check if the UA is Opera.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n opera: function() {\n return _populate() || _opera;\n },\n\n\n /**\n * Check if the UA is WebKit.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n webkit: function() {\n return _populate() || _webkit;\n },\n\n /**\n * For Push\n * WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit\n */\n safari: function() {\n return UserAgent_DEPRECATED.webkit();\n },\n\n /**\n * Check if the UA is a Chrome browser.\n *\n *\n * @return float|NaN Version number (if match) or NaN.\n */\n chrome : function() {\n return _populate() || _chrome;\n },\n\n\n /**\n * Check if the user is running Windows.\n *\n * @return bool `true' if the user's OS is Windows.\n */\n windows: function() {\n return _populate() || _windows;\n },\n\n\n /**\n * Check if the user is running Mac OS X.\n *\n * @return float|bool Returns a float if a version number is detected,\n * otherwise true/false.\n */\n osx: function() {\n return _populate() || _osx;\n },\n\n /**\n * Check if the user is running Linux.\n *\n * @return bool `true' if the user's OS is some flavor of Linux.\n */\n linux: function() {\n return _populate() || _linux;\n },\n\n /**\n * Check if the user is running on an iPhone or iPod platform.\n *\n * @return bool `true' if the user is running some flavor of the\n * iPhone OS.\n */\n iphone: function() {\n return _populate() || _iphone;\n },\n\n mobile: function() {\n return _populate() || (_iphone || _ipad || _android || _mobile);\n },\n\n nativeApp: function() {\n // webviews inside of the native apps\n return _populate() || _native;\n },\n\n android: function() {\n return _populate() || _android;\n },\n\n ipad: function() {\n return _populate() || _ipad;\n }\n};\n\nmodule.exports = UserAgent_DEPRECATED;\n","/**\n * Copyright (c) 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule ExecutionEnvironment\n */\n\n/*jslint evil: true */\n\n'use strict';\n\nvar canUseDOM = !!(\n typeof window !== 'undefined' &&\n window.document &&\n window.document.createElement\n);\n\n/**\n * Simple, lightweight module assisting with the detection and context of\n * Worker. Helps avoid circular dependencies and allows code to reason about\n * whether or not they are in a Worker, even if they never include the main\n * `ReactWorker` dependency.\n */\nvar ExecutionEnvironment = {\n\n canUseDOM: canUseDOM,\n\n canUseWorkers: typeof Worker !== 'undefined',\n\n canUseEventListeners:\n canUseDOM && !!(window.addEventListener || window.attachEvent),\n\n canUseViewport: canUseDOM && !!window.screen,\n\n isInWorker: !canUseDOM // For now, this is true - might change in the future.\n\n};\n\nmodule.exports = ExecutionEnvironment;\n","/**\n * Copyright 2013-2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule isEventSupported\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('./ExecutionEnvironment');\n\nvar useHasFeature;\nif (ExecutionEnvironment.canUseDOM) {\n useHasFeature =\n document.implementation &&\n document.implementation.hasFeature &&\n // always returns true in newer browsers as per the standard.\n // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n document.implementation.hasFeature('', '') !== true;\n}\n\n/**\n * Checks if an event is supported in the current execution environment.\n *\n * NOTE: This will not work correctly for non-generic events such as `change`,\n * `reset`, `load`, `error`, and `select`.\n *\n * Borrows from Modernizr.\n *\n * @param {string} eventNameSuffix Event name, e.g. \"click\".\n * @param {?boolean} capture Check if the capture phase is supported.\n * @return {boolean} True if the event is supported.\n * @internal\n * @license Modernizr 3.0.0pre (Custom Build) | MIT\n */\nfunction isEventSupported(eventNameSuffix, capture) {\n if (!ExecutionEnvironment.canUseDOM ||\n capture && !('addEventListener' in document)) {\n return false;\n }\n\n var eventName = 'on' + eventNameSuffix;\n var isSupported = eventName in document;\n\n if (!isSupported) {\n var element = document.createElement('div');\n element.setAttribute(eventName, 'return;');\n isSupported = typeof element[eventName] === 'function';\n }\n\n if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {\n // This is the only way to test support for the `wheel` event in IE9+.\n isSupported = document.implementation.hasFeature('Events.wheel', '3.0');\n }\n\n return isSupported;\n}\n\nmodule.exports = isEventSupported;\n","/**\n * Copyright (c) 2015, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @providesModule normalizeWheel\n * @typechecks\n */\n\n'use strict';\n\nvar UserAgent_DEPRECATED = require('./UserAgent_DEPRECATED');\n\nvar isEventSupported = require('./isEventSupported');\n\n\n// Reasonable defaults\nvar PIXEL_STEP = 10;\nvar LINE_HEIGHT = 40;\nvar PAGE_HEIGHT = 800;\n\n/**\n * Mouse wheel (and 2-finger trackpad) support on the web sucks. It is\n * complicated, thus this doc is long and (hopefully) detailed enough to answer\n * your questions.\n *\n * If you need to react to the mouse wheel in a predictable way, this code is\n * like your bestest friend. * hugs *\n *\n * As of today, there are 4 DOM event types you can listen to:\n *\n * 'wheel' -- Chrome(31+), FF(17+), IE(9+)\n * 'mousewheel' -- Chrome, IE(6+), Opera, Safari\n * 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother!\n * 'DOMMouseScroll' -- FF(0.9.7+) since 2003\n *\n * So what to do? The is the best:\n *\n * normalizeWheel.getEventType();\n *\n * In your event callback, use this code to get sane interpretation of the\n * deltas. This code will return an object with properties:\n *\n * spinX -- normalized spin speed (use for zoom) - x plane\n * spinY -- \" - y plane\n * pixelX -- normalized distance (to pixels) - x plane\n * pixelY -- \" - y plane\n *\n * Wheel values are provided by the browser assuming you are using the wheel to\n * scroll a web page by a number of lines or pixels (or pages). Values can vary\n * significantly on different platforms and browsers, forgetting that you can\n * scroll at different speeds. Some devices (like trackpads) emit more events\n * at smaller increments with fine granularity, and some emit massive jumps with\n * linear speed or acceleration.\n *\n * This code does its best to normalize the deltas for you:\n *\n * - spin is trying to normalize how far the wheel was spun (or trackpad\n * dragged). This is super useful for zoom support where you want to\n * throw away the chunky scroll steps on the PC and make those equal to\n * the slow and smooth tiny steps on the Mac. Key data: This code tries to\n * resolve a single slow step on a wheel to 1.\n *\n * - pixel is normalizing the desired scroll delta in pixel units. You'll\n * get the crazy differences between browsers, but at least it'll be in\n * pixels!\n *\n * - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This\n * should translate to positive value zooming IN, negative zooming OUT.\n * This matches the newer 'wheel' event.\n *\n * Why are there spinX, spinY (or pixels)?\n *\n * - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn\n * with a mouse. It results in side-scrolling in the browser by default.\n *\n * - spinY is what you expect -- it's the classic axis of a mouse wheel.\n *\n * - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and\n * probably is by browsers in conjunction with fancy 3D controllers .. but\n * you know.\n *\n * Implementation info:\n *\n * Examples of 'wheel' event if you scroll slowly (down) by one step with an\n * average mouse:\n *\n * OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120)\n * OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12)\n * OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A)\n * Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120)\n * Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120)\n *\n * On the trackpad:\n *\n * OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6)\n * OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A)\n *\n * On other/older browsers.. it's more complicated as there can be multiple and\n * also missing delta values.\n *\n * The 'wheel' event is more standard:\n *\n * http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents\n *\n * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and\n * deltaX, deltaY and deltaZ. Some browsers provide other values to maintain\n * backward compatibility with older events. Those other values help us\n * better normalize spin speed. Example of what the browsers provide:\n *\n * | event.wheelDelta | event.detail\n * ------------------+------------------+--------------\n * Safari v5/OS X | -120 | 0\n * Safari v5/Win7 | -120 | 0\n * Chrome v17/OS X | -120 | 0\n * Chrome v17/Win7 | -120 | 0\n * IE9/Win7 | -120 | undefined\n * Firefox v4/OS X | undefined | 1\n * Firefox v4/Win7 | undefined | 3\n *\n */\nfunction normalizeWheel(/*object*/ event) /*object*/ {\n var sX = 0, sY = 0, // spinX, spinY\n pX = 0, pY = 0; // pixelX, pixelY\n\n // Legacy\n if ('detail' in event) { sY = event.detail; }\n if ('wheelDelta' in event) { sY = -event.wheelDelta / 120; }\n if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; }\n if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; }\n\n // side scrolling on FF with DOMMouseScroll\n if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {\n sX = sY;\n sY = 0;\n }\n\n pX = sX * PIXEL_STEP;\n pY = sY * PIXEL_STEP;\n\n if ('deltaY' in event) { pY = event.deltaY; }\n if ('deltaX' in event) { pX = event.deltaX; }\n\n if ((pX || pY) && event.deltaMode) {\n if (event.deltaMode == 1) { // delta in LINE units\n pX *= LINE_HEIGHT;\n pY *= LINE_HEIGHT;\n } else { // delta in PAGE units\n pX *= PAGE_HEIGHT;\n pY *= PAGE_HEIGHT;\n }\n }\n\n // Fall-back if spin cannot be determined\n if (pX && !sX) { sX = (pX < 1) ? -1 : 1; }\n if (pY && !sY) { sY = (pY < 1) ? -1 : 1; }\n\n return { spinX : sX,\n spinY : sY,\n pixelX : pX,\n pixelY : pY };\n}\n\n\n/**\n * The best combination if you prefer spinX + spinY normalization. It favors\n * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with\n * 'wheel' event, making spin speed determination impossible.\n */\nnormalizeWheel.getEventType = function() /*string*/ {\n return (UserAgent_DEPRECATED.firefox())\n ? 'DOMMouseScroll'\n : (isEventSupported('wheel'))\n ? 'wheel'\n : 'mousewheel';\n};\n\nmodule.exports = normalizeWheel;\n","module.exports = require('./src/normalizeWheel.js');\n","export type EasingFunction = (progress: number) => number;\n\n// Adapted from\n// https://github.com/ai/easings.net/blob/master/src/easings/easingsFunctions.ts\n\nconst pow = Math.pow;\nconst sqrt = Math.sqrt;\nconst sin = Math.sin;\nconst cos = Math.cos;\nconst PI = Math.PI;\nconst c1 = 1.70158;\nconst c2 = c1 * 1.525;\nconst c3 = c1 + 1;\nconst c4 = (2 * PI) / 3;\nconst c5 = (2 * PI) / 4.5;\n\nexport const bounceOut: EasingFunction = function (x) {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n};\n\nexport type EasingFunctionNames =\n | 'linear'\n | 'easeInQuad'\n | 'easeOutQuad'\n | 'easeInOutQuad'\n | 'easeInCubic'\n | 'easeOutCubic'\n | 'easeInOutCubic'\n | 'easeInQuart'\n | 'easeOutQuart'\n | 'easeInOutQuart'\n | 'easeInQuint'\n | 'easeOutQuint'\n | 'easeInOutQuint'\n | 'easeInSine'\n | 'easeOutSine'\n | 'easeInOutSine'\n | 'easeInExpo'\n | 'easeOutExpo'\n | 'easeInOutExpo'\n | 'easeInCirc'\n | 'easeOutCirc'\n | 'easeInOutCirc'\n | 'easeInBack'\n | 'easeOutBack'\n | 'easeInOutBack'\n | 'easeInElastic'\n | 'easeOutElastic'\n | 'easeInOutElastic'\n | 'easeInBounce'\n | 'easeOutBounce'\n | 'easeInOutBounce';\n\nexport const easingFunctions: { [key in EasingFunctionNames]: EasingFunction } = {\n linear: (x) => x,\n easeInQuad: function (x) {\n return x * x;\n },\n easeOutQuad: function (x) {\n return 1 - (1 - x) * (1 - x);\n },\n easeInOutQuad: function (x) {\n return x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2;\n },\n easeInCubic: function (x) {\n return x * x * x;\n },\n easeOutCubic: function (x) {\n return 1 - pow(1 - x, 3);\n },\n easeInOutCubic: function (x) {\n return x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2;\n },\n easeInQuart: function (x) {\n return x * x * x * x;\n },\n easeOutQuart: function (x) {\n return 1 - pow(1 - x, 4);\n },\n easeInOutQuart: function (x) {\n return x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2;\n },\n easeInQuint: function (x) {\n return x * x * x * x * x;\n },\n easeOutQuint: function (x) {\n return 1 - pow(1 - x, 5);\n },\n easeInOutQuint: function (x) {\n return x < 0.5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2;\n },\n easeInSine: function (x) {\n return 1 - cos((x * PI) / 2);\n },\n easeOutSine: function (x) {\n return sin((x * PI) / 2);\n },\n easeInOutSine: function (x) {\n return -(cos(PI * x) - 1) / 2;\n },\n easeInExpo: function (x) {\n return x === 0 ? 0 : pow(2, 10 * x - 10);\n },\n easeOutExpo: function (x) {\n return x === 1 ? 1 : 1 - pow(2, -10 * x);\n },\n easeInOutExpo: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? pow(2, 20 * x - 10) / 2 : (2 - pow(2, -20 * x + 10)) / 2;\n },\n easeInCirc: function (x) {\n return 1 - sqrt(1 - pow(x, 2));\n },\n easeOutCirc: function (x) {\n return sqrt(1 - pow(x - 1, 2));\n },\n easeInOutCirc: function (x) {\n return x < 0.5 ? (1 - sqrt(1 - pow(2 * x, 2))) / 2 : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2;\n },\n easeInBack: function (x) {\n return c3 * x * x * x - c1 * x * x;\n },\n easeOutBack: function (x) {\n return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2);\n },\n easeInOutBack: function (x) {\n return x < 0.5\n ? (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2\n : (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;\n },\n easeInElastic: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4);\n },\n easeOutElastic: function (x) {\n return x === 0 ? 0 : x === 1 ? 1 : pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1;\n },\n easeInOutElastic: function (x) {\n return x === 0\n ? 0\n : x === 1\n ? 1\n : x < 0.5\n ? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2\n : (pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5)) / 2 + 1;\n },\n easeInBounce: function (x) {\n return 1 - bounceOut(1 - x);\n },\n easeOutBounce: bounceOut,\n easeInOutBounce: function (x) {\n return x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2;\n },\n};\n","import { compose, DnaFactory, dna, scaleAtOrigin, transform, translate } from '@atlas-viewer/dna';\n/** @ts-expect-error */\nimport normalizeWheel from 'normalize-wheel';\nimport type { RuntimeController } from '../../types';\nimport { easingFunctions } from '../../utility/easing-functions';\nimport { distance } from '../../utils';\n\nconst INTENT_PAN = 'pan';\nconst INTENT_SCROLL = 'scroll';\nconst INTENT_GESTURE = 'gesture';\n\nexport type PopmotionControllerConfig = {\n zoomOutFactor?: number;\n zoomInFactor?: number;\n maxZoomFactor?: number;\n minZoomFactor?: number;\n zoomDuration?: number;\n zoomClamp?: number;\n zoomWheelConstant?: number;\n panBounceStiffness?: number;\n panBounceDamping?: number;\n panTimeConstant?: number;\n panPower?: number;\n /**\n * Enable inertial momentum when releasing from pan.\n */\n enablePanMomentum?: boolean;\n /**\n * Pan momentum intensity multiplier. 1 is the default \"Apple-like\" feel.\n */\n panMomentumStrength?: number;\n nudgeDistance?: number;\n panPadding?: number;\n devicePixelRatio?: number;\n enableWheel?: boolean;\n enableClickToZoom?: boolean;\n enableDoubleTapZoom?: boolean;\n ignoreSingleFingerTouch?: boolean;\n enablePanOnWait?: boolean;\n requireMetaKeyForWheelZoom?: boolean;\n wheelInExploreModeOnly?: boolean;\n panOnWaitDelay?: number;\n parentElement?: HTMLElement | null;\n onPanInSketchMode?: () => void;\n};\n\nexport const defaultConfig: Required<PopmotionControllerConfig> = {\n // Zoom options\n zoomOutFactor: 0.8,\n zoomInFactor: 1.25,\n maxZoomFactor: 1,\n minZoomFactor: 0.05,\n zoomDuration: 300,\n zoomWheelConstant: 20, // 30 = OSD\n // zoomWheelConstant: 15, // 15 = fast\n // zoomWheelConstant: 18,\n zoomClamp: 0.6,\n // Pan options.\n panBounceStiffness: 120,\n panBounceDamping: 15,\n panTimeConstant: 325,\n panPower: 0.1,\n enablePanMomentum: true,\n panMomentumStrength: 1,\n nudgeDistance: 100,\n panPadding: 0,\n devicePixelRatio: 1,\n // Flags\n enableWheel: true,\n enableClickToZoom: true,\n enableDoubleTapZoom: true,\n ignoreSingleFingerTouch: false,\n enablePanOnWait: false,\n requireMetaKeyForWheelZoom: false,\n wheelInExploreModeOnly: false,\n panOnWaitDelay: 40,\n onPanInSketchMode: () => {\n // no-op\n },\n parentElement: null,\n};\n\nexport const popmotionController = (config: PopmotionControllerConfig = {}): RuntimeController => {\n return {\n start: (runtime) => {\n const {\n zoomWheelConstant,\n enableWheel,\n enableClickToZoom,\n enableDoubleTapZoom,\n ignoreSingleFingerTouch,\n enablePanOnWait,\n panOnWaitDelay,\n parentElement,\n requireMetaKeyForWheelZoom,\n wheelInExploreModeOnly,\n enablePanMomentum,\n panMomentumStrength,\n panBounceStiffness,\n panBounceDamping,\n panTimeConstant,\n panPadding,\n } = {\n ...defaultConfig,\n ...config,\n };\n\n const state = {\n pointerStart: { x: 0, y: 0 },\n isPressing: false,\n mousemoveBuffer: dna(5),\n multiTouch: {\n distance: 0,\n },\n hasMovedSincePress: false,\n };\n const panSamples: Array<{ x: number; y: number; t: number }> = [];\n const momentum = {\n active: false,\n vx: 0,\n vy: 0,\n };\n let lastGestureTarget: any = null;\n let lastGestureOrigin: { x: number; y: number } | undefined;\n let lastTapAt = 0;\n let lastTapPoint: { x: number; y: number } | undefined;\n let currentTapPoint: { x: number; y: number } | undefined;\n const MIN_MOMENTUM_SPEED_PX_PER_MS = 0.08;\n const MOMENTUM_STOP_SPEED_PX_PER_MS = 0.02;\n const MOMENTUM_SAMPLE_WINDOW_MS = 80;\n const MOMENTUM_SAMPLE_MAX_AGE_MS = 140;\n const DOUBLE_TAP_INTERVAL_MS = 350;\n const DOUBLE_TAP_DISTANCE_PX = 100;\n const MAX_TAP_DURATION_MS = 250;\n const DOUBLE_TAP_HOME_ZOOM_TOLERANCE = 0.1;\n const DOUBLE_TAP_TRANSITION_DURATION_MS = 500;\n\n function clearPanSamples() {\n panSamples.length = 0;\n }\n\n function recordPanSample(x: number, y: number) {\n const t = performance.now();\n const last = panSamples[panSamples.length - 1];\n if (last && last.x === x && last.y === y) {\n last.t = t;\n return;\n }\n panSamples.push({ x, y, t });\n while (panSamples.length > 1 && t - panSamples[0].t > MOMENTUM_SAMPLE_MAX_AGE_MS) {\n panSamples.shift();\n }\n }\n\n function stopPanMomentum() {\n momentum.active = false;\n momentum.vx = 0;\n momentum.vy = 0;\n }\n\n function clearGestureState() {\n lastGestureTarget = null;\n lastGestureOrigin = undefined;\n }\n\n function maybeHandleDoubleTap() {\n if (!enableDoubleTapZoom || runtime.mode !== 'explore' || state.hasMovedSincePress || !currentTapPoint) {\n return false;\n }\n\n const now = performance.now();\n if (touchStartTime && now - touchStartTime > MAX_TAP_DURATION_MS) {\n return false;\n }\n\n const isDoubleTap =\n lastTapPoint &&\n lastTapAt > 0 &&\n now - lastTapAt <= DOUBLE_TAP_INTERVAL_MS &&\n distance(lastTapPoint, currentTapPoint) <= DOUBLE_TAP_DISTANCE_PX;\n\n lastTapAt = now;\n lastTapPoint = { ...currentTapPoint };\n\n if (!isDoubleTap) {\n return false;\n }\n\n const target = runtime.isViewportAtHomeZoomLevel({ tolerance: DOUBLE_TAP_HOME_ZOOM_TOLERANCE })\n ? runtime.getHomeTarget({ cover: true })\n : runtime.getHomeTarget();\n runtime.transitionManager.goToRegion(target, {\n transition: {\n duration: DOUBLE_TAP_TRANSITION_DURATION_MS,\n easing: easingFunctions.easeInOutQuad,\n },\n });\n lastTapAt = 0;\n lastTapPoint = undefined;\n return true;\n }\n\n function stepConstrainedMomentumAxis(current: number, velocity: number, deltaMs: number, boundary: number) {\n const deltaSec = Math.min(deltaMs, 32) / 1000;\n const velocityPerSec = velocity * 1000;\n const projected = current + velocityPerSec * deltaSec;\n const displacement = projected - boundary;\n const acceleration = -panBounceStiffness * displacement - panBounceDamping * velocityPerSec;\n const nextVelocityPerSec = velocityPerSec + acceleration * deltaSec;\n const nextPosition = projected + 0.5 * acceleration * deltaSec * deltaSec;\n return {\n position: nextPosition,\n velocity: nextVelocityPerSec / 1000,\n };\n }\n\n function applyPanTransition(toTarget: any) {\n runtime.transitionManager.customTransition((pendingTransition) => {\n pendingTransition.from = dna(runtime.target);\n pendingTransition.to = toTarget;\n pendingTransition.elapsed_time = 0;\n pendingTransition.total_time = 0;\n pendingTransition.timingFunction = easingFunctions.easeInOutExpo;\n pendingTransition.done = false;\n });\n }\n\n function calculateReleaseVelocity() {\n if (panSamples.length < 2) {\n return null;\n }\n const last = panSamples[panSamples.length - 1];\n let first = panSamples[0];\n for (let i = panSamples.length - 2; i >= 0; i--) {\n first = panSamples[i];\n if (last.t - first.t >= MOMENTUM_SAMPLE_WINDOW_MS) {\n break;\n }\n }\n const dt = last.t - first.t;\n if (dt <= 0) {\n return null;\n }\n return {\n vx: (last.x - first.x) / dt,\n vy: (last.y - first.y) / dt,\n };\n }\n\n function maybeStartPanMomentum() {\n if (!enablePanMomentum || !state.hasMovedSincePress || panSamples.length < 2) {\n return false;\n }\n const releaseVelocity = calculateReleaseVelocity();\n if (!releaseVelocity) {\n return false;\n }\n const strength = Math.max(0, panMomentumStrength);\n const vx = releaseVelocity.vx * strength;\n const vy = releaseVelocity.vy * strength;\n const speedPxPerMs = Math.hypot(vx, vy) * runtime.getScaleFactor();\n if (speedPxPerMs < MIN_MOMENTUM_SPEED_PX_PER_MS) {\n return false;\n }\n momentum.active = true;\n momentum.vx = vx;\n momentum.vy = vy;\n runtime.updateNextFrame();\n return true;\n }\n\n function releasePointer() {\n if (!state.isPressing) {\n clearGestureState();\n resetState();\n return;\n }\n const startedMomentum = runtime.mode === 'explore' ? maybeStartPanMomentum() : false;\n if (runtime.mode === 'explore' && !startedMomentum) {\n runtime.world.constraintBounds();\n }\n state.isPressing = false;\n state.hasMovedSincePress = false;\n clearPanSamples();\n clearGestureState();\n resetState();\n }\n\n function releaseGesturePointer() {\n if (!state.isPressing) {\n clearGestureState();\n resetState();\n return;\n }\n\n stopPanMomentum();\n\n if (runtime.mode === 'explore') {\n const pendingTransition = runtime.transitionManager.getPendingTransition();\n const sourceTarget =\n lastGestureTarget ||\n (pendingTransition && pendingTransition.total_time === 0 && !pendingTransition.done\n ? pendingTransition.to\n : runtime.target);\n\n runtime.transitionManager.constrainTarget(sourceTarget, {\n origin: lastGestureOrigin,\n panPadding,\n });\n }\n\n state.isPressing = false;\n state.hasMovedSincePress = false;\n clearPanSamples();\n clearGestureState();\n resetState();\n }\n\n runtime.world.activatedEvents.push(\n // List of events we are supporting.\n 'onMouseUp',\n 'onMouseDown',\n 'onMouseMove',\n 'onTouchStart',\n 'onTouchEnd',\n 'onTouchCancel',\n 'onTouchMove',\n 'onContextMenu'\n );\n\n /**\n * Resets the event state after the gesture of behavior has finished\n */\n function resetState() {\n currentDistance = 0;\n intent = '';\n setDataAttribute();\n setDataAttribute(undefined, 'notice');\n touchStartTime = 0;\n currentTapPoint = undefined;\n }\n\n function onMouseUp() {\n releasePointer();\n }\n\n function onTouchEnd(e: TouchEvent) {\n if (intent === INTENT_GESTURE && e.touches.length < 2) {\n releaseGesturePointer();\n return;\n }\n\n if (e.touches.length === 0) {\n maybeHandleDoubleTap();\n releasePointer();\n }\n }\n\n function onTouchCancel(e: TouchEvent) {\n if (intent === INTENT_GESTURE) {\n releaseGesturePointer();\n return;\n }\n\n releasePointer();\n }\n\n function onMouseDown(e: MouseEvent & { atlas: { x: number; y: number } }) {\n if (e.which > 1) {\n state.isPressing = false;\n return;\n }\n if (runtime.mode === 'explore') {\n e.preventDefault();\n stopPanMomentum();\n clearPanSamples();\n state.hasMovedSincePress = false;\n state.pointerStart.x = e.atlas.x;\n state.pointerStart.y = e.atlas.y;\n recordPanSample(runtime.target[1], runtime.target[2]);\n\n runtime.transitionManager.stopTransition();\n\n state.isPressing = true;\n }\n }\n\n function onWindowMouseUp() {\n releasePointer();\n }\n\n let currentDistance = 0;\n // the performance.now() time at 'touch-start'\n let touchStartTime = 0;\n // what the user's intent would be for the behavior\n let intent = '';\n function onTouchStart(\n e: TouchEvent & {\n atlasTouches: Array<{ id: number; x: number; y: number }>;\n }\n ) {\n if (runtime.mode === 'explore') {\n stopPanMomentum();\n clearPanSamples();\n state.hasMovedSincePress = false;\n if (e.atlasTouches.length === 1) {\n touchStartTime = performance.now();\n if (ignoreSingleFingerTouch == false) {\n // this prevents the touch propagation to the window, and thus doesn't drag the page\n e.preventDefault();\n }\n state.pointerStart.x = e.atlasTouches[0].x;\n state.pointerStart.y = e.atlasTouches[0].y;\n currentTapPoint = { x: e.atlasTouches[0].x, y: e.atlasTouches[0].y };\n recordPanSample(runtime.target[1], runtime.target[2]);\n }\n if (e.atlasTouches.length === 2) {\n intent = INTENT_GESTURE;\n e.preventDefault();\n const x1 = e.atlasTouches[0].x;\n const x2 = e.atlasTouches[1].x;\n state.pointerStart.x = (x1 + x2) / 2;\n const y1 = e.atlasTouches[0].y;\n const y2 = e.atlasTouches[1].y;\n state.pointerStart.y = (y1 + y2) / 2;\n\n currentDistance = distance(\n { x: e.touches[0].clientX, y: e.touches[0].clientY },\n { x: e.touches[1].clientX, y: e.touches[1].clientY }\n );\n clearPanSamples();\n clearGestureState();\n }\n\n runtime.transitionManager.stopTransition();\n\n state.isPressing = true;\n }\n }\n\n /**\n * Sets a data attribute to expose the current intent/behavior/note to the user\n *\n * @param value {string} - the data-attribute value\n * @param dataAttribute {string} - the data-attribute name\n */\n function setDataAttribute(value?: string, dataAttribute = 'intent') {\n if (parentElement) {\n parentElement.dataset[dataAttribute] = value;\n }\n }\n\n function onTouchMove(\n e: TouchEvent & {\n atlasTouches: Array<{ id: number; x: number; y: number }>;\n }\n ) {\n let clientX = null;\n let clientY = null;\n let newDistance = 0;\n let shouldRecordMomentum = false;\n if (state.isPressing && e.touches.length === 2) {\n // We have 2?\n const x1 = e.touches[0].clientX;\n const x2 = e.touches[1].clientX;\n clientX = (x1 + x2) / 2;\n const y1 = e.touches[0].clientY;\n const y2 = e.touches[1].clientY;\n clientY = (y1 + y2) / 2;\n\n newDistance = distance(\n { x: e.touches[0].clientX, y: e.touches[0].clientY },\n { x: e.touches[1].clientX, y: e.touches[1].clientY }\n );\n }\n setDataAttribute(intent);\n\n if (state.isPressing && e.touches.length === 1) {\n if (enablePanOnWait) {\n // if there is a delay between the touch-start and the 1st touch-move of < xms, then treat that as a PAN,\n // anything faster is a window scroll\n if (performance.now() - touchStartTime < panOnWaitDelay && intent == '') {\n intent = INTENT_SCROLL;\n }\n if (intent == '') {\n intent = INTENT_PAN;\n }\n }\n setDataAttribute(intent);\n // if we are ignoring a single finger touch, or it's a window-scroll, just 'return'\n if ((intent == '' && ignoreSingleFingerTouch == true) || intent == INTENT_SCROLL) {\n // have CanvasPanel do nothing... scroll the page\n setDataAttribute('require-two-finger', 'notice');\n return;\n }\n const touch = e.touches[0];\n clientX = touch.clientX;\n clientY = touch.clientY;\n shouldRecordMomentum = true;\n }\n\n // Translate.\n if (clientX !== null && clientY !== null) {\n const bounds = runtime.getRendererScreenPosition();\n if (bounds) {\n const { x, y } = runtime.viewerToWorld(clientX - bounds.x, clientY - bounds.y);\n\n const deltaDistance = newDistance && currentDistance ? newDistance / currentDistance : 1;\n const nextTarget = transform(\n dna(runtime.target),\n compose(\n translate(state.pointerStart.x - x, state.pointerStart.y - y),\n scaleAtOrigin(1 / deltaDistance, x, y)\n ),\n state.mousemoveBuffer\n );\n\n if (shouldRecordMomentum) {\n const previousSample = panSamples[panSamples.length - 1];\n if (previousSample && (previousSample.x !== nextTarget[1] || previousSample.y !== nextTarget[2])) {\n state.hasMovedSincePress = true;\n }\n recordPanSample(nextTarget[1], nextTarget[2]);\n }\n\n if (e.touches.length === 2) {\n lastGestureTarget = dna(nextTarget);\n lastGestureOrigin = { x, y };\n }\n\n applyPanTransition(nextTarget);\n }\n currentDistance = newDistance;\n }\n\n if (intent == INTENT_PAN) {\n // if we're panning, prevent default\n // this does the same thing as touchEvents: none; pointerEvents: none;\n e.preventDefault();\n }\n }\n\n function onMouseMove(e: MouseEvent | PointerEvent) {\n if (state.isPressing) {\n const bounds = runtime.getRendererScreenPosition();\n if (bounds) {\n const { x, y } = runtime.viewerToWorld(e.clientX - bounds.x, e.clientY - bounds.y);\n const nextTarget = transform(\n dna(runtime.target),\n translate(state.pointerStart.x - x, state.pointerStart.y - y),\n state.mousemoveBuffer\n );\n const previousSample = panSamples[panSamples.length - 1];\n if (previousSample && (previousSample.x !== nextTarget[1] || previousSample.y !== nextTarget[2])) {\n state.hasMovedSincePress = true;\n }\n recordPanSample(nextTarget[1], nextTarget[2]);\n applyPanTransition(nextTarget);\n }\n }\n }\n\n function onClick(e: MouseEvent & { atlas: { x: number; y: number } }) {\n if (runtime.mode === 'explore') {\n runtime.world.zoomIn(e.atlas);\n }\n }\n\n function onWheel(e: WheelEvent & { atlas: { x: number; y: number } }) {\n if (wheelInExploreModeOnly && runtime.mode !== 'explore') {\n return;\n }\n stopPanMomentum();\n const normalized = normalizeWheel(e);\n const zoomFactor = 1 + normalized.spinY / zoomWheelConstant;\n runtime.world.zoomTo(\n // Generating a zoom from the wheel delta\n zoomFactor,\n e.atlas,\n true\n );\n }\n\n function onWheelGuard(e: WheelEvent) {\n if (requireMetaKeyForWheelZoom && e.metaKey == false) {\n setDataAttribute('meta-required', 'notice');\n e.stopPropagation();\n return false;\n }\n return true;\n }\n\n runtime.world.addEventListener('mouseup', onMouseUp);\n runtime.world.addEventListener('touchend', onTouchEnd);\n runtime.world.addEventListener('touchcancel', onTouchCancel);\n runtime.world.addEventListener('touchstart', onTouchStart);\n runtime.world.addEventListener('mousedown', onMouseDown);\n\n window.addEventListener('touchend', onWindowMouseUp);\n window.addEventListener('mouseup', onWindowMouseUp);\n\n window.addEventListener('mousemove', onMouseMove);\n\n if (parentElement) {\n // if this is bound to the window, then the entire interaction model goes haywire\n // unclear 100% why\n parentElement.addEventListener('touchmove', onTouchMove as any);\n }\n\n if (enableClickToZoom) {\n runtime.world.activatedEvents.push('onClick');\n runtime.world.addEventListener('click', onClick);\n }\n\n if (enableWheel) {\n runtime.world.activatedEvents.push('onWheel');\n if (requireMetaKeyForWheelZoom) {\n // add an event listener above the world to guard the wheel event if the 'meta' key is pressed\n parentElement?.addEventListener('wheel', onWheelGuard as any, {\n passive: true,\n capture: true,\n });\n }\n runtime.world.addEventListener('wheel', onWheel);\n }\n\n // Layout subscriber - move more into here.\n const removeLayout = runtime.world.addLayoutSubscriber((type, data?: any) => {\n if (type === 'zone-changed') {\n stopPanMomentum();\n // Avoid overriding an in-flight zone-fit transition (e.g. goToZone).\n if (!runtime.transitionManager.hasPending()) {\n runtime.transitionManager.constrainBounds();\n }\n }\n if (type === 'zoom-to' && data) {\n stopPanMomentum();\n // zoomTo(data.factor, data.point, data.stream);\n runtime.transitionManager.zoomTo(data.factor, {\n origin: data.point,\n stream: data.stream,\n });\n }\n if (type === 'go-home') {\n stopPanMomentum();\n const transition = data.immediate ? { duration: 0 } : undefined;\n // Use getHomeTarget to calculate the padded home position\n const paddingPx = data?.paddingPx;\n const homeTarget = runtime.getHomeTarget({ paddingPx });\n runtime.transitionManager.goToRegion(homeTarget, { transition });\n }\n if (type === 'goto-region' && data) {\n stopPanMomentum();\n const transition = data.immediate ? { duration: 0 } : {};\n // If paddingPx is provided, use getHomeTarget to calculate the padded region\n if (data.paddingPx !== undefined) {\n const targetRegion = runtime.getHomeTarget({\n position: DnaFactory.singleBox(data.width, data.height, data.x, data.y),\n paddingPx: data.paddingPx,\n });\n runtime.transitionManager.goToRegion(targetRegion, {\n transition,\n });\n } else {\n runtime.transitionManager.goToRegion(data, { transition });\n }\n }\n if (type === 'constrain-bounds') {\n stopPanMomentum();\n runtime.transitionManager.constrainBounds({\n panPadding,\n transition: data?.immediate ? { duration: 0 } : undefined,\n });\n }\n });\n\n const removeMomentumHook = runtime.registerHook('useFrame', (delta: number) => {\n if (!momentum.active) {\n return;\n }\n const decay = Math.exp(-delta / Math.max(1, panTimeConstant));\n const width = runtime.target[3] - runtime.target[1];\n const height = runtime.target[4] - runtime.target[2];\n const proposed = transform(\n dna(runtime.target),\n translate(momentum.vx * delta, momentum.vy * delta),\n state.mousemoveBuffer\n );\n const [, constrained] = runtime.constrainBounds(proposed, { panPadding });\n\n const xConstrained = proposed[1] !== constrained[1];\n const yConstrained = proposed[2] !== constrained[2];\n\n let nextVx = xConstrained ? momentum.vx : momentum.vx * decay;\n let nextVy = yConstrained ? momentum.vy : momentum.vy * decay;\n const nextTarget = dna(proposed);\n\n if (xConstrained) {\n const stepped = stepConstrainedMomentumAxis(runtime.target[1], momentum.vx, delta, constrained[1]);\n nextTarget[1] = stepped.position;\n nextTarget[3] = stepped.position + width;\n nextVx = stepped.velocity;\n } else {\n nextTarget[1] = runtime.target[1] + nextVx * delta;\n nextTarget[3] = nextTarget[1] + width;\n }\n\n if (yConstrained) {\n const stepped = stepConstrainedMomentumAxis(runtime.target[2], momentum.vy, delta, constrained[2]);\n nextTarget[2] = stepped.position;\n nextTarget[4] = stepped.position + height;\n nextVy = stepped.velocity;\n } else {\n nextTarget[2] = runtime.target[2] + nextVy * delta;\n nextTarget[4] = nextTarget[2] + height;\n }\n\n momentum.vx = nextVx;\n momentum.vy = nextVy;\n\n const [, constrainedNext] = runtime.constrainBounds(nextTarget, { panPadding });\n const overshootPx =\n Math.hypot(nextTarget[1] - constrainedNext[1], nextTarget[2] - constrainedNext[2]) * runtime.getScaleFactor();\n const speedPxPerMs = Math.hypot(momentum.vx, momentum.vy) * runtime.getScaleFactor();\n\n if (overshootPx <= 0.5 && speedPxPerMs <= MOMENTUM_STOP_SPEED_PX_PER_MS) {\n stopPanMomentum();\n applyPanTransition(constrainedNext);\n return;\n }\n\n applyPanTransition(nextTarget);\n runtime.updateNextFrame();\n });\n\n return () => {\n stopPanMomentum();\n runtime.world.removeEventListener('mouseup', onMouseUp);\n runtime.world.removeEventListener('touchend', onTouchEnd);\n runtime.world.removeEventListener('touchcancel', onTouchCancel);\n runtime.world.removeEventListener('touchstart', onTouchStart);\n runtime.world.removeEventListener('mousedown', onMouseDown);\n\n window.removeEventListener('touchend', onWindowMouseUp);\n window.removeEventListener('mouseup', onWindowMouseUp);\n\n window.removeEventListener('mousemove', onMouseMove);\n if (parentElement) {\n (parentElement as any).removeEventListener('touchmove', onTouchMove);\n (parentElement as any).removeEventListener('wheel', onWheelGuard, {\n passive: true,\n capture: true,\n });\n }\n if (enableClickToZoom) {\n runtime.world.removeEventListener('click', onClick);\n }\n\n if (enableWheel) {\n runtime.world.removeEventListener('wheel', onWheel);\n }\n\n removeMomentumHook();\n removeLayout();\n };\n },\n updatePosition() {\n // no-op\n },\n };\n};\n","/** @ts-expect-error */\nimport normalizeWheel from 'normalize-wheel';\nimport type { RuntimeController } from '../../types';\nimport type { ZoneInterface } from '../../world-objects/zone';\nimport { type PopmotionControllerConfig, popmotionController } from '../popmotion-controller/popmotion-controller';\n\ntype ScrollViewport = { x: number; y: number; width: number; height: number };\ntype ControllerMode = 'scroll-mode' | 'zone-active';\ntype WorldPoint = { x: number; y: number };\n\nexport type PdfScrollZoneControllerConfig = PopmotionControllerConfig & {\n scrollWheelFactor?: number;\n scrollLoadAheadFactor?: number;\n clickDragThresholdPx?: number;\n touchScrollMomentumStrength?: number;\n touchScrollMomentumMinStartPxPerMs?: number;\n};\n\nconst defaultConfig: Required<\n Pick<\n PdfScrollZoneControllerConfig,\n | 'scrollWheelFactor'\n | 'scrollLoadAheadFactor'\n | 'clickDragThresholdPx'\n | 'touchScrollMomentumStrength'\n | 'touchScrollMomentumMinStartPxPerMs'\n >\n> = {\n scrollWheelFactor: 1,\n scrollLoadAheadFactor: 1,\n clickDragThresholdPx: 6,\n touchScrollMomentumStrength: 1.4,\n touchScrollMomentumMinStartPxPerMs: 0.04,\n};\nconst ZONE_VIEWPORT_HEIGHT_RATIO = 0.9;\nconst ZONE_VIEWPORT_VERTICAL_PADDING_RATIO = (1 - ZONE_VIEWPORT_HEIGHT_RATIO) / 2;\nconst ZONE_AUTO_EXIT_MIN_COVERAGE_RATIO = 0.8;\nconst SCROLL_MOMENTUM_MIN_START_PX_PER_MS = 0.08;\nconst SCROLL_MOMENTUM_STOP_PX_PER_MS = 0.02;\nconst SCROLL_MOMENTUM_SAMPLE_WINDOW_MS = 80;\nconst SCROLL_MOMENTUM_SAMPLE_MAX_AGE_MS = 140;\nlet nextPdfControllerSessionId = 1;\nconst activePdfControllerSessionByRuntime = new WeakMap<object, number>();\n\nfunction toScrollViewport(viewport: { x: number; y: number; width: number; height: number }): ScrollViewport {\n return {\n x: viewport.x,\n y: viewport.y,\n width: viewport.width,\n height: viewport.height,\n };\n}\n\nfunction pointInZone(zone: ZoneInterface, x: number, y: number): boolean {\n return (\n zone.points[0] !== 0 && x >= zone.points[1] && x <= zone.points[3] && y >= zone.points[2] && y <= zone.points[4]\n );\n}\n\nexport const pdfScrollZoneController = (config: PdfScrollZoneControllerConfig = {}): RuntimeController => {\n return {\n start(runtime) {\n const sessionId = nextPdfControllerSessionId++;\n activePdfControllerSessionByRuntime.set(runtime as object, sessionId);\n const isActiveSession = () => activePdfControllerSessionByRuntime.get(runtime as object) === sessionId;\n const {\n scrollWheelFactor,\n scrollLoadAheadFactor,\n clickDragThresholdPx,\n touchScrollMomentumStrength,\n touchScrollMomentumMinStartPxPerMs,\n enablePanMomentum = true,\n panMomentumStrength = 1,\n panTimeConstant = 325,\n } = {\n ...defaultConfig,\n ...config,\n };\n const queueFollowUpFrame = () => {\n if (followUpFrameQueued) {\n return;\n }\n followUpFrameQueued = true;\n window.requestAnimationFrame(() => {\n followUpFrameQueued = false;\n if (!isActiveSession()) {\n return;\n }\n runtime.updateNextFrame();\n });\n };\n\n const originalMode = runtime.mode;\n const originalManualHomePosition = runtime.manualHomePosition;\n let mode: ControllerMode = 'scroll-mode';\n let restoringViewport = false;\n let exitTransitionInFlight = false;\n let zoneEnteredViaController = false;\n let pendingProgrammaticRestoreZoneId: string | undefined;\n let savedScrollViewport: ScrollViewport | undefined;\n let initialHomeAnchorLocked = false;\n let initialHomeAnchorKey: string | undefined;\n const initialHomeSyncRetryDeadlineMs = performance.now() + 5000;\n let followUpFrameQueued = false;\n let dragStartClientY = 0;\n let dragStartViewportY = 0;\n let pointerDownClientX = 0;\n let pointerDownClientY = 0;\n let activeTouchId: number | null = null;\n let isTouchTapCandidate = false;\n let lastTouchPoint: WorldPoint | null = null;\n let suppressNextClick = false;\n let isDragging = false;\n let scrollViewY = 0;\n let scrollBaseViewportCache: ScrollViewport | undefined;\n let scrollBaseViewportDirty = true;\n let scrollBaseViewportWorldWidth = -1;\n let scrollBaseViewportWorldHeight = -1;\n let scrollBaseViewportScreenWidth = -1;\n let scrollBaseViewportScreenHeight = -1;\n let scrollBaseViewportZoneCount = -1;\n const panSamples: Array<{ y: number; t: number }> = [];\n const momentum = {\n active: false,\n vy: 0,\n };\n\n const popmotion = popmotionController({\n ...config,\n // Keep popmotion wheel enabled for zone-active zoom.\n // Scroll-mode wheel is guarded via wheelInExploreModeOnly + controller mode sync.\n enableWheel: true,\n enableClickToZoom: false,\n wheelInExploreModeOnly: true,\n });\n\n const ensureEventActivated = (eventName: string) => {\n if (runtime.world.activatedEvents.indexOf(eventName) === -1) {\n runtime.world.activatedEvents.push(eventName);\n }\n };\n\n const setMode = (nextMode: ControllerMode) => {\n mode = nextMode;\n runtime.mode = nextMode === 'zone-active' ? 'explore' : 'sketch';\n };\n const clearPanSamples = () => {\n panSamples.length = 0;\n };\n const recordPanSample = (y: number) => {\n const t = performance.now();\n const last = panSamples[panSamples.length - 1];\n if (last && last.y === y) {\n last.t = t;\n return;\n }\n panSamples.push({ y, t });\n while (panSamples.length > 1 && t - panSamples[0].t > SCROLL_MOMENTUM_SAMPLE_MAX_AGE_MS) {\n panSamples.shift();\n }\n };\n const stopScrollMomentum = () => {\n momentum.active = false;\n momentum.vy = 0;\n };\n const calculateReleaseVelocityY = () => {\n if (panSamples.length < 2) {\n return null;\n }\n const last = panSamples[panSamples.length - 1];\n let first = panSamples[0];\n for (let i = panSamples.length - 2; i >= 0; i--) {\n first = panSamples[i];\n if (last.t - first.t >= SCROLL_MOMENTUM_SAMPLE_WINDOW_MS) {\n break;\n }\n }\n const dy = last.y - first.y;\n const dt = last.t - first.t;\n if (dt <= 0 || Math.abs(dy) <= 0.5) {\n return null;\n }\n return dy / dt;\n };\n const maybeStartScrollMomentum = ({\n strengthMultiplier = 1,\n minStartPxPerMs = SCROLL_MOMENTUM_MIN_START_PX_PER_MS,\n }: {\n strengthMultiplier?: number;\n minStartPxPerMs?: number;\n } = {}) => {\n if (!enablePanMomentum || panSamples.length < 2) {\n return false;\n }\n const releaseVelocityY = calculateReleaseVelocityY();\n if (releaseVelocityY === null) {\n return false;\n }\n const strength = Math.max(0, panMomentumStrength);\n const vy = releaseVelocityY * strength * Math.max(0, strengthMultiplier);\n const speedPxPerMs = Math.abs(vy) * runtime.getScaleFactor();\n if (speedPxPerMs < minStartPxPerMs) {\n return false;\n }\n momentum.active = true;\n momentum.vy = vy;\n runtime.updateNextFrame();\n return true;\n };\n const syncRuntimeModeToController = () => {\n const expectedMode = mode === 'zone-active' ? 'explore' : 'sketch';\n if (runtime.mode !== expectedMode) {\n runtime.mode = expectedMode;\n }\n };\n const invalidateScrollBaseViewport = () => {\n scrollBaseViewportDirty = true;\n };\n const hasViewportChanged = (\n from: { x: number; y: number; width: number; height: number },\n to: { x: number; y: number; width: number; height: number }\n ) => {\n return (\n Math.abs(from.x - to.x) > 0.01 ||\n Math.abs(from.y - to.y) > 0.01 ||\n Math.abs(from.width - to.width) > 0.01 ||\n Math.abs(from.height - to.height) > 0.01\n );\n };\n const getTopVisibleZone = () => {\n let topZone: ZoneInterface | undefined;\n let topY = 0;\n for (const zone of runtime.world.zones) {\n zone.recalculateBounds();\n if (zone.points[0] === 0) {\n continue;\n }\n if (!topZone || zone.points[2] < topY) {\n topZone = zone;\n topY = zone.points[2];\n }\n }\n return topZone;\n };\n const getZoneViewportPaddingPx = () => {\n const screen = runtime.getRendererScreenPosition();\n const screenHeight = Math.max(0, screen?.height || 0);\n if (screenHeight === 0) {\n return undefined;\n }\n const verticalPaddingPx = Math.round(screenHeight * ZONE_VIEWPORT_VERTICAL_PADDING_RATIO);\n return {\n top: verticalPaddingPx,\n bottom: verticalPaddingPx,\n };\n };\n\n const getDocumentStartY = () => {\n const topZone = getTopVisibleZone();\n if (topZone) {\n return topZone.points[2];\n }\n\n let didFind = false;\n let topY = 0;\n for (const worldObject of runtime.world.getObjects()) {\n if (!worldObject || worldObject.points[0] === 0) {\n continue;\n }\n if (!didFind || worldObject.points[2] < topY) {\n topY = worldObject.points[2];\n didFind = true;\n }\n }\n\n return didFind ? topY : 0;\n };\n const getInitialHomeAnchorKey = (): string | undefined => {\n const rendererScreen = runtime.getRendererScreenPosition();\n const screenWidth = Math.round((rendererScreen?.width || runtime.width || 0) * 100) / 100;\n const screenHeight = Math.round((rendererScreen?.height || runtime.height || 0) * 100) / 100;\n const screenSource = rendererScreen?.width && rendererScreen?.height ? 'renderer' : 'runtime';\n const topZone = getTopVisibleZone();\n if (topZone) {\n return [\n 'zone',\n topZone.id,\n topZone.points[1],\n topZone.points[2],\n topZone.points[3] - topZone.points[1],\n topZone.points[4] - topZone.points[2],\n `screen:${screenWidth}x${screenHeight}:${screenSource}`,\n ].join(':');\n }\n\n let foundIndex = -1;\n let topY = 0;\n const objects = runtime.world.getObjects();\n for (let i = 0; i < objects.length; i++) {\n const worldObject = objects[i];\n if (!worldObject || worldObject.points[0] === 0) {\n continue;\n }\n if (foundIndex === -1 || worldObject.points[2] < topY) {\n foundIndex = i;\n topY = worldObject.points[2];\n }\n }\n if (foundIndex !== -1) {\n const object = objects[foundIndex]!;\n return [\n 'object',\n object.id || foundIndex,\n object.points[1],\n object.points[2],\n object.points[3] - object.points[1],\n object.points[4] - object.points[2],\n `screen:${screenWidth}x${screenHeight}:${screenSource}`,\n ].join(':');\n }\n return undefined;\n };\n const syncInitialHomeAnchor = () => {\n if (!isActiveSession()) {\n return;\n }\n if (\n initialHomeAnchorLocked ||\n mode !== 'scroll-mode' ||\n restoringViewport ||\n isDragging ||\n exitTransitionInFlight ||\n runtime.world.hasActiveZone()\n ) {\n return;\n }\n const nextAnchorKey = getInitialHomeAnchorKey();\n if (!nextAnchorKey) {\n if (performance.now() < initialHomeSyncRetryDeadlineMs) {\n runtime.updateNextFrame();\n }\n return;\n }\n if (nextAnchorKey === initialHomeAnchorKey) {\n return;\n }\n initialHomeAnchorKey = nextAnchorKey;\n scrollViewY = getDocumentStartY();\n applyScrollViewport(scrollViewY);\n queueFollowUpFrame();\n };\n\n const getScrollBaseViewport = (): ScrollViewport | undefined => {\n const worldWidth = runtime.world.width;\n const worldHeight = runtime.world.height;\n const screen = runtime.getRendererScreenPosition();\n const screenWidth = Math.max(1, screen?.width || runtime.width);\n const screenHeight = Math.max(1, screen?.height || runtime.height);\n const zoneCount = runtime.world.zones.length;\n\n if (\n !scrollBaseViewportDirty &&\n scrollBaseViewportCache &&\n scrollBaseViewportWorldWidth === worldWidth &&\n scrollBaseViewportWorldHeight === worldHeight &&\n scrollBaseViewportScreenWidth === screenWidth &&\n scrollBaseViewportScreenHeight === screenHeight &&\n scrollBaseViewportZoneCount === zoneCount\n ) {\n return scrollBaseViewportCache;\n }\n\n const firstZone = getTopVisibleZone();\n let nextBaseViewport: ScrollViewport | undefined;\n\n if (firstZone) {\n const fitted = runtime.getHomeTarget({\n position: firstZone.points,\n paddingPx: getZoneViewportPaddingPx(),\n });\n nextBaseViewport = {\n x: fitted.x,\n y: fitted.y,\n width: fitted.width,\n height: fitted.height,\n };\n } else if (worldWidth > 0 && worldHeight > 0) {\n const visibleHeight = (worldWidth / screenWidth) * screenHeight;\n nextBaseViewport = {\n x: 0,\n y: 0,\n width: worldWidth,\n height: visibleHeight,\n };\n } else {\n nextBaseViewport = undefined;\n }\n\n scrollBaseViewportCache = nextBaseViewport;\n scrollBaseViewportDirty = false;\n scrollBaseViewportWorldWidth = worldWidth;\n scrollBaseViewportWorldHeight = worldHeight;\n scrollBaseViewportScreenWidth = screenWidth;\n scrollBaseViewportScreenHeight = screenHeight;\n scrollBaseViewportZoneCount = zoneCount;\n\n return scrollBaseViewportCache;\n };\n\n const getScrollViewport = (preferredY: number): ScrollViewport | undefined => {\n const baseViewport = getScrollBaseViewport();\n if (!baseViewport) {\n return undefined;\n }\n\n const worldHeight = runtime.world.height;\n const loadAhead = Math.max(1, scrollLoadAheadFactor);\n const width = baseViewport.width * loadAhead;\n const visibleHeight = baseViewport.height;\n const height = baseViewport.height * loadAhead;\n const minY = Math.min(0, worldHeight - visibleHeight);\n const maxY = Math.max(0, worldHeight - visibleHeight);\n\n return {\n x: baseViewport.x - (width - baseViewport.width) / 2,\n y: Math.min(maxY, Math.max(minY, preferredY)),\n width,\n height,\n };\n };\n const getScrollViewportForZone = (zone: ZoneInterface): ScrollViewport | undefined => {\n zone.recalculateBounds();\n if (zone.points[0] === 0) {\n return undefined;\n }\n return getScrollViewport(zone.points[2]);\n };\n\n const applyScrollViewport = (preferredY: number) => {\n const nextViewport = getScrollViewport(preferredY);\n if (!nextViewport) {\n return;\n }\n scrollViewY = nextViewport.y;\n const currentViewport = runtime.getViewport();\n if (!runtime.transitionManager.hasPending() && !hasViewportChanged(currentViewport, nextViewport)) {\n return;\n }\n if (runtime.transitionManager.hasPending()) {\n runtime.transitionManager.stopTransition();\n }\n runtime.setViewport(nextViewport);\n runtime.updateNextFrame();\n };\n const animateToScrollViewport = (preferredY: number) => {\n const nextViewport = getScrollViewport(preferredY);\n if (!nextViewport) {\n return false;\n }\n scrollViewY = nextViewport.y;\n runtime.transitionManager.goToRegion(nextViewport);\n runtime.updateNextFrame();\n return true;\n };\n const normalizeScrollModeViewport = () => {\n if (mode !== 'scroll-mode' || restoringViewport || exitTransitionInFlight || runtime.world.hasActiveZone()) {\n return;\n }\n const currentViewport = runtime.getViewport();\n const normalizedViewport = getScrollViewport(currentViewport.y);\n if (!normalizedViewport) {\n return;\n }\n scrollViewY = normalizedViewport.y;\n if (!hasViewportChanged(currentViewport, normalizedViewport)) {\n return;\n }\n if (runtime.transitionManager.hasPending()) {\n runtime.transitionManager.stopTransition();\n }\n runtime.setViewport(normalizedViewport);\n runtime.updateNextFrame();\n };\n\n const findZoneAtPoint = (x: number, y: number) => {\n for (const zone of runtime.world.zones) {\n zone.recalculateBounds();\n if (pointInZone(zone, x, y)) {\n return zone;\n }\n }\n return undefined;\n };\n\n const enterZone = (zoneId: string) => {\n if (!isActiveSession()) {\n return;\n }\n stopScrollMomentum();\n clearPanSamples();\n initialHomeAnchorLocked = true;\n if (!savedScrollViewport) {\n savedScrollViewport = toScrollViewport({\n ...runtime.getViewport(),\n y: scrollViewY,\n });\n }\n zoneEnteredViaController = true;\n const didNavigate = runtime.goToZone(zoneId);\n if (didNavigate) {\n setMode('zone-active');\n } else {\n zoneEnteredViaController = false;\n }\n };\n const restoreScrollViewport = () => {\n if (!isActiveSession()) {\n return;\n }\n const targetY = savedScrollViewport ? savedScrollViewport.y : scrollViewY;\n const didAnimate = animateToScrollViewport(targetY);\n savedScrollViewport = undefined;\n exitTransitionInFlight = didAnimate;\n if (!didAnimate) {\n exitTransitionInFlight = false;\n restoringViewport = false;\n applyScrollViewport(scrollViewY);\n }\n runtime.updateNextFrame();\n };\n const shouldAutoExitActiveZone = () => {\n if (!isActiveSession()) {\n return false;\n }\n if (mode !== 'zone-active') {\n return false;\n }\n const activeZone = runtime.world.getActiveZone();\n if (!activeZone) {\n return false;\n }\n activeZone.recalculateBounds();\n if (activeZone.points[0] === 0) {\n return false;\n }\n const viewport = runtime.getViewport();\n if (viewport.width <= 0 || viewport.height <= 0) {\n return false;\n }\n const zoneWidth = activeZone.points[3] - activeZone.points[1];\n const zoneHeight = activeZone.points[4] - activeZone.points[2];\n const widthCoverage = zoneWidth / viewport.width;\n const heightCoverage = zoneHeight / viewport.height;\n return widthCoverage < ZONE_AUTO_EXIT_MIN_COVERAGE_RATIO && heightCoverage < ZONE_AUTO_EXIT_MIN_COVERAGE_RATIO;\n };\n\n const exitZone = () => {\n if (!isActiveSession()) {\n return;\n }\n if (mode !== 'zone-active') {\n return;\n }\n stopScrollMomentum();\n clearPanSamples();\n setMode('scroll-mode');\n restoringViewport = true;\n runtime.deselectZone();\n restoreScrollViewport();\n };\n\n const beginScrollDrag = (clientX: number, clientY: number) => {\n stopScrollMomentum();\n clearPanSamples();\n initialHomeAnchorLocked = true;\n isDragging = true;\n suppressNextClick = false;\n pointerDownClientX = clientX;\n pointerDownClientY = clientY;\n dragStartClientY = clientY;\n dragStartViewportY = scrollViewY;\n recordPanSample(scrollViewY);\n };\n\n const updateScrollDrag = (clientX: number, clientY: number) => {\n if (!isDragging) {\n return false;\n }\n const movedPx = Math.hypot(clientX - pointerDownClientX, clientY - pointerDownClientY);\n if (movedPx > clickDragThresholdPx) {\n suppressNextClick = true;\n }\n const deltaPx = clientY - dragStartClientY;\n const deltaWorld = deltaPx / Math.max(0.0001, runtime.getScaleFactor());\n applyScrollViewport(dragStartViewportY - deltaWorld);\n recordPanSample(scrollViewY);\n return true;\n };\n\n const endScrollDrag = ({\n allowMomentum = true,\n momentumStrengthMultiplier = 1,\n momentumMinStartPxPerMs = SCROLL_MOMENTUM_MIN_START_PX_PER_MS,\n }: {\n allowMomentum?: boolean;\n momentumStrengthMultiplier?: number;\n momentumMinStartPxPerMs?: number;\n } = {}) => {\n const releasedDrag = isDragging;\n const tapSuppressed = suppressNextClick;\n isDragging = false;\n suppressNextClick = false;\n\n if (!releasedDrag) {\n clearPanSamples();\n return {\n releasedDrag: false,\n tapSuppressed,\n };\n }\n\n if (allowMomentum && mode === 'scroll-mode' && !exitTransitionInFlight) {\n maybeStartScrollMomentum({\n strengthMultiplier: momentumStrengthMultiplier,\n minStartPxPerMs: momentumMinStartPxPerMs,\n });\n } else {\n stopScrollMomentum();\n }\n clearPanSamples();\n return {\n releasedDrag: true,\n tapSuppressed,\n };\n };\n\n const cancelScrollDrag = () => {\n isDragging = false;\n suppressNextClick = false;\n clearPanSamples();\n stopScrollMomentum();\n };\n\n const clearTouchTapCandidate = () => {\n activeTouchId = null;\n isTouchTapCandidate = false;\n lastTouchPoint = null;\n suppressNextClick = false;\n };\n\n const handleTapAtPoint = (point: WorldPoint) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (suppressNextClick || exitTransitionInFlight) {\n return;\n }\n if (mode === 'scroll-mode') {\n const zone = findZoneAtPoint(point.x, point.y);\n if (zone) {\n enterZone(zone.id);\n }\n return;\n }\n const activeZone = runtime.world.getActiveZone();\n if (!activeZone || !pointInZone(activeZone, point.x, point.y)) {\n exitZone();\n }\n };\n\n const onClick = (e: MouseEvent & { atlas: { x: number; y: number } }) => {\n if (!isActiveSession()) {\n return;\n }\n if (!e.atlas) {\n return;\n }\n handleTapAtPoint(e.atlas);\n };\n\n const onWheel = (e: WheelEvent) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (exitTransitionInFlight) {\n e.stopPropagation();\n return;\n }\n if (mode !== 'scroll-mode') {\n return;\n }\n stopScrollMomentum();\n initialHomeAnchorLocked = true;\n e.stopPropagation();\n const normalized = normalizeWheel(e);\n const deltaPx = normalized.pixelY || (e as any).deltaY || 0;\n const deltaWorld = (deltaPx / Math.max(0.0001, runtime.getScaleFactor())) * scrollWheelFactor;\n applyScrollViewport(scrollViewY + deltaWorld);\n };\n\n const onMouseDown = (e: MouseEvent & { atlas: { x: number; y: number } }) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (mode !== 'scroll-mode' || exitTransitionInFlight || !e.atlas) {\n return;\n }\n e.stopPropagation();\n beginScrollDrag(typeof e.clientX === 'number' ? e.clientX : 0, e.clientY);\n };\n\n const onMouseMove = (e: MouseEvent & { atlas: { x: number; y: number } }) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (!isDragging || mode !== 'scroll-mode' || exitTransitionInFlight || !e.atlas) {\n return;\n }\n e.stopPropagation();\n updateScrollDrag(typeof e.clientX === 'number' ? e.clientX : 0, e.clientY);\n };\n\n const onMouseUp = () => {\n if (!isActiveSession()) {\n return;\n }\n endScrollDrag();\n };\n\n const onTouchStart = (\n e: TouchEvent & {\n atlasTouches?: Array<{ id: number; x: number; y: number }>;\n }\n ) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (mode === 'zone-active') {\n if (!e.atlasTouches || e.atlasTouches.length !== 1 || e.touches.length !== 1) {\n clearTouchTapCandidate();\n return;\n }\n const touch = e.touches[0];\n const atlasTouch = e.atlasTouches[0];\n activeTouchId = atlasTouch.id;\n isTouchTapCandidate = true;\n suppressNextClick = false;\n pointerDownClientX = touch.clientX;\n pointerDownClientY = touch.clientY;\n lastTouchPoint = { x: atlasTouch.x, y: atlasTouch.y };\n return;\n }\n if (mode !== 'scroll-mode' || exitTransitionInFlight) {\n return;\n }\n e.preventDefault();\n e.stopPropagation?.();\n if (!e.atlasTouches || e.atlasTouches.length !== 1 || e.touches.length !== 1) {\n clearTouchTapCandidate();\n cancelScrollDrag();\n return;\n }\n const touch = e.touches[0];\n const atlasTouch = e.atlasTouches[0];\n activeTouchId = atlasTouch.id;\n isTouchTapCandidate = true;\n lastTouchPoint = { x: atlasTouch.x, y: atlasTouch.y };\n beginScrollDrag(touch.clientX, touch.clientY);\n };\n\n const onTouchMove = (\n e: TouchEvent & {\n atlasTouches?: Array<{ id: number; x: number; y: number }>;\n }\n ) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (mode === 'zone-active') {\n if (!isTouchTapCandidate) {\n return;\n }\n if (!e.atlasTouches || e.atlasTouches.length !== 1 || e.touches.length !== 1) {\n clearTouchTapCandidate();\n return;\n }\n const atlasTouch = e.atlasTouches.find((touch) => touch.id === activeTouchId) || e.atlasTouches[0];\n const touch = Array.from(e.touches).find((entry) => entry.identifier === atlasTouch.id) || e.touches[0];\n lastTouchPoint = { x: atlasTouch.x, y: atlasTouch.y };\n if (\n Math.hypot(touch.clientX - pointerDownClientX, touch.clientY - pointerDownClientY) > clickDragThresholdPx\n ) {\n suppressNextClick = true;\n }\n return;\n }\n if (mode !== 'scroll-mode' || exitTransitionInFlight || !isDragging) {\n return;\n }\n e.preventDefault();\n e.stopPropagation?.();\n if (!e.atlasTouches || e.atlasTouches.length !== 1 || e.touches.length !== 1) {\n clearTouchTapCandidate();\n cancelScrollDrag();\n return;\n }\n const atlasTouch = e.atlasTouches.find((touch) => touch.id === activeTouchId) || e.atlasTouches[0];\n const touch = Array.from(e.touches).find((entry) => entry.identifier === atlasTouch.id) || e.touches[0];\n activeTouchId = atlasTouch.id;\n lastTouchPoint = { x: atlasTouch.x, y: atlasTouch.y };\n updateScrollDrag(touch.clientX, touch.clientY);\n };\n\n const onTouchEnd = (\n e: TouchEvent & {\n atlasTouches?: Array<{ id: number; x: number; y: number }>;\n }\n ) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (mode === 'zone-active') {\n const tapPoint = lastTouchPoint;\n const shouldHandleTap = isTouchTapCandidate && !suppressNextClick && e.touches.length === 0;\n clearTouchTapCandidate();\n if (tapPoint && shouldHandleTap) {\n handleTapAtPoint(tapPoint);\n }\n return;\n }\n if (mode !== 'scroll-mode') {\n return;\n }\n e.preventDefault();\n e.stopPropagation?.();\n if (e.touches.length > 0) {\n clearTouchTapCandidate();\n cancelScrollDrag();\n return;\n }\n const tapPoint = lastTouchPoint;\n const result = endScrollDrag({\n momentumStrengthMultiplier: touchScrollMomentumStrength,\n momentumMinStartPxPerMs: touchScrollMomentumMinStartPxPerMs,\n });\n clearTouchTapCandidate();\n if (tapPoint && !result.tapSuppressed) {\n handleTapAtPoint(tapPoint);\n }\n };\n\n const onTouchCancel = (e: TouchEvent) => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n if (mode === 'zone-active') {\n clearTouchTapCandidate();\n return;\n }\n if (mode !== 'scroll-mode') {\n return;\n }\n e.preventDefault();\n e.stopPropagation?.();\n clearTouchTapCandidate();\n cancelScrollDrag();\n };\n\n const onWindowTouchEnd = () => {\n if (!isActiveSession()) {\n return;\n }\n if (mode === 'zone-active') {\n clearTouchTapCandidate();\n return;\n }\n endScrollDrag({\n momentumStrengthMultiplier: touchScrollMomentumStrength,\n momentumMinStartPxPerMs: touchScrollMomentumMinStartPxPerMs,\n });\n clearTouchTapCandidate();\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (!isActiveSession()) {\n return;\n }\n if (e.key === 'Escape') {\n exitZone();\n }\n };\n\n ensureEventActivated('onClick');\n ensureEventActivated('onWheel');\n ensureEventActivated('onMouseDown');\n ensureEventActivated('onMouseMove');\n ensureEventActivated('onMouseUp');\n ensureEventActivated('onTouchStart');\n ensureEventActivated('onTouchMove');\n ensureEventActivated('onTouchEnd');\n ensureEventActivated('onTouchCancel');\n\n runtime.world.addEventListener('click', onClick);\n runtime.world.addEventListener('wheel', onWheel);\n runtime.world.addEventListener('mousedown', onMouseDown);\n runtime.world.addEventListener('mousemove', onMouseMove);\n runtime.world.addEventListener('mouseup', onMouseUp);\n runtime.world.addEventListener('touchstart', onTouchStart);\n runtime.world.addEventListener('touchmove', onTouchMove);\n runtime.world.addEventListener('touchend', onTouchEnd);\n runtime.world.addEventListener('touchcancel', onTouchCancel);\n\n window.addEventListener('mouseup', onMouseUp);\n window.addEventListener('touchend', onWindowTouchEnd);\n window.addEventListener('touchcancel', onTouchCancel);\n window.addEventListener('keydown', onKeyDown);\n\n runtime.manualHomePosition = true;\n setMode('scroll-mode');\n scrollViewY = getDocumentStartY();\n syncInitialHomeAnchor();\n\n const stopPopmotion = popmotion.start(runtime);\n const removeMomentumHook = runtime.registerHook('useFrame', (delta: number) => {\n if (!momentum.active) {\n return;\n }\n if (\n !isActiveSession() ||\n mode !== 'scroll-mode' ||\n restoringViewport ||\n exitTransitionInFlight ||\n isDragging ||\n runtime.world.hasActiveZone()\n ) {\n stopScrollMomentum();\n return;\n }\n\n const decay = Math.exp(-delta / Math.max(1, panTimeConstant));\n momentum.vy *= decay;\n\n const speedPxPerMs = Math.abs(momentum.vy) * runtime.getScaleFactor();\n if (speedPxPerMs <= SCROLL_MOMENTUM_STOP_PX_PER_MS) {\n stopScrollMomentum();\n return;\n }\n\n const previousY = scrollViewY;\n applyScrollViewport(scrollViewY + momentum.vy * delta);\n if (Math.abs(scrollViewY - previousY) <= 0.01) {\n stopScrollMomentum();\n return;\n }\n runtime.updateNextFrame();\n });\n const removeAutoExitHook = runtime.registerHook('useAfterFrame', () => {\n if (!isActiveSession()) {\n return;\n }\n syncRuntimeModeToController();\n normalizeScrollModeViewport();\n syncInitialHomeAnchor();\n if (exitTransitionInFlight && !runtime.transitionManager.hasPending()) {\n exitTransitionInFlight = false;\n restoringViewport = false;\n }\n if (pendingProgrammaticRestoreZoneId && mode === 'zone-active' && !runtime.transitionManager.hasPending()) {\n const activeZone = runtime.world.getActiveZone();\n if (activeZone && activeZone.id === pendingProgrammaticRestoreZoneId) {\n const zoneScrollViewport = getScrollViewportForZone(activeZone);\n if (zoneScrollViewport) {\n savedScrollViewport = toScrollViewport(zoneScrollViewport);\n scrollViewY = zoneScrollViewport.y;\n }\n }\n pendingProgrammaticRestoreZoneId = undefined;\n }\n if (restoringViewport) {\n return;\n }\n if (shouldAutoExitActiveZone()) {\n exitZone();\n }\n });\n\n const removeLayout = runtime.world.addLayoutSubscriber((type) => {\n if (!isActiveSession()) {\n return;\n }\n if (type === 'recalculate-world-size' || type === 'zone-changed') {\n invalidateScrollBaseViewport();\n }\n if (type === 'goto-region') {\n restoringViewport = false;\n }\n if (type === 'recalculate-world-size' && mode === 'scroll-mode' && !restoringViewport) {\n const nextY = savedScrollViewport ? savedScrollViewport.y : scrollViewY;\n if (runtime.world.zones.length && nextY === 0) {\n scrollViewY = getDocumentStartY();\n }\n applyScrollViewport(scrollViewY);\n queueFollowUpFrame();\n }\n if (type === 'zone-changed') {\n if (runtime.world.hasActiveZone()) {\n stopScrollMomentum();\n clearPanSamples();\n initialHomeAnchorLocked = true;\n const activeZone = runtime.world.getActiveZone();\n if (!zoneEnteredViaController && activeZone) {\n pendingProgrammaticRestoreZoneId = activeZone.id;\n } else if (!savedScrollViewport) {\n savedScrollViewport = toScrollViewport({\n ...runtime.getViewport(),\n y: scrollViewY,\n });\n }\n zoneEnteredViaController = false;\n setMode('zone-active');\n return;\n }\n const wasZoneActive = mode === 'zone-active';\n pendingProgrammaticRestoreZoneId = undefined;\n setMode('scroll-mode');\n if (exitTransitionInFlight) {\n return;\n }\n if (wasZoneActive) {\n restoringViewport = true;\n restoreScrollViewport();\n } else if (!restoringViewport) {\n applyScrollViewport(scrollViewY);\n }\n }\n });\n\n return () => {\n stopScrollMomentum();\n clearPanSamples();\n stopPopmotion();\n removeMomentumHook();\n removeAutoExitHook();\n removeLayout();\n runtime.world.removeEventListener('click', onClick);\n runtime.world.removeEventListener('wheel', onWheel);\n runtime.world.removeEventListener('mousedown', onMouseDown);\n runtime.world.removeEventListener('mousemove', onMouseMove);\n runtime.world.removeEventListener('mouseup', onMouseUp);\n runtime.world.removeEventListener('touchstart', onTouchStart);\n runtime.world.removeEventListener('touchmove', onTouchMove);\n runtime.world.removeEventListener('touchend', onTouchEnd);\n runtime.world.removeEventListener('touchcancel', onTouchCancel);\n window.removeEventListener('mouseup', onMouseUp);\n window.removeEventListener('touchend', onWindowTouchEnd);\n window.removeEventListener('touchcancel', onTouchCancel);\n window.removeEventListener('keydown', onKeyDown);\n if (isActiveSession()) {\n activePdfControllerSessionByRuntime.delete(runtime as object);\n runtime.manualHomePosition = originalManualHomePosition;\n runtime.mode = originalMode;\n }\n };\n },\n\n updatePosition() {\n // no-op\n },\n };\n};\n","import React from 'react';\nimport { Preset } from '../presets/_types';\nimport { RectReadOnly } from 'react-use-measure';\n\nexport const AtlasContext = React.createContext<Preset | null>(null);\nAtlasContext.displayName = 'Atlas';\n\nexport const BoundsContext = React.createContext<RectReadOnly | null>(null);\nBoundsContext.displayName = 'Bounds';\n","import React, { useContext } from 'react';\nimport { ViewerMode } from '../../../renderer/runtime';\n\nexport const ModeContext = React.createContext<ViewerMode>('explore');\nModeContext.displayName = 'Mode';\n\nexport const useMode: () => ViewerMode = () => {\n return useContext(ModeContext);\n};\n\nexport function ModeProvider(props: { mode: ViewerMode; children: React.ReactNode }) {\n return <ModeContext.Provider value={props.mode}>{props.children}</ModeContext.Provider>;\n}\n","import { Runtime } from '../../renderer/runtime';\nimport { Position } from '../../types';\nimport { dna, DnaFactory, Strand } from '@atlas-viewer/dna';\nimport { easingFunctions, EasingFunction } from '../../utility/easing-functions';\n\nexport type PendingTransition = {\n from: Strand;\n to: Strand;\n elapsed_time: number;\n total_time: number;\n timingFunction: EasingFunction;\n done: boolean;\n constrain: boolean;\n callback?: () => void;\n};\n\nexport class TransitionManager {\n runtime: Runtime;\n readonly pendingTransition: PendingTransition;\n\n constructor(runtime: Runtime) {\n this.runtime = runtime;\n this.pendingTransition = {\n from: dna(5),\n to: dna(5),\n elapsed_time: 0,\n done: true,\n total_time: 0,\n timingFunction: easingFunctions.easeInOutQuad,\n constrain: false,\n };\n }\n\n hasPending() {\n return !this.pendingTransition.done;\n }\n\n getPendingTransition() {\n return this.pendingTransition;\n }\n\n getPendingFrom() {\n return this.pendingTransition.from;\n }\n\n customTransition(func: (transition: PendingTransition) => void) {\n func(this.pendingTransition);\n }\n\n stopTransition() {\n this.pendingTransition.from = dna(this.runtime.target);\n this.pendingTransition.to = dna(this.runtime.target);\n this.pendingTransition.done = true;\n this.pendingTransition.elapsed_time = 0;\n this.pendingTransition.total_time = 0;\n }\n\n runTransition(target: Strand, delta: number) {\n if (!this.pendingTransition.done) {\n const transition = this.pendingTransition;\n const td = transition.total_time === 0 ? 0 : (transition.elapsed_time + delta) / transition.total_time;\n const step = transition.total_time === 0 ? 1 : td === 0 ? 0 : transition.timingFunction(td);\n\n // Update our target.\n target[1] = transition.from[1] + (transition.to[1] - transition.from[1]) * step;\n target[2] = transition.from[2] + (transition.to[2] - transition.from[2]) * step;\n target[3] = transition.from[3] + (transition.to[3] - transition.from[3]) * step;\n target[4] = transition.from[4] + (transition.to[4] - transition.from[4]) * step;\n\n // Update our transition.\n this.pendingTransition.elapsed_time += delta;\n if (this.pendingTransition.elapsed_time >= this.pendingTransition.total_time) {\n this.pendingTransition.done = true;\n this.pendingTransition.callback?.();\n\n if (this.pendingTransition.constrain) {\n // @todo make this configurable per transition?\n this.constrainBounds({\n transition: {\n duration: this.pendingTransition.total_time === 0 ? 0 : 500,\n easing: easingFunctions.easeOutExpo,\n },\n });\n }\n }\n }\n }\n\n lastZoomTo: {\n factor: number;\n options: any;\n } | null = null;\n\n resumeTransition() {\n if (this.lastZoomTo) {\n this.zoomTo(this.lastZoomTo.factor, this.lastZoomTo.options);\n }\n if (this.isConstraining) {\n this.constrainBounds();\n }\n if (this.lastGoToRegion) {\n this.goToRegion(this.lastGoToRegion.target, this.lastGoToRegion.options);\n }\n }\n\n zoomTo(\n factor: number,\n options: {\n origin?: Position;\n stream?: boolean;\n minZoomFactor?: number;\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}\n ) {\n const {\n origin,\n stream = false,\n transition,\n } = options;\n\n this.lastZoomTo = { factor, options };\n\n const newPoints = this.runtime.getZoomedPosition(factor, { origin });\n\n const dist = Math.abs(1 - factor);\n\n this.applyTransition(\n newPoints,\n transition,\n {\n duration: 2000 * dist,\n easing: easingFunctions.easeOutExpo,\n constrain: true,\n callback: () => {\n this.lastZoomTo = null;\n }\n },\n { stream: false }\n );\n }\n\n isConstraining = false;\n\n constrainBounds({\n transition,\n panPadding = 0,\n }: {\n panPadding?: number;\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}) {\n this.isConstraining = true;\n const [isConstrained, constrained] = this.runtime.constrainBounds(this.runtime.target, { panPadding });\n\n if (isConstrained) {\n this.applyTransition(constrained, transition, {\n duration: 500,\n easing: easingFunctions.easeOutQuart,\n constrain: false,\n callback: () => {\n this.isConstraining = false;\n }\n });\n this.runtime.updateNextFrame();\n return;\n }\n\n this.isConstraining = false;\n }\n\n constrainTarget(\n target: Strand,\n {\n origin,\n transition,\n panPadding = 0,\n }: {\n origin?: Position;\n panPadding?: number;\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}\n ) {\n this.isConstraining = true;\n const [isConstrained, constrained] = this.runtime.constrainTarget(target, { origin, panPadding });\n\n if (isConstrained) {\n this.applyTransition(constrained, transition, {\n duration: 500,\n easing: easingFunctions.easeOutQuart,\n constrain: false,\n callback: () => {\n this.isConstraining = false;\n },\n });\n this.runtime.updateNextFrame();\n return;\n }\n\n this.isConstraining = false;\n }\n\n applyTransition(\n target: Strand,\n transition?: { duration?: number; easing?: EasingFunction; constrain?: boolean },\n defaults?: {\n duration: number;\n easing: EasingFunction;\n constrain?: boolean;\n callback?: () => void;\n },\n {\n stream,\n }: {\n stream?: boolean;\n } = {}\n ) {\n this.pendingTransition.from = dna(this.runtime.target);\n this.pendingTransition.to = target;\n if (!stream) {\n this.pendingTransition.elapsed_time = 0;\n }\n this.pendingTransition.done = false;\n this.pendingTransition.total_time =\n typeof transition?.duration !== 'undefined'\n ? transition.duration\n : typeof defaults?.duration !== 'undefined'\n ? defaults.duration\n : 1000;\n this.pendingTransition.constrain =\n typeof transition?.constrain !== 'undefined'\n ? transition.constrain\n : typeof defaults?.constrain !== 'undefined'\n ? defaults.constrain\n : false;\n this.pendingTransition.timingFunction = transition?.easing || defaults?.easing || easingFunctions.easeInOutSine;\n }\n\n lastGoToRegion: null | { target: any; options: any } = null;\n\n goToRegion(\n target: {\n x: number;\n y: number;\n width: number;\n height: number;\n padding?: number;\n },\n {\n transition,\n }: {\n transition?: {\n duration?: number;\n easing?: EasingFunction;\n };\n } = {}\n ) {\n this.lastGoToRegion = { target, options: { transition } };\n const clampedRegion = this.runtime.clampRegion(target);\n this.applyTransition(\n DnaFactory.singleBox(clampedRegion.width, clampedRegion.height, clampedRegion.x, clampedRegion.y),\n transition,\n {\n duration: 1000,\n easing: easingFunctions.easeOutExpo,\n constrain: true,\n callback: () => {\n this.lastGoToRegion = null;\n }\n }\n );\n this.runtime.updateNextFrame();\n }\n}\n","import {\n compose,\n DnaFactory,\n dna,\n mutate,\n type Strand,\n scale,\n scaleAtOrigin,\n transform,\n translate,\n} from '@atlas-viewer/dna';\nimport { nanoid } from 'nanoid';\nimport type { RuntimeDebugEvent } from '../modules/react-reconciler/devtools/types';\nimport type { AtlasReadyResetReason } from '../modules/shared/ready-events';\nimport { TransitionManager } from '../modules/transition-manager/transition-manager';\nimport type { Projection, RuntimeController, Viewer } from '../types';\nimport { easingFunctions } from '../utility/easing-functions';\nimport { getZoneConstrainedBounds } from '../utility/get-zone-constrained-bounds';\nimport type { World } from '../world';\nimport type { Paint } from '../world-objects/paint';\nimport type { Renderer } from './renderer';\n\nexport type RuntimeHooks = {\n useFrame: Array<(time: number) => void>;\n useBeforeFrame: Array<(time: number) => void>;\n useAfterFrame: Array<(time: number) => void>;\n useAfterPaint: Array<(paint: Paint) => void>;\n};\n\ntype UnwrapHook<T> = T extends Array<infer R> ? R : never;\ntype UnwrapHookArg<T> = T extends Array<(arg: infer R) => any> ? R : never;\n\nexport type ViewerMode = 'static' | 'explore' | 'sketch';\nconst MIN = Number.MIN_VALUE + 1;\n\nexport type ViewerFilters = {\n grayscale: number;\n contrast: number;\n brightness: number;\n saturate: number;\n hueRotate: number;\n sepia: number;\n invert: number;\n blur: number;\n};\n\nexport type HookOptions = {\n enableFilters?: boolean;\n filters: ViewerFilters;\n};\n\nexport type RuntimeOptions = {\n visibilityRatio: number;\n maxOverZoom: number;\n maxUnderZoom: number;\n};\n\nexport type RuntimeZoneState = {\n zoneId: string;\n exists: boolean;\n active: boolean;\n visibleInViewport: boolean;\n};\n\nexport class Runtime {\n id = nanoid();\n ready = false;\n readyCycle = 0;\n readyReason: AtlasReadyResetReason = 'initial';\n readyTimestamp: number | undefined;\n // Helper getters.\n get x(): number {\n return this.target[1];\n }\n\n set x(x: number) {\n this.target[1] = x;\n }\n\n get y(): number {\n return this.target[2];\n }\n\n set y(y: number) {\n this.target[2] = y;\n }\n\n get x2(): number {\n return this.target[3];\n }\n\n set x2(x2: number) {\n this.target[3] = x2;\n }\n\n get y2(): number {\n return this.target[4];\n }\n\n set y2(y2: number) {\n this.target[4] = y2;\n }\n\n get width(): number {\n return this.target[3] - this.target[1];\n }\n\n set width(width: number) {\n this.target[3] = this.target[1] + width;\n }\n\n get height(): number {\n return this.target[4] - this.target[2];\n }\n\n set height(height: number) {\n this.target[4] = this.target[2] = height;\n }\n\n renderer: Renderer;\n world: World;\n target: Strand;\n homePosition: Strand;\n manualHomePosition: boolean;\n manualFocalPosition: boolean;\n focalPosition: Strand;\n homePaddingPx: number | { left?: number; right?: number; top?: number; bottom?: number } | undefined;\n transitionManager: TransitionManager;\n aggregate: Strand;\n transformBuffer = dna(500);\n lastTarget = dna(5);\n zoomBuffer = dna(5);\n logNextRender = false;\n pendingUpdate = true;\n isCommitting = false;\n firstRender = true;\n lastTime: number;\n stopId?: number;\n mode: ViewerMode = 'explore';\n controllers: RuntimeController[] = [];\n controllersRunning = false;\n controllerStopFunctions: Array<() => void> = [];\n maxScaleFactor = 1;\n _viewerToWorld = { x: 0, y: 0 };\n _lastGoodScale = 1;\n debugFrame = 0;\n debugSubscribers = new Set<(event: RuntimeDebugEvent) => void>();\n hooks: RuntimeHooks = {\n useFrame: [],\n useBeforeFrame: [],\n useAfterPaint: [],\n useAfterFrame: [],\n };\n fpsLimit: number | undefined;\n options: RuntimeOptions;\n hookOptions: HookOptions = {\n filters: {\n grayscale: 0,\n contrast: 0,\n brightness: 0,\n saturate: 0,\n sepia: 0,\n invert: 0,\n hueRotate: 0,\n blur: 0,\n },\n };\n\n constructor(\n renderer: Renderer,\n world: World,\n target: Viewer,\n controllers: RuntimeController[] = [],\n options?: Partial<RuntimeOptions>\n ) {\n this.renderer = renderer;\n this.world = world;\n this.options = {\n maxOverZoom: 1,\n maxUnderZoom: 1,\n visibilityRatio: 1,\n ...(options || {}),\n };\n this.target = DnaFactory.projection(target);\n this.manualHomePosition = false;\n this.pendingUpdate = true;\n this.homePosition = DnaFactory.projection(this.world);\n this.manualFocalPosition = false;\n this.focalPosition = this.target; // Follow target by default.\n this.updateFocalPosition();\n this.transitionManager = new TransitionManager(this);\n this.aggregate = scale(1);\n this.world.addLayoutSubscriber((type: string) => {\n if (type === 'repaint' || type === 'zone-changed') {\n this.pendingUpdate = true;\n }\n if (type === 'recalculate-world-size') {\n if (!this.manualHomePosition) {\n this.setHomePosition();\n this.goHome();\n } else {\n // recalculate world size?\n }\n this.updateFocalPosition();\n }\n });\n this.lastTime = performance.now();\n this.controllers = controllers;\n this.render(this.lastTime);\n this.startControllers();\n this.homePaddingPx = undefined;\n }\n\n setHomePosition(position?: Projection) {\n this.homePosition.set(DnaFactory.projection(position ? position : this.world));\n this.pendingUpdate = true;\n }\n\n setHomePaddingPx(px?: number | { left?: number; right?: number; top?: number; bottom?: number }) {\n this.homePaddingPx = px;\n this.pendingUpdate = true;\n }\n\n getHomePaddingPx(): number | { left?: number; right?: number; top?: number; bottom?: number } | undefined {\n return this.homePaddingPx;\n }\n\n startControllers() {\n if (this.controllersRunning) {\n return;\n }\n for (const controller of this.controllers) {\n this.controllerStopFunctions.push(controller.start(this));\n }\n this.controllersRunning = true;\n }\n\n stopControllers() {\n if (!this.controllersRunning) {\n return;\n }\n for (const controller of this.controllerStopFunctions) {\n controller();\n }\n this.controllersRunning = false;\n this.controllerStopFunctions = [];\n }\n\n updateControllerPosition() {\n for (const controller of this.controllers) {\n controller.updatePosition(this.x, this.y, this.width, this.height);\n }\n }\n\n triggerResize() {\n if (this.renderer.triggerResize) {\n this.renderer.triggerResize();\n }\n this.pendingUpdate = true;\n }\n\n addController(controller: RuntimeController) {\n this.controllers.push(controller);\n if (this.controllersRunning) {\n controller.start(this);\n }\n this.pendingUpdate = true;\n }\n\n cover() {\n return this.goHome({ cover: true });\n }\n\n getRendererScreenPosition() {\n return this.renderer.getRendererScreenPosition();\n }\n\n updateRendererScreenPosition() {\n this.pendingUpdate = true;\n this.renderer.resize();\n }\n\n setOptions(options: Partial<RuntimeOptions>) {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * Normalize padding input to a consistent per-side format.\n */\n private normalizePadding(paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number }): {\n left: number;\n right: number;\n top: number;\n bottom: number;\n } {\n if (typeof paddingPx === 'number') {\n return {\n left: paddingPx,\n right: paddingPx,\n top: paddingPx,\n bottom: paddingPx,\n };\n }\n if (paddingPx) {\n return {\n left: paddingPx.left || 0,\n right: paddingPx.right || 0,\n top: paddingPx.top || 0,\n bottom: paddingPx.bottom || 0,\n };\n }\n return { left: 0, right: 0, top: 0, bottom: 0 };\n }\n\n /**\n * Calculate the viewport region that fits the target content within the available\n * canvas area (accounting for CSS pixel padding).\n */\n getHomeTarget(\n options: {\n cover?: boolean;\n position?: Strand;\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n } = {}\n ): { x: number; y: number; width: number; height: number } {\n // Get actual canvas dimensions in CSS pixels\n const rendererPosition = this.getRendererScreenPosition();\n const canvasWidth = rendererPosition?.width || this.width;\n const canvasHeight = rendererPosition?.height || this.height;\n\n // Use provided padding or fall back to default homePaddingPx\n const paddingPx = options.paddingPx !== undefined ? options.paddingPx : this.homePaddingPx;\n const padding = this.normalizePadding(paddingPx);\n\n // Calculate available area after padding (in CSS pixels)\n const availableWidth = Math.max(1, canvasWidth - padding.left - padding.right);\n const availableHeight = Math.max(1, canvasHeight - padding.top - padding.bottom);\n\n // Get the target content bounds (what we want to show)\n const content = options.position\n ? {\n x: options.position[1],\n y: options.position[2],\n width: options.position[3] - options.position[1],\n height: options.position[4] - options.position[2],\n }\n : {\n x: this.homePosition[1],\n y: this.homePosition[2],\n width: this.homePosition[3] - this.homePosition[1],\n height: this.homePosition[4] - this.homePosition[2],\n };\n\n // Calculate aspect ratios\n const availableAspect = availableWidth / availableHeight;\n const contentAspect = content.width / content.height;\n\n // Determine the world-unit dimensions needed to fit content in available area\n let viewWidth: number;\n let viewHeight: number;\n let viewX: number;\n let viewY: number;\n\n const fitToWidth = options.cover ? contentAspect < availableAspect : contentAspect > availableAspect;\n\n if (fitToWidth) {\n // Content is wider relative to available area - fit to width\n viewWidth = content.width;\n viewHeight = content.width / availableAspect;\n viewX = content.x;\n viewY = content.y - (viewHeight - content.height) / 2;\n } else {\n // Content is taller relative to available area - fit to height\n viewHeight = content.height;\n viewWidth = content.height * availableAspect;\n viewX = content.x - (viewWidth - content.width) / 2;\n viewY = content.y;\n }\n\n // Now we need to expand the viewport to account for the padding.\n // The ratio of world units per CSS pixel in the available area:\n const worldPerCssPixel = viewWidth / availableWidth;\n\n // Convert padding from CSS pixels to world units\n const padLeftWorld = padding.left * worldPerCssPixel;\n const padRightWorld = padding.right * worldPerCssPixel;\n const padTopWorld = padding.top * worldPerCssPixel;\n const padBottomWorld = padding.bottom * worldPerCssPixel;\n\n // Expand the viewport to include padding areas\n return {\n x: viewX - padLeftWorld,\n y: viewY - padTopWorld,\n width: viewWidth + padLeftWorld + padRightWorld,\n height: viewHeight + padTopWorld + padBottomWorld,\n };\n }\n\n isViewportAtHome(\n options: {\n cover?: boolean;\n tolerance?: number;\n target?: Projection;\n } = {}\n ): boolean {\n const { cover = false, tolerance = 1, target = this.getViewport() } = options;\n const homeTarget = this.getHomeTarget({ cover });\n\n return (\n Math.abs(target.x - homeTarget.x) <= tolerance &&\n Math.abs(target.y - homeTarget.y) <= tolerance &&\n Math.abs(target.width - homeTarget.width) <= tolerance &&\n Math.abs(target.height - homeTarget.height) <= tolerance\n );\n }\n\n isViewportAtHomeZoomLevel(\n options: {\n cover?: boolean;\n tolerance?: number;\n target?: Projection;\n } = {}\n ): boolean {\n const { cover = false, tolerance = 0.05, target = this.getViewport() } = options;\n const homeTarget = this.getHomeTarget({ cover });\n const targetScale = this.renderer.getScale(target.width, target.height) || this._lastGoodScale;\n const homeScale = this.renderer.getScale(homeTarget.width, homeTarget.height) || this._lastGoodScale;\n\n if (homeScale === 0) {\n return false;\n }\n\n return Math.abs(targetScale / homeScale - 1) <= tolerance;\n }\n\n goHome(\n options: {\n cover?: boolean;\n position?: Strand;\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n } = {}\n ) {\n if (this.world.width <= 0 || this.world.height <= 0) return;\n\n // Check if we have any padding to apply\n const paddingPx = options.paddingPx !== undefined ? options.paddingPx : this.homePaddingPx;\n const padding = this.normalizePadding(paddingPx);\n const hasPadding = padding.left > 0 || padding.right > 0 || padding.top > 0 || padding.bottom > 0;\n\n if (hasPadding) {\n // Use the new padding-aware calculation\n const target = this.getHomeTarget(options);\n this.target[1] = Math.round(target.x);\n this.target[2] = Math.round(target.y);\n this.target[3] = Math.round(target.x + target.width);\n this.target[4] = Math.round(target.y + target.height);\n } else {\n // Original behavior without padding\n const scaleFactor = this.getScaleFactor();\n\n const target = options.position\n ? {\n x: options.position[1],\n y: options.position[2],\n width: options.position[3] - options.position[1],\n height: options.position[4] - options.position[2],\n }\n : {\n x: this.homePosition[1],\n y: this.homePosition[2],\n width: this.homePosition[3] - this.homePosition[1],\n height: this.homePosition[4] - this.homePosition[2],\n };\n\n const width = this.width * scaleFactor;\n const height = this.height * scaleFactor;\n\n const widthScale = target.width / width;\n const heightScale = target.height / height;\n const ar = width / height;\n\n if (options.cover ? widthScale > heightScale : widthScale < heightScale) {\n const fullWidth = ar * target.height;\n const space = (fullWidth - target.width) / 2;\n\n this.target[1] = Math.round(-space + target.x);\n this.target[2] = Math.round(target.y);\n this.target[3] = Math.round(fullWidth - space + target.x);\n this.target[4] = Math.round(target.height + target.y);\n } else {\n const fullHeight = target.width / ar;\n const space = (fullHeight - target.height) / 2;\n\n this.target[1] = Math.round(target.x);\n this.target[2] = Math.round(target.y - space);\n this.target[3] = Math.round(target.x + target.width);\n this.target[4] = Math.round(target.y + fullHeight - space);\n }\n }\n\n this.constrainBounds(this.target);\n\n this.updateControllerPosition();\n }\n\n /**\n * Resize world\n *\n * This is generally called when the world is re-sized. This recalculates the current target accordingly. It needs to\n * be improved, tested and planned.\n *\n * @param fromWidth\n * @param toWidth\n * @param fromHeight\n * @param toHeight\n */\n resize(fromWidth: number, toWidth: number, fromHeight: number, toHeight: number) {\n // Step 1. Do we need to calculate a new focal point?\n\n if (this.transitionManager.hasPending()) {\n this.transitionManager.stopTransition();\n }\n\n // @todo figure out if there is some focal point that we can trim, given the resize request.\n // for example if it expand beyond the world, we can crop the focal point.\n this.updateFocalPosition(fromWidth - toWidth, fromHeight - toHeight);\n\n const widthRatio = toWidth / fromWidth;\n const heightRatio = toHeight / fromHeight;\n\n this.target[3] = this.target[1] + (this.target[3] - this.target[1]) * widthRatio;\n this.target[4] = this.target[2] + (this.target[4] - this.target[2]) * heightRatio;\n\n // console.log('resize -> ', toBox(this.target), toBox(this.focalPosition));\n // 1st bad case\n // 1302 738 500 500\n // {x: 0, y: -352.8966979980469, width: 580.4239501953125, height: 1729.7934265136719}\n // {x: 0, y: 0.0000152587890625, width: 1024, height: 1023.9999847412109}\n // 2nd bad case\n // 738 295.9891062144095 500 500\n // {x: 0, y: 0, width: 295.9891052246094, height: 500}\n // {x: 119, y: 0, width: 500, height: 500}\n\n this.goHome({ position: this.focalPosition });\n this.renderer.resize(toWidth, toHeight);\n this.pendingUpdate = true;\n\n this.transitionManager.resumeTransition();\n }\n\n updateFocalPosition(widthDiff?: number, heightDiff?: number) {\n if (!this.manualFocalPosition) {\n const w = this.width;\n const h = this.height;\n const min = Math.min(w, h);\n\n const marginTrimWidth = 0;\n const marginTrimHeight = 0;\n\n // console.log(widthDiff, heightDiff);\n // @todo An way to trim margins - breaks reversible resizing.\n // if (\n // (widthDiff || widthDiff === 0) &&\n // this.x + this.width > this.world.width &&\n // (heightDiff || heightDiff === 0) &&\n // this.y + this.height > this.world.height\n // ) {\n // // const maxMarginW = this.width - this.world.width;\n // // marginTrimWidth = (maxMarginW < widthDiff ? maxMarginW : widthDiff) * 2;\n // // const maxMarginH = this.height - this.world.height;\n // // marginTrimHeight = maxMarginH < heightDiff ? maxMarginH : heightDiff;\n // // console.log('A');\n // }\n\n const baseX = this.x + marginTrimWidth;\n const baseY = this.y + marginTrimHeight;\n\n if (w < h) {\n const diff = this.height - this.width;\n // []\n this.focalPosition = DnaFactory.projection({\n x: baseX,\n y: baseY + diff / 2,\n width: min - marginTrimWidth * 2,\n height: min - marginTrimHeight * 2,\n });\n this.pendingUpdate = true;\n } else {\n const diff = this.width - this.height;\n // [ ]\n this.focalPosition = DnaFactory.projection({\n x: baseX + diff / 2,\n y: baseY,\n width: min - marginTrimWidth * 2,\n height: min - marginTrimHeight * 2,\n });\n this.pendingUpdate = true;\n }\n }\n }\n\n _viewport = { x: 0, y: 0, width: 0, height: 0 };\n\n /**\n * Get Viewport\n *\n * Returns a projection based on the current target.\n *\n * @todo rename to getProjection.\n * @todo evaluate if we actually need this.\n */\n getViewport(): Projection {\n this._viewport.x = this.target[1];\n this._viewport.y = this.target[2];\n this._viewport.width = this.target[3] - this.target[1];\n this._viewport.height = this.target[4] - this.target[2];\n return this._viewport;\n }\n\n /**\n * Set Viewport\n *\n * This is a helper for setting the viewport based on x, y, width and height, opposed to the x1, y1, x2, y2 native\n * co-ordinates of the target.\n *\n * @param data\n */\n setViewport = (data: { x?: number; y?: number; width?: number; height?: number }) => {\n const x = Math.round(typeof data.x === 'undefined' ? this.target[1] : data.x);\n const y = Math.round(typeof data.y === 'undefined' ? this.target[2] : data.y);\n\n if (data.width) {\n this.target[3] = x + data.width;\n } else {\n this.target[3] = this.target[3] - this.target[1] + x;\n }\n if (data.height) {\n this.target[4] = y + data.height;\n } else {\n this.target[4] = this.target[4] - this.target[2] + y;\n }\n\n if (Math.abs(this.target[1] - x) > 0.01) {\n this.target[1] = x;\n }\n if (Math.abs(this.target[2] - y) > 0.01) {\n this.target[2] = y;\n }\n\n this.pendingUpdate = true;\n };\n\n constrainBounds(target: Strand, { panPadding = 0, ref = false }: { ref?: boolean; panPadding?: number } = {}) {\n const { minX, maxX, minY, maxY } = this.getBounds({\n target,\n padding: panPadding,\n });\n\n let isConstrained = false;\n const constrained = ref ? target : dna(target);\n const width = Math.round(target[3] - target[1]);\n const height = Math.round(target[4] - target[2]);\n\n if (minX > target[1]) {\n isConstrained = true;\n constrained[1] = minX;\n constrained[3] = minX + width;\n }\n if (minY > target[2]) {\n isConstrained = true;\n constrained[2] = minY;\n constrained[4] = minY + height;\n }\n if (maxX < target[1]) {\n isConstrained = true;\n constrained[1] = maxX;\n constrained[3] = maxX + width;\n }\n if (maxY < target[2]) {\n isConstrained = true;\n constrained[2] = maxY;\n constrained[4] = maxY + height;\n }\n\n return [isConstrained, constrained] as const;\n }\n\n /**\n * Get bounds\n *\n * Returns the minimum and maximum bounds. This absolutely needs improved. With the addition of zones this is becoming\n * more of an issue. It has to take into account the current layout. There also needs to be a new method for creating\n * a \"home\" view that will fit the content to the view.\n */\n getBounds(options: { padding: number; target?: Strand }) {\n const target = options.target || this.target;\n const padding = options.padding;\n const visRatio = this.options.visibilityRatio;\n const hiddenRatio = Math.abs(1 - visRatio);\n\n if (this.world.hasActiveZone()) {\n const zone = this.world.getActiveZone();\n\n if (zone) {\n zone.recalculateBounds();\n const zoneBounds = getZoneConstrainedBounds(target, zone.points, padding);\n if (zoneBounds) {\n return zoneBounds;\n }\n }\n }\n\n const wt = target[3] - target[1];\n const ww = this.world.width;\n\n // const addConstraintPaddingX = ww / visRatio < wt;\n\n // Add constrain padding = false (zoomed in)\n const xB = -wt * hiddenRatio;\n const xD = ww - wt - xB;\n\n // ADd constrain padding = true (zoomed out)\n // const xA = ww * visRatio - wt;\n // const xC = ww * visRatio;\n // const xA = -500 / this.getScaleFactor(true);\n // const xC = -200 / this.getScaleFactor(true);\n // const xC = Math.min(-((wt - ww) / 2), ww * hiddenRatio);\n // const xA = Math.max(xC, ww - wt);\n\n // const minX = addConstraintPaddingX ? xA : xB;\n // const maxX = addConstraintPaddingX ? xC : xD;\n\n const ht = target[4] - target[2];\n const hw = this.world.height;\n\n // Add constrain padding = false (zoomed in)\n const yB = -ht * hiddenRatio;\n const yD = hw - ht - yB;\n\n // Add constrain padding = true (zoomed out)\n // const yA = hw * visRatio - ht;\n // const yC = hw * visRatio;\n // const yC = Math.min(-((ht - hw) / 2), hw * hiddenRatio);\n // const yA = Math.max(yC, hw * hiddenRatio - ht);\n //\n // const addConstraintPaddingY = hw / visRatio < ht;\n\n // const minY = addConstraintPaddingY ? yA : yB;\n // const maxY = addConstraintPaddingY ? yC : yD;\n\n const maxX = Math.round(Math.max(xB, xD));\n const minX = Math.round(Math.min(xB, xD));\n const maxY = Math.round(Math.max(yB, yD));\n const minY = Math.round(Math.min(yB, yD));\n\n return { minX, maxX, minY, maxY } as const;\n }\n\n getScaleFactor(dpi = false) {\n const scale = this.renderer.getScale(this.target[3] - this.target[1], this.target[4] - this.target[2], dpi);\n if (scale === 0) {\n return this._lastGoodScale;\n }\n this._lastGoodScale = scale;\n return scale;\n }\n\n private copyStrandValues(target: Strand, next: Strand) {\n target[0] = next[0];\n target[1] = next[1];\n target[2] = next[2];\n target[3] = next[3];\n target[4] = next[4];\n }\n\n private getZoomConstraintState(target: Strand) {\n const width = target[3] - target[1];\n const height = target[4] - target[2];\n const nextScale = this.renderer.getScale(width, height);\n const scaleFactor = nextScale === 0 ? this._lastGoodScale : nextScale;\n\n if (nextScale !== 0) {\n this._lastGoodScale = nextScale;\n }\n\n const displayWidth = width * scaleFactor;\n const displayHeight = height * scaleFactor;\n const widthScale = this.world.width / displayWidth;\n const heightScale = this.world.height / displayHeight;\n\n const minScale =\n widthScale > heightScale\n ? (displayWidth * this.options.maxUnderZoom) / this.world.width\n : (displayHeight * this.options.maxUnderZoom) / this.world.height;\n\n const sWidth = this.getRendererScreenPosition()?.width;\n const ratio = sWidth ? sWidth / this.world.width : 1;\n const maxScale = Math.max(ratio || 1, this.options.maxOverZoom);\n\n return {\n scaleFactor,\n minScale,\n maxScale,\n };\n }\n\n constrainTarget(\n target: Strand,\n {\n origin,\n panPadding = 0,\n ref = false,\n }: {\n origin?: { x: number; y: number };\n panPadding?: number;\n ref?: boolean;\n } = {}\n ) {\n let isConstrained = false;\n const constrained = ref ? target : dna(target);\n const { scaleFactor, minScale, maxScale } = this.getZoomConstraintState(constrained);\n const clampedScale = Math.max(minScale, Math.min(maxScale, scaleFactor));\n\n if (Math.abs(clampedScale - scaleFactor) > 0.000001) {\n const zoomOrigin = origin || {\n x: constrained[1] + (constrained[3] - constrained[1]) / 2,\n y: constrained[2] + (constrained[4] - constrained[2]) / 2,\n };\n const adjusted = transform(\n constrained,\n scaleAtOrigin(scaleFactor / clampedScale, zoomOrigin.x, zoomOrigin.y),\n this.zoomBuffer\n );\n\n this.copyStrandValues(constrained, adjusted);\n isConstrained = true;\n }\n\n const [isPanConstrained] = this.constrainBounds(constrained, {\n ref: true,\n panPadding,\n });\n\n return [isConstrained || isPanConstrained, constrained] as const;\n }\n\n /**\n * Zoom\n */\n getZoomedPosition(\n factor: number,\n {\n origin,\n fromPos: _fromPos,\n }: {\n origin?: { x: number; y: number };\n fromPos?: Strand;\n }\n ) {\n const source = _fromPos || this.target;\n const { scaleFactor, minScale, maxScale } = this.getZoomConstraintState(source);\n\n const realFactor = 1 / factor;\n const proposedScale = scaleFactor * realFactor;\n const isZoomingOut = realFactor < 1;\n\n if (isZoomingOut) {\n if (proposedScale < minScale) {\n factor = scaleFactor / minScale;\n }\n } else {\n // Zooming in.\n if (proposedScale > maxScale) {\n factor = scaleFactor / maxScale;\n }\n }\n\n // set the new scale.\n const proposedStrand = transform(\n source,\n scaleAtOrigin(\n factor,\n origin ? origin.x : source[1] + (source[3] - source[1]) / 2,\n origin ? origin.y : source[2] + (source[4] - source[2]) / 2\n ),\n this.zoomBuffer\n );\n\n const zoomPanPadding = this.world.hasActiveZone() ? 0 : 100;\n this.constrainBounds(proposedStrand, {\n ref: true,\n panPadding: zoomPanPadding,\n });\n\n return proposedStrand;\n }\n\n clampRegion({\n x,\n y,\n width,\n height,\n padding = 0,\n }: {\n x: number;\n y: number;\n width: number;\n height: number;\n padding?: number;\n }) {\n const w = this.width;\n const h = this.height;\n const matchesHeight = width / w < height / h;\n\n const rx = x - padding;\n const ry = y - padding;\n const rWidth = width + padding * 2;\n const rHeight = height + padding * 2;\n\n if (matchesHeight) {\n // pad on the left and right.\n const actualWidth = (rHeight / h) * w;\n return {\n x: rx - (actualWidth - rWidth) / 2,\n y: ry,\n width: actualWidth,\n height: rHeight,\n };\n }\n // pad on the top and bottom.\n const actualHeight = (rWidth / w) * h;\n return {\n x: rx,\n y: ry - (actualHeight - rHeight) / 2,\n width: rWidth,\n height: actualHeight,\n };\n }\n\n /**\n * Converts units from the viewer to the world.\n *\n * Needs to be tested, as this will become more important with the event system.\n *\n * @param x\n * @param y\n */\n viewerToWorld(x: number, y: number) {\n const scaleFactor = this.getScaleFactor();\n this._viewerToWorld.x = this.target[1] + x / scaleFactor;\n this._viewerToWorld.y = this.target[2] + y / scaleFactor;\n return this._viewerToWorld;\n }\n\n /**\n * Converts units from the viewer to the world.\n *\n * Needs to be tested, as this will become more important with the event system.\n *\n * @param x\n * @param y\n * @param width\n * @param height\n */\n worldToViewer(x: number, y: number, width: number, height: number) {\n const strand = DnaFactory.singleBox(width, height, x, y);\n\n mutate(strand, compose(scale(this.getScaleFactor()), translate(-this.target[1], -this.target[2])));\n\n return {\n // visible: visible[0] !== 0,\n x: strand[1],\n y: strand[2],\n width: strand[3] - strand[1],\n height: strand[4] - strand[2],\n strand,\n };\n }\n\n /**\n * Set scale\n *\n * This will set the scale of the target, with an optional origin.\n *\n * @param scaleFactor\n * @param origin\n */\n setScale(scaleFactor: number, origin?: { x: number; y: number }) {\n mutate(\n this.target,\n scaleAtOrigin(\n scaleFactor,\n origin ? origin.x : this.target[1] + (this.target[3] - this.target[1]) / 2,\n origin ? origin.y : this.target[2] + (this.target[4] - this.target[2]) / 2\n )\n );\n this.pendingUpdate = true;\n }\n\n /**\n * Sync runtime instances\n *\n * Allows a single controller to drive 2 runtime instances, or 2 controllers to both\n * control each other.\n *\n * @param runtime\n */\n syncTo(runtime: Runtime) {\n const oldTarget = this.target;\n this.target = runtime.target;\n this.pendingUpdate = true;\n\n // Return an unsubscribe.\n return () => {\n this.target = oldTarget;\n };\n }\n\n /**\n * Stop the runtime\n *\n * Stops the internal clock, where no more updates will occur. Returns a function to restart it.\n */\n stop(): () => void {\n if (typeof this.stopId !== 'undefined') {\n window.cancelAnimationFrame(this.stopId);\n this.stopId = undefined;\n }\n\n return () => {\n this.render(performance.now());\n };\n }\n\n reset() {\n this.renderer.reset();\n this.resetReadyState('runtime-reset');\n }\n\n resetReadyState(reason: AtlasReadyResetReason = 'manual') {\n this.ready = false;\n this.readyCycle += 1;\n this.readyReason = reason;\n this.readyTimestamp = undefined;\n if (this.renderer.resetReadyState) {\n this.renderer.resetReadyState();\n }\n this.pendingUpdate = true;\n }\n\n getReadyState(): {\n ready: boolean;\n cycle: number;\n reason: AtlasReadyResetReason;\n timestamp?: number;\n } {\n return {\n ready: this.ready,\n cycle: this.readyCycle,\n reason: this.readyReason,\n timestamp: this.readyTimestamp,\n };\n }\n\n selectZone(zone: number | string) {\n this.world.selectZone(zone);\n this.pendingUpdate = true;\n }\n\n goToZone(\n id: string,\n options: {\n paddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n immediate?: boolean;\n } = {}\n ): boolean {\n const zone = this.world.getZoneById(id);\n if (!zone) {\n return false;\n }\n\n zone.recalculateBounds();\n if (zone.points[0] === 0) {\n return false;\n }\n\n this.world.selectZone(id);\n\n const homeTarget = this.getHomeTarget({\n position: zone.points,\n paddingPx: options.paddingPx,\n });\n\n if (options.immediate) {\n this.transitionManager.stopTransition();\n this.setViewport(homeTarget);\n this.constrainBounds(this.target, { ref: true });\n this.updateControllerPosition();\n this.pendingUpdate = true;\n return true;\n }\n\n this.transitionManager.applyTransition(\n DnaFactory.singleBox(homeTarget.width, homeTarget.height, homeTarget.x, homeTarget.y),\n undefined,\n {\n duration: 1000,\n easing: easingFunctions.easeOutExpo,\n constrain: false,\n }\n );\n this.updateNextFrame();\n this.pendingUpdate = true;\n\n return true;\n }\n\n deselectZone() {\n this.world.deselectZone();\n this.pendingUpdate = true;\n }\n\n getZoneRuntimeState(zoneId: string, viewport: Projection = this.getViewport()): RuntimeZoneState {\n const zone = this.world.getZoneById(zoneId);\n if (!zone) {\n return {\n zoneId,\n exists: false,\n active: false,\n visibleInViewport: false,\n };\n }\n\n zone.recalculateBounds();\n const active = this.world.getActiveZone()?.id === zoneId;\n\n if (zone.points[0] === 0) {\n return {\n zoneId,\n exists: true,\n active,\n visibleInViewport: false,\n };\n }\n\n const zoneX = zone.points[1];\n const zoneY = zone.points[2];\n const zoneWidth = zone.points[3] - zone.points[1];\n const zoneHeight = zone.points[4] - zone.points[2];\n const visibleInViewport =\n zoneX < viewport.x + viewport.width &&\n zoneX + zoneWidth > viewport.x &&\n zoneY < viewport.y + viewport.height &&\n zoneY + zoneHeight > viewport.y;\n\n return {\n zoneId,\n exists: true,\n active,\n visibleInViewport,\n };\n }\n\n hook<Name extends keyof RuntimeHooks, Arg = UnwrapHookArg<Name>>(name: keyof RuntimeHooks, arg: Arg) {\n const len = this.hooks[name].length;\n if (len !== 0) {\n for (let x = 0; x < len; x++) {\n this.hooks[name][x](arg as any);\n }\n }\n }\n\n registerHook<Name extends keyof RuntimeHooks, Hook = UnwrapHook<Name>>(name: Name, hook: Hook) {\n this.hooks[name].push(hook as any);\n return () => {\n this.hooks[name] = (this.hooks[name] as any[]).filter((e) => e !== (hook as any));\n };\n }\n\n /**\n * Render\n *\n * The hottest path in the runtime, called every 16.7ms, if possible in the future be double-timed on 120hz monitors.\n *\n * @ param t\n */\n render = (t: number) => {\n const delta = t - this.lastTime;\n\n if (this.isCommitting || (this.fpsLimit && delta < 1000 / this.fpsLimit)) {\n this.stopId = window.requestAnimationFrame(this.render);\n return;\n }\n\n this.lastTime = t;\n // First flush\n this.world.flushSubscriptions();\n // Set up our loop.\n this.stopId = window.requestAnimationFrame(this.render);\n\n // Called every frame.\n this.hook('useFrame', delta);\n\n let pendingUpdate = this.pendingUpdate;\n const rendererPendingUpdate = this.renderer.pendingUpdate();\n const worldPendingUpdate = this.world.hasPendingAnimation();\n const debugEnabled = this.hasDebugSubscribers();\n\n if (this.transitionManager.hasPending()) {\n this.transitionManager.runTransition(this.target, delta);\n\n this.pendingUpdate = true;\n pendingUpdate = true;\n this.updateControllerPosition();\n }\n\n if (worldPendingUpdate) {\n this.pendingUpdate = true;\n pendingUpdate = true;\n }\n\n if (\n !this.firstRender &&\n !pendingUpdate &&\n // Check if there was a pending update from the renderer.\n !rendererPendingUpdate &&\n !worldPendingUpdate &&\n // Then check the points, the first will catch invalidation.\n this.target[0] === this.lastTarget[0] &&\n // The following are x1, y1, x2, y2 points of the target.\n this.target[1] === this.lastTarget[1] &&\n this.target[2] === this.lastTarget[2] &&\n this.target[3] === this.lastTarget[3] &&\n this.target[4] === this.lastTarget[4]\n ) {\n // Nothing to do, target didn't change since last time.\n return;\n }\n\n // Group.\n // console.groupCollapsed(`Previous frame took ${delta} ${delta > 17 ? '<-' : ''} ${delta > 40 ? '<--' : ''}`);\n const frame = ++this.debugFrame;\n let paintCount = 0;\n\n if (debugEnabled) {\n this.emitDebug({\n type: 'frame-start',\n at: t,\n runtimeId: this.id,\n frame,\n delta,\n mode: this.mode,\n pendingUpdate,\n rendererPendingUpdate,\n target: [this.target[1], this.target[2], this.target[3], this.target[4]],\n });\n }\n\n this.hook('useBeforeFrame', delta);\n // Before everything kicks off, add a hook.\n this.renderer.beforeFrame(this.world, delta, this.target, this.hookOptions);\n // Calculate a scale factor by passing in the height and width of the target.\n const scaleFactor = this.getScaleFactor();\n // Get the points to render based on this scale factor and the current x,y,w,h in the target buffer.\n const points = this.renderer.getPointsAt(this.world, this.target, this.aggregate, scaleFactor);\n const pointsLen = points.length;\n for (let p = 0; p < pointsLen; p++) {\n // each point is an array of [SpacialContent, Strand, Strand]\n // The first is used to get real rendering data, like Image URLs etc.\n // The second is the points themselves for the layer. If this is a single\n // image this will be a single set of 5 points, for tiled images, it will be\n // the correct list of tiles, and a much longer list of points.\n const paint = points[p][0];\n const point = points[p][1];\n const transformation = points[p][2];\n\n // This is the position of the points. We apply the transform that came with the points.\n // The points before the transformation are just points relative to their parent (canvas?)\n // When we apply the transform, they become relative to the viewer. Both of these point\n // values are useful, but for rendering, we want the viewer-points.\n // @todo add option in renderer to omit this transform, instead passing it as a param.\n const position = transformation ? transform(point, transformation, this.transformBuffer) : point;\n // Another hook before painting a layer.\n this.renderer.prepareLayer(\n paint,\n paint.__parent && transformation\n ? transform(paint.__parent.crop || paint.__parent.points, transformation)\n : position\n );\n // For loop helps keep this fast, looping through all of the tiles that make up an image.\n // This could be a single point, where len is one.\n const totalTiles = position.length / 5;\n for (let i = 0; i < totalTiles; i++) {\n const key = i * 5;\n // First key position tells us if we should render or not. A 0 will usually\n // indicate that the image is off-screen.\n if (position[key] === 0) {\n continue;\n }\n\n // This is the most expensive call by a long shot, the client implementation.\n // In the reference Canvas implementation, this will grab the URL of the image,\n // load it into an image tag and then paint it onto the canvas at the viewer points.\n this.renderer.paint(\n paint,\n i,\n position[key + 1],\n position[key + 2],\n position[key + 3] - position[key + 1],\n position[key + 4] - position[key + 2]\n );\n paintCount++;\n if (debugEnabled) {\n let imageUrl: string | undefined;\n if ((paint as any).getImageUrl) {\n try {\n imageUrl = (paint as any).getImageUrl(i);\n } catch (err) {\n imageUrl = undefined;\n }\n }\n this.emitDebug({\n type: 'paint',\n at: t,\n runtimeId: this.id,\n frame,\n layerIndex: p,\n tileIndex: i,\n x: position[key + 1],\n y: position[key + 2],\n width: position[key + 3] - position[key + 1],\n height: position[key + 4] - position[key + 2],\n paintId: (paint as any).id || `${p}:${i}`,\n paintType: paint?.constructor?.name || paint.type || 'UnknownPaint',\n ownerId: (paint as any).__owner?.value?.id,\n compositeId: (paint as any).__parent?.id,\n imageUrl,\n });\n }\n this.hook('useAfterPaint', paint);\n }\n\n this.renderer.finishLayer(paint, point);\n }\n // A final hook after the entire frame is complete.\n this.renderer.afterFrame(this.world, delta, this.target, this.hookOptions);\n // Mark this frame as consumed before running after-frame hooks so hooks can request the next frame.\n this.pendingUpdate = false;\n this.hook('useAfterFrame', delta);\n // Finally at the end, we set up the frame we just rendered.\n this.lastTarget[0] = this.target[0];\n this.lastTarget[1] = this.target[1];\n this.lastTarget[2] = this.target[2];\n this.lastTarget[3] = this.target[3];\n this.lastTarget[4] = this.target[4];\n // We've just finished our first render.\n this.firstRender = false;\n this.logNextRender = false;\n if (!this.ready && this.renderer.isReady()) {\n this.ready = true;\n this.readyTimestamp = performance.now();\n this.world.trigger('ready');\n }\n\n if (debugEnabled) {\n this.emitDebug({\n type: 'frame-end',\n at: t,\n runtimeId: this.id,\n frame,\n delta,\n scaleFactor,\n paintCount,\n ready: this.ready,\n pendingUpdate: this.pendingUpdate,\n worldWidth: this.world.width,\n worldHeight: this.world.height,\n target: [this.target[1], this.target[2], this.target[3], this.target[4]],\n });\n }\n // Flush world subscriptions.\n this.world.flushSubscriptions();\n const updates = this.world.getScheduledUpdates(this.target, scaleFactor);\n const len = updates.length;\n if (len > 0) {\n for (let i = 0; i < len; i++) {\n const update = updates[len - i - 1]();\n if (update) {\n update.then(() => {\n this.pendingUpdate = true;\n });\n } else {\n this.pendingUpdate = true;\n }\n }\n }\n };\n\n updateNextFrame() {\n this.pendingUpdate = true;\n }\n\n addDebugSubscriber(callback: (event: RuntimeDebugEvent) => void) {\n this.debugSubscribers.add(callback);\n return () => {\n this.removeDebugSubscriber(callback);\n };\n }\n\n removeDebugSubscriber(callback: (event: RuntimeDebugEvent) => void) {\n this.debugSubscribers.delete(callback);\n }\n\n private hasDebugSubscribers() {\n return this.debugSubscribers.size > 0;\n }\n\n private emitDebug(event: RuntimeDebugEvent) {\n if (this.debugSubscribers.size === 0) {\n return;\n }\n for (const callback of this.debugSubscribers) {\n callback(event);\n }\n }\n}\n","import { dna, type Strand } from '@atlas-viewer/dna';\nimport type { Paint } from './paint';\nimport type { WorldObject } from './world-object';\n\nexport interface ZoneInterface {\n id: string;\n config: ZoneResolvedConfig;\n objects: WorldObject[];\n points: Strand;\n recalculateBounds(): void;\n getPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[];\n}\n\nexport type ZoneConfig = {\n margin?: number;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n};\n\nexport type ZoneResolvedConfig = {\n margin: number;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n};\n\nconst defaultConfig: ZoneResolvedConfig = {\n margin: 0,\n};\n\nexport class Zone implements ZoneInterface {\n id: string;\n config: ZoneResolvedConfig;\n points: Strand;\n objects: WorldObject[];\n\n constructor(objects: [WorldObject, ...WorldObject[]], config?: ZoneConfig);\n constructor(config: ZoneConfig & { id: string; objects?: WorldObject[] });\n constructor(\n objectsOrConfig: [WorldObject, ...WorldObject[]] | (ZoneConfig & { id: string; objects?: WorldObject[] }),\n config: ZoneConfig = {}\n ) {\n if (Array.isArray(objectsOrConfig)) {\n this.id = objectsOrConfig.map((obj) => obj.id).join('$$');\n this.config = {\n ...defaultConfig,\n ...config,\n };\n this.objects = [...objectsOrConfig];\n } else {\n this.id = objectsOrConfig.id;\n this.config = {\n ...defaultConfig,\n margin: typeof objectsOrConfig.margin === 'number' ? objectsOrConfig.margin : defaultConfig.margin,\n x: objectsOrConfig.x,\n y: objectsOrConfig.y,\n width: objectsOrConfig.width,\n height: objectsOrConfig.height,\n };\n this.objects = [...(objectsOrConfig.objects || [])];\n }\n\n this.points = dna(5);\n this.recalculateBounds();\n }\n\n applyProps(config: ZoneConfig & { id?: string }) {\n if (typeof config.id !== 'undefined') {\n this.id = config.id;\n }\n this.config = {\n ...this.config,\n ...config,\n };\n this.recalculateBounds();\n }\n\n addObject(object: WorldObject) {\n if (this.objects.indexOf(object) !== -1) {\n return;\n }\n this.objects.push(object);\n this.recalculateBounds();\n }\n\n removeObject(object: WorldObject) {\n this.objects = this.objects.filter((zoneObject) => zoneObject !== object);\n this.recalculateBounds();\n }\n\n recalculateBounds(): void {\n const hasManualBounds =\n Number.isFinite(this.config.x) &&\n Number.isFinite(this.config.y) &&\n Number.isFinite(this.config.width) &&\n Number.isFinite(this.config.height) &&\n (this.config.width as number) > 0 &&\n (this.config.height as number) > 0;\n\n if (!hasManualBounds) {\n this.points.set([0, 0, 0, 0, 0]);\n return;\n }\n\n const margin = this.config.margin;\n const x = this.config.x as number;\n const y = this.config.y as number;\n const width = this.config.width as number;\n const height = this.config.height as number;\n this.points.set([1, x - margin, y - margin, x + width + margin, y + height + margin]);\n }\n\n getPointsAt(target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return [];\n }\n}\n","let getCurrentTime: () => number;\nconst hasPerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';\n\nif (hasPerformanceNow) {\n const localPerformance = performance;\n getCurrentTime = () => localPerformance.now();\n} else {\n const localDate = Date;\n const initialTime = localDate.now();\n getCurrentTime = () => localDate.now() - initialTime;\n}\n\nexport { getCurrentTime as now };\n","import React, { version } from 'react';\nimport type { OpaqueHandle } from 'react-reconciler';\nimport Reconciler_ from 'react-reconciler';\nimport type { AtlasObjectModel } from '../../aom';\nimport { supportedEventAttributes, supportedEventMap } from '../../events';\nimport { BaseObject } from '../../objects/base-object';\nimport { Box } from '../../objects/box';\nimport { Geometry } from '../../objects/geometry';\nimport { Text } from '../../objects/text';\nimport { Runtime } from '../../renderer/runtime';\nimport { CompositeResource } from '../../spacial-content/composite-resource';\nimport { ImageTexture } from '../../spacial-content/image-texture';\nimport { MapTiledImage } from '../../spacial-content/map-tiled-image';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { World } from '../../world';\nimport { WorldObject } from '../../world-objects/world-object';\nimport { Zone } from '../../world-objects/zone';\nimport { now } from './utility/now';\n\nconst Reconciler =\n typeof Reconciler_ === 'function'\n ? Reconciler_\n : typeof (Reconciler_ as any)?.default === 'function'\n ? (Reconciler_ as any).default\n : null;\n\n// From react-reconciler/constants;\n// import { ContinuousEventPriority, DiscreteEventPriority, DefaultEventPriority } from 'react-reconciler/constants'\nconst ConcurrentRoot = 1;\nconst ContinuousEventPriority = 8;\nconst DefaultEventPriority = 32;\nconst DiscreteEventPriority = 2;\nconst IdleEventPriority = 268435456;\nconst LegacyRoot = 0;\nconst NoEventPriority = 0;\n\ntype ZoneHostProps = {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n margin?: number;\n};\n\nclass ZoneHostInstance implements AtlasObjectModel<ZoneHostProps, any> {\n world: World;\n zone: Zone;\n private isRegistered = false;\n private directWorldObjects: WorldObject[] = [];\n\n constructor(world: World) {\n this.world = world;\n this.zone = new Zone({ id: '' });\n }\n\n applyProps(props: ZoneHostProps): void {\n this.zone.applyProps({\n id: props.id,\n x: props.x,\n y: props.y,\n width: props.width,\n height: props.height,\n margin: props.margin,\n });\n }\n\n appendChild(item: unknown): void {\n if (!(item instanceof WorldObject)) {\n return;\n }\n this.registerDirectWorldObject(item);\n this.world.appendChild(item);\n }\n\n removeChild(item: unknown): void {\n if (!(item instanceof WorldObject)) {\n return;\n }\n this.unregisterDirectWorldObject(item);\n this.world.removeChild(item);\n }\n\n insertBefore(item: unknown, before: unknown): void {\n if (!(item instanceof WorldObject)) {\n return;\n }\n this.registerDirectWorldObject(item);\n if (before instanceof WorldObject) {\n this.world.insertBefore(item, before);\n return;\n }\n this.world.appendChild(item);\n }\n\n hideInstance(): void {\n // no-op\n }\n\n attachToWorld(world: World) {\n if (this.isRegistered && this.world !== world) {\n this.world.removeZone(this.zone);\n this.isRegistered = false;\n }\n this.world = world;\n if (!this.isRegistered) {\n this.world.addZone(this.zone);\n this.isRegistered = true;\n }\n }\n\n unmount() {\n this.directWorldObjects = [];\n if (this.isRegistered) {\n this.world.removeZone(this.zone);\n this.isRegistered = false;\n }\n }\n\n private registerDirectWorldObject(item: WorldObject) {\n if (this.directWorldObjects.indexOf(item) === -1) {\n this.directWorldObjects.push(item);\n }\n this.zone.addObject(item);\n }\n\n private unregisterDirectWorldObject(item: WorldObject) {\n this.directWorldObjects = this.directWorldObjects.filter((zoneObject) => zoneObject !== item);\n this.zone.removeObject(item);\n }\n}\n\nfunction appendChild(parent: AtlasObjectModel<any, any>, child: any) {\n if (parent instanceof World && child instanceof ZoneHostInstance) {\n child.attachToWorld(parent);\n return;\n }\n if (parent instanceof ZoneHostInstance) {\n parent.appendChild(child);\n return;\n }\n if (parent && parent.appendChild && child) {\n parent.appendChild(child);\n }\n}\n\nfunction removeChild(parent: AtlasObjectModel<any, any>, child: any) {\n if (parent instanceof World && child instanceof ZoneHostInstance) {\n child.unmount();\n return;\n }\n if (parent instanceof ZoneHostInstance) {\n parent.removeChild(child);\n return;\n }\n if (parent && parent.removeChild && child) {\n parent.removeChild(child);\n }\n}\n\nfunction removeChildFromContainer(parent: Runtime, child: any) {\n if (child instanceof ZoneHostInstance) {\n child.unmount();\n return;\n }\n return removeChild(parent.world, child);\n}\nfunction insertInContainerBefore(\n container: Runtime,\n child: AtlasObjectModel<any, any>,\n beforeChild: AtlasObjectModel<any, any>\n) {\n if (child instanceof ZoneHostInstance) {\n child.attachToWorld(container.world);\n return;\n }\n return insertBefore(container.world, child, beforeChild);\n}\n\nfunction insertBefore(parent: Runtime | AtlasObjectModel<any, any>, child: any, before: any) {\n if (parent && parent instanceof Runtime) {\n parent = parent.world;\n }\n if (parent instanceof World && child instanceof ZoneHostInstance) {\n return;\n }\n if (parent instanceof ZoneHostInstance) {\n parent.insertBefore(child, before);\n return;\n }\n if (parent && parent.insertBefore) {\n parent.insertBefore(child, before);\n }\n}\n\nexport function applyProps(instance: any, oldProps: any, newProps: any) {\n if (!newProps) {\n return;\n }\n if (instance.applyProps) {\n instance.applyProps(newProps);\n }\n\n if (instance instanceof BaseObject) {\n for (const ev of supportedEventAttributes) {\n const event = ev.slice(2).toLowerCase();\n if (newProps[ev] !== oldProps[ev]) {\n if (oldProps[ev]) {\n instance.removeEventListener(event as any, oldProps[ev]);\n }\n instance.addEventListener(event as any, newProps[ev]);\n }\n }\n }\n}\n\nexport function activateEvents(world: World, props: any) {\n const keys = Object.keys(props);\n let didActivate = false;\n for (const key of keys) {\n if (supportedEventAttributes.indexOf(key as any) !== -1) {\n const ev = (supportedEventMap as any)[key];\n if (ev) {\n if (world.activatedEvents.indexOf(ev) !== -1) continue;\n didActivate = true;\n world.activatedEvents.push(ev);\n }\n }\n }\n if (didActivate) {\n world.triggerEventActivation();\n }\n}\n\nconst roots = new Map<any, any>();\nconst emptyObject = {};\n\nfunction createInstance(\n type: string,\n { args = [], ...props }: any,\n runtime: Runtime,\n hostContext?: any,\n internalInstanceHandle?: Reconciler_.Fiber\n) {\n if (!(runtime instanceof Runtime) && internalInstanceHandle) {\n const fn = (node: Reconciler_.Fiber): Runtime => {\n if (!node.return) return node.stateNode && node.stateNode.containerInfo;\n else return fn(node.return);\n };\n runtime = fn(internalInstanceHandle);\n }\n\n let instance: BaseObject<any, any> | ZoneHostInstance;\n let world: World = runtime.world;\n switch (type) {\n case 'world':\n instance = World.withProps({\n width: props.width,\n height: props.height,\n viewingDirection: 'left-to-right',\n });\n (instance as World).activatedEvents = world.activatedEvents;\n (instance as World).eventHandlers = world.eventHandlers;\n (instance as World).subscriptions = world.subscriptions;\n (instance as World).triggerEventActivation();\n world = instance as World;\n break;\n case 'box':\n instance = new Box();\n break;\n case 'shape':\n instance = new Geometry();\n break;\n case 'worldObject':\n case 'world-object':\n instance = new WorldObject();\n break;\n case 'zone':\n instance = new ZoneHostInstance(world);\n break;\n case 'worldImage':\n case 'world-image':\n instance = new SingleImage();\n break;\n case 'texture':\n instance = new ImageTexture();\n break;\n case 'compositeImage':\n case 'composite-image':\n // @todo switch to applyProps\n instance = new CompositeResource({\n id: props.id,\n width: props.width,\n height: props.height,\n images: [],\n renderOptions: props.renderOptions,\n });\n break;\n case 'tiledImage':\n case 'tiled-image':\n instance = TiledImage.fromTile(\n props.uri,\n props.display,\n props.tile,\n props.scaleFactor,\n undefined,\n props.format,\n props.useFloorCalc,\n props.version3\n );\n break;\n case 'mapTiledImage':\n case 'map-tiled-image':\n instance = new MapTiledImage({\n id: props.id,\n bounds: props.bounds,\n worldWidth: props.worldWidth,\n worldHeight: props.worldHeight,\n zoom: props.zoom,\n tileSize: props.tileSize,\n scaleFactor: props.scaleFactor,\n tileSource: props.tileSource,\n tileUrlTemplate: props.tileUrlTemplate,\n subdomains: props.subdomains,\n });\n break;\n case 'paragraph':\n instance = new Text();\n (instance as Text).text = props.children;\n break;\n default:\n // throw new Error(`Element <${type} /> not found`);\n return;\n }\n\n activateEvents(world, props);\n applyProps(instance as any, {}, props);\n\n return instance;\n}\n\nfunction appendChildToContainer(runtime: Runtime, world: any) {\n if (world instanceof World) {\n runtime.world = world;\n } else if (world instanceof ZoneHostInstance) {\n world.attachToWorld(runtime.world);\n } else if (world instanceof WorldObject) {\n runtime.world.appendChild(world);\n } else if (world) {\n throw new Error('Invalid root');\n }\n}\n\nlet currentUpdatePriority = NoEventPriority;\n\nconst reconciler = Reconciler\n ? Reconciler<\n any,\n any,\n Runtime,\n unknown, // Instance,\n unknown, // TextInstance,\n unknown, // SuspenseInstance,\n unknown, // HydratableInstance,\n unknown, // PublicInstance,\n unknown, // HostContext,\n unknown, // UpdatePayload,\n unknown, // _ChildSet,\n unknown, // TimeoutHandle,\n unknown // NoTimeout\n >({\n // @ts-expect-error\n unstable_now: now,\n // @ts-expect-error\n now,\n createInstance,\n removeChild,\n appendChild,\n appendInitialChild: appendChild,\n insertBefore: insertBefore,\n warnsIfNotActing: true,\n supportsMutation: true,\n isPrimaryRenderer: false,\n // @ts-expect-error\n scheduleTimeout: typeof setTimeout !== 'undefined' ? setTimeout : undefined,\n // @ts-expect-error\n cancelTimeout: typeof clearTimeout !== 'undefined' ? clearTimeout : undefined,\n setTimeout: typeof setTimeout !== 'undefined' ? setTimeout : undefined,\n clearTimeout: typeof clearTimeout !== 'undefined' ? clearTimeout : undefined,\n noTimeout: -1,\n appendChildToContainer,\n removeChildFromContainer: removeChildFromContainer,\n createTextInstance() {\n // no-op\n },\n insertInContainerBefore: insertInContainerBefore,\n prepareUpdate(instance: any, type: any, oldProps: any, newProps: any, runtime: Runtime) {\n activateEvents(runtime.world, newProps);\n return newProps;\n },\n commitUpdate(instance: any, type_: any, prevProps_: any, updatePayload_: any, internalHandle: OpaqueHandle) {\n let type = type_,\n updatePayload = updatePayload_;\n const prevProps = prevProps_;\n if (typeof updatePayload === 'string') {\n // react <= 18\n type = updatePayload_;\n updatePayload = prevProps_;\n }\n\n if (instance.applyProps && updatePayload) {\n applyProps(instance, prevProps, updatePayload);\n }\n },\n\n finalizeInitialChildren(instance: any) {\n // https://github.com/facebook/react/issues/20271\n // Returning true will trigger commitMount\n return instance?.__handlers;\n },\n getChildHostContext() {\n return emptyObject;\n },\n getRootHostContext() {\n return emptyObject;\n },\n prepareForCommit(runtime) {\n runtime.isCommitting = true;\n return null;\n },\n preparePortalMount() {\n // no-op\n },\n hideInstance(instance: BaseObject) {\n if (instance && instance.points) {\n instance.points[0] = 0;\n }\n // @todo these are called when a component is suspended\n },\n unhideInstance(instance: BaseObject, props: any) {\n if (instance && instance.points) {\n instance.points[0] = 1;\n }\n // @todo these are called when a component is suspended\n },\n getPublicInstance(instance: BaseObject) {\n return instance;\n },\n hideTextInstance() {\n throw new Error(\n 'Text is not allowed in the react-three-fibre tree. You may have extraneous whitespace between components.'\n );\n },\n resetAfterCommit(runtime) {\n runtime.isCommitting = false;\n runtime.pendingUpdate = true;\n if (runtime.world) {\n if (runtime.world.needsRecalculate) {\n runtime.world.recalculateWorldSize();\n runtime.world.triggerRepaint();\n }\n }\n },\n shouldSetTextContent() {\n return false;\n },\n clearContainer() {\n return false;\n },\n\n // 0.29.0 and later\n supportsHydration: false,\n supportsPersistence: false,\n\n detachDeletedInstance(node) {\n // no-op?\n // console.log('detachDeletedInstance', node);\n },\n\n afterActiveInstanceBlur() {\n // no-op\n },\n\n beforeActiveInstanceBlur() {\n // no-op\n },\n\n getCurrentEventPriority() {\n // If in the browser, check `window.event` and maybe do something different.\n return DefaultEventPriority;\n },\n\n getInstanceFromNode(node) {\n throw new Error('Not implemented');\n },\n\n getInstanceFromScope(scopeInstance) {\n throw new Error('Not implemented');\n // return nodeToInstanceMap.get(scopeInstance) || null;\n },\n\n prepareScopeUpdate(scopeInstance, instance) {\n throw new Error('Not implemented');\n // nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n logRecoverableError() {\n // noop\n },\n\n requestPostPaintCallback() {\n // noop\n },\n\n rendererPackageName: '@atlas-viewer/atlas',\n rendererVersion: version,\n\n // React 19.\n shouldAttemptEagerTransition: () => false,\n trackSchedulerEvent: () => {},\n resolveEventType: () => null,\n resolveEventTimeStamp: () => -1.1,\n maySuspendCommit: () => false,\n preloadInstance: () => true, // true indicates already loaded\n startSuspendingCommit() {},\n suspendInstance() {},\n waitForCommitToBeReady: () => null,\n NotPendingTransition: null,\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n resolveUpdatePriority() {\n if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;\n\n switch (typeof window !== 'undefined' && window.event?.type) {\n case 'click':\n case 'contextmenu':\n case 'dblclick':\n case 'pointercancel':\n case 'pointerdown':\n case 'pointerup':\n return DiscreteEventPriority;\n case 'pointermove':\n case 'pointerout':\n case 'pointerover':\n case 'pointerenter':\n case 'pointerleave':\n case 'wheel':\n return ContinuousEventPriority;\n default:\n return DefaultEventPriority;\n }\n },\n resetFormInstance() {},\n })\n : null;\n\nif (reconciler) {\n // @ts-expect-error DefinitelyTyped is not up to date\n reconciler.injectIntoDevTools();\n}\n\nexport function unmountComponentAtNode(runtime: Runtime, callback?: (runtime: any) => void) {\n const root = roots.get(runtime);\n if (root) {\n if (!reconciler) return;\n reconciler.updateContainer(null, root, null, () => {\n roots.delete(runtime);\n if (callback) callback(runtime);\n });\n }\n}\n\nexport const ReactAtlas = {\n render(whatToRender: any, runtime: any) {\n const root = roots.get(runtime);\n\n if (!reconciler) return;\n\n if (root) {\n reconciler.updateContainer(whatToRender, root, null);\n } else {\n const newRoot = reconciler.createContainer(\n runtime,\n 0,\n null,\n false,\n null,\n '',\n () => {\n // on recoverable error.\n },\n null\n );\n\n reconciler.updateContainer(whatToRender, newRoot, null);\n roots.set(runtime, newRoot);\n }\n },\n unmountComponentAtNode(runtime: Runtime, callback?: (runtime: any) => void) {\n unmountComponentAtNode(runtime, callback);\n },\n};\n","import * as React from 'react';\n\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' && (window.document?.createElement || window.navigator?.product === 'ReactNative')\n ? React.useLayoutEffect\n : React.useEffect;\n","import React, { type ReactNode, useEffect, useRef } from 'react';\nimport type { RectReadOnly } from 'react-use-measure';\nimport type { ViewerMode } from '../../../renderer/runtime';\nimport { ModeContext } from '../hooks/use-mode';\nimport type { Preset } from '../presets/_types';\nimport { ReactAtlas } from '../reconciler';\nimport { useIsomorphicLayoutEffect } from '../utility/react';\nimport { AtlasContext, BoundsContext } from './AtlasContext';\n\ntype AtlasWithReconcilerProps = {\n onCreated?: (ctx: Preset) => void | Promise<void>;\n setIsReady: (value: boolean) => void;\n mode?: ViewerMode;\n interactionMode?: 'popmotion' | 'pdf-scroll-zone';\n bounds: RectReadOnly;\n preset: Preset | null;\n children?: ReactNode;\n};\n\nexport const AtlasWithReconciler: React.FC<AtlasWithReconcilerProps> = React.memo(\n ({ children, setIsReady, onCreated, bounds, preset, mode = 'explore', interactionMode = 'popmotion' }) => {\n const initializedPresetsRef = useRef(new WeakSet<Preset>());\n\n useEffect(() => {\n if (!preset) {\n return;\n }\n if (initializedPresetsRef.current.has(preset)) {\n return;\n }\n\n initializedPresetsRef.current.add(preset);\n\n if (interactionMode !== 'pdf-scroll-zone') {\n preset.runtime.goHome();\n }\n\n let cancelled = false;\n Promise.resolve(onCreated?.(preset)).then(() => {\n if (!cancelled) {\n setIsReady(true);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [interactionMode, onCreated, preset, setIsReady]);\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n if (mode !== runtime.mode) {\n runtime.mode = mode;\n }\n\n ReactAtlas.render(\n <React.StrictMode>\n <BoundsContext.Provider value={bounds}>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </BoundsContext.Provider>\n </React.StrictMode>,\n runtime\n );\n }\n }, [preset, mode, bounds, children]);\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n\n return () => {\n ReactAtlas.unmountComponentAtNode(runtime);\n };\n }\n return () => {\n // no-op\n };\n }, [preset]);\n\n return null;\n }\n);\n","import React from 'react';\n\nexport const Container = React.forwardRef<HTMLDivElement, any>((props, ref) => {\n // @ts-ignore\n return <div {...props} ref={ref} part={props.className} />;\n});\n","import { useContext } from 'react';\nimport { AtlasContext } from '../components/AtlasContext';\n\nexport const useAtlas = () => {\n return useContext(AtlasContext);\n};\n","import { useAtlas } from './use-atlas';\n\nexport const useRuntime = () => {\n const atlas = useAtlas();\n return atlas ? atlas.runtime : undefined;\n};\n","import { Runtime } from '../../../renderer/runtime';\nimport { Preset } from '../presets/_types';\n\ntype AtlasRuntimeEntry = {\n runtime: Runtime;\n preset: Preset;\n};\n\ntype DevToolsCandidate = {\n id: string;\n runtimeId?: string;\n};\n\nexport type DevToolsRegistryRuntime = {\n id: string;\n runtime: Runtime;\n preset: Preset;\n label: string;\n};\n\nexport type DevToolsRegistrySnapshot = {\n activeCandidateId?: string;\n selectedRuntimeId?: string;\n candidates: string[];\n runtimes: DevToolsRegistryRuntime[];\n};\n\nconst listeners = new Set<() => void>();\nconst atlasRuntimes = new Map<string, AtlasRuntimeEntry>();\nconst candidates = new Map<string, DevToolsCandidate>();\nconst candidateOrder: string[] = [];\n\nlet activeCandidateId: string | undefined;\nlet selectedRuntimeId: string | undefined;\nlet snapshotCache: DevToolsRegistrySnapshot = {\n activeCandidateId: undefined,\n selectedRuntimeId: undefined,\n candidates: [],\n runtimes: [],\n};\n\nfunction rebuildSnapshot() {\n const runtimes = Array.from(atlasRuntimes.entries()).map(([id, entry], index) => ({\n id,\n runtime: entry.runtime,\n preset: entry.preset,\n label: `Atlas ${index + 1} (${id.slice(0, 6)})`,\n }));\n\n snapshotCache = {\n activeCandidateId,\n selectedRuntimeId,\n candidates: [...candidateOrder],\n runtimes,\n };\n}\n\nfunction emit() {\n rebuildSnapshot();\n for (const listener of listeners) {\n listener();\n }\n}\n\nfunction ensureSelectedRuntime() {\n if (selectedRuntimeId && atlasRuntimes.has(selectedRuntimeId)) {\n return;\n }\n const first = atlasRuntimes.keys().next();\n selectedRuntimeId = first.done ? undefined : first.value;\n}\n\nfunction ensureActiveCandidate() {\n if (activeCandidateId && candidates.has(activeCandidateId)) {\n return;\n }\n activeCandidateId = candidateOrder[0];\n}\n\nexport function subscribeDevToolsRegistry(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\nexport function getDevToolsRegistrySnapshot(): DevToolsRegistrySnapshot {\n return snapshotCache;\n}\n\nexport function registerAtlasRuntime(preset: Preset) {\n const runtimeId = preset.runtime.id;\n atlasRuntimes.set(runtimeId, {\n runtime: preset.runtime,\n preset,\n });\n ensureSelectedRuntime();\n emit();\n\n return () => {\n unregisterAtlasRuntime(runtimeId);\n };\n}\n\nexport function unregisterAtlasRuntime(runtimeId: string) {\n atlasRuntimes.delete(runtimeId);\n ensureSelectedRuntime();\n emit();\n}\n\nexport function registerDevToolsCandidate(candidate: DevToolsCandidate) {\n const existing = candidates.get(candidate.id);\n\n if (!existing) {\n candidateOrder.push(candidate.id);\n }\n\n candidates.set(candidate.id, candidate);\n ensureActiveCandidate();\n\n if (!selectedRuntimeId && candidate.runtimeId && atlasRuntimes.has(candidate.runtimeId)) {\n selectedRuntimeId = candidate.runtimeId;\n }\n\n ensureSelectedRuntime();\n emit();\n\n return () => {\n unregisterDevToolsCandidate(candidate.id);\n };\n}\n\nexport function updateDevToolsCandidateRuntime(candidateId: string, runtimeId?: string) {\n const existing = candidates.get(candidateId);\n if (!existing) {\n return;\n }\n\n existing.runtimeId = runtimeId;\n\n if (!selectedRuntimeId && runtimeId && atlasRuntimes.has(runtimeId)) {\n selectedRuntimeId = runtimeId;\n }\n\n ensureSelectedRuntime();\n emit();\n}\n\nexport function unregisterDevToolsCandidate(candidateId: string) {\n candidates.delete(candidateId);\n const idx = candidateOrder.indexOf(candidateId);\n if (idx !== -1) {\n candidateOrder.splice(idx, 1);\n }\n ensureActiveCandidate();\n emit();\n}\n\nexport function setSelectedRuntimeId(runtimeId?: string) {\n if (!runtimeId) {\n selectedRuntimeId = undefined;\n ensureSelectedRuntime();\n emit();\n return;\n }\n\n if (atlasRuntimes.has(runtimeId)) {\n selectedRuntimeId = runtimeId;\n emit();\n }\n}\n\nexport function getRuntimeEntry(runtimeId?: string) {\n if (!runtimeId) {\n return undefined;\n }\n return atlasRuntimes.get(runtimeId);\n}\n\nexport function getPreferredRuntimeIdForCandidate(candidateId: string): string | undefined {\n const candidate = candidates.get(candidateId);\n if (!candidate) {\n return undefined;\n }\n\n if (candidate.runtimeId && atlasRuntimes.has(candidate.runtimeId)) {\n return candidate.runtimeId;\n }\n\n return selectedRuntimeId;\n}\n\nexport function __resetDevToolsRegistryForTests() {\n atlasRuntimes.clear();\n candidates.clear();\n candidateOrder.length = 0;\n activeCandidateId = undefined;\n selectedRuntimeId = undefined;\n rebuildSnapshot();\n}\n\nrebuildSnapshot();\n","import { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { CompositeResource } from '../../../spacial-content/composite-resource';\nimport { SingleImage } from '../../../spacial-content/single-image';\nimport { TiledImage } from '../../../spacial-content/tiled-image';\nimport { WorldObject } from '../../../world-objects/world-object';\nimport { RuntimeDebugEvent } from './types';\n\nexport type RendererSummary = {\n rendererTypes: string[];\n canvas: Array<{\n type: string;\n loadingQueue: number;\n imagesPending: number;\n imagesLoaded: number;\n tasksRunning: number;\n firstMeaningfulPaint: boolean;\n }>;\n webgl: Array<{\n type: string;\n }>;\n};\n\nexport type ImageDiagnostic = {\n id: string;\n type: string;\n ownerId?: string;\n compositeId?: string;\n canvas?: {\n loading: boolean;\n indices: number;\n loaded: number;\n };\n webgl?: {\n loading: number;\n loaded: number;\n textures: number;\n };\n anomalies: string[];\n};\n\nexport type CompositeFrameSelection = {\n frame: number;\n composites: Array<{\n compositeId: string;\n layers: Array<{\n paintId: string;\n paintType: string;\n tileIndex: number;\n imageUrl?: string;\n }>;\n }>;\n};\n\nfunction flattenRenderers(renderer: any, out: any[] = []) {\n if (!renderer) {\n return out;\n }\n\n if (Array.isArray(renderer.renderers)) {\n for (const child of renderer.renderers) {\n flattenRenderers(child, out);\n }\n return out;\n }\n\n out.push(renderer);\n return out;\n}\n\nfunction walkLayer(layer: any, out: ImageDiagnostic[], ownerId?: string, compositeId?: string) {\n if (!layer) {\n return;\n }\n\n if (layer instanceof WorldObject) {\n if (Array.isArray(layer.layers)) {\n for (const child of layer.layers) {\n walkLayer(child, out, layer.id, compositeId);\n }\n }\n return;\n }\n\n if (layer instanceof CompositeResource) {\n const childCompositeId = layer.id;\n const imageSet = new Set<any>([...layer.allImages, ...layer.images]);\n for (const image of imageSet) {\n walkLayer(image, out, ownerId, childCompositeId);\n }\n return;\n }\n\n if (layer instanceof SingleImage || layer instanceof TiledImage) {\n const entry: ImageDiagnostic = {\n id: layer.id,\n type: layer.constructor.name,\n ownerId,\n compositeId,\n anomalies: [],\n };\n\n if (layer.__host?.canvas) {\n entry.canvas = {\n loading: !!layer.__host.canvas.loading,\n indices: layer.__host.canvas.indices?.length || 0,\n loaded: layer.__host.canvas.loaded?.length || 0,\n };\n\n if (entry.canvas.loading && entry.canvas.indices === 0) {\n entry.anomalies.push('Canvas host marked loading with empty queue.');\n }\n if (entry.canvas.loaded > entry.canvas.indices && entry.canvas.indices > 0) {\n entry.anomalies.push('Canvas loaded count exceeds scheduled indices.');\n }\n }\n\n if (layer.__host?.webgl) {\n entry.webgl = {\n loading: layer.__host.webgl.loading?.length || 0,\n loaded: layer.__host.webgl.loaded?.length || 0,\n textures: layer.__host.webgl.textures?.filter(Boolean)?.length || 0,\n };\n\n if (entry.webgl.loading > 0 && entry.webgl.textures === 0 && entry.webgl.loaded === 0) {\n entry.anomalies.push('WebGL has pending loads but no loaded textures.');\n }\n }\n\n out.push(entry);\n }\n}\n\nexport function collectImageDiagnostics(world: World): ImageDiagnostic[] {\n const out: ImageDiagnostic[] = [];\n const objects = world.getObjects();\n\n for (const object of objects) {\n if (!object) {\n continue;\n }\n walkLayer(object, out, object.id, undefined);\n }\n\n return out;\n}\n\nexport function getRendererSummary(runtime: Runtime): RendererSummary {\n const renderers = flattenRenderers(runtime.renderer);\n\n return {\n rendererTypes: renderers.map((renderer) => renderer?.constructor?.name || 'UnknownRenderer'),\n canvas: renderers\n .filter((renderer) => typeof renderer?.loadingQueue !== 'undefined')\n .map((renderer) => ({\n type: renderer?.constructor?.name || 'CanvasRenderer',\n loadingQueue: renderer.loadingQueue?.length || 0,\n imagesPending: renderer.imagesPending || 0,\n imagesLoaded: renderer.imagesLoaded || 0,\n tasksRunning: renderer.tasksRunning || 0,\n firstMeaningfulPaint: !!renderer.firstMeaningfulPaint,\n })),\n webgl: renderers\n .filter((renderer) => typeof renderer?.gl !== 'undefined')\n .map((renderer) => ({\n type: renderer?.constructor?.name || 'WebGLRenderer',\n })),\n };\n}\n\nexport function getCompositeSelectionsByFrame(\n events: RuntimeDebugEvent[],\n limit = 30\n): CompositeFrameSelection[] {\n const frames = new Map<\n number,\n Map<\n string,\n Array<{\n paintId: string;\n paintType: string;\n tileIndex: number;\n imageUrl?: string;\n }>\n >\n >();\n\n for (const event of events) {\n if (event.type !== 'paint' || !event.compositeId) {\n continue;\n }\n\n if (!frames.has(event.frame)) {\n frames.set(event.frame, new Map());\n }\n\n const composites = frames.get(event.frame)!;\n if (!composites.has(event.compositeId)) {\n composites.set(event.compositeId, []);\n }\n\n composites.get(event.compositeId)!.push({\n paintId: event.paintId,\n paintType: event.paintType,\n tileIndex: event.tileIndex,\n imageUrl: event.imageUrl,\n });\n }\n\n return Array.from(frames.entries())\n .sort((a, b) => b[0] - a[0])\n .slice(0, limit)\n .map(([frame, composites]) => ({\n frame,\n composites: Array.from(composites.entries()).map(([compositeId, layers]) => ({\n compositeId,\n layers,\n })),\n }));\n}\n","import { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { CompositeResource } from '../../../spacial-content/composite-resource';\nimport { SingleImage } from '../../../spacial-content/single-image';\nimport { TiledImage } from '../../../spacial-content/tiled-image';\nimport { WorldObject } from '../../../world-objects/world-object';\n\nexport type ImageRecoveryResult = {\n imageHostsReset: number;\n renderersReset: number;\n};\n\nfunction flattenRenderers(renderer: any, out: any[] = []) {\n if (!renderer) {\n return out;\n }\n\n if (Array.isArray(renderer.renderers)) {\n for (const child of renderer.renderers) {\n flattenRenderers(child, out);\n }\n return out;\n }\n\n out.push(renderer);\n return out;\n}\n\nfunction walkImages(layer: any, out: Array<SingleImage | TiledImage>) {\n if (!layer) {\n return;\n }\n\n if (layer instanceof SingleImage || layer instanceof TiledImage) {\n out.push(layer);\n return;\n }\n\n if (layer instanceof CompositeResource) {\n const imageSet = new Set<any>([...layer.allImages, ...layer.images]);\n for (const image of imageSet) {\n walkImages(image, out);\n }\n return;\n }\n\n if (layer instanceof WorldObject && Array.isArray(layer.layers)) {\n for (const child of layer.layers) {\n walkImages(child, out);\n }\n }\n}\n\nexport function collectWorldImagePaintables(world: World): Array<SingleImage | TiledImage> {\n const out: Array<SingleImage | TiledImage> = [];\n const objects = world.getObjects();\n\n for (const object of objects) {\n if (!object) {\n continue;\n }\n walkImages(object, out);\n }\n\n return out;\n}\n\nexport function resetImageLoadingState(runtime: Runtime): ImageRecoveryResult {\n const images = collectWorldImagePaintables(runtime.world);\n let imageHostsReset = 0;\n\n for (const image of images) {\n imageHostsReset++;\n\n if (!image.__host) {\n image.__host = {};\n }\n\n image.__host.canvas = {\n canvas: undefined,\n canvases: [],\n tiles: {},\n indices: [],\n loaded: [],\n loading: false,\n };\n\n if (image.__host.webgl) {\n image.__host.webgl.loading = [];\n image.__host.webgl.loaded = [];\n if (Array.isArray(image.__host.webgl.textures)) {\n image.__host.webgl.textures = [...new Array(image.points.length / 5)];\n }\n }\n }\n\n const renderers = flattenRenderers(runtime.renderer);\n let renderersReset = 0;\n\n for (const renderer of renderers) {\n renderersReset++;\n\n if (Array.isArray(renderer.loadingQueue)) {\n renderer.loadingQueue = [];\n }\n if (Array.isArray(renderer.tileRequestQueue)) {\n renderer.tileRequestQueue = [];\n }\n\n if (Array.isArray(renderer.drawCalls)) {\n renderer.drawCalls = [];\n }\n\n if (Array.isArray(renderer.invalidated)) {\n renderer.invalidated = [];\n }\n\n if (Array.isArray(renderer.imageIdsLoaded)) {\n renderer.imageIdsLoaded = [];\n }\n\n if (renderer.hostCache?.clear) {\n renderer.hostCache.clear();\n }\n\n if (typeof renderer.tasksRunning === 'number') {\n renderer.tasksRunning = 0;\n }\n\n if (typeof renderer.imagesPending === 'number') {\n renderer.imagesPending = 0;\n }\n\n if (typeof renderer.imagesLoaded === 'number') {\n renderer.imagesLoaded = 0;\n }\n\n if (typeof renderer.pendingDrawCall === 'boolean') {\n renderer.pendingDrawCall = false;\n }\n\n if (typeof renderer.loadingQueueOrdered === 'boolean') {\n renderer.loadingQueueOrdered = true;\n }\n\n if (renderer.requiredTileKeys?.clear) {\n renderer.requiredTileKeys.clear();\n }\n\n if (renderer.requiredPrefetchTileKeys?.clear) {\n renderer.requiredPrefetchTileKeys.clear();\n }\n\n if (renderer.queuedTileRequestKeys?.clear) {\n renderer.queuedTileRequestKeys.clear();\n }\n\n if (renderer.imageRequestPool?.cancelAll) {\n renderer.imageRequestPool.cancelAll({ silent: true });\n }\n\n if (renderer.inFlightImageLoads?.clear) {\n renderer.inFlightImageLoads.clear();\n }\n\n if (typeof renderer.reset === 'function') {\n renderer.reset();\n }\n }\n\n runtime.updateNextFrame();\n\n return {\n imageHostsReset,\n renderersReset,\n };\n}\n","import { MutableRefObject, version } from 'react';\n\nexport async function renderReactDom(html: HTMLElement, toRender: any, root: MutableRefObject<any>) {\n if (version.startsWith('18.') || version.startsWith('19.')) {\n // @ts-ignore\n const module = await import('react-dom/client');\n const createRoot = module.default ? module.default.createRoot : module.createRoot;\n if (!root.current) {\n root.current = createRoot(html);\n }\n root.current.render(toRender);\n } else {\n // @ts-ignore\n if (typeof ReactDOM !== 'undefined') {\n // @ts-ignore\n const { render, unmountComponentAtNode } = ReactDOM;\n render(toRender, html);\n root.current = {\n unmount() {\n unmountComponentAtNode(html);\n },\n };\n } else {\n // Probably only bundlers or\n const module = await import('react-dom');\n const render = module.default ? module.default.render : module.render;\n const unmountComponentAtNode = module.default\n ? module.default.unmountComponentAtNode\n : module.unmountComponentAtNode;\n render(toRender, html);\n root.current = {\n unmount() {\n unmountComponentAtNode(html);\n },\n };\n }\n }\n}\n","import React, { CSSProperties, useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { DnaFactory } from '@atlas-viewer/dna';\nimport { useRuntime } from '../hooks/use-runtime';\nimport {\n getDevToolsRegistrySnapshot,\n getRuntimeEntry,\n registerDevToolsCandidate,\n setSelectedRuntimeId,\n subscribeDevToolsRegistry,\n updateDevToolsCandidateRuntime,\n} from '../devtools/registry';\nimport { collectImageDiagnostics, getCompositeSelectionsByFrame, getRendererSummary } from '../devtools/diagnostics';\nimport { resetImageLoadingState } from '../devtools/actions';\nimport { DevToolsTab, RuntimeDebugEvent, WorldDebugEvent } from '../devtools/types';\nimport { renderReactDom } from '../utility/react-dom';\n\nconst TABS: DevToolsTab[] = ['Overview', 'World', 'Inspector', 'Events', 'Images', 'Actions'];\nlet candidateCount = 0;\n\ntype InspectorNode = {\n key: string;\n depth: number;\n label: string;\n ref: any;\n};\n\nexport const DevTools: React.FC<DevToolsProps> = (props) => {\n const contextRuntime = useRuntime();\n const resolvedRuntimeId = props.runtimeId || contextRuntime?.id;\n const portalContainerRef = useRef<HTMLDivElement | null>(null);\n const portalRoot = useRef<any>(null);\n\n useEffect(() => {\n if (typeof document === 'undefined') {\n return;\n }\n\n const container = document.createElement('div');\n container.dataset.atlasDevtools = 'true';\n document.body.appendChild(container);\n portalContainerRef.current = container;\n\n return () => {\n if (portalRoot.current?.unmount) {\n portalRoot.current.unmount();\n }\n container.remove();\n portalContainerRef.current = null;\n };\n }, []);\n\n useEffect(() => {\n const container = portalContainerRef.current;\n if (!container) {\n return;\n }\n\n renderReactDom(container, <DevToolsPanel {...props} runtimeId={resolvedRuntimeId} />, portalRoot);\n });\n\n return null;\n};\n\nfunction pushBounded<T>(arr: T[], item: T, max: number) {\n arr.push(item);\n if (arr.length > max) {\n arr.splice(0, arr.length - max);\n }\n}\n\nfunction formatPoints(points?: any) {\n if (!points || points.length < 5) {\n return undefined;\n }\n return {\n x1: Number(points[1].toFixed ? points[1].toFixed(2) : points[1]),\n y1: Number(points[2].toFixed ? points[2].toFixed(2) : points[2]),\n x2: Number(points[3].toFixed ? points[3].toFixed(2) : points[3]),\n y2: Number(points[4].toFixed ? points[4].toFixed(2) : points[4]),\n };\n}\n\nfunction typeName(ref: any) {\n return ref?.constructor?.name || ref?.type || 'Unknown';\n}\n\nfunction buildInspectorNodes(runtime: any) {\n const nodes: InspectorNode[] = [];\n const seen = new Set<any>();\n\n const walk = (ref: any, depth: number, key: string) => {\n if (!ref || seen.has(ref)) {\n return;\n }\n seen.add(ref);\n\n const id = ref.id ? ` #${ref.id}` : '';\n nodes.push({\n key,\n depth,\n label: `${typeName(ref)}${id}`,\n ref,\n });\n\n if (Array.isArray(ref.layers)) {\n for (let i = 0; i < ref.layers.length; i++) {\n walk(ref.layers[i], depth + 1, `${key}.layers.${i}`);\n }\n }\n\n if (Array.isArray(ref.images) || Array.isArray(ref.allImages)) {\n const set = new Set<any>([...(ref.allImages || []), ...(ref.images || [])]);\n let index = 0;\n for (const image of set) {\n walk(image, depth + 1, `${key}.images.${index}`);\n index++;\n }\n }\n };\n\n walk(runtime.world, 0, 'world');\n\n const objects = runtime.world.getObjects();\n for (let i = 0; i < objects.length; i++) {\n const object = objects[i];\n if (!object) {\n continue;\n }\n walk(object, 1, `world.objects.${i}`);\n }\n\n return nodes;\n}\n\nfunction getHostSummary(ref: any) {\n if (!ref?.__host) {\n return 'No host';\n }\n\n if (ref.__host.canvas) {\n return `Canvas host loading=${!!ref.__host.canvas.loading} indices=${ref.__host.canvas.indices?.length || 0} loaded=${\n ref.__host.canvas.loaded?.length || 0\n }`;\n }\n\n if (ref.__host.webgl) {\n return `WebGL host loading=${ref.__host.webgl.loading?.length || 0} loaded=${ref.__host.webgl.loaded?.length || 0}`;\n }\n\n return 'Host attached';\n}\n\nexport type DevToolsProps = {\n initialOpen?: boolean;\n bottom?: number;\n right?: number;\n zIndex?: number;\n maxEvents?: number;\n maxRuntimeEvents?: number;\n runtimeId?: string;\n className?: string;\n style?: CSSProperties;\n};\n\nconst DevToolsPanel: React.FC<DevToolsProps> = ({\n initialOpen = false,\n bottom = 16,\n right = 16,\n zIndex = 1000,\n maxEvents = 500,\n maxRuntimeEvents = 1000,\n runtimeId: explicitRuntimeId,\n className,\n style,\n}) => {\n const candidateId = useRef(`devtools-${++candidateCount}`);\n\n const [open, setOpen] = useState(initialOpen);\n const [tab, setTab] = useState<DevToolsTab>('Overview');\n const [pauseEventLog, setPauseEventLog] = useState(false);\n const [pickMode, setPickMode] = useState(false);\n const [selectedNodeRef, setSelectedNodeRef] = useState<any>(null);\n const [modeDraft, setModeDraft] = useState('explore');\n const [zoneDraft, setZoneDraft] = useState('');\n const [pausedRuntime, setPausedRuntime] = useState(false);\n const [actionMessage, setActionMessage] = useState('');\n const [eventFilter, setEventFilter] = useState<'all' | 'trigger' | 'pointer' | 'touch'>('all');\n const [, forceUpdate] = useState(0);\n\n const runtimeEventsRef = useRef<RuntimeDebugEvent[]>([]);\n const worldEventsRef = useRef<WorldDebugEvent[]>([]);\n const pauseHandleRef = useRef<(() => void) | null>(null);\n const scheduledRefresh = useRef(false);\n\n const scheduleRefresh = () => {\n if (scheduledRefresh.current) {\n return;\n }\n scheduledRefresh.current = true;\n requestAnimationFrame(() => {\n scheduledRefresh.current = false;\n forceUpdate((v) => v + 1);\n });\n };\n\n const preferredRuntimeId = explicitRuntimeId;\n\n useEffect(() => {\n const unregister = registerDevToolsCandidate({\n id: candidateId.current,\n runtimeId: preferredRuntimeId,\n });\n\n return unregister;\n }, []);\n\n useEffect(() => {\n updateDevToolsCandidateRuntime(candidateId.current, preferredRuntimeId);\n }, [preferredRuntimeId]);\n\n const snapshot = useSyncExternalStore(subscribeDevToolsRegistry, getDevToolsRegistrySnapshot, getDevToolsRegistrySnapshot);\n\n const isActiveHost = snapshot.activeCandidateId === candidateId.current;\n\n const selectedRuntimeId = snapshot.selectedRuntimeId || preferredRuntimeId || snapshot.runtimes[0]?.id;\n const runtimeEntry = getRuntimeEntry(selectedRuntimeId);\n const runtime = runtimeEntry?.runtime;\n const preset = runtimeEntry?.preset;\n\n useEffect(() => {\n if (selectedRuntimeId && selectedRuntimeId !== snapshot.selectedRuntimeId) {\n setSelectedRuntimeId(selectedRuntimeId);\n }\n }, [selectedRuntimeId, snapshot.selectedRuntimeId]);\n\n useEffect(() => {\n if (!runtime) {\n return;\n }\n setModeDraft(runtime.mode);\n }, [runtime?.id]);\n\n useEffect(() => {\n if (!isActiveHost || !open || !runtime) {\n return;\n }\n\n const unsubscribeRuntime = runtime.addDebugSubscriber((event) => {\n if (pauseEventLog) {\n return;\n }\n pushBounded(runtimeEventsRef.current, event, maxRuntimeEvents);\n scheduleRefresh();\n });\n\n const unsubscribeWorld = runtime.world.addDebugSubscriber((event) => {\n if (pauseEventLog) {\n return;\n }\n pushBounded(worldEventsRef.current, event, maxEvents);\n scheduleRefresh();\n });\n\n return () => {\n unsubscribeRuntime();\n unsubscribeWorld();\n };\n }, [isActiveHost, open, runtime?.id, pauseEventLog, maxEvents, maxRuntimeEvents]);\n\n useEffect(() => {\n if (!isActiveHost || !open) {\n return;\n }\n\n const interval = setInterval(() => {\n forceUpdate((v) => v + 1);\n }, 250);\n\n return () => {\n clearInterval(interval);\n };\n }, [isActiveHost, open]);\n\n useEffect(() => {\n if (!pickMode || !runtime || !preset?.em?.element) {\n return;\n }\n\n const element = preset.em.element;\n\n const onPointerDown = (e: PointerEvent) => {\n const bounds = element.getBoundingClientRect();\n const { x, y } = runtime.viewerToWorld(e.clientX - bounds.left, e.clientY - bounds.top);\n const point = DnaFactory.singleBox(1, 1, x, y);\n const hits = runtime.world.getObjectsAt(point, true);\n const hit = hits[hits.length - 1];\n if (hit) {\n const nested = hit[1];\n const target = nested.length ? nested[nested.length - 1] : hit[0];\n setSelectedNodeRef(target);\n }\n setTab('Inspector');\n setPickMode(false);\n scheduleRefresh();\n e.preventDefault();\n e.stopPropagation();\n };\n\n element.addEventListener('pointerdown', onPointerDown, true);\n\n return () => {\n element.removeEventListener('pointerdown', onPointerDown, true);\n };\n }, [pickMode, runtime?.id, preset?.em?.element]);\n\n useEffect(() => {\n return () => {\n const resume = pauseHandleRef.current;\n if (resume) {\n pauseHandleRef.current = null;\n resume();\n }\n };\n }, []);\n\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return null;\n }\n\n if (!isActiveHost) {\n return null;\n }\n\n const inspectorNodes = runtime ? buildInspectorNodes(runtime) : [];\n const selectedNode = selectedNodeRef || inspectorNodes[0]?.ref;\n const rendererSummary = runtime ? getRendererSummary(runtime) : { rendererTypes: [], canvas: [], webgl: [] };\n const imageDiagnostics = runtime ? collectImageDiagnostics(runtime.world) : [];\n const compositeFrames = getCompositeSelectionsByFrame(runtimeEventsRef.current, 15);\n const filteredWorldEvents = worldEventsRef.current.filter((event) => eventFilter === 'all' || event.type === eventFilter);\n\n const worldMap = (() => {\n if (!runtime) {\n return { width: 220, height: 220, rects: [], viewport: null };\n }\n\n const points = runtime.world.getPoints();\n const worldWidth = Math.max(1, runtime.world.width);\n const worldHeight = Math.max(1, runtime.world.height);\n const width = 220;\n const height = 220;\n\n const scaleX = width / worldWidth;\n const scaleY = height / worldHeight;\n const rects: Array<{ x: number; y: number; width: number; height: number }> = [];\n\n const maxRects = Math.min(points.length / 5, 300);\n for (let i = 0; i < maxRects; i++) {\n const key = i * 5;\n if (points[key] === 0) {\n continue;\n }\n rects.push({\n x: points[key + 1] * scaleX,\n y: points[key + 2] * scaleY,\n width: Math.max(1, (points[key + 3] - points[key + 1]) * scaleX),\n height: Math.max(1, (points[key + 4] - points[key + 2]) * scaleY),\n });\n }\n\n const viewport = {\n x: runtime.target[1] * scaleX,\n y: runtime.target[2] * scaleY,\n width: Math.max(1, (runtime.target[3] - runtime.target[1]) * scaleX),\n height: Math.max(1, (runtime.target[4] - runtime.target[2]) * scaleY),\n };\n\n return { width, height, rects, viewport };\n })();\n\n const containerStyle: CSSProperties = {\n position: 'fixed',\n right,\n bottom,\n zIndex,\n color: '#eef1ff',\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',\n pointerEvents: 'auto',\n ...(style || {}),\n };\n\n const buttonStyle: CSSProperties = {\n background: '#111827',\n color: '#f9fafb',\n border: '1px solid #374151',\n borderRadius: 999,\n fontSize: 12,\n padding: '8px 12px',\n cursor: 'pointer',\n boxShadow: '0 8px 24px rgba(0, 0, 0, 0.35)',\n };\n\n const panelStyle: CSSProperties = {\n width: 460,\n maxHeight: '70vh',\n overflow: 'hidden',\n background: '#0f172a',\n border: '1px solid #334155',\n borderRadius: 10,\n boxShadow: '0 12px 36px rgba(0, 0, 0, 0.4)',\n marginBottom: 10,\n display: 'flex',\n flexDirection: 'column',\n };\n\n const sectionStyle: CSSProperties = {\n padding: 10,\n overflow: 'auto',\n fontSize: 12,\n lineHeight: 1.4,\n display: 'grid',\n gap: 8,\n };\n\n const pauseRuntime = () => {\n if (!runtime || pauseHandleRef.current) {\n return;\n }\n pauseHandleRef.current = runtime.stop();\n setPausedRuntime(true);\n };\n\n const resumeRuntime = () => {\n const resume = pauseHandleRef.current;\n pauseHandleRef.current = null;\n if (resume) {\n resume();\n }\n setPausedRuntime(false);\n };\n\n const stepRuntime = () => {\n if (!runtime) {\n return;\n }\n\n if (pauseHandleRef.current) {\n const resume = pauseHandleRef.current;\n pauseHandleRef.current = null;\n resume();\n requestAnimationFrame(() => {\n if (runtime) {\n pauseHandleRef.current = runtime.stop();\n setPausedRuntime(true);\n }\n });\n return;\n }\n\n runtime.updateNextFrame();\n };\n\n const clearLogs = () => {\n runtimeEventsRef.current = [];\n worldEventsRef.current = [];\n setActionMessage('Logs cleared');\n scheduleRefresh();\n };\n\n return (\n <div className={className} style={containerStyle}>\n {open ? (\n <div style={panelStyle}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: 10, borderBottom: '1px solid #1f2937' }}>\n <strong style={{ fontSize: 12, letterSpacing: 0.4 }}>Atlas DevTools</strong>\n <select\n style={{ marginLeft: 'auto', fontSize: 12, background: '#111827', color: '#e2e8f0', border: '1px solid #334155' }}\n value={selectedRuntimeId || ''}\n onChange={(e) => setSelectedRuntimeId(e.target.value)}\n >\n {snapshot.runtimes.map((entry) => (\n <option key={entry.id} value={entry.id}>\n {entry.label}\n </option>\n ))}\n </select>\n <button style={buttonStyle} onClick={() => setOpen(false)}>\n Close\n </button>\n </div>\n\n <div style={{ display: 'flex', gap: 6, padding: 8, borderBottom: '1px solid #1f2937', flexWrap: 'wrap' }}>\n {TABS.map((tabName) => (\n <button\n key={tabName}\n style={{\n ...buttonStyle,\n padding: '4px 8px',\n borderRadius: 6,\n background: tab === tabName ? '#334155' : '#111827',\n }}\n onClick={() => setTab(tabName)}\n >\n {tabName}\n </button>\n ))}\n </div>\n\n <div style={sectionStyle}>\n {!runtime ? <div>No Atlas runtime available.</div> : null}\n\n {runtime && tab === 'Overview' ? (\n <>\n <div>Runtime id: {runtime.id}</div>\n <div>Mode: {runtime.mode}</div>\n <div>Scale factor: {runtime.getScaleFactor().toFixed(4)}</div>\n <div>World: {runtime.world.width} x {runtime.world.height}</div>\n <div>Target: {JSON.stringify(formatPoints(runtime.target))}</div>\n <div>Pending update: {String(runtime.pendingUpdate)}</div>\n <div>Renderer chain: {rendererSummary.rendererTypes.join(' -> ') || 'None'}</div>\n <div>Runtime log entries: {runtimeEventsRef.current.length}</div>\n <div>World log entries: {worldEventsRef.current.length}</div>\n </>\n ) : null}\n\n {runtime && tab === 'World' ? (\n <>\n <div>World dimensions: {runtime.world.width} x {runtime.world.height}</div>\n <div>Viewport target: {JSON.stringify(formatPoints(runtime.target))}</div>\n <svg width={worldMap.width} height={worldMap.height} style={{ background: '#020617', border: '1px solid #334155' }}>\n {worldMap.rects.map((rect, idx) => (\n <rect\n key={`rect-${idx}`}\n x={rect.x}\n y={rect.y}\n width={rect.width}\n height={rect.height}\n fill=\"rgba(56, 189, 248, 0.18)\"\n stroke=\"rgba(56, 189, 248, 0.7)\"\n />\n ))}\n {worldMap.viewport ? (\n <rect\n x={worldMap.viewport.x}\n y={worldMap.viewport.y}\n width={worldMap.viewport.width}\n height={worldMap.viewport.height}\n fill=\"rgba(251, 191, 36, 0.1)\"\n stroke=\"rgba(251, 191, 36, 1)\"\n />\n ) : null}\n </svg>\n </>\n ) : null}\n\n {runtime && tab === 'Inspector' ? (\n <>\n <div style={{ display: 'flex', gap: 8 }}>\n <button style={buttonStyle} onClick={() => setPickMode((v) => !v)}>\n {pickMode ? 'Cancel Pick' : 'Pick in Viewport'}\n </button>\n </div>\n <div style={{ maxHeight: 180, overflow: 'auto', border: '1px solid #1f2937', borderRadius: 6 }}>\n {inspectorNodes.map((node) => (\n <button\n key={node.key}\n onClick={() => setSelectedNodeRef(node.ref)}\n style={{\n width: '100%',\n display: 'block',\n textAlign: 'left',\n padding: `2px 6px 2px ${6 + node.depth * 14}px`,\n background: selectedNode === node.ref ? '#1e293b' : 'transparent',\n color: '#e2e8f0',\n border: 0,\n cursor: 'pointer',\n fontSize: 12,\n }}\n >\n {node.label}\n </button>\n ))}\n </div>\n {selectedNode ? (\n <div style={{ border: '1px solid #1f2937', borderRadius: 6, padding: 8 }}>\n <div>Type: {typeName(selectedNode)}</div>\n <div>ID: {selectedNode.id || '(none)'}</div>\n <div>Points: {JSON.stringify(formatPoints(selectedNode.points))}</div>\n <div>Display scale: {selectedNode.display?.scale ?? '(n/a)'}</div>\n <div>Crop: {selectedNode.cropData ? JSON.stringify(selectedNode.cropData) : '(none)'}</div>\n <div>Host: {getHostSummary(selectedNode)}</div>\n </div>\n ) : null}\n </>\n ) : null}\n\n {runtime && tab === 'Events' ? (\n <>\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n <button style={buttonStyle} onClick={() => setPauseEventLog((v) => !v)}>\n {pauseEventLog ? 'Resume Log' : 'Pause Log'}\n </button>\n <button style={buttonStyle} onClick={clearLogs}>Clear</button>\n <select\n value={eventFilter}\n onChange={(e) => setEventFilter(e.target.value as any)}\n style={{ fontSize: 12, background: '#111827', color: '#e2e8f0', border: '1px solid #334155' }}\n >\n <option value=\"all\">All</option>\n <option value=\"trigger\">Trigger</option>\n <option value=\"pointer\">Pointer</option>\n <option value=\"touch\">Touch</option>\n </select>\n </div>\n <div style={{ maxHeight: 240, overflow: 'auto', border: '1px solid #1f2937', borderRadius: 6, padding: 6 }}>\n {filteredWorldEvents\n .slice()\n .reverse()\n .map((event, index) => (\n <div key={`event-${index}`} style={{ marginBottom: 4 }}>\n [{event.type}] {JSON.stringify(event)}\n </div>\n ))}\n </div>\n </>\n ) : null}\n\n {runtime && tab === 'Images' ? (\n <>\n <div>Renderer health</div>\n {rendererSummary.canvas.map((entry, index) => (\n <div key={`canvas-${index}`} style={{ border: '1px solid #1f2937', borderRadius: 6, padding: 8 }}>\n <div>{entry.type}</div>\n <div>loadingQueue: {entry.loadingQueue}</div>\n <div>imagesPending: {entry.imagesPending}</div>\n <div>imagesLoaded: {entry.imagesLoaded}</div>\n <div>tasksRunning: {entry.tasksRunning}</div>\n <div>firstMeaningfulPaint: {String(entry.firstMeaningfulPaint)}</div>\n </div>\n ))}\n {rendererSummary.webgl.map((entry, index) => (\n <div key={`webgl-${index}`} style={{ border: '1px solid #1f2937', borderRadius: 6, padding: 8 }}>\n <div>{entry.type}</div>\n </div>\n ))}\n\n <div>Image hosts ({imageDiagnostics.length})</div>\n <div style={{ maxHeight: 180, overflow: 'auto', border: '1px solid #1f2937', borderRadius: 6, padding: 6 }}>\n {imageDiagnostics.map((entry) => (\n <div key={`${entry.type}-${entry.id}-${entry.ownerId || 'none'}`} style={{ marginBottom: 6 }}>\n <div>{entry.type} #{entry.id}</div>\n <div>owner: {entry.ownerId || '(none)'} composite: {entry.compositeId || '(none)'}</div>\n <div>canvas: {entry.canvas ? JSON.stringify(entry.canvas) : '(none)'}</div>\n <div>webgl: {entry.webgl ? JSON.stringify(entry.webgl) : '(none)'}</div>\n {entry.anomalies.length ? <div>anomalies: {entry.anomalies.join(' | ')}</div> : null}\n </div>\n ))}\n </div>\n\n <div>Chosen composite layers by frame</div>\n <div style={{ maxHeight: 180, overflow: 'auto', border: '1px solid #1f2937', borderRadius: 6, padding: 6 }}>\n {compositeFrames.map((frame) => (\n <div key={`frame-${frame.frame}`} style={{ marginBottom: 8 }}>\n <div>frame {frame.frame}</div>\n {frame.composites.map((composite) => (\n <div key={`${frame.frame}-${composite.compositeId}`} style={{ paddingLeft: 8 }}>\n <div>composite {composite.compositeId}</div>\n {composite.layers.map((layer, idx) => (\n <div key={`${composite.compositeId}-${idx}`} style={{ paddingLeft: 10 }}>\n {layer.paintType} #{layer.paintId} tile={layer.tileIndex}\n </div>\n ))}\n </div>\n ))}\n </div>\n ))}\n </div>\n </>\n ) : null}\n\n {runtime && tab === 'Actions' ? (\n <>\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n <button style={buttonStyle} onClick={pausedRuntime ? resumeRuntime : pauseRuntime}>\n {pausedRuntime ? 'Resume Loop' : 'Pause Loop'}\n </button>\n <button style={buttonStyle} onClick={stepRuntime}>Step Frame</button>\n <button style={buttonStyle} onClick={() => runtime.updateNextFrame()}>Repaint</button>\n <button style={buttonStyle} onClick={() => runtime.triggerResize()}>Trigger Resize</button>\n </div>\n\n <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>\n <select\n value={modeDraft}\n onChange={(e) => setModeDraft(e.target.value)}\n style={{ fontSize: 12, background: '#111827', color: '#e2e8f0', border: '1px solid #334155' }}\n >\n <option value=\"explore\">explore</option>\n <option value=\"sketch\">sketch</option>\n <option value=\"static\">static</option>\n </select>\n <button\n style={buttonStyle}\n onClick={() => {\n runtime.mode = modeDraft as any;\n runtime.updateNextFrame();\n }}\n >\n Apply Mode\n </button>\n </div>\n\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n <button style={buttonStyle} onClick={() => runtime.world.goHome()}>goHome</button>\n <button style={buttonStyle} onClick={() => runtime.world.zoomIn()}>zoomIn</button>\n <button style={buttonStyle} onClick={() => runtime.world.zoomOut()}>zoomOut</button>\n <button style={buttonStyle} onClick={() => runtime.world.constraintBounds(true)}>constrain-bounds</button>\n </div>\n\n <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>\n <select\n value={zoneDraft}\n onChange={(e) => setZoneDraft(e.target.value)}\n style={{ fontSize: 12, background: '#111827', color: '#e2e8f0', border: '1px solid #334155' }}\n >\n <option value=\"\">Select zone</option>\n {runtime.world.zones.map((zone, idx) => (\n <option key={`${zone.id}-${idx}`} value={String(zone.id || idx)}>\n {zone.id || `zone-${idx}`}\n </option>\n ))}\n </select>\n <button\n style={buttonStyle}\n onClick={() => {\n if (zoneDraft) {\n runtime.selectZone(zoneDraft);\n }\n }}\n >\n Select Zone\n </button>\n <button style={buttonStyle} onClick={() => runtime.deselectZone()}>\n Deselect Zone\n </button>\n </div>\n\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n <button\n style={buttonStyle}\n onClick={() => {\n const result = resetImageLoadingState(runtime);\n setActionMessage(`Reset image hosts=${result.imageHostsReset}, renderers=${result.renderersReset}`);\n scheduleRefresh();\n }}\n >\n Recover Images\n </button>\n <button style={buttonStyle} onClick={clearLogs}>Clear Logs</button>\n </div>\n\n {actionMessage ? <div>{actionMessage}</div> : null}\n </>\n ) : null}\n </div>\n </div>\n ) : null}\n\n <button style={buttonStyle} onClick={() => setOpen((value) => !value)}>\n {open ? 'Hide DevTools' : 'Open DevTools'}\n </button>\n </div>\n );\n};\n","import { hash } from '../../../utility/hash';\nimport { useMemo } from 'react';\n\nexport function useClassname(deps: any[]) {\n return useMemo(() => hash(deps), deps);\n}\n","import { useRef } from \"react\";\nimport type { AtlasProps } from \"../Atlas\";\n\nfunction diffProps(\n beforeProps: AtlasProps & {\n width: number;\n height: number;\n },\n afterProps: AtlasProps & {\n width: number;\n height: number;\n }\n) {\n const changes: Record<string, { before: any; after: any }> = {};\n\n // Get all unique keys from both objects\n const allKeys = new Set([...Object.keys(beforeProps), ...Object.keys(afterProps)]);\n\n for (const key of allKeys) {\n const beforeValue = (beforeProps as any)[key];\n const afterValue = (afterProps as any)[key];\n\n // Simple comparison - could be enhanced for deep object comparison if needed\n if (beforeValue !== afterValue) {\n changes[key] = {\n before: beforeValue,\n after: afterValue,\n };\n }\n }\n\n return Object.keys(changes).length > 0 ? changes : null;\n}\n\nexport function useDiffProps(props: any, name = '', enabled = false) {\n const prevProps = useRef(props);\n if (prevProps.current && enabled) {\n console.log('Diff:', name, diffProps(prevProps.current, props));\n prevProps.current = props;\n }\n}\n","import { SpacialContent } from '../../spacial-content/spacial-content';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\n\nexport function isWebGLImageFastPathCandidate(\n paint: SpacialContent,\n index: number\n): paint is SingleImage | TiledImage {\n if (!(paint instanceof SingleImage || paint instanceof TiledImage)) {\n return false;\n }\n\n if (paint.crop || paint.cropData) {\n return false;\n }\n\n if (paint.display.rotation) {\n return false;\n }\n\n if (paint.style && typeof paint.style.opacity !== 'undefined' && paint.style.opacity !== 1) {\n return false;\n }\n\n if (paint.__owner?.value?.rotation) {\n return false;\n }\n\n // Reserved for tile-specific checks without changing the API.\n void index;\n\n return true;\n}\n","import type { Strand } from '@atlas-viewer/dna';\nimport type { Box } from '../../objects/box';\nimport type { Renderer } from '../../renderer/renderer';\nimport type { HookOptions } from '../../renderer/runtime';\nimport { ImageTexture } from '../../spacial-content/image-texture';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport type { SpacialContent } from '../../spacial-content/spacial-content';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport type { PositionPair } from '../../types';\nimport type { World } from '../../world';\nimport type { Paint } from '../../world-objects/paint';\nimport { buildCssFilter } from '../shared/build-css-filter';\nimport type { AtlasImageLoadErrorEvent } from '../shared/image-load-events';\nimport { getRetryDelayMs, type ImageLoadingConfig, resolveImageLoadingConfig } from '../shared/image-loading-config';\nimport { ImageRequestPool, isImageRequestCancelledError } from '../shared/image-request-pool';\nimport type { AtlasWebGLFallbackEvent } from './types';\nimport { isWebGLImageFastPathCandidate } from './webgl-eligibility';\n\nexport type { AtlasWebGLFallbackEvent, AtlasWebGLFallbackReason } from './types';\n\nexport type WebGLRendererOptions = {\n dpi?: number;\n onFatalImageError?: (event: AtlasWebGLFallbackEvent) => void;\n onImageError?: (event: AtlasImageLoadErrorEvent) => void;\n imageLoading?: Partial<ImageLoadingConfig>;\n fallbackOnImageLoadError?: boolean;\n readiness?: 'first-meaningful-paint' | 'immediate';\n};\n\ntype WebGLTileRequest = {\n key: string;\n tileKey: string;\n requestKey: string;\n paint: SingleImage | TiledImage;\n index: number;\n url: string;\n priority: number;\n scale: number;\n prefetch: boolean;\n};\n\ntype WebGLTileLoadingState = {\n state: 'idle' | 'queued' | 'loading' | 'decoded' | 'error';\n attempts?: number;\n nextRetryAt?: number;\n lastRequestKey?: string;\n cancelledAt?: number;\n error?: unknown;\n url?: string;\n requestedAt?: number;\n skipFade?: boolean;\n};\n\ntype InFlightTileLoad = {\n tileKey: string;\n requestKey: string;\n consumerId: string;\n paint: SingleImage | TiledImage;\n index: number;\n release: (opts?: { silent?: boolean }) => void;\n};\n\ntype ScissorRect = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nconst imageCache = new Map<string, HTMLImageElement>();\n\nexport class WebGLRenderer implements Renderer {\n canvas: HTMLCanvasElement;\n gl: WebGL2RenderingContext;\n options: WebGLRendererOptions;\n fatalImageError?: AtlasWebGLFallbackEvent;\n\n program: WebGLProgram;\n fragmentShader: WebGLShader;\n vertexShader: WebGLShader;\n\n rectBuffer: Float32Array;\n\n // language=GLSL\n fragmentShaderSource = `\n precision mediump float;\n\n uniform sampler2D u_image;\n uniform float u_alpha;\n varying vec2 v_texCoord;\n\n void main() {\n vec4 color = texture2D(u_image, v_texCoord);\n gl_FragColor = vec4(color.rgb, color.a * u_alpha);\n }\n `;\n\n // language=GLSL\n vertexShaderSource = `\n attribute vec2 a_position;\n uniform vec2 u_resolution;\n varying vec4 v_color;\n uniform sampler2D u_texture;\n\n attribute vec2 a_texCoord;\n varying vec2 v_texCoord;\n\n void main() {\n\n // convert the position from pixels to 0.0 to 1.0\n vec2 zeroToOne = a_position / u_resolution;\n\n // convert from 0->1 to 0->2\n vec2 zeroToTwo = zeroToOne * 2.0;\n\n // convert from 0->2 to -1->+1 (clip space)\n vec2 clipSpace = zeroToTwo - 1.0;\n\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n\n v_texCoord = a_texCoord;\n }\n `;\n\n attributes: {\n position: number;\n texCoord: number;\n };\n uniforms: {\n resolution: WebGLUniformLocation | null;\n texture: WebGLUniformLocation | null;\n alpha: WebGLUniformLocation | null;\n };\n buffers: {\n position: WebGLBuffer;\n texCoord: WebGLBuffer;\n };\n rendererPosition: DOMRect;\n dpi: number;\n maxConcurrentTasks = 6;\n maxPrefetchPerFrame = 8;\n imageLoadingConfig: ImageLoadingConfig;\n imageRequestPool: ImageRequestPool;\n framePrefetchCount = 0;\n loadingCount = 0;\n hasTilesFading = false;\n firstMeaningfulPaint = false;\n frameSawFastPathCandidate = false;\n requiresRepaint = true;\n tileRequestQueue: WebGLTileRequest[] = [];\n queuedTileRequestKeys = new Set<string>();\n inFlightImageLoads = new Map<string, InFlightTileLoad>();\n requiredTileKeys = new Set<string>();\n requiredPrefetchTileKeys = new Set<string>();\n requestGeneration = 0;\n frameCounter = 0;\n pendingTileReveals = new Map<\n string,\n {\n paint: SingleImage | TiledImage;\n index: number;\n queuedFrame: number;\n }\n >();\n activeLayerScissorRect: ScissorRect | undefined;\n onContextLost = (event: Event) => {\n event.preventDefault();\n this.emitFatalImageError({\n reason: 'webgl-context-lost',\n error: event,\n });\n };\n\n constructor(canvas: HTMLCanvasElement, options?: WebGLRendererOptions) {\n this.canvas = canvas;\n this.rendererPosition = canvas.getBoundingClientRect();\n this.options = options || {};\n this.imageLoadingConfig = resolveImageLoadingConfig(this.options.imageLoading);\n this.maxConcurrentTasks = this.imageLoadingConfig.maxConcurrentRequests;\n this.maxPrefetchPerFrame = this.imageLoadingConfig.maxPrefetchPerFrame;\n this.imageRequestPool = new ImageRequestPool({\n timeoutMs: this.imageLoadingConfig.timeoutMs,\n crossOrigin: 'anonymous',\n useFetch: true,\n cache: imageCache,\n });\n\n const gl = canvas.getContext('webgl2');\n if (!gl) {\n this.emitFatalImageError({\n reason: 'webgl-context-unavailable',\n error: new Error('WebGL2 context unavailable'),\n });\n throw new Error('WebGL2 context unavailable');\n }\n this.gl = gl;\n this.canvas.addEventListener('webglcontextlost', this.onContextLost as EventListener);\n\n this.fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSource);\n this.vertexShader = this.createShader(this.gl.VERTEX_SHADER, this.vertexShaderSource);\n this.program = this.createProgram(this.vertexShader, this.fragmentShader);\n this.dpi = options?.dpi || 1;\n\n // Shader locations.\n this.attributes = {\n position: this.gl.getAttribLocation(this.program, 'a_position'),\n texCoord: this.gl.getAttribLocation(this.program, 'a_texCoord'),\n };\n this.uniforms = {\n resolution: this.gl.getUniformLocation(this.program, 'u_resolution'),\n texture: this.gl.getUniformLocation(this.program, 'u_texture'),\n alpha: this.gl.getUniformLocation(this.program, 'u_alpha'),\n };\n\n this.buffers = {\n position: this.createArrayBuffer(),\n texCoord: this.createArrayBuffer(new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0])),\n };\n\n this.rectBuffer = new Float32Array(12);\n\n // Resize step.\n this.resize();\n\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.gl.clearColor(0, 0, 0, 0);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n this.gl.useProgram(this.program);\n this.gl.enableVertexAttribArray(this.attributes.position);\n this.gl.enable(this.gl.BLEND);\n this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);\n\n if (this.isImmediateReadiness()) {\n this.firstMeaningfulPaint = true;\n }\n }\n\n private isImmediateReadiness() {\n return this.options.readiness === 'immediate';\n }\n\n emitFatalImageError(event: Omit<AtlasWebGLFallbackEvent, 'from' | 'to'>) {\n if (this.fatalImageError) {\n return;\n }\n const fullEvent: AtlasWebGLFallbackEvent = {\n from: 'webgl',\n to: 'canvas',\n ...event,\n };\n this.fatalImageError = fullEvent;\n if (this.options.onFatalImageError) {\n this.options.onFatalImageError(fullEvent);\n }\n }\n\n resize() {\n this.resizeCanvasToDisplaySize();\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n this.rendererPosition = this.canvas.getBoundingClientRect();\n }\n\n isReady() {\n if (this.isImmediateReadiness()) {\n return true;\n }\n\n if (this.firstMeaningfulPaint) {\n return true;\n }\n\n if (!this.frameSawFastPathCandidate) {\n return (\n this.tileRequestQueue.length === 0 &&\n this.loadingCount === 0 &&\n this.inFlightImageLoads.size === 0 &&\n this.pendingTileReveals.size === 0\n );\n }\n\n return false;\n }\n\n beforeFrame(world: World, delta: number, target: Strand, options: HookOptions) {\n this.hasTilesFading = false;\n this.requiresRepaint = false;\n this.frameSawFastPathCandidate = false;\n this.framePrefetchCount = 0;\n this.frameCounter += 1;\n this.requiredTileKeys.clear();\n this.requiredPrefetchTileKeys.clear();\n this.flushTileRevealBatch();\n\n const filter = buildCssFilter(options);\n if (this.canvas.style.filter !== filter) {\n this.canvas.style.filter = filter;\n }\n\n this.gl.clearColor(0, 0, 0, 0);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n this.gl.disable(this.gl.SCISSOR_TEST);\n this.activeLayerScissorRect = undefined;\n\n this.gl.vertexAttribPointer(this.attributes.position, 2, this.gl.FLOAT, false, 0, 0);\n // Runtime coordinates are in CSS pixels, so keep shader resolution in CSS pixel space.\n this.gl.uniform2f(this.uniforms.resolution, this.gl.canvas.width / this.dpi, this.gl.canvas.height / this.dpi);\n if (this.lastResize > 1000) {\n this.lastResize = 0;\n this.resizeCanvasToDisplaySize();\n }\n this.lastResize += delta;\n }\n\n lastResize = 0;\n\n private getCompositeRenderOptions(paint: SingleImage | TiledImage) {\n return paint.__parent?.renderOptions;\n }\n\n private shouldClipLayerToBounds(paint: SpacialContent): boolean {\n if (!(paint instanceof SingleImage || paint instanceof TiledImage)) {\n return false;\n }\n return !!this.getCompositeRenderOptions(paint)?.clipToBounds;\n }\n\n private getBoundsFromPoints(points: Strand): { x: number; y: number; width: number; height: number } | undefined {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < points.length; i += 5) {\n if (!points[i]) {\n continue;\n }\n minX = Math.min(minX, points[i + 1]);\n minY = Math.min(minY, points[i + 2]);\n maxX = Math.max(maxX, points[i + 3]);\n maxY = Math.max(maxY, points[i + 4]);\n }\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {\n return undefined;\n }\n if (maxX <= minX || maxY <= minY) {\n return undefined;\n }\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n }\n\n private toScissorRect(bounds: { x: number; y: number; width: number; height: number }): ScissorRect | undefined {\n const canvasWidthCss = this.gl.canvas.width / this.dpi;\n const canvasHeightCss = this.gl.canvas.height / this.dpi;\n\n const x1 = Math.max(0, Math.min(canvasWidthCss, bounds.x));\n const y1 = Math.max(0, Math.min(canvasHeightCss, bounds.y));\n const x2 = Math.max(0, Math.min(canvasWidthCss, bounds.x + bounds.width));\n const y2 = Math.max(0, Math.min(canvasHeightCss, bounds.y + bounds.height));\n if (x2 <= x1 || y2 <= y1) {\n return undefined;\n }\n\n let scissorX = Math.floor(x1 * this.dpi);\n let scissorY = Math.floor((canvasHeightCss - y2) * this.dpi);\n let scissorWidth = Math.ceil((x2 - x1) * this.dpi);\n let scissorHeight = Math.ceil((y2 - y1) * this.dpi);\n\n if (scissorX < 0) {\n scissorWidth += scissorX;\n scissorX = 0;\n }\n if (scissorY < 0) {\n scissorHeight += scissorY;\n scissorY = 0;\n }\n scissorWidth = Math.min(scissorWidth, this.gl.canvas.width - scissorX);\n scissorHeight = Math.min(scissorHeight, this.gl.canvas.height - scissorY);\n if (scissorWidth <= 0 || scissorHeight <= 0) {\n return undefined;\n }\n\n return {\n x: scissorX,\n y: scissorY,\n width: scissorWidth,\n height: scissorHeight,\n };\n }\n\n prepareLayer(paint: SpacialContent, points?: Strand) {\n this.activeLayerScissorRect = undefined;\n if (points && this.shouldClipLayerToBounds(paint)) {\n const bounds = this.getBoundsFromPoints(points);\n if (bounds) {\n const scissorRect = this.toScissorRect(bounds);\n if (scissorRect) {\n this.activeLayerScissorRect = scissorRect;\n this.gl.enable(this.gl.SCISSOR_TEST);\n this.gl.scissor(scissorRect.x, scissorRect.y, scissorRect.width, scissorRect.height);\n } else {\n this.gl.enable(this.gl.SCISSOR_TEST);\n this.gl.scissor(0, 0, 0, 0);\n this.activeLayerScissorRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n }\n }\n }\n\n if (!paint.__host || !paint.__host.webgl) {\n if ((paint instanceof SingleImage || paint instanceof TiledImage) && isWebGLImageFastPathCandidate(paint, 0)) {\n this.createImageHost(paint);\n }\n if (paint instanceof ImageTexture) {\n this.createTextureHost(paint);\n }\n }\n }\n\n createTextureHost(paint: ImageTexture | Box) {\n paint.__host = paint.__host ? paint.__host : {};\n\n const gl = this.gl;\n const texture = this.gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n let lastImage;\n\n if (paint instanceof ImageTexture) {\n const initial = paint.getTexture();\n if (initial.source) {\n try {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, initial.source);\n } catch (error) {\n this.emitFatalImageError({\n reason: 'teximage-security',\n contentId: paint.id,\n error,\n });\n }\n }\n lastImage = initial;\n } else {\n // @todo draw box and set webgl.updateTexture function.\n }\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\n paint.__host.webgl = {\n height: paint.height,\n width: paint.width,\n texture,\n lastImage,\n };\n }\n\n createImageHost(paint: SingleImage | TiledImage) {\n const textures = [...new Array(paint.points.length / 5)];\n\n paint.__host = paint.__host ? paint.__host : {};\n\n paint.__host.webgl = {\n height: paint.height,\n width: paint.width,\n textures,\n loading: [],\n loaded: [],\n loadedAt: [],\n tileState: {},\n lastLevelRendered: -1,\n onLoad: (index: number, image: any) => {\n const gl = this.gl;\n const texture = this.gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n try {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n } catch (error) {\n this.emitFatalImageError({\n reason: 'teximage-security',\n imageUrl: paint.getImageUrl ? paint.getImageUrl(index) : undefined,\n contentId: paint.id,\n tileIndex: index,\n error,\n });\n this.removeLoadingIndex(paint, index);\n return;\n }\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.bindTexture(gl.TEXTURE_2D, null);\n paint.__host.webgl.textures[index] = texture;\n paint.__host.webgl.loaded.push(index);\n paint.__host.webgl.loadedAt[index] = undefined;\n this.setTileState(paint, index, {\n ...this.getTileState(paint, index),\n state: 'decoded',\n attempts: 0,\n nextRetryAt: undefined,\n error: undefined,\n });\n this.enqueueTileReveal(this.getTileKey(paint, index), paint, index);\n this.requiresRepaint = true;\n this.removeLoadingIndex(paint, index);\n },\n };\n }\n\n removeLoadingIndex(paint: SpacialContent, index: number) {\n if (!paint.__host?.webgl?.loading) {\n return;\n }\n const loadingIndex = paint.__host.webgl.loading.indexOf(index);\n if (loadingIndex !== -1) {\n paint.__host.webgl.loading.splice(loadingIndex, 1);\n this.loadingCount = Math.max(0, this.loadingCount - 1);\n this.requiresRepaint = true;\n }\n }\n\n private getTileKey(paint: SingleImage | TiledImage, index: number): string {\n return `${paint.id}::${paint.display.scale}::${index}`;\n }\n\n private nextRequestKey(tileKey: string): string {\n this.requestGeneration += 1;\n return `${tileKey}::${this.requestGeneration}`;\n }\n\n private getTileState(paint: SingleImage | TiledImage, index: number): WebGLTileLoadingState {\n const host = paint.__host?.webgl;\n if (!host) {\n return { state: 'idle' };\n }\n if (!host.tileState) {\n host.tileState = {};\n }\n if (!host.tileState[index]) {\n host.tileState[index] = { state: 'idle' };\n }\n return host.tileState[index] as WebGLTileLoadingState;\n }\n\n private setTileState(paint: SingleImage | TiledImage, index: number, state: WebGLTileLoadingState) {\n const host = paint.__host?.webgl;\n if (!host) {\n return;\n }\n if (!host.tileState) {\n host.tileState = {};\n }\n host.tileState[index] = state;\n }\n\n private markTileRequired(tileKey: string, prefetch: boolean) {\n if (prefetch) {\n this.requiredPrefetchTileKeys.add(tileKey);\n return;\n }\n this.requiredTileKeys.add(tileKey);\n }\n\n private isTileRequired(tileKey: string): boolean {\n return this.requiredTileKeys.has(tileKey) || this.requiredPrefetchTileKeys.has(tileKey);\n }\n\n private shouldSkipFade(tileState: WebGLTileLoadingState | undefined, now = performance.now()): boolean {\n if (!tileState?.requestedAt) {\n return false;\n }\n return now - tileState.requestedAt <= this.imageLoadingConfig.skipFadeIfLoadedWithinMs;\n }\n\n private enqueueTileReveal(tileKey: string, paint: SingleImage | TiledImage, index: number) {\n const now = performance.now();\n if (this.imageLoadingConfig.revealDelayFrames === 0 && this.imageLoadingConfig.revealBatchWindowFrames === 0) {\n if (paint.__host?.webgl?.loadedAt) {\n paint.__host.webgl.loadedAt[index] = now;\n }\n const state = this.getTileState(paint, index);\n this.setTileState(paint, index, {\n ...state,\n skipFade: this.shouldSkipFade(state, now),\n });\n return;\n }\n\n this.pendingTileReveals.set(tileKey, {\n paint,\n index,\n queuedFrame: this.frameCounter,\n });\n }\n\n private flushTileRevealBatch() {\n if (this.pendingTileReveals.size === 0) {\n return;\n }\n\n const delay = this.imageLoadingConfig.revealDelayFrames;\n const windowFrames = this.imageLoadingConfig.revealBatchWindowFrames;\n const now = performance.now();\n\n const entries = [...this.pendingTileReveals.entries()].sort((a, b) => a[1].queuedFrame - b[1].queuedFrame);\n let cursor = 0;\n\n while (cursor < entries.length) {\n const first = entries[cursor];\n if (this.frameCounter - first[1].queuedFrame < delay) {\n break;\n }\n\n const cutoffFrame = first[1].queuedFrame + windowFrames;\n while (cursor < entries.length && entries[cursor][1].queuedFrame <= cutoffFrame) {\n const [tileKey, pending] = entries[cursor];\n const host = pending.paint.__host?.webgl;\n const state = this.getTileState(pending.paint, pending.index);\n if (host?.loadedAt && state.state === 'decoded' && !host.loadedAt[pending.index]) {\n host.loadedAt[pending.index] = now;\n this.setTileState(pending.paint, pending.index, {\n ...state,\n skipFade: this.shouldSkipFade(state, now),\n });\n this.requiresRepaint = true;\n }\n this.pendingTileReveals.delete(tileKey);\n cursor += 1;\n }\n }\n }\n\n private emitImageError(event: Omit<AtlasImageLoadErrorEvent, 'renderer'>) {\n if (this.options.onImageError) {\n this.options.onImageError({\n renderer: 'webgl',\n ...event,\n });\n }\n }\n\n private releaseInFlightTileLoad(tileKey: string, opts: { silent?: boolean } = {}) {\n const inFlight = this.inFlightImageLoads.get(tileKey);\n if (!inFlight) {\n return;\n }\n inFlight.release(opts);\n this.inFlightImageLoads.delete(tileKey);\n }\n\n private pruneStaleTileWork() {\n this.tileRequestQueue = this.tileRequestQueue.filter((request) => {\n if (this.isTileRequired(request.tileKey)) {\n return true;\n }\n this.queuedTileRequestKeys.delete(request.key);\n const state = this.getTileState(request.paint, request.index);\n if (state.lastRequestKey === request.requestKey && state.state === 'queued') {\n this.setTileState(request.paint, request.index, {\n ...state,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n this.pendingTileReveals.delete(request.tileKey);\n return false;\n });\n\n for (const [tileKey, inFlight] of [...this.inFlightImageLoads.entries()]) {\n if (this.isTileRequired(tileKey)) {\n continue;\n }\n const state = this.getTileState(inFlight.paint, inFlight.index);\n if (state.lastRequestKey === inFlight.requestKey && state.state === 'loading') {\n this.setTileState(inFlight.paint, inFlight.index, {\n ...state,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n this.pendingTileReveals.delete(tileKey);\n this.removeLoadingIndex(inFlight.paint, inFlight.index);\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n }\n }\n\n private getPrefetchRadius(paint: SingleImage | TiledImage): number {\n const options = this.getCompositeRenderOptions(paint);\n if (!options) {\n return 0;\n }\n if (typeof options.prefetchRadius === 'number') {\n return Math.max(0, options.prefetchRadius);\n }\n if (options.loadingBias === 'speed') {\n return 2;\n }\n if (options.loadingBias === 'data') {\n return 0;\n }\n return 1;\n }\n\n private isLayerActive(paint: SingleImage | TiledImage): boolean {\n const parent = paint.__parent as any;\n if (!parent) {\n return true;\n }\n if (typeof parent.isImageActive === 'function') {\n return !!parent.isImageActive(paint);\n }\n return true;\n }\n\n private shouldDrawLayer(paint: SingleImage | TiledImage, index: number, isActiveLayer: boolean): boolean {\n const policy = this.getCompositeRenderOptions(paint)?.layerPolicy || 'fallback-only';\n if (policy === 'active-only') {\n if (isActiveLayer) {\n return true;\n }\n const texture = paint.__host?.webgl?.texture\n ? paint.__host.webgl.texture\n : paint.__host?.webgl?.textures?.[index];\n return !!texture;\n }\n return true;\n }\n\n private getFadeAlpha(paint: SingleImage | TiledImage, index: number, isActiveLayer: boolean): number {\n if (this.getTileState(paint, index).skipFade) {\n return 1;\n }\n\n const isRevealDeferred =\n this.getTileState(paint, index).state === 'decoded' &&\n !paint.__host?.webgl?.loadedAt?.[index] &&\n (this.imageLoadingConfig.revealDelayFrames > 0 || this.imageLoadingConfig.revealBatchWindowFrames > 0);\n if (isRevealDeferred) {\n return 0;\n }\n\n const options = this.getCompositeRenderOptions(paint);\n if (!options || !options.fadeInMs || options.fadeInMs <= 0) {\n return 1;\n }\n\n const now = performance.now();\n let fadeAlpha = 1;\n\n if (isActiveLayer && options.fadeOnLayerChange && options.layerPolicy !== 'active-only') {\n const parent = paint.__parent as any;\n if (parent && typeof parent.getImageActivatedAt === 'function') {\n const activatedAt = parent.getImageActivatedAt(paint);\n if (typeof activatedAt === 'number') {\n fadeAlpha = Math.min(fadeAlpha, Math.max(0, Math.min(1, (now - activatedAt) / options.fadeInMs)));\n }\n }\n }\n\n const loadedAt = paint.__host?.webgl?.loadedAt?.[index];\n if (loadedAt && (isActiveLayer || options.fadeFallbackTiles)) {\n fadeAlpha = Math.min(fadeAlpha, Math.max(0, Math.min(1, (now - loadedAt) / options.fadeInMs)));\n }\n\n return fadeAlpha;\n }\n\n private getTileRequestKey(paint: SingleImage | TiledImage, index: number): string {\n return `${paint.id}::${paint.display.scale}::${index}`;\n }\n\n private getCompositeOwner(paint?: SingleImage | TiledImage): unknown {\n const parent = paint?.__parent as any;\n return parent && parent.renderOptions ? parent : undefined;\n }\n\n private compareCompositeLoadPriority(\n aPaint?: SingleImage | TiledImage,\n bPaint?: SingleImage | TiledImage\n ): number {\n const aOwner = this.getCompositeOwner(aPaint);\n const bOwner = this.getCompositeOwner(bPaint);\n if (!aOwner || aOwner !== bOwner) {\n return 0;\n }\n\n const aScale = aPaint?.display.scale || 0;\n const bScale = bPaint?.display.scale || 0;\n return bScale - aScale;\n }\n\n private enqueueTileRequest(\n paint: SingleImage | TiledImage,\n index: number,\n priority: number,\n prefetch: boolean\n ): boolean {\n if (!paint.getImageUrl || !paint.__host?.webgl) {\n return false;\n }\n\n const tileKey = this.getTileKey(paint, index);\n this.markTileRequired(tileKey, prefetch);\n\n const texture = paint.__host.webgl.texture ? paint.__host.webgl.texture : paint.__host.webgl.textures?.[index];\n if (texture) {\n return false;\n }\n\n if (paint.__host.webgl.loading && paint.__host.webgl.loading.indexOf(index) !== -1) {\n return false;\n }\n\n const tileState = this.getTileState(paint, index);\n const now = performance.now();\n if (tileState.nextRetryAt && tileState.nextRetryAt > now) {\n return false;\n }\n\n const key = this.getTileRequestKey(paint, index);\n if (this.queuedTileRequestKeys.has(key)) {\n return false;\n }\n\n const requestKey = this.nextRequestKey(tileKey);\n this.pendingTileReveals.delete(tileKey);\n this.setTileState(paint, index, {\n ...tileState,\n state: 'queued',\n requestedAt: now,\n lastRequestKey: requestKey,\n cancelledAt: undefined,\n error: undefined,\n skipFade: false,\n });\n\n this.tileRequestQueue.push({\n key,\n tileKey,\n requestKey,\n paint,\n index,\n url: paint.getImageUrl(index),\n priority,\n scale: paint.display.scale,\n prefetch,\n });\n this.queuedTileRequestKeys.add(key);\n this.requiresRepaint = true;\n return true;\n }\n\n private schedulePrefetchNeighbours(paint: TiledImage, index: number, priority: number) {\n if (this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n return;\n }\n\n const options = this.getCompositeRenderOptions(paint);\n if (options?.loadingBias === 'data') {\n return;\n }\n\n const radius = this.getPrefetchRadius(paint);\n if (radius <= 0 || !paint.columns || !paint.rows) {\n return;\n }\n\n const x = index % paint.columns;\n const y = Math.floor(index / paint.columns);\n\n for (let ring = 1; ring <= radius; ring++) {\n for (let dy = -ring; dy <= ring; dy++) {\n for (let dx = -ring; dx <= ring; dx++) {\n if (Math.max(Math.abs(dx), Math.abs(dy)) !== ring) {\n continue;\n }\n\n const nx = x + dx;\n const ny = y + dy;\n if (nx < 0 || ny < 0 || nx >= paint.columns || ny >= paint.rows) {\n continue;\n }\n\n const neighbourIndex = ny * paint.columns + nx;\n if (this.enqueueTileRequest(paint, neighbourIndex, priority + ring * 1000, true)) {\n this.framePrefetchCount++;\n if (this.framePrefetchCount >= this.maxPrefetchPerFrame) {\n return;\n }\n }\n }\n }\n }\n }\n\n private processTileQueue() {\n if (!this.tileRequestQueue.length) {\n return;\n }\n\n this.tileRequestQueue.sort((a, b) => {\n if (a.prefetch !== b.prefetch) {\n return a.prefetch ? 1 : -1;\n }\n const compositePriority = this.compareCompositeLoadPriority(a.paint, b.paint);\n if (compositePriority !== 0) {\n return compositePriority;\n }\n if (a.priority !== b.priority) {\n return a.priority - b.priority;\n }\n // Larger display scale is lower quality, and should load first.\n return b.scale - a.scale;\n });\n\n while (this.loadingCount < this.maxConcurrentTasks && this.tileRequestQueue.length) {\n const next = this.tileRequestQueue.shift() as WebGLTileRequest;\n this.queuedTileRequestKeys.delete(next.key);\n\n const host = next.paint.__host?.webgl;\n if (!host || !next.paint.getImageUrl) {\n continue;\n }\n\n const state = this.getTileState(next.paint, next.index);\n if (state.lastRequestKey !== next.requestKey) {\n continue;\n }\n\n const texture = host.texture ? host.texture : host.textures?.[next.index];\n if (texture) {\n continue;\n }\n if (host.loading && host.loading.indexOf(next.index) !== -1) {\n continue;\n }\n\n this.setTileState(next.paint, next.index, {\n ...state,\n state: 'loading',\n url: next.url,\n requestedAt: state.requestedAt || performance.now(),\n });\n host.loading.push(next.index);\n this.loadingCount++;\n this.requiresRepaint = true;\n\n const consumerId = `${next.tileKey}::${next.requestKey}`;\n const acquired = this.imageRequestPool.acquire(next.url, consumerId);\n this.inFlightImageLoads.set(next.tileKey, {\n tileKey: next.tileKey,\n requestKey: next.requestKey,\n consumerId,\n paint: next.paint,\n index: next.index,\n release: acquired.release,\n });\n\n acquired.promise\n .then((image) => {\n this.releaseInFlightTileLoad(next.tileKey, { silent: true });\n const currentState = this.getTileState(next.paint, next.index);\n if (currentState.lastRequestKey !== next.requestKey || currentState.state !== 'loading') {\n this.removeLoadingIndex(next.paint, next.index);\n return;\n }\n next.paint.__host?.webgl?.onLoad(next.index, image);\n })\n .catch((error) => {\n this.releaseInFlightTileLoad(next.tileKey, { silent: true });\n if (isImageRequestCancelledError(error)) {\n const cancelledState = this.getTileState(next.paint, next.index);\n if (cancelledState.lastRequestKey === next.requestKey) {\n this.setTileState(next.paint, next.index, {\n ...cancelledState,\n state: 'idle',\n cancelledAt: performance.now(),\n });\n }\n this.pendingTileReveals.delete(next.tileKey);\n this.removeLoadingIndex(next.paint, next.index);\n return;\n }\n\n const failedState = this.getTileState(next.paint, next.index);\n if (failedState.lastRequestKey !== next.requestKey) {\n this.removeLoadingIndex(next.paint, next.index);\n return;\n }\n\n const attempts = (failedState.attempts || 0) + 1;\n const willRetry = attempts < this.imageLoadingConfig.maxAttempts;\n const nextRetryAt = willRetry\n ? performance.now() + getRetryDelayMs(this.imageLoadingConfig, attempts)\n : performance.now() + this.imageLoadingConfig.errorRetryIntervalMs;\n\n this.setTileState(next.paint, next.index, {\n ...failedState,\n state: willRetry ? 'idle' : 'error',\n attempts,\n nextRetryAt,\n error,\n });\n this.pendingTileReveals.delete(next.tileKey);\n this.removeLoadingIndex(next.paint, next.index);\n\n this.emitImageError({\n severity: 'recoverable',\n imageUrl: next.url,\n contentId: next.paint.id,\n tileIndex: next.index,\n attempt: attempts,\n maxAttempts: this.imageLoadingConfig.maxAttempts,\n willRetry,\n nextRetryAt,\n error,\n });\n\n if (!willRetry && this.options.fallbackOnImageLoadError) {\n this.emitFatalImageError({\n reason: 'image-cors-or-load',\n imageUrl: next.url,\n contentId: next.paint.id,\n tileIndex: next.index,\n error,\n });\n }\n })\n .finally(() => {\n this.processTileQueue();\n });\n }\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n if (paint.type !== 'spacial-content') {\n return;\n }\n if (!paint.__host || !paint.__host.webgl) {\n return;\n }\n\n const imagePaint = paint instanceof SingleImage || paint instanceof TiledImage;\n if (imagePaint && !isWebGLImageFastPathCandidate(paint, index)) {\n return;\n }\n if (imagePaint) {\n this.frameSawFastPathCandidate = true;\n }\n const isActiveLayer = imagePaint ? this.isLayerActive(paint) : true;\n\n if (paint.getTexture) {\n const newText = paint.getTexture();\n if (newText && paint.__host.webgl.lastImage !== newText.hash && newText.source && !paint.__host.webgl.error) {\n try {\n const level = 0;\n const internalFormat = this.gl.RGBA;\n const srcFormat = this.gl.RGBA;\n const srcType = this.gl.UNSIGNED_BYTE;\n this.gl.bindTexture(this.gl.TEXTURE_2D, paint.__host.webgl.texture);\n this.gl.texImage2D(this.gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, newText.source);\n paint.__host.webgl.lastImage = newText.hash;\n } catch (error) {\n paint.__host.webgl.error = error;\n this.emitFatalImageError({\n reason: 'teximage-security',\n contentId: paint.id,\n tileIndex: index,\n error,\n });\n }\n }\n }\n\n const texture = paint.__host.webgl.texture ? paint.__host.webgl.texture : paint.__host.webgl.textures[index];\n if (imagePaint && isActiveLayer) {\n const canvasCenterX = this.gl.canvas.width / this.dpi / 2;\n const canvasCenterY = this.gl.canvas.height / this.dpi / 2;\n const tileCenterX = x + width / 2;\n const tileCenterY = y + height / 2;\n const priority = Math.hypot(tileCenterX - canvasCenterX, tileCenterY - canvasCenterY);\n\n if (!texture) {\n this.enqueueTileRequest(paint, index, priority, false);\n }\n if (paint instanceof TiledImage) {\n this.schedulePrefetchNeighbours(paint, index, priority);\n }\n }\n\n if (imagePaint && !this.shouldDrawLayer(paint, index, isActiveLayer)) {\n return;\n }\n\n if (texture) {\n const baseAlpha = imagePaint ? (typeof paint.style?.opacity === 'number' ? paint.style.opacity : 1) : 1;\n const zoneVisibilityAlpha =\n typeof (paint as any).__zoneVisibilityAlpha === 'number' ? (paint as any).__zoneVisibilityAlpha : 1;\n if (!baseAlpha) {\n return;\n }\n const fadeAlpha = imagePaint ? this.getFadeAlpha(paint, index, isActiveLayer) : 1;\n if (fadeAlpha < 1) {\n this.hasTilesFading = true;\n }\n const alpha = baseAlpha * fadeAlpha * zoneVisibilityAlpha;\n\n this.gl.enableVertexAttribArray(this.attributes.texCoord);\n\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.texCoord);\n this.gl.enableVertexAttribArray(this.attributes.texCoord);\n this.gl.vertexAttribPointer(this.attributes.texCoord, 2, this.gl.FLOAT, false, 0, 0);\n\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.position);\n this.gl.enableVertexAttribArray(this.attributes.position);\n this.gl.vertexAttribPointer(this.attributes.position, 2, this.gl.FLOAT, false, 0, 0);\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n this.gl.uniform1i(this.uniforms.texture, 0);\n this.gl.uniform1f(this.uniforms.alpha, alpha);\n this.setRectangle(x, y, width, height);\n this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n if (!this.isImmediateReadiness() && imagePaint && alpha > 0) {\n this.firstMeaningfulPaint = true;\n }\n }\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand) {\n // no-op\n }\n\n pendingUpdate(): boolean {\n return (\n this.requiresRepaint ||\n this.tileRequestQueue.length > 0 ||\n this.loadingCount > 0 ||\n this.inFlightImageLoads.size > 0 ||\n this.pendingTileReveals.size > 0 ||\n this.hasTilesFading\n );\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n afterFrame() {\n this.pruneStaleTileWork();\n this.processTileQueue();\n }\n\n lastKnownScale = 1;\n\n getScale(width: number, height: number, dpi?: boolean): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const canvas = this.getCanvasDims();\n const w = canvas.width / width;\n const h = canvas.height / height;\n const scale = (w < h ? h : w) * (dpi ? this.dpi || 1 : 1);\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n getCanvasDims() {\n return {\n width: this.canvas.width / this.dpi,\n height: this.canvas.height / this.dpi,\n };\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n // Helpers.\n createShader(type: number, source: string) {\n const shader = this.gl.createShader(type);\n if (shader) {\n this.gl.shaderSource(shader, source);\n this.gl.compileShader(shader);\n const success = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);\n if (success) {\n return shader;\n }\n\n const info = this.gl.getShaderInfoLog(shader);\n this.gl.deleteShader(shader);\n if (info) {\n throw new Error(info);\n }\n }\n\n throw new Error('Invalid shader');\n }\n\n createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = this.gl.createProgram();\n if (program) {\n this.gl.attachShader(program, vertexShader);\n this.gl.attachShader(program, fragmentShader);\n this.gl.linkProgram(program);\n const success = this.gl.getProgramParameter(program, this.gl.LINK_STATUS);\n if (success) {\n return program;\n }\n\n const info = this.gl.getProgramInfoLog(program);\n this.gl.deleteProgram(program);\n if (info) {\n throw new Error(info);\n }\n }\n throw new Error('Invalid program');\n }\n\n resizeCanvasToDisplaySize() {\n const canvas = this.gl.canvas as HTMLCanvasElement;\n // Lookup the size the browser is displaying the canvas in CSS pixels.\n const displayWidth = canvas.clientWidth;\n const displayHeight = canvas.clientHeight;\n const targetWidth = Math.round(displayWidth * this.dpi);\n const targetHeight = Math.round(displayHeight * this.dpi);\n\n // Check if the canvas is not the same size.\n const needResize = canvas.width !== targetWidth || canvas.height !== targetHeight;\n\n if (needResize) {\n // Make the canvas the same size\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n }\n\n return needResize;\n }\n\n createArrayBuffer(data?: Float32Array) {\n const buffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n if (data) {\n this.gl.bufferData(this.gl.ARRAY_BUFFER, data, this.gl.STATIC_DRAW);\n }\n\n if (!buffer) {\n throw new Error('Cannot create buffer');\n }\n return buffer;\n }\n\n setRectangle(x: number, y: number, width: number, height: number) {\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.getRectangle(x, y, width, height), this.gl.STATIC_DRAW);\n }\n\n getRectangle(x: number, y: number, width: number, height: number) {\n const x1 = x;\n const x2 = x + width;\n const y1 = y;\n const y2 = y + height;\n this.rectBuffer.set([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]);\n return this.rectBuffer;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n finishLayer() {\n if (this.activeLayerScissorRect) {\n this.gl.disable(this.gl.SCISSOR_TEST);\n this.activeLayerScissorRect = undefined;\n }\n }\n resetReadyState() {\n if (this.isImmediateReadiness()) {\n return;\n }\n this.firstMeaningfulPaint = false;\n }\n\n reset() {\n this.canvas.removeEventListener('webglcontextlost', this.onContextLost as EventListener);\n this.canvas.style.filter = 'none';\n this.framePrefetchCount = 0;\n this.loadingCount = 0;\n this.hasTilesFading = false;\n this.requiresRepaint = false;\n this.tileRequestQueue = [];\n this.queuedTileRequestKeys.clear();\n for (const tileKey of [...this.inFlightImageLoads.keys()]) {\n this.releaseInFlightTileLoad(tileKey, { silent: true });\n }\n this.imageRequestPool.cancelAll({ silent: true });\n this.inFlightImageLoads.clear();\n this.requiredTileKeys.clear();\n this.requiredPrefetchTileKeys.clear();\n this.pendingTileReveals.clear();\n this.requestGeneration += 1;\n this.frameCounter = 0;\n this.frameSawFastPathCandidate = false;\n this.firstMeaningfulPaint = this.isImmediateReadiness();\n }\n}\n","import { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { CanvasRenderer } from '../../canvas-renderer/canvas-renderer';\nimport { CompositeRenderer } from '../../composite-renderer/composite-renderer';\nimport { NavigatorRenderer, type NavigatorRendererOptions } from '../../navigator-renderer/navigator-renderer';\nimport { OverlayRenderer } from '../../overlay-renderer/overlay-renderer';\nimport { pdfScrollZoneController } from '../../pdf-scroll-zone-controller/pdf-scroll-zone-controller';\nimport { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { isWebGLImageFastPathCandidate } from '../../webgl-renderer/webgl-eligibility';\nimport { WebGLRenderer } from '../../webgl-renderer/webgl-renderer';\nimport { unmountComponentAtNode } from '../reconciler';\nimport type { Preset, PresetArgs } from './_types';\n\nexport type DefaultPresetName = 'default-preset';\n\nexport type DefaultPresetOptions = {\n controllerConfig?: any;\n interactionMode?: 'popmotion' | 'pdf-scroll-zone';\n unstable_webglRenderer?: boolean;\n interactive?: boolean;\n dpi?: number;\n debug?: boolean;\n canvasBox?: boolean;\n polygon?: boolean;\n navigatorRendererOptions?: NavigatorRendererOptions;\n};\n\nexport function defaultPreset({\n interactive = true,\n viewport,\n forceRefresh,\n canvasElement,\n parityCanvasElement,\n overlayElement,\n controllerConfig,\n interactionMode = 'popmotion',\n unstable_webglRenderer,\n dpi,\n debug,\n canvasBox = true,\n polygon = true,\n navigatorElement,\n runtimeOptions,\n onWebGLFallback,\n onImageError,\n imageLoading,\n webglFallbackOnImageLoadError,\n webglReadiness,\n navigatorRendererOptions,\n}: PresetArgs & DefaultPresetOptions): Preset {\n if (!canvasElement) {\n throw new Error('Invalid container');\n }\n\n canvasElement.style.userSelect = 'none';\n\n const controllerFactory = interactionMode === 'pdf-scroll-zone' ? pdfScrollZoneController : popmotionController;\n const controller = interactive\n ? controllerFactory({\n minZoomFactor: 0.5,\n maxZoomFactor: 3,\n enableClickToZoom: false,\n parentElement: canvasElement,\n ...(controllerConfig || {}),\n })\n : undefined;\n\n let baseRenderer: CanvasRenderer | WebGLRenderer;\n let parityCanvasRenderer: CanvasRenderer | undefined;\n\n if (unstable_webglRenderer) {\n try {\n baseRenderer = new WebGLRenderer(canvasElement, {\n dpi,\n onFatalImageError: onWebGLFallback,\n onImageError,\n imageLoading,\n fallbackOnImageLoadError: webglFallbackOnImageLoadError,\n readiness: webglReadiness,\n });\n } catch (error) {\n baseRenderer = new CanvasRenderer(canvasElement, {\n dpi,\n debug,\n box: canvasBox,\n polygon,\n imageLoading,\n onImageError,\n });\n }\n } else {\n baseRenderer = new CanvasRenderer(canvasElement, {\n dpi,\n debug,\n box: canvasBox,\n polygon,\n imageLoading,\n onImageError,\n });\n }\n\n const usingWebGL = baseRenderer instanceof WebGLRenderer;\n\n if (usingWebGL && parityCanvasElement) {\n parityCanvasRenderer = new CanvasRenderer(parityCanvasElement, {\n dpi,\n debug,\n box: canvasBox,\n polygon,\n paintImages: true,\n shouldPaintImage: (paint, index) => !isWebGLImageFastPathCandidate(paint, index),\n readiness: 'immediate',\n imageLoading,\n onImageError,\n });\n }\n\n const shouldRenderBoxesInOverlay = usingWebGL && !parityCanvasRenderer ? true : !canvasBox;\n const runtimeRef: { current?: Runtime } = {};\n const externalNavigatorRenderRequest = navigatorRendererOptions?.onRequestRender;\n const navigatorRenderer = navigatorElement\n ? new NavigatorRenderer(navigatorElement, {\n ...(navigatorRendererOptions || {}),\n sharedCanvasRenderer: baseRenderer instanceof CanvasRenderer ? (baseRenderer as any) : undefined,\n onRequestRender: () => {\n if (externalNavigatorRenderRequest) {\n externalNavigatorRenderRequest();\n }\n if (runtimeRef.current) {\n runtimeRef.current.updateNextFrame();\n }\n },\n })\n : undefined;\n\n const renderer = new CompositeRenderer([\n baseRenderer,\n parityCanvasRenderer,\n overlayElement\n ? new OverlayRenderer(overlayElement, {\n box: shouldRenderBoxesInOverlay,\n text: true,\n triggerResize: forceRefresh,\n })\n : undefined,\n navigatorRenderer,\n ]);\n\n const runtime = new Runtime(\n renderer,\n new World(1024, 1024),\n viewport,\n controller ? [controller] : [],\n runtimeOptions\n );\n runtimeRef.current = runtime;\n\n const em = new BrowserEventManager(canvasElement, runtime);\n\n return {\n name: 'default-preset',\n em,\n runtime,\n renderer,\n controller,\n canvas: canvasElement,\n parityCanvas: parityCanvasRenderer ? parityCanvasElement : undefined,\n navigator: navigatorElement,\n unmount() {\n unmountComponentAtNode(runtime);\n runtime.stopControllers();\n runtime.stop();\n runtime.reset();\n if (em) {\n em.stop();\n }\n },\n };\n}\n","import { Renderer } from '../../renderer/renderer';\nimport { World } from '../../world';\nimport { Paint } from '../../world-objects/paint';\nimport { Strand } from '@atlas-viewer/dna';\nimport { SpacialContent } from '../../spacial-content/spacial-content';\nimport { PositionPair } from '../../types';\nimport { SingleImage } from '../../spacial-content/single-image';\nimport { TiledImage } from '../../spacial-content/tiled-image';\nimport { Stylesheet } from '../../utility/stylesheet';\n\ntype StaticRendererOptions = {\n imageClass: string;\n addPart: boolean;\n setDraggableFalse: boolean;\n widthStylesheet: boolean;\n sheetPrefix: string;\n background: string;\n};\n\n// @todo make this configurable.\nconst MIN = 1 + Number.MIN_VALUE;\n\nexport class StaticRenderer implements Renderer {\n container: HTMLElement;\n width: number;\n height: number;\n pending = true;\n options: StaticRendererOptions;\n stylesheet: Stylesheet;\n zIndex = 0;\n lastKnownScale = 1;\n rendererPosition: DOMRect;\n\n constructor(container: HTMLElement, options?: Partial<StaticRendererOptions>) {\n this.container = container;\n this.rendererPosition = container.getBoundingClientRect();\n const { width, height } = this.rendererPosition;\n this.width = width;\n this.height = height;\n this.options = {\n addPart: false,\n setDraggableFalse: false,\n imageClass: '',\n widthStylesheet: false,\n sheetPrefix: 'position-',\n background: '#000',\n ...(options || {}),\n };\n this.stylesheet = new Stylesheet({ sheetPrefix: this.options.sheetPrefix });\n this.container.classList.add(\n this.stylesheet.addStylesheet(`\n background: ${this.options.background};\n `)\n );\n if (this.options.widthStylesheet) {\n this.container.appendChild(this.stylesheet.getElement());\n }\n }\n\n isReady(): boolean {\n return true;\n }\n\n resize() {\n this.rendererPosition = this.container.getBoundingClientRect();\n this.width = this.rendererPosition.width;\n this.height = this.rendererPosition.height;\n this.pending = true;\n }\n\n getRendererScreenPosition() {\n return this.rendererPosition;\n }\n\n afterFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.updateSheet();\n\n for (const item of this.previouslyVisible) {\n if (this.currentlyVisible.indexOf(item) === -1) {\n this.container.removeChild(item);\n }\n }\n\n for (const item of this.currentlyVisible) {\n if (this.previouslyVisible.indexOf(item) === -1) {\n this.container.appendChild(item);\n }\n }\n\n this.previouslyVisible = this.currentlyVisible;\n this.currentlyVisible = [];\n this.pending = false;\n }\n\n afterPaintLayer(paint: SpacialContent, transform?: Strand): void {}\n\n beforeFrame(world: World, delta: number, target: Strand): void {\n this.stylesheet.clearClasses();\n this.zIndex = 0;\n }\n\n getPointsAt(world: World, target: Strand, aggregate: Strand, scaleFactor: number): Paint[] {\n return world.getPointsAt(target, aggregate, scaleFactor);\n }\n\n getScale(width: number, height: number): number {\n // It shouldn't happen, but it will. If the canvas is a different shape\n // to the viewport, then this will choose the largest scale to use.\n if (Number.isNaN(width) || Number.isNaN(height)) {\n return this.lastKnownScale;\n }\n\n const w = this.width / width;\n const h = this.height / height;\n const scale = w < h ? h : w;\n\n if (!Number.isNaN(scale)) {\n this.lastKnownScale = scale;\n }\n\n return this.lastKnownScale;\n }\n\n getViewportBounds(world: World, target: Strand, padding: number): PositionPair | null {\n return null;\n }\n\n currentlyVisible: HTMLElement[] = [];\n previouslyVisible: HTMLElement[] = [];\n\n createImage() {\n const image = document.createElement('img');\n\n if (this.options.imageClass) {\n image.className = this.options.imageClass;\n if (this.options.addPart) {\n image.setAttribute('part', this.options.imageClass);\n }\n } else {\n image.style.position = 'absolute';\n image.style.pointerEvents = 'none';\n image.style.userSelect = 'none';\n }\n if (this.options.setDraggableFalse) {\n image.setAttribute('draggable', 'false');\n }\n return image;\n }\n\n paint(paint: SpacialContent, index: number, x: number, y: number, width: number, height: number): void {\n this.zIndex++;\n\n if (paint instanceof SingleImage) {\n if (!paint.__host) {\n const image = this.createImage();\n image.src = paint.uri;\n paint.__host = image;\n this.container.appendChild(paint.__host);\n }\n\n const element: HTMLImageElement = paint.__host;\n this.currentlyVisible.push(element);\n\n element.style.zIndex = `${this.zIndex}`;\n element.style.opacity = `${paint.style.opacity}`;\n\n if (this.options.widthStylesheet) {\n element.className =\n this.options.imageClass +\n ' ' +\n this.stylesheet.addStylesheet(`width:${(width + MIN).toFixed(2)}px;height:${(height + MIN).toFixed(2)}px;`);\n } else {\n element.style.width = `${width + MIN}px`;\n element.style.height = `${height + MIN}px`;\n }\n element.style.transform = `translate(${x}px, ${y}px)`;\n }\n if (paint instanceof TiledImage) {\n if (!paint.__host) {\n paint.__host = {\n images: [],\n };\n }\n\n if (!paint.__host.images[index]) {\n const url = paint.getImageUrl(index);\n const image = this.createImage();\n image.src = url;\n paint.__host.images[index] = image;\n this.container.appendChild(image);\n }\n const element: HTMLImageElement = paint.__host.images[index];\n element.style.zIndex = `${this.zIndex}`;\n element.style.opacity = `${paint.style.opacity}`;\n\n this.currentlyVisible.push(element);\n\n if (this.options.widthStylesheet) {\n element.className =\n this.options.imageClass +\n ' ' +\n this.stylesheet.addStylesheet(`width:${(width + MIN).toFixed(2)}px;height:${(height + MIN).toFixed(2)}px;`);\n } else {\n element.style.width = `${width + MIN}px`;\n element.style.height = `${height + MIN}px`;\n }\n element.style.transform = `translate(${x}px, ${y}px)`;\n }\n }\n\n pendingUpdate(): boolean {\n return this.pending;\n }\n\n prepareLayer(paint: SpacialContent): void {}\n finishLayer(paint: SpacialContent): void {}\n reset() {\n this.pending = true;\n }\n}\n","import { Runtime } from '../../../renderer/runtime';\nimport { World } from '../../../world';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { CompositeRenderer } from '../../composite-renderer/composite-renderer';\nimport { OverlayRenderer } from '../../overlay-renderer/overlay-renderer';\nimport { pdfScrollZoneController } from '../../pdf-scroll-zone-controller/pdf-scroll-zone-controller';\nimport { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { StaticRenderer } from '../../static-renderer/static-renderer';\nimport { unmountComponentAtNode } from '../reconciler';\nimport type { Preset, PresetArgs } from './_types';\n\nexport type StaticPresetName = 'static-preset';\n\nexport type StaticPresetOptions = {\n controllerConfig?: any;\n interactionMode?: 'popmotion' | 'pdf-scroll-zone';\n interactive?: boolean;\n};\n\nexport function staticPreset({\n interactive,\n viewport,\n forceRefresh,\n containerElement,\n overlayElement,\n controllerConfig,\n interactionMode = 'popmotion',\n}: PresetArgs & StaticPresetOptions): Preset {\n if (!containerElement) {\n throw new Error('Invalid container');\n }\n containerElement.style.userSelect = 'none';\n\n const controllerFactory = interactionMode === 'pdf-scroll-zone' ? pdfScrollZoneController : popmotionController;\n const controller = interactive\n ? controllerFactory({\n minZoomFactor: 0.5,\n maxZoomFactor: 3,\n enableClickToZoom: false,\n parentElement: containerElement,\n ...(controllerConfig || {}),\n })\n : undefined;\n\n const staticRenderer = new StaticRenderer(containerElement, {\n addPart: false,\n setDraggableFalse: false,\n imageClass: 'atlas-static-image',\n });\n const renderer = overlayElement\n ? new CompositeRenderer([\n staticRenderer,\n new OverlayRenderer(overlayElement, {\n box: true,\n text: true,\n triggerResize: forceRefresh,\n }),\n ])\n : staticRenderer;\n\n const runtime = new Runtime(renderer, new World(1024, 1024), viewport, controller ? [controller] : []);\n\n const em = new BrowserEventManager(containerElement, runtime);\n\n return {\n name: 'static-preset',\n em,\n runtime,\n renderer,\n controller,\n container: containerElement,\n overlay: overlayElement,\n unmount() {\n unmountComponentAtNode(runtime);\n runtime.stopControllers();\n runtime.stop();\n if (em) {\n em.stop();\n }\n },\n };\n}\n","import { defaultPreset, DefaultPresetName, DefaultPresetOptions } from './default-preset';\nimport { staticPreset, StaticPresetName, StaticPresetOptions } from './static-preset';\nimport { Preset } from './_types';\n\nexport const presets: { [key in PresetNames]: (options: any) => Preset } = {\n 'default-preset': defaultPreset,\n 'static-preset': staticPreset,\n};\n\nexport type PresetNames = DefaultPresetName | StaticPresetName;\n\nexport type Presets =\n | readonly [DefaultPresetName, DefaultPresetOptions]\n | readonly [StaticPresetName, StaticPresetOptions];\n","import { useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { type PresetNames, type Presets, presets } from '../presets';\nimport type { Preset, PresetArgs } from '../presets/_types';\nimport { defaultPreset } from '../presets/default-preset';\n\nconst defaultArgs = {};\n\nexport function usePreset(\n renderPreset: PresetNames | Presets | undefined,\n options: {\n width: number;\n height: number;\n forceRefresh?: any;\n controllerConfig?: PresetArgs['controllerConfig'];\n interactionMode?: PresetArgs['interactionMode'];\n unstable_webglRenderer?: boolean;\n onWebGLFallback?: PresetArgs['onWebGLFallback'];\n onImageError?: PresetArgs['onImageError'];\n imageLoading?: PresetArgs['imageLoading'];\n webglFallbackOnImageLoadError?: PresetArgs['webglFallbackOnImageLoadError'];\n webglReadiness?: PresetArgs['webglReadiness'];\n runtimeOptions?: PresetArgs['runtimeOptions'];\n }\n) {\n const overlayRef = useRef<HTMLDivElement>();\n const canvasRef = useRef<HTMLCanvasElement>();\n const parityCanvasRef = useRef<HTMLCanvasElement>();\n const navigatorRef = useRef<HTMLCanvasElement>();\n const containerRef = useRef<HTMLElement>();\n const viewport = useRef<\n PresetArgs['viewport'] & {\n didUpdate?: boolean;\n }\n >({\n x: 0,\n y: 0,\n width: options.width,\n height: options.height,\n scale: 1,\n didUpdate: true,\n });\n const liveCallbacksRef = useRef<{\n onWebGLFallback?: PresetArgs['onWebGLFallback'];\n onImageError?: PresetArgs['onImageError'];\n }>({\n onWebGLFallback: options.onWebGLFallback,\n onImageError: options.onImageError,\n });\n\n const [presetName = 'default-preset', presetArgs = defaultArgs] = Array.isArray(renderPreset)\n ? renderPreset || []\n : [renderPreset];\n\n const [preset, setPreset] = useState<Preset | null>(null);\n\n useLayoutEffect(() => {\n liveCallbacksRef.current.onWebGLFallback = options.onWebGLFallback;\n liveCallbacksRef.current.onImageError = options.onImageError;\n }, [options.onImageError, options.onWebGLFallback]);\n\n useLayoutEffect(() => {\n const canvasElement = canvasRef.current;\n const containerElement = containerRef.current;\n const overlayElement = overlayRef.current;\n const navigatorElement = navigatorRef.current;\n const presetFn = ((presets as any)[presetName as any] as (config: PresetArgs) => Preset) || defaultPreset;\n\n const createdPreset = presetFn({\n containerElement,\n canvasElement,\n parityCanvasElement: parityCanvasRef.current,\n overlayElement,\n navigatorElement,\n viewport: viewport.current,\n dpi: window.devicePixelRatio || 1,\n forceRefresh: options.forceRefresh,\n controllerConfig: options.controllerConfig,\n interactionMode: options.interactionMode,\n unstable_webglRenderer: options.unstable_webglRenderer,\n onWebGLFallback: (event) => {\n if (liveCallbacksRef.current.onWebGLFallback) {\n liveCallbacksRef.current.onWebGLFallback(event);\n }\n },\n onImageError: (event) => {\n if (liveCallbacksRef.current.onImageError) {\n liveCallbacksRef.current.onImageError(event);\n }\n },\n imageLoading: options.imageLoading,\n webglFallbackOnImageLoadError: options.webglFallbackOnImageLoadError,\n webglReadiness: options.webglReadiness,\n runtimeOptions: options.runtimeOptions,\n ...(presetArgs || {}),\n });\n\n setPreset(createdPreset);\n\n return () => {\n if (createdPreset) {\n const currentViewport = createdPreset.runtime.getViewport();\n viewport.current = {\n ...viewport.current,\n ...currentViewport,\n didUpdate: true,\n };\n createdPreset.unmount();\n\n if (canvasElement) {\n canvasElement.height = 0;\n canvasElement.width = 0;\n }\n if (overlayElement) {\n overlayElement.innerHTML = '';\n }\n if (navigatorElement) {\n navigatorElement.height = 0;\n navigatorElement.width = 0;\n }\n }\n };\n }, [\n presetName,\n presetArgs,\n options.unstable_webglRenderer,\n options.controllerConfig,\n options.interactionMode,\n options.imageLoading,\n options.webglFallbackOnImageLoadError,\n options.webglReadiness,\n ]);\n\n const refs = useMemo(\n () => ({\n canvas: canvasRef,\n parityCanvas: parityCanvasRef,\n overlay: overlayRef,\n container: containerRef,\n navigator: navigatorRef,\n }),\n []\n );\n\n return [presetName, preset, viewport, refs] as const;\n}\n","import { DnaFactory, type Projection } from '@atlas-viewer/dna';\nimport type React from 'react';\nimport { memo, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport useMeasure from 'react-use-measure';\nimport type { Runtime, RuntimeOptions, ViewerFilters, ViewerMode } from '../../renderer/runtime';\nimport {\n getNavigatorVisibleZoneIdSet,\n getNavigatorWorldRegion,\n getNavigatorWorldTransform,\n type NavigatorDebugEvent,\n type NavigatorRendererStyle,\n type NavigatorZoneWindowOptions,\n navigatorToWorldPoint,\n} from '../navigator-renderer/navigator-renderer';\nimport type { PdfScrollZoneControllerConfig } from '../pdf-scroll-zone-controller/pdf-scroll-zone-controller';\nimport type { PopmotionControllerConfig } from '../popmotion-controller/popmotion-controller';\nimport type { AtlasImageLoadErrorEvent } from '../shared/image-load-events';\nimport type { ImageLoadingConfig } from '../shared/image-loading-config';\nimport type { AtlasReadyEvent, AtlasReadyRenderer } from '../shared/ready-events';\nimport type { AtlasWebGLFallbackEvent } from '../webgl-renderer/types';\nimport { AtlasContext, BoundsContext } from './components/AtlasContext';\nimport { AtlasWithReconciler } from './components/AtlasWithReconciler';\nimport { Container } from './components/Container';\nimport { DevTools, type DevToolsProps } from './components/DevTools';\nimport { registerAtlasRuntime } from './devtools/registry';\nimport { useClassname } from './hooks/use-classname';\nimport { useDiffProps } from './hooks/use-diff-props';\nimport { ModeContext } from './hooks/use-mode';\nimport { usePreset } from './hooks/use-preset';\nimport type { PresetNames, Presets } from './presets';\nimport type { Preset } from './presets/_types';\nimport { useIsomorphicLayoutEffect } from './utility/react';\n\nfunction getReadyRenderer(renderer: unknown): AtlasReadyRenderer {\n const maybeRenderer = renderer as {\n renderers?: unknown[];\n constructor?: { name?: string };\n };\n if (Array.isArray(maybeRenderer?.renderers)) {\n return 'composite';\n }\n const constructorName = maybeRenderer?.constructor?.name || '';\n if (constructorName === 'CanvasRenderer') {\n return 'canvas';\n }\n if (constructorName === 'WebGLRenderer') {\n return 'webgl';\n }\n if (constructorName === 'StaticRenderer') {\n return 'static';\n }\n return 'unknown';\n}\n\nconst NAVIGATOR_HOME_TOLERANCE = 1;\n\nexport type AtlasProps = {\n debug?: boolean;\n mode?: ViewerMode;\n onCreated?: (ctx: Preset) => void | Promise<void>;\n resetWorldOnChange?: boolean;\n unstable_webglRenderer?: boolean;\n onWebGLFallback?: (event: AtlasWebGLFallbackEvent) => void;\n onReady?: (event: AtlasReadyEvent) => void;\n onImageError?: (event: AtlasImageLoadErrorEvent) => void;\n readyResetKey?: string | number;\n webglFallbackOnImageLoadError?: boolean;\n // compatibility: webglReadiness?: 'first-meaningful-paint' | 'immediate'\n webglReadiness?: 'first-meaningful-paint' | 'immediate';\n imageLoading?: Partial<ImageLoadingConfig>;\n unstable_noReconciler?: boolean;\n overlayStyle?: any;\n containerStyle?: any;\n containerProps?: any;\n controllerConfig?: PopmotionControllerConfig | PdfScrollZoneControllerConfig;\n interactionMode?: 'popmotion' | 'pdf-scroll-zone';\n renderPreset?: PresetNames | Presets;\n hideInlineStyle?: boolean;\n homeCover?: true | false | 'start' | 'end';\n homeOnResize?: boolean;\n homePosition?: Projection;\n /**\n * Home padding in CSS pixels. Can be a number (symmetric) or an object with any of\n * `left`, `right`, `top`, `bottom` for per-side CSS pixel margins.\n */\n homePaddingPx?: number | { left?: number; right?: number; top?: number; bottom?: number };\n className?: string;\n background?: string;\n enableNavigator?: boolean;\n navigatorOptions?: {\n width?: number;\n idleFade?: boolean;\n idleMs?: number;\n fadeDurationMs?: number;\n opacityActive?: number;\n opacityIdle?: number;\n style?: Partial<NavigatorRendererStyle>;\n pdfScrollZoneZoneWindow?: NavigatorZoneWindowOptions;\n };\n htmlChildren?: ReactNode;\n children: ReactNode;\n devTools?: boolean | DevToolsProps;\n runtimeOptions?: Partial<RuntimeOptions>;\n filters?: Partial<ViewerFilters>;\n};\n\nconst filterProperties = [\n 'brightness',\n 'contrast',\n 'grayscale',\n 'hueRotate',\n 'invert',\n 'saturate',\n 'sepia',\n 'blur',\n] as const;\n\nexport const Atlas: React.FC<\n AtlasProps & {\n width: number;\n height: number;\n }\n> = memo(function Atlas(props) {\n let {\n htmlChildren,\n renderPreset: _renderPreset,\n onCreated,\n mode: _mode = 'explore',\n resetWorldOnChange = true,\n // eslint-disable-next-line\n unstable_webglRenderer = false,\n onWebGLFallback,\n onReady,\n onImageError,\n readyResetKey,\n webglFallbackOnImageLoadError = false,\n webglReadiness,\n imageLoading,\n // eslint-disable-next-line\n unstable_noReconciler = false,\n hideInlineStyle = false,\n controllerConfig,\n interactionMode = 'popmotion',\n children,\n overlayStyle,\n containerStyle,\n enableNavigator,\n className,\n containerProps = {},\n homePosition,\n homeOnResize,\n homeCover,\n background,\n navigatorOptions,\n runtimeOptions,\n debug,\n filters,\n homePaddingPx,\n devTools,\n ...restProps\n } = props;\n\n useDiffProps(props, 'Atlas.tsx', props.debug);\n\n const [mode, setMode] = useState(_mode);\n const [activeWebGL, setActiveWebGL] = useState(unstable_webglRenderer);\n const fallbackLockedRef = useRef(false);\n const pendingRestoreViewportRef = useRef<Projection | null>(null);\n const currentRuntimeRef = useRef<Runtime | null>(null);\n const readyResetBaselineRef = useRef<string | number | undefined>(undefined);\n const lastReadyNotifiedCycleRef = useRef<number | undefined>(undefined);\n // Reference to the current HTML Canvas element\n // Set by React by passing <canvas ref={...} />\n // Used to instantiate the controller and viewer with the correct HTML element.\n const [isReady, setIsReady] = useState(false);\n const navigatorIdleTimer = useRef<number | undefined>(undefined);\n const [isNavigatorIdle, setIsNavigatorIdle] = useState(false);\n const [isNavigatorDragging, setIsNavigatorDragging] = useState(false);\n const [isNavigatorHiddenAtHome, setIsNavigatorHiddenAtHome] = useState(false);\n const navigatorDraggingRef = useRef(false);\n\n const navigatorStyleBackground = navigatorOptions?.style?.background;\n const navigatorStyleObjectFill = navigatorOptions?.style?.objectFill;\n const navigatorStyleObjectStroke = navigatorOptions?.style?.objectStroke;\n const navigatorStyleViewportFill = navigatorOptions?.style?.viewportFill;\n const navigatorStyleViewportStroke = navigatorOptions?.style?.viewportStroke;\n const navigatorStyleViewportLineWidth = navigatorOptions?.style?.viewportLineWidth;\n const navigatorZoneWindowTotal = navigatorOptions?.pdfScrollZoneZoneWindow?.total;\n const navigatorZoneWindowBefore = navigatorOptions?.pdfScrollZoneZoneWindow?.before;\n const navigatorZoneWindowAfter = navigatorOptions?.pdfScrollZoneZoneWindow?.after;\n\n const resolvedNavigatorStyle = useMemo(() => {\n if (\n typeof navigatorStyleBackground === 'undefined' &&\n typeof navigatorStyleObjectFill === 'undefined' &&\n typeof navigatorStyleObjectStroke === 'undefined' &&\n typeof navigatorStyleViewportFill === 'undefined' &&\n typeof navigatorStyleViewportStroke === 'undefined' &&\n typeof navigatorStyleViewportLineWidth === 'undefined'\n ) {\n return undefined;\n }\n\n return {\n background: navigatorStyleBackground,\n objectFill: navigatorStyleObjectFill,\n objectStroke: navigatorStyleObjectStroke,\n viewportFill: navigatorStyleViewportFill,\n viewportStroke: navigatorStyleViewportStroke,\n viewportLineWidth: navigatorStyleViewportLineWidth,\n };\n }, [\n navigatorStyleBackground,\n navigatorStyleObjectFill,\n navigatorStyleObjectStroke,\n navigatorStyleViewportFill,\n navigatorStyleViewportStroke,\n navigatorStyleViewportLineWidth,\n ]);\n\n const resolvedNavigatorZoneWindow = useMemo(() => {\n if (interactionMode !== 'pdf-scroll-zone') {\n return undefined;\n }\n return {\n total: navigatorZoneWindowTotal ?? 9,\n before: navigatorZoneWindowBefore,\n after: navigatorZoneWindowAfter,\n };\n }, [interactionMode, navigatorZoneWindowAfter, navigatorZoneWindowBefore, navigatorZoneWindowTotal]);\n\n const handleNavigatorDebugEvent = useCallback(\n (event: NavigatorDebugEvent) => {\n if (debug) {\n console.debug('[Atlas navigator]', event);\n }\n },\n [debug]\n );\n\n const resolvedNavigatorOptions = useMemo(\n () => ({\n width: navigatorOptions?.width ?? 120,\n idleFade: navigatorOptions?.idleFade ?? true,\n idleMs: navigatorOptions?.idleMs ?? 800,\n fadeDurationMs: navigatorOptions?.fadeDurationMs ?? 250,\n opacityActive: navigatorOptions?.opacityActive ?? 0.94,\n opacityIdle: navigatorOptions?.opacityIdle ?? 0,\n style: resolvedNavigatorStyle,\n zoneWindow: resolvedNavigatorZoneWindow,\n }),\n [\n navigatorOptions?.fadeDurationMs,\n navigatorOptions?.idleFade,\n navigatorOptions?.idleMs,\n navigatorOptions?.opacityActive,\n navigatorOptions?.opacityIdle,\n navigatorOptions?.width,\n resolvedNavigatorStyle,\n resolvedNavigatorZoneWindow,\n ]\n );\n\n const renderPreset = useMemo<PresetNames | Presets>(() => {\n let presetName: PresetNames = 'default-preset';\n let presetOptions: Record<string, unknown> = {};\n let hasExplicitPresetOptions = false;\n\n if (Array.isArray(_renderPreset)) {\n presetName = _renderPreset[0];\n presetOptions = { ...(_renderPreset[1] || {}) };\n hasExplicitPresetOptions = true;\n } else if (typeof _renderPreset === 'string') {\n presetName = _renderPreset;\n }\n\n if (debug) {\n presetOptions.debug = debug;\n hasExplicitPresetOptions = true;\n }\n\n if (presetName === 'default-preset') {\n const injectedNavigatorRendererOptions: Record<string, unknown> = {};\n if (resolvedNavigatorOptions.style) {\n injectedNavigatorRendererOptions.style = resolvedNavigatorOptions.style;\n }\n if (resolvedNavigatorOptions.zoneWindow) {\n injectedNavigatorRendererOptions.zoneWindow = resolvedNavigatorOptions.zoneWindow;\n }\n if (debug) {\n injectedNavigatorRendererOptions.onDebugEvent = handleNavigatorDebugEvent;\n }\n\n if (Object.keys(injectedNavigatorRendererOptions).length > 0) {\n const existingNavigatorRendererOptions = (presetOptions.navigatorRendererOptions || {}) as Record<\n string,\n unknown\n >;\n presetOptions.navigatorRendererOptions = {\n ...existingNavigatorRendererOptions,\n ...injectedNavigatorRendererOptions,\n };\n hasExplicitPresetOptions = true;\n }\n }\n\n if (hasExplicitPresetOptions) {\n return [presetName, presetOptions as any] as Presets;\n }\n\n return _renderPreset || 'default-preset';\n }, [\n _renderPreset,\n debug,\n handleNavigatorDebugEvent,\n resolvedNavigatorOptions.style,\n resolvedNavigatorOptions.zoneWindow,\n ]);\n\n // This is an HTML element that sits above the Canvas element that is passed to the controller.\n // Additional non-canvas drawn elements can be placed here and positioned. CSS is applied to this\n // element by this component to absolutely position it. The overlay is updated if the \"bounds\" change\n // on the parent element and matches the size of it.\n\n // This measures the height and width of the Atlas element.\n const [_ref, bounds, forceRefresh] = useMeasure({ scroll: true });\n const outerContainerRef = useRef<HTMLDivElement>();\n const ref = (component: HTMLDivElement) => {\n outerContainerRef.current = component;\n _ref(component);\n };\n\n const handleWebGLFallback = useCallback(\n (event: AtlasWebGLFallbackEvent) => {\n if (fallbackLockedRef.current) {\n return;\n }\n\n fallbackLockedRef.current = true;\n if (currentRuntimeRef.current) {\n // compatibility: pendingRestoreViewportRef.current = currentRuntimeRef.current.getViewport();\n pendingRestoreViewportRef.current = currentRuntimeRef.current.getViewport();\n }\n setActiveWebGL(false);\n if (onWebGLFallback) {\n onWebGLFallback(event);\n }\n },\n [onWebGLFallback]\n );\n\n const handleCreated = useCallback(\n (ctx: Preset) => {\n if (pendingRestoreViewportRef.current) {\n ctx.runtime.setViewport(pendingRestoreViewportRef.current);\n ctx.runtime.updateNextFrame();\n pendingRestoreViewportRef.current = null;\n }\n\n if (onCreated) {\n return onCreated(ctx);\n }\n },\n [onCreated]\n );\n\n const [presetName, preset, viewport, refs] = usePreset(renderPreset, {\n width: restProps.width,\n height: restProps.height,\n forceRefresh,\n controllerConfig,\n interactionMode,\n unstable_webglRenderer: activeWebGL,\n onWebGLFallback: handleWebGLFallback,\n onImageError,\n webglFallbackOnImageLoadError,\n webglReadiness,\n imageLoading,\n runtimeOptions,\n });\n\n useEffect(() => {\n if (!preset) {\n return;\n }\n return registerAtlasRuntime(preset);\n }, [preset]);\n\n // This holds the class name for the container. This is changes when the\n // editing mode changes.\n const [containerClassName, setContainerClassName] = useState('');\n\n useEffect(() => {\n setMode(_mode);\n }, [_mode]);\n\n useEffect(() => {\n setIsReady(false);\n currentRuntimeRef.current = preset ? preset.runtime : null;\n readyResetBaselineRef.current = undefined;\n lastReadyNotifiedCycleRef.current = undefined;\n }, [preset]);\n\n useEffect(() => {\n if (!unstable_webglRenderer) {\n setActiveWebGL(false);\n return;\n }\n\n if (!fallbackLockedRef.current) {\n setActiveWebGL(true);\n }\n }, [unstable_webglRenderer]);\n\n useEffect(() => {\n if (!preset || !onReady) {\n return;\n }\n\n const runtime = preset.runtime;\n return runtime.world.addLayoutSubscriber((type) => {\n // compatibility: if (type !== 'ready')\n if (type !== 'ready') {\n return;\n }\n\n const readyState = runtime.getReadyState();\n if (lastReadyNotifiedCycleRef.current === readyState.cycle) {\n return;\n }\n lastReadyNotifiedCycleRef.current = readyState.cycle;\n if (!readyState.timestamp) {\n return;\n }\n onReady({\n runtimeId: runtime.id,\n cycle: readyState.cycle,\n reason: readyState.reason,\n renderer: getReadyRenderer(runtime.renderer),\n timestamp: readyState.timestamp,\n });\n });\n }, [preset, onReady]);\n\n useEffect(() => {\n if (!preset) {\n return;\n }\n if (typeof readyResetKey === 'undefined') {\n readyResetBaselineRef.current = undefined;\n return;\n }\n\n if (typeof readyResetBaselineRef.current === 'undefined') {\n readyResetBaselineRef.current = readyResetKey;\n return;\n }\n\n if (readyResetBaselineRef.current !== readyResetKey) {\n readyResetBaselineRef.current = readyResetKey;\n lastReadyNotifiedCycleRef.current = undefined;\n // compatibility: preset.runtime.resetReadyState('ready-reset-key-change');\n preset.runtime.resetReadyState('ready-reset-key-change');\n }\n }, [preset, readyResetKey]);\n\n // This changes the mutable state object with the position (top/left/width/height) of the\n // canvas element on the page. This is used in the editing tools such as BoxDraw for comparing\n // positions.\n useEffect(() => {\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n }, [preset, bounds]);\n\n useEffect(() => {\n if (!preset) {\n return;\n }\n preset.runtime.setOptions(runtimeOptions || {});\n }, [preset, runtimeOptions]);\n\n // This changes the mode in the state object when the prop passed in changes. This will\n // be picked up by the renderer on the next method. There is not current way to detect this change.\n // @todo create a mode change event.\n useEffect(() => {\n if (preset && preset.runtime) {\n preset.runtime.mode = mode;\n }\n if (isReady && preset) {\n preset.ready = true;\n }\n }, [preset, isReady, mode]);\n\n useEffect(() => {\n if (preset) {\n // Home cover handled separately.\n if (!homeCover) {\n // PDF scroll mode owns viewport positioning and must not be overridden by world goHome.\n preset.runtime.manualHomePosition = interactionMode === 'pdf-scroll-zone' || !!homePosition;\n preset.runtime.setHomePosition(homePosition);\n }\n }\n }, [preset, homeCover, homePosition, interactionMode]);\n\n // Home padding: apply to runtime when preset or prop changes.\n useEffect(() => {\n if (preset) {\n preset.runtime.setHomePaddingPx(homePaddingPx);\n }\n }, [preset, homePaddingPx]);\n\n // When the width and height change this will resize the viewer and then reset the view to fit the element.\n // @todo improve or make configurable.\n // @todo resize event.\n useEffect(() => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n const didDimensionChange =\n viewport.current.width !== restProps.width || viewport.current.height !== restProps.height;\n\n if (didDimensionChange) {\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n viewport.current.didUpdate = true;\n rt.updateNextFrame();\n }\n }\n }, [preset, restProps.width, restProps.height, viewport]);\n\n useEffect(() => {\n if (filters && preset) {\n const rt: Runtime = preset.runtime;\n let didUpdate = false;\n rt.hookOptions.enableFilters = true;\n\n for (const property of filterProperties) {\n if (filters[property]) {\n if (filters[property] !== preset.runtime.hookOptions.filters[property]) {\n rt.hookOptions.filters[property] = filters[property] as number;\n didUpdate = true;\n }\n } else if (rt.hookOptions.filters[property]) {\n rt.hookOptions.filters[property] = 0;\n didUpdate = true;\n }\n }\n\n if (didUpdate) {\n rt.updateNextFrame();\n }\n } else {\n if (preset) {\n const rt: Runtime = preset.runtime;\n for (const property of filterProperties) {\n rt.hookOptions.filters[property] = 0;\n }\n rt.hookOptions.enableFilters = false;\n rt.updateNextFrame();\n }\n }\n }, [preset, filters]);\n\n function recalculateHomeCover() {\n if (preset) {\n if (preset.overlay) {\n preset.overlay.style.width = `${bounds.width}px`;\n preset.overlay.style.height = `${bounds.height}px`;\n }\n\n if (preset.container) {\n preset.container.style.width = `${bounds.width}px`;\n preset.container.style.height = `${bounds.height}px`;\n }\n\n if (homeCover) {\n const w = preset.runtime.world.width;\n const h = preset.runtime.world.height;\n const ratio = w / h;\n\n const viewportWidth = viewport.current.width;\n const viewportHeight = viewport.current.height;\n let viewportRatio = viewportWidth / viewportHeight;\n\n if (ratio > viewportRatio) {\n viewportRatio = viewportHeight / viewportWidth;\n // Viewport too tall.\n preset.runtime.manualHomePosition = true;\n let x = (w - h / viewportRatio) / 2;\n if (homeCover === 'start') {\n x = 0;\n }\n if (homeCover === 'end') {\n x = w - h / viewportRatio;\n }\n\n const newHomePosition = {\n x,\n y: 0,\n width: h / viewportRatio,\n height: h,\n };\n\n preset.runtime.setHomePosition(newHomePosition);\n } else {\n let y = (h - w / viewportRatio) / 2;\n if (homeCover === 'start') {\n y = 0;\n }\n if (homeCover === 'end') {\n y = h - w / viewportRatio;\n }\n\n // Viewport too wide. Need to make the home position cover the entire width.\n preset.runtime.manualHomePosition = true;\n\n const newHomePosition = {\n x: 0,\n y,\n width: w,\n height: w / viewportRatio,\n };\n\n preset.runtime.setHomePosition(newHomePosition);\n }\n if (homeOnResize) {\n preset.runtime.goHome({});\n }\n }\n }\n }\n\n // When the bounds of the container change, we need to reflect those changes in the overlay.\n // @todo move to canvas.\n useIsomorphicLayoutEffect(() => {\n recalculateHomeCover();\n }, [preset, props.runtimeOptions?.maxOverZoom, bounds.height, bounds.width, homeCover]);\n\n // When the window resizes we need to recalculate the width.\n // @todo possibly move to controller.\n useIsomorphicLayoutEffect(() => {\n const windowResizeCallback = () => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n if (viewport.current.width !== restProps.width || viewport.current.height !== restProps.height) {\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n viewport.current.didUpdate = true;\n }\n }\n };\n\n window.addEventListener('resize', windowResizeCallback);\n\n return () => window.removeEventListener('resize', windowResizeCallback);\n }, [preset, restProps.height, restProps.width]);\n\n const getNavigatorRenderer = () => {\n if (!preset) {\n return undefined;\n }\n const renderer = preset.renderer as {\n renderers?: Array<{ invalidateWorldLayer?: () => void }>;\n };\n if (!Array.isArray(renderer.renderers)) {\n return undefined;\n }\n return renderer.renderers.find((item) => typeof item.invalidateWorldLayer === 'function');\n };\n\n const getRendererDpi = useCallback(() => {\n if (!preset) {\n return window.devicePixelRatio || 1;\n }\n const renderer = preset.renderer as {\n dpi?: number;\n renderers?: Array<{ dpi?: number }>;\n };\n const primaryRenderer = Array.isArray(renderer.renderers) ? renderer.renderers[0] : renderer;\n const dpi = primaryRenderer?.dpi;\n if (typeof dpi === 'number' && Number.isFinite(dpi) && dpi > 0) {\n return dpi;\n }\n return window.devicePixelRatio || 1;\n }, [preset]);\n\n const getNavigatorRegion = useCallback(\n (runtime: Runtime) =>\n getNavigatorWorldRegion(runtime.world, {\n target: runtime.getViewport(),\n zoneWindow: resolvedNavigatorOptions.zoneWindow,\n }),\n [resolvedNavigatorOptions.zoneWindow]\n );\n\n const shouldHideNavigatorAtHome = useCallback(\n (runtime: Runtime) => runtime.isViewportAtHome({ cover: !!homeCover, tolerance: NAVIGATOR_HOME_TOLERANCE }),\n [homeCover, homePaddingPx]\n );\n\n const recalculateNavigatorDimensions = () => {\n if (preset && preset.navigator) {\n const region = getNavigatorRegion(preset.runtime);\n const wHeight = region.height;\n const wWidth = region.width;\n\n const ratio = getRendererDpi();\n const safeWorldWidth = Math.max(1, wWidth);\n const safeWorldHeight = Math.max(1, wHeight);\n const configuredWidth = Math.max(1, resolvedNavigatorOptions.width);\n const maxNavigatorHeight = Math.max(1, restProps.height - 20);\n let canvasWidth = configuredWidth;\n let canvasHeight = (configuredWidth / safeWorldWidth) * safeWorldHeight;\n\n if (canvasHeight > maxNavigatorHeight) {\n const scale = maxNavigatorHeight / canvasHeight;\n canvasHeight = maxNavigatorHeight;\n canvasWidth = Math.max(1, configuredWidth * scale);\n }\n\n preset.navigator.width = canvasWidth * ratio;\n preset.navigator.height = canvasHeight * ratio;\n preset.navigator.style.width = canvasWidth + 'px';\n preset.navigator.style.height = canvasHeight + 'px';\n\n const navigatorRenderer = getNavigatorRenderer();\n if (navigatorRenderer && navigatorRenderer.invalidateWorldLayer) {\n navigatorRenderer.invalidateWorldLayer();\n }\n }\n };\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n recalculateNavigatorDimensions();\n const rt = preset.runtime;\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'repaint') {\n const navigatorRenderer = getNavigatorRenderer();\n if (navigatorRenderer && navigatorRenderer.invalidateWorldLayer) {\n navigatorRenderer.invalidateWorldLayer();\n }\n }\n if (type === 'recalculate-world-size' || type === 'zone-changed') {\n recalculateNavigatorDimensions();\n recalculateHomeCover();\n if (\n type === 'recalculate-world-size' &&\n (viewport.current.width !== restProps.width || viewport.current.height !== restProps.height)\n ) {\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n }\n }\n });\n }\n return () => {\n // no-op\n };\n }, [preset, restProps.width, restProps.height, resolvedNavigatorOptions.width, getNavigatorRegion, getRendererDpi]);\n\n useEffect(() => {\n if (!preset || !enableNavigator) {\n setIsNavigatorHiddenAtHome(false);\n return;\n }\n\n const runtime = preset.runtime;\n const syncNavigatorVisibility = () => {\n const hideAtHome = shouldHideNavigatorAtHome(runtime);\n setIsNavigatorHiddenAtHome((prev) => (prev === hideAtHome ? prev : hideAtHome));\n };\n\n syncNavigatorVisibility();\n return runtime.world.addLayoutSubscriber(() => {\n syncNavigatorVisibility();\n });\n }, [preset, enableNavigator, shouldHideNavigatorAtHome]);\n\n const Canvas = useCallback(\n function Canvas(props: { children: React.ReactElement }): JSX.Element {\n const activate = () => {\n setIsReady(true);\n };\n\n useEffect(() => {\n if (!preset) {\n return;\n }\n\n if (interactionMode !== 'pdf-scroll-zone') {\n preset.runtime.goHome();\n }\n\n const result = handleCreated && handleCreated(preset);\n return void (result && result.then ? result.then(activate) : activate());\n }, []);\n\n return props.children;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [preset, handleCreated, interactionMode]\n );\n\n useEffect(() => {\n if (preset) {\n const rt = preset.runtime;\n if (resetWorldOnChange) {\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'recalculate-world-size' && interactionMode !== 'pdf-scroll-zone') {\n rt.goHome();\n }\n });\n }\n }\n return () => {\n // no-op\n };\n }, [preset, resetWorldOnChange, interactionMode]);\n\n useEffect(() => {\n if (preset) {\n const rt = preset.runtime;\n return rt.registerHook('useBeforeFrame', () => {\n if (viewport.current.didUpdate && preset.canvas) {\n const ratio = getRendererDpi();\n const canvasWidth = viewport.current.width;\n const canvasHeight = viewport.current.height;\n\n preset.canvas.width = canvasWidth * ratio;\n preset.canvas.height = canvasHeight * ratio;\n preset.canvas.style.width = canvasWidth + 'px';\n preset.canvas.style.height = canvasHeight + 'px';\n\n const context = preset.canvas.getContext('2d');\n if (context) {\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.scale(ratio, ratio);\n }\n\n if (preset.parityCanvas) {\n preset.parityCanvas.width = canvasWidth * ratio;\n preset.parityCanvas.height = canvasHeight * ratio;\n preset.parityCanvas.style.width = canvasWidth + 'px';\n preset.parityCanvas.style.height = canvasHeight + 'px';\n\n const parityContext = preset.parityCanvas.getContext('2d');\n if (parityContext) {\n parityContext.setTransform(1, 0, 0, 1, 0, 0);\n parityContext.scale(ratio, ratio);\n }\n }\n\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n\n viewport.current.didUpdate = false;\n }\n });\n }\n return () => {\n // no-op\n };\n }, [preset, resetWorldOnChange, getRendererDpi]);\n\n // @todo move to controller.\n useEffect(() => {\n const keyupSpace = () => {\n if (preset) {\n setMode('sketch');\n setContainerClassName('mode-sketch');\n }\n window.removeEventListener('keyup', keyupSpace);\n };\n\n const keydownSpace = (e: KeyboardEvent) => {\n if (e.code === 'Space' && preset && preset.runtime.mode === 'sketch') {\n const tagName = (e.target as any)?.tagName?.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea') return;\n // Check if content-editable\n if ((e.target as any)?.isContentEditable) return;\n\n e.preventDefault();\n setMode('explore');\n setContainerClassName('mode-explore');\n window.addEventListener('keyup', keyupSpace);\n }\n };\n\n window.addEventListener('keydown', keydownSpace);\n\n return () => {\n // no-op\n window.removeEventListener('keydown', keydownSpace);\n window.removeEventListener('keyup', keyupSpace);\n };\n }, [preset]);\n\n const markNavigatorActive = useCallback(() => {\n if (!enableNavigator || !resolvedNavigatorOptions.idleFade) {\n return;\n }\n setIsNavigatorIdle(false);\n if (typeof navigatorIdleTimer.current !== 'undefined') {\n window.clearTimeout(navigatorIdleTimer.current);\n }\n navigatorIdleTimer.current = window.setTimeout(() => {\n if (!navigatorDraggingRef.current) {\n setIsNavigatorIdle(true);\n }\n }, resolvedNavigatorOptions.idleMs);\n }, [enableNavigator, resolvedNavigatorOptions.idleFade, resolvedNavigatorOptions.idleMs]);\n\n useEffect(\n () => () => {\n if (typeof navigatorIdleTimer.current !== 'undefined') {\n window.clearTimeout(navigatorIdleTimer.current);\n navigatorIdleTimer.current = undefined;\n }\n },\n []\n );\n\n useEffect(() => {\n if (!preset?.canvas || !enableNavigator || !resolvedNavigatorOptions.idleFade) {\n return;\n }\n\n const element = preset.canvas;\n const activate = () => markNavigatorActive();\n const eventNames = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'wheel',\n ] as const;\n\n for (const eventName of eventNames) {\n element.addEventListener(eventName, activate, { passive: true });\n }\n markNavigatorActive();\n\n return () => {\n for (const eventName of eventNames) {\n element.removeEventListener(eventName, activate);\n }\n };\n }, [preset, enableNavigator, resolvedNavigatorOptions.idleFade, markNavigatorActive]);\n\n useEffect(() => {\n if (!preset?.navigator || !enableNavigator) {\n return;\n }\n\n const navigatorCanvas = preset.navigator;\n const runtime = preset.runtime;\n const drag = {\n active: false,\n pointerId: -1,\n offsetX: 0,\n offsetY: 0,\n startClientX: 0,\n startClientY: 0,\n startWorldX: 0,\n startWorldY: 0,\n };\n\n const setDragging = (dragging: boolean) => {\n navigatorDraggingRef.current = dragging;\n setIsNavigatorDragging(dragging);\n };\n\n const getWorldPointFromEvent = (event: PointerEvent) => {\n const rect = navigatorCanvas.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) {\n return { x: 0, y: 0 };\n }\n const localX = event.clientX - rect.left;\n const localY = event.clientY - rect.top;\n const region = getNavigatorRegion(runtime);\n const transform = getNavigatorWorldTransform(\n region.width,\n region.height,\n rect.width,\n rect.height,\n region.x,\n region.y\n );\n return navigatorToWorldPoint(transform, localX, localY);\n };\n\n const moveViewport = (\n worldX: number,\n worldY: number,\n {\n preserveOffset = true,\n constrainAfterMove = false,\n }: { preserveOffset?: boolean; constrainAfterMove?: boolean } = {}\n ) => {\n const viewport = runtime.getViewport();\n const nextX = preserveOffset ? worldX - drag.offsetX : worldX - viewport.width / 2;\n const nextY = preserveOffset ? worldY - drag.offsetY : worldY - viewport.height / 2;\n const proposed = DnaFactory.singleBox(viewport.width, viewport.height, nextX, nextY);\n const [, constrained] = runtime.constrainBounds(proposed, { ref: true });\n\n runtime.setViewport({\n x: constrained[1],\n y: constrained[2],\n width: constrained[3] - constrained[1],\n height: constrained[4] - constrained[2],\n });\n runtime.updateControllerPosition();\n runtime.updateNextFrame();\n\n if (constrainAfterMove) {\n runtime.world.constraintBounds(true);\n }\n };\n const getZoneAtWorldPoint = (worldX: number, worldY: number) => {\n const visibleZoneIds = getNavigatorVisibleZoneIdSet(runtime.world, {\n target: runtime.getViewport(),\n zoneWindow: resolvedNavigatorOptions.zoneWindow,\n });\n for (const zone of runtime.world.zones) {\n if (visibleZoneIds && !visibleZoneIds.has(zone.id)) {\n continue;\n }\n zone.recalculateBounds();\n if (zone.points[0] === 0) {\n continue;\n }\n if (\n worldX >= zone.points[1] &&\n worldX <= zone.points[3] &&\n worldY >= zone.points[2] &&\n worldY <= zone.points[4]\n ) {\n return zone;\n }\n }\n return undefined;\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (event.button !== 0) {\n return;\n }\n\n markNavigatorActive();\n const worldPoint = getWorldPointFromEvent(event);\n const viewport = runtime.getViewport();\n const isInsideViewport =\n worldPoint.x >= viewport.x &&\n worldPoint.y >= viewport.y &&\n worldPoint.x <= viewport.x + viewport.width &&\n worldPoint.y <= viewport.y + viewport.height;\n\n drag.active = true;\n drag.pointerId = event.pointerId;\n drag.startClientX = event.clientX;\n drag.startClientY = event.clientY;\n drag.startWorldX = worldPoint.x;\n drag.startWorldY = worldPoint.y;\n\n if (isInsideViewport) {\n drag.offsetX = worldPoint.x - viewport.x;\n drag.offsetY = worldPoint.y - viewport.y;\n } else {\n drag.offsetX = viewport.width / 2;\n drag.offsetY = viewport.height / 2;\n moveViewport(worldPoint.x, worldPoint.y, {\n preserveOffset: true,\n constrainAfterMove: true,\n });\n }\n\n setDragging(true);\n navigatorCanvas.setPointerCapture(event.pointerId);\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onPointerMove = (event: PointerEvent) => {\n if (!drag.active || event.pointerId !== drag.pointerId) {\n return;\n }\n const worldPoint = getWorldPointFromEvent(event);\n moveViewport(worldPoint.x, worldPoint.y, {\n preserveOffset: true,\n });\n markNavigatorActive();\n event.preventDefault();\n event.stopPropagation();\n };\n\n const finishDrag = (event: PointerEvent) => {\n if (!drag.active || event.pointerId !== drag.pointerId) {\n return;\n }\n const worldPoint = getWorldPointFromEvent(event);\n const dragDistance = Math.hypot(event.clientX - drag.startClientX, event.clientY - drag.startClientY);\n let didNavigateToZone = false;\n if (dragDistance < 4) {\n const zone = getZoneAtWorldPoint(drag.startWorldX, drag.startWorldY);\n if (zone) {\n didNavigateToZone = runtime.goToZone(zone.id);\n if (didNavigateToZone) {\n runtime.updateNextFrame();\n }\n }\n }\n drag.active = false;\n drag.pointerId = -1;\n setDragging(false);\n if (!didNavigateToZone) {\n runtime.world.constraintBounds(true);\n }\n if (navigatorCanvas.hasPointerCapture(event.pointerId)) {\n navigatorCanvas.releasePointerCapture(event.pointerId);\n }\n markNavigatorActive();\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n if (!drag.active || event.pointerId !== drag.pointerId) {\n return;\n }\n drag.active = false;\n drag.pointerId = -1;\n setDragging(false);\n if (navigatorCanvas.hasPointerCapture(event.pointerId)) {\n navigatorCanvas.releasePointerCapture(event.pointerId);\n }\n markNavigatorActive();\n };\n\n navigatorCanvas.addEventListener('pointerdown', onPointerDown);\n navigatorCanvas.addEventListener('pointermove', onPointerMove);\n navigatorCanvas.addEventListener('pointerup', finishDrag);\n navigatorCanvas.addEventListener('pointercancel', onPointerCancel);\n\n return () => {\n setDragging(false);\n navigatorCanvas.removeEventListener('pointerdown', onPointerDown);\n navigatorCanvas.removeEventListener('pointermove', onPointerMove);\n navigatorCanvas.removeEventListener('pointerup', finishDrag);\n navigatorCanvas.removeEventListener('pointercancel', onPointerCancel);\n };\n }, [preset, enableNavigator, markNavigatorActive, getNavigatorRegion]);\n\n const { height: _, width: __, ...canvasProps } = restProps;\n const widthClassName = useClassname([restProps.width, restProps.height]);\n let isInteractive = true;\n // if we have a render preset and that render preset sets interactive to false, then... disable it\n if (\n renderPreset &&\n Array.isArray(renderPreset) &&\n renderPreset.length > 1 &&\n (renderPreset[1] as any).interactive === false\n ) {\n isInteractive = false;\n }\n\n // use css custom prop if set, otherwise background prop, or default\n background = background ?? '#000';\n if (outerContainerRef.current) {\n const computed = getComputedStyle(outerContainerRef.current);\n background = computed.getPropertyValue('--atlas-background') || background;\n }\n\n const autoDevToolsProps = typeof devTools === 'object' ? devTools : undefined;\n const navigatorContainerStyle = useMemo(\n () =>\n ({\n '--atlas-navigator-fade-duration': `${resolvedNavigatorOptions.fadeDurationMs}ms`,\n '--atlas-navigator-opacity-active': `${resolvedNavigatorOptions.opacityActive}`,\n '--atlas-navigator-opacity-idle': `${resolvedNavigatorOptions.opacityIdle}`,\n } as React.CSSProperties),\n [\n resolvedNavigatorOptions.fadeDurationMs,\n resolvedNavigatorOptions.opacityActive,\n resolvedNavigatorOptions.opacityIdle,\n ]\n );\n\n return (\n <Container\n ref={ref}\n className={[\n 'atlas',\n `atlas-interaction-${interactionMode}`,\n hideInlineStyle ? '' : `atlas-width-${widthClassName}`,\n containerClassName,\n className,\n `atlas-${presetName}`,\n ]\n .filter(Boolean)\n .join(' ')\n .trim()}\n style={{\n ...containerStyle,\n ...(hideInlineStyle ? {} : { width: restProps.width, height: restProps.height }),\n }}\n >\n {presetName === 'static-preset' ? (\n <Container className=\"atlas-static-container\" ref={refs.container as any} tabIndex={0} {...containerProps} />\n ) : (\n <>\n <canvas\n className=\"atlas-canvas\"\n /*@ts-expect-error*/\n part=\"atlas-canvas\"\n tabIndex={0}\n {...canvasProps}\n {...containerProps}\n ref={refs.canvas as any}\n data-background={background}\n />\n {activeWebGL ? (\n <canvas\n className=\"atlas-parity-canvas\"\n /*@ts-expect-error*/\n part=\"atlas-parity-canvas\"\n aria-hidden=\"true\"\n data-background=\"transparent\"\n ref={refs.parityCanvas as any}\n />\n ) : null}\n </>\n )}\n\n <Container\n className={['atlas-overlay', isInteractive ? 'atlas-overlay--interactive' : '']\n .filter(Boolean)\n .join(' ')\n .trim()}\n style={{ ...(overlayStyle || {}) }}\n ref={refs.overlay as any}\n >\n {unstable_noReconciler ? (\n <Canvas>\n <BoundsContext.Provider value={bounds}>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </BoundsContext.Provider>\n </Canvas>\n ) : (\n <AtlasWithReconciler\n bounds={bounds}\n preset={preset}\n mode={mode}\n interactionMode={interactionMode}\n setIsReady={setIsReady}\n onCreated={handleCreated}\n >\n {children}\n </AtlasWithReconciler>\n )}\n </Container>\n {enableNavigator ? (\n <Container\n className={[\n 'atlas-navigator',\n isNavigatorHiddenAtHome ? 'atlas-navigator--hidden-at-home' : '',\n resolvedNavigatorOptions.idleFade && isNavigatorIdle ? 'atlas-navigator--idle' : '',\n isNavigatorDragging ? 'atlas-navigator--dragging' : '',\n ]\n .filter(Boolean)\n .join(' ')\n .trim()}\n style={navigatorContainerStyle}\n >\n <canvas\n className=\"atlas-navigator-canvas\"\n /*@ts-expect-error*/\n part=\"atlas-navigator-canvas\"\n ref={refs.navigator as any}\n />\n </Container>\n ) : null}\n {/* compatibility: {devTools ? <DevTools */}\n {devTools ? (\n <DevTools {...autoDevToolsProps} runtimeId={autoDevToolsProps?.runtimeId || preset?.runtime.id} />\n ) : null}\n {hideInlineStyle ? (\n // We still need this, even if inline styles are hidden, this classname is unique to this viewport.\n <style>{`.atlas-width-${widthClassName} { width: ${restProps.width}px; height: ${restProps.height}px; }`}</style>\n ) : (\n <style>{`\n .atlas { position: relative; display: flex; background: ${background}; z-index: var(--atlas-z-index, 10); -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\n .atlas-width-${widthClassName} { width: ${restProps.width}px; height: ${restProps.height}px; }\n .atlas-canvas { flex: 1 1 0px; }\n .atlas-interaction-pdf-scroll-zone .atlas-canvas,\n .atlas-interaction-pdf-scroll-zone .atlas-static-container { touch-action: none; }\n .atlas-parity-canvas { position: absolute; top: 0; left: 0; pointer-events: none; }\n .atlas-canvas:focus, .atlas-static-container:focus { outline: none }\n .atlas-canvas:focus-visible, .atlas-canvas-container:focus-visible { outline: var(--atlas-focus, 2px solid darkorange) }\n .atlas-static-preset { touch-action: inherit; }\n .atlas-static-container { position: relative; overflow: hidden; flex: 1 1 0px; }\n .atlas-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow: hidden; }\n /** setting the pointer events to none means that Atlas will own the touch and mousewheel events **/\n .atlas-overlay--interactive { pointer-events: none; }\n .atlas-static-image { position: absolute; user-select: none; transform-origin: 0px 0px; }\n .atlas-navigator { position: absolute; top: var(--atlas-navigator-top, 10px); right: var(--atlas-navigator-right, 10px); left: var(--atlas-navigator-left); bottom: var(--atlas-navigator-bottom); opacity: var(--atlas-navigator-opacity-active, .94); transition: opacity var(--atlas-navigator-fade-duration, 250ms) ease; z-index: var(--atlas-navigator-z-index, 30); }\n .atlas-navigator--idle { opacity: var(--atlas-navigator-opacity-idle, .4); }\n .atlas-navigator--hidden-at-home { opacity: 0; pointer-events: none; }\n .atlas-navigator-canvas { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; border-radius: var(--atlas-navigator-radius, 6px); border: var(--atlas-navigator-border, 1px solid rgba(0, 0, 0, 0.7)); box-shadow: var(--atlas-navigator-shadow, 0 6px 16px rgba(2, 6, 23, 0.45)); box-sizing: border-box; }\n .atlas-navigator--dragging .atlas-navigator-canvas { cursor: grabbing; }\n `}</style>\n )}\n {htmlChildren}\n </Container>\n );\n});\n","export function toPx(str: string | number) {\n if (Number(str) == str) {\n return `${str}px`;\n }\n\n return str;\n}\n","import { Atlas, AtlasProps } from '../Atlas';\nimport React, { memo, useEffect, useId, useMemo } from 'react';\nimport useMeasure from 'react-use-measure';\nimport { Container } from './Container';\nimport { toPx } from '../utility/to-px';\n\nexport const AtlasAuto: React.FC<\n AtlasProps & {\n height?: number | string;\n width?: number | string;\n resizeHash?: number;\n containerProps?: any;\n aspectRatio?: number;\n }\n> = memo(function AtlasAuto({ resizeHash, aspectRatio, containerProps = {}, htmlChildren, ...props }) {\n const [ref, _bounds, forceRefresh] = useMeasure();\n const autoId = useId();\n\n const { height, width, ...restProps } = props as any;\n\n useEffect(() => {\n forceRefresh();\n }, [width, height, resizeHash, forceRefresh]);\n\n const bounds = useMemo(() => {\n if (!aspectRatio) {\n return _bounds;\n }\n\n // Need to find the case where this is not the solution.\n return {\n width: _bounds.width,\n height: _bounds.width * (1 / aspectRatio),\n };\n }, [_bounds, aspectRatio]);\n\n const autoClassName = useMemo(() => `atlas-auto-${autoId.replace(/[^a-zA-Z0-9_-]/g, '')}`, [autoId]);\n const combinedClassName = useMemo(\n () => [autoClassName, containerProps.className].filter(Boolean).join(' ').trim(),\n [autoClassName, containerProps.className]\n );\n const inlineStyle = useMemo(\n () => `.${autoClassName} {\n display: var(--atlas-container-display, block);\n flex: var(--atlas-container-flex, none);\n width: var(--atlas-container-width, ${toPx(width ?? '100%')});\n height: var(--atlas-container-height, ${toPx(height ? height : aspectRatio ? bounds.height : 512)})\n }`,\n [aspectRatio, autoClassName, bounds.height, height, width]\n );\n\n return (\n <Container ref={ref} className={combinedClassName} {...containerProps}>\n {bounds.width ? (\n <Atlas width={bounds.width || 100} height={bounds.height || 100} {...restProps}>\n {props.children}\n </Atlas>\n ) : null}\n {props.hideInlineStyle ? null : <style>{inlineStyle}</style>}\n {htmlChildren}\n </Container>\n );\n});\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useAfterFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useAfterFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useAtlas } from './use-atlas';\n\nexport const useCanvas = () => {\n const atlas = useAtlas();\n return atlas && atlas.canvas ? atlas.canvas : undefined;\n};\n","import { useContext } from 'react';\nimport { BoundsContext } from '../components/AtlasContext';\n\nexport function useCanvasPosition() {\n return useContext(BoundsContext);\n}\n","import React, { ReactNode, useEffect, useRef, useState } from 'react';\nimport { useAfterFrame } from '../hooks/use-after-frame';\nimport { useFrame } from '../hooks/use-frame';\nimport { useCanvas } from '../hooks/use-canvas';\nimport { useRuntime } from '../hooks/use-runtime';\nimport { useMode } from '../hooks/use-mode';\nimport { useCanvasPosition } from '../hooks/use-canvas-position';\n\nexport const DrawBox: React.FC<{\n children?: ReactNode;\n onCreate: (bounds: { x: number; y: number; width: number; height: number }) => void;\n}> = ({ onCreate }) => {\n const mousePosition = useRef({ x: 0, y: 0 });\n const canvas = useCanvas();\n const canvasPosition = useCanvasPosition();\n const runtime = useRuntime();\n const [firstCorner, setFirstCorner] = useState<{ x: number; y: number } | undefined>();\n const [secondCorner, setSecondCorner] = useState<{ x: number; y: number } | undefined>();\n const mode = useMode();\n\n useFrame(() => {\n if (runtime && firstCorner && !secondCorner) {\n runtime.pendingUpdate = true;\n }\n }, [firstCorner, secondCorner]);\n\n useAfterFrame(() => {\n if (firstCorner && canvas && runtime) {\n const ctx = canvas.getContext('2d');\n if (ctx) {\n const { x, y, width, height } = runtime.worldToViewer(\n firstCorner.x,\n firstCorner.y,\n (secondCorner ? secondCorner.x : mousePosition.current.x) - firstCorner.x,\n (secondCorner ? secondCorner.y : mousePosition.current.y) - firstCorner.y\n );\n\n ctx.lineWidth = secondCorner ? 3 : 1;\n ctx.strokeStyle = '#fff';\n ctx.strokeRect(x, y, width, height);\n\n ctx.lineWidth = secondCorner ? 3 : 1;\n ctx.strokeStyle = '#000';\n ctx.strokeRect(x + 1, y + 1, width - 2, height - 2);\n }\n }\n }, [firstCorner, secondCorner]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (canvasPosition && runtime) {\n const { x, y } = runtime.viewerToWorld(e.clientX - canvasPosition.left, e.clientY - canvasPosition.top);\n mousePosition.current.x = ~~x;\n mousePosition.current.y = ~~y;\n }\n };\n if (canvas) {\n canvas.addEventListener('mousemove', cb);\n return () => canvas.removeEventListener('mousemove', cb);\n }\n return () => {\n // no-op\n };\n }, [canvasPosition, canvas, runtime]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (mode === 'sketch') {\n setFirstCorner({ x: Math.round(mousePosition.current.x), y: Math.round(mousePosition.current.y) });\n setSecondCorner(undefined);\n }\n };\n if (canvas) {\n canvas.addEventListener('mousedown', cb);\n\n return () => canvas.removeEventListener('mousedown', cb);\n }\n return () => {\n // no-op\n };\n }, [canvas, mode]);\n\n useEffect(() => {\n const cb = (e: MouseEvent) => {\n if (firstCorner && !secondCorner) {\n setSecondCorner({ x: Math.round(mousePosition.current.x), y: Math.round(mousePosition.current.y) });\n }\n };\n\n if (canvas) {\n canvas.addEventListener('mouseup', cb);\n\n return () => canvas.removeEventListener('mouseup', cb);\n }\n return () => {\n // no-op\n };\n }, [canvas, firstCorner, secondCorner]);\n\n useEffect(() => {\n if (firstCorner && secondCorner) {\n onCreate({\n x: Math.min(firstCorner.x, secondCorner.x),\n y: Math.min(firstCorner.y, secondCorner.y),\n width: Math.abs(secondCorner.x - firstCorner.x),\n height: Math.abs(secondCorner.y - firstCorner.y),\n });\n }\n }, [firstCorner, onCreate, secondCorner]);\n\n return null;\n};\n","import React, { ReactNode, useLayoutEffect, useRef } from 'react';\nimport { Box } from '../../../objects/box';\nimport { useFrame } from '../hooks/use-frame';\nimport { useRuntime } from '../hooks/use-runtime';\nimport { renderReactDom } from '../utility/react-dom';\n\nexport const HTMLPortal: React.FC<\n {\n children?: ReactNode;\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n } & React.RefAttributes<Box>\n> = React.forwardRef<\n Box,\n {\n backgroundColor?: string;\n interactive?: boolean;\n relative?: boolean;\n target?: { x: number; y: number; width: number; height: number };\n style?: any;\n children?: any;\n }\n>(({ children, ...props }, fwdRef) => {\n const ref = useRef<HTMLDivElement>();\n const runtime = useRuntime();\n const lastScale = useRef(0);\n const boxRef = useRef<Box>();\n const root = useRef<any>();\n\n useFrame(() => {\n if (props.relative) {\n const relativeBox = ref.current;\n if (relativeBox && runtime) {\n const scaleFactor = runtime.getScaleFactor();\n if (lastScale.current !== scaleFactor) {\n lastScale.current = scaleFactor;\n relativeBox.style.transformOrigin = '0 0';\n relativeBox.style.transform = `scale(${1 / lastScale.current})`;\n relativeBox.style.width = `${lastScale.current * 100}%`;\n relativeBox.style.height = `${lastScale.current * 100}%`;\n if (ref.current && boxRef.current?.__owner.value?.rotation) {\n relativeBox.style.transform = `scale(${1 / lastScale.current}) translate(50%, 50%) rotate(${\n boxRef.current?.__owner.value?.rotation || 0\n }deg) translate(-50%, -50%)`;\n }\n }\n }\n }\n }, [props.relative]);\n\n useLayoutEffect(() => {\n const box = boxRef.current;\n if (fwdRef && box) {\n if (typeof fwdRef === 'function') {\n fwdRef(box);\n } else {\n fwdRef.current = box;\n }\n }\n async function renderHost() {\n if (box && box.__host) {\n const toRender = props.relative ? <div ref={ref as any}>{children as any}</div> : (children as any);\n\n await renderReactDom(box.__host.element, toRender, root);\n }\n }\n\n if (box && box.__host) {\n renderHost();\n } else if (box) {\n box.__onCreate = renderHost;\n }\n }, [fwdRef, children, boxRef, props.relative]);\n\n useLayoutEffect(() => {\n return () => {\n if (root.current) {\n setTimeout(() => {\n root.current.unmount();\n }, 0);\n }\n };\n }, []);\n\n return <box html {...props} ref={boxRef} />;\n});\n\nHTMLPortal.displayName = 'HTMLPortal';\n","import React, { ReactNode, useMemo } from 'react';\nimport { GetTile } from '../../iiif/shared';\nimport { CompositeResourceProps } from '../../../spacial-content';\n\nexport const TileSet: React.FC<{\n tiles: GetTile;\n x?: number;\n y?: number;\n width: number;\n height: number;\n rotation?: number;\n crop?: any;\n children?: ReactNode;\n enableThumbnail?: boolean;\n enableSizes?: boolean;\n onClick?: (e: any) => void;\n renderOptions?: CompositeResourceProps;\n}> = (props) => {\n const scale = props.width / (props.crop?.width || props.tiles.width);\n const sizes = props.tiles.imageService.sizes || [];\n const enableThumbnail = props.enableThumbnail;\n const enableSizes = props.enableSizes;\n const canonicalId = useMemo(() => {\n const id = props.tiles.imageService.id || (props.tiles.imageService['@id'] as string);\n if (id && id.endsWith('/info.json')) {\n return id.slice(0, -1 * '/info.json'.length);\n }\n return id;\n }, [props.tiles.imageService.id]);\n\n const tiles = useMemo(() => {\n const tiles = props.tiles.imageService.tiles || [];\n\n if (!tiles.length) {\n const width = props.width;\n let scaleFactors = [1];\n let last = 1;\n while (Math.pow(2, last) < width) {\n last = last * 2;\n scaleFactors.push(last);\n }\n\n return [\n // {\n // width: 256,\n // height: 256,\n // scaleFactors: [1, 2, 4, 8],\n // },\n ];\n }\n\n return tiles;\n }, [props.tiles.imageService]);\n\n const isVersion3 = useMemo(() => {\n const service = props.tiles.imageService;\n const ctx = service ? service['@context']\n ? Array.isArray(service['@context'])\n ? service['@context']\n : [service['@context']]\n : [] : [];\n return ctx.indexOf('http://iiif.io/api/image/3/context.json') !== -1;\n }, [props.tiles.imageService.id]);\n\n return (\n <world-object\n rotation={props.rotation}\n key={props.tiles.imageService.id}\n scale={scale}\n height={props.crop?.height || props.tiles.height}\n width={props.crop?.width || props.tiles.width}\n x={props.x}\n y={props.y}\n onClick={props.onClick}\n >\n <composite-image\n key={props.tiles.imageService.id}\n id={props.tiles.imageService.id}\n width={props.crop?.width || props.tiles.width}\n height={props.crop?.height || props.tiles.height}\n crop={props.crop}\n renderOptions={props.renderOptions}\n >\n {enableThumbnail && props.tiles.thumbnail ? (\n <world-image\n priority\n uri={props.tiles.thumbnail.id}\n target={{ width: props.tiles.width, height: props.tiles.height }}\n display={{ width: props.tiles.thumbnail.width, height: props.tiles.thumbnail.height }}\n crop={props.crop}\n />\n ) : null}\n {enableSizes &&\n sizes.map((size, n) => (\n <world-image\n key={n}\n uri={`${canonicalId}/full/${size.width},${size.height}/0/default.jpg`}\n target={{ width: props.tiles.width, height: props.tiles.height }}\n display={{ width: size.width, height: size.height }}\n crop={props.crop}\n />\n ))}\n {tiles.map((tile: any) =>\n (tile.scaleFactors || []).map((size: number) => {\n return (\n <tiled-image\n key={`${props.tiles.imageService.id}-tile-${size}-${tile.width}x${tile.height || tile.width}`}\n uri={props.tiles.imageService.id}\n display={{ width: props.tiles.width, height: props.tiles.height }}\n tile={tile}\n scaleFactor={size}\n crop={props.crop}\n version3={isVersion3}\n />\n );\n })\n )}\n </composite-image>\n </world-object>\n );\n};\n","import React, { ReactNode, useEffect, useState } from 'react';\nimport { GetTile } from '../../iiif/shared';\nimport { TileSet } from './TileSet';\nimport { getTileFromImageService } from '../../iiif/get-tiles';\nimport { CompositeResourceProps } from '../../../spacial-content';\n\nexport const ImageService: React.FC<{\n id: string;\n width: number;\n height: number;\n x?: number;\n y?: number;\n rotation?: number;\n scale?: number;\n children?: ReactNode;\n crop?: any;\n enableSizes?: boolean;\n enableThumbnail?: boolean;\n renderOptions?: CompositeResourceProps;\n}> = (props) => {\n const [tiles, setTile] = useState<GetTile | undefined>();\n\n useEffect(() => {\n getTileFromImageService(props.id, props.width, props.height).then((s) => {\n setTile(s);\n });\n }, [props.height, props.id, props.width]);\n\n return (\n <world-object x={props.x || 0} y={props.y || 0} width={props.width} height={props.height} scale={props.scale}>\n {tiles ? (\n <TileSet\n tiles={tiles}\n x={props.x}\n y={props.y}\n width={props.crop?.width || props.width}\n height={props.crop?.height || props.height}\n rotation={props.rotation}\n crop={props.crop}\n enableSizes={props.enableSizes}\n enableThumbnail={props.enableThumbnail}\n renderOptions={props.renderOptions}\n >\n {props.children}\n </TileSet>\n ) : null}\n </world-object>\n );\n};\n","import { createContext, useContext } from 'react';\nimport type { MapBounds, MapProjection } from '../../maps/types';\n\nexport type MapProjectionContextValue = {\n bounds: MapBounds;\n width: number;\n height: number;\n mapRect: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n projection: MapProjection;\n};\n\nexport const MapProjectionContext = createContext<MapProjectionContextValue | null>(null);\nMapProjectionContext.displayName = 'MapProjection';\n\nexport function useMapProjectionContext(): MapProjectionContextValue {\n const context = useContext(MapProjectionContext);\n if (!context) {\n throw new Error('useMapProjection must be used within <MapObject />');\n }\n return context;\n}\n\nexport function useMapProjection(): MapProjection {\n return useMapProjectionContext().projection;\n}\n","import { useMemo } from 'react';\nimport type { MapGeoJSONFeature, MapGeoJSONFeatureCollection, MapGeoJSONGeometry, MapGeoJSONInput } from '../../maps/types';\nimport { useMapProjection } from './use-map-projection';\n\nexport type ProjectedMapGeoJSONShape = {\n kind: 'shape';\n open: boolean;\n points: Array<[number, number]>;\n key: string;\n feature?: MapGeoJSONFeature;\n};\n\nexport type ProjectedMapGeoJSONPoint = {\n kind: 'point';\n x: number;\n y: number;\n key: string;\n feature?: MapGeoJSONFeature;\n};\n\nexport type ProjectedMapGeoJSONItem = ProjectedMapGeoJSONShape | ProjectedMapGeoJSONPoint;\n\nfunction projectGeometry(\n geometry: MapGeoJSONGeometry,\n projectRing: (ring: Array<[number, number]>) => Array<[number, number]>,\n lngLatToWorld: (lng: number, lat: number) => { x: number; y: number },\n keyPrefix: string,\n feature?: MapGeoJSONFeature\n): ProjectedMapGeoJSONItem[] {\n switch (geometry.type) {\n case 'Point': {\n const point = lngLatToWorld(geometry.coordinates[0], geometry.coordinates[1]);\n return [{ kind: 'point', x: point.x, y: point.y, key: `${keyPrefix}-point`, feature }];\n }\n\n case 'MultiPoint': {\n return geometry.coordinates.map(([lng, lat], idx) => {\n const point = lngLatToWorld(lng, lat);\n return {\n kind: 'point' as const,\n x: point.x,\n y: point.y,\n key: `${keyPrefix}-point-${idx}`,\n feature,\n };\n });\n }\n\n case 'LineString': {\n return [\n {\n kind: 'shape',\n open: true,\n points: projectRing(geometry.coordinates),\n key: `${keyPrefix}-line`,\n feature,\n },\n ];\n }\n\n case 'MultiLineString': {\n return geometry.coordinates.map((line, idx) => ({\n kind: 'shape' as const,\n open: true,\n points: projectRing(line),\n key: `${keyPrefix}-line-${idx}`,\n feature,\n }));\n }\n\n case 'Polygon': {\n return geometry.coordinates.map((ring, idx) => ({\n kind: 'shape' as const,\n open: false,\n points: projectRing(ring),\n key: `${keyPrefix}-polygon-${idx}`,\n feature,\n }));\n }\n\n case 'MultiPolygon': {\n const items: ProjectedMapGeoJSONItem[] = [];\n for (let polygonIndex = 0; polygonIndex < geometry.coordinates.length; polygonIndex++) {\n const polygon = geometry.coordinates[polygonIndex];\n for (let ringIndex = 0; ringIndex < polygon.length; ringIndex++) {\n items.push({\n kind: 'shape',\n open: false,\n points: projectRing(polygon[ringIndex]),\n key: `${keyPrefix}-polygon-${polygonIndex}-${ringIndex}`,\n feature,\n });\n }\n }\n return items;\n }\n\n default:\n return [];\n }\n}\n\nexport function projectMapGeoJSON(\n input: MapGeoJSONInput | null | undefined,\n projection: {\n projectRing: (ring: Array<[number, number]>) => Array<[number, number]>;\n lngLatToWorld: (lng: number, lat: number) => { x: number; y: number };\n }\n): ProjectedMapGeoJSONItem[] {\n if (!input) {\n return [];\n }\n\n if (input.type === 'FeatureCollection') {\n const collection = input as MapGeoJSONFeatureCollection;\n const all: ProjectedMapGeoJSONItem[] = [];\n for (let i = 0; i < collection.features.length; i++) {\n const feature = collection.features[i];\n if (!feature.geometry) {\n continue;\n }\n all.push(\n ...projectGeometry(\n feature.geometry,\n projection.projectRing,\n projection.lngLatToWorld,\n `feature-${feature.id || i}`,\n feature\n )\n );\n }\n return all;\n }\n\n if (input.type === 'Feature') {\n const feature = input as MapGeoJSONFeature;\n if (!feature.geometry) {\n return [];\n }\n return projectGeometry(feature.geometry, projection.projectRing, projection.lngLatToWorld, `feature-${feature.id || 0}`, feature);\n }\n\n return projectGeometry(input as MapGeoJSONGeometry, projection.projectRing, projection.lngLatToWorld, 'geometry');\n}\n\nexport type MapGeoJSONProjector = {\n project: (input: MapGeoJSONInput | null | undefined) => ProjectedMapGeoJSONItem[];\n};\n\nexport function useMapGeoJSON(): MapGeoJSONProjector {\n const projection = useMapProjection();\n\n return useMemo(\n () => ({\n project: (input: MapGeoJSONInput | null | undefined) => projectMapGeoJSON(input, projection),\n }),\n [projection]\n );\n}\n","/* @refresh skip */\nimport React from \"react\";\nimport type { BoxStyle } from \"../../../objects/box\";\nimport type { GeometryStyle } from \"../../../objects/geometry\";\nimport type { MapGeoJSONInput } from \"../../maps/types\";\nimport { useMapGeoJSON } from \"../hooks/use-map-geojson\";\nimport { useMapProjectionContext } from \"../hooks/use-map-projection\";\n\nexport type MapGeoJSONProps = {\n\tdata: MapGeoJSONInput;\n\tmarkerSize?: number;\n\tmarkerStyle?: BoxStyle;\n\tlineStyle?: GeometryStyle;\n\tpolygonStyle?: GeometryStyle;\n\tinteractive?: boolean;\n};\n\nexport const MapGeoJSON: React.FC<MapGeoJSONProps> = ({\n\tdata,\n\tmarkerSize = 8,\n\tmarkerStyle = {\n\t\tbackgroundColor: \"rgba(220, 38, 38, 0.9)\",\n\t\tborder: \"1px solid white\",\n\t},\n\tlineStyle = {\n\t\tborderColor: \"#1d4ed8\",\n\t\tborderWidth: \"2\",\n\t\tborderStyle: \"solid\",\n\t},\n\tpolygonStyle = {\n\t\tbackgroundColor: \"rgba(37, 99, 235, 0.25)\",\n\t\tborderColor: \"#1d4ed8\",\n\t\tborderWidth: \"2\",\n\t\tborderStyle: \"solid\",\n\t},\n\tinteractive,\n}) => {\n\tconst map = useMapProjectionContext();\n\tconst geoJSON = useMapGeoJSON();\n\tconst projected = geoJSON.project(data);\n\n\treturn React.createElement(\n\t\tReact.Fragment,\n\t\tnull,\n\t\tprojected.map((item) => {\n\t\t\tif (item.kind === \"point\") {\n\t\t\t\treturn React.createElement(\"box\", {\n\t\t\t\t\tkey: item.key,\n\t\t\t\t\tinteractive,\n\t\t\t\t\ttarget: {\n\t\t\t\t\t\tx: item.x - markerSize / 2,\n\t\t\t\t\t\ty: item.y - markerSize / 2,\n\t\t\t\t\t\twidth: markerSize,\n\t\t\t\t\t\theight: markerSize,\n\t\t\t\t\t},\n\t\t\t\t\tstyle: markerStyle,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn React.createElement(\"shape\", {\n\t\t\t\tid: item.key,\n\t\t\t\tkey: item.key,\n\t\t\t\tinteractive,\n\t\t\t\topen: item.open,\n\t\t\t\ttarget: { x: 0, y: 0, width: map.width, height: map.height },\n\t\t\t\tpoints: item.points,\n\t\t\t\tstyle: item.open ? lineStyle : polygonStyle,\n\t\t\t});\n\t\t}),\n\t);\n};\n","/* @refresh skip */\nimport React, { useMemo } from \"react\";\nimport {\n\tcreateMapProjection,\n\tlatitudeToMercatorY,\n\tlongitudeToMercatorX,\n\tvalidateMapBounds,\n} from \"../../maps/projection\";\nimport type { MapBounds } from \"../../maps/types\";\nimport { MapProjectionContext } from \"../hooks/use-map-projection\";\n\nexport type MapObjectProps = {\n\tid?: string;\n\tbounds: MapBounds;\n\tx?: number;\n\ty?: number;\n\twidth: number;\n\theight: number;\n\tpreserveAspectRatio?: boolean;\n\tscale?: number;\n\trotation?: number;\n\tchildren?: React.ReactNode;\n};\n\nexport const MapObject: React.FC<MapObjectProps> = ({\n\tbounds,\n\twidth,\n\theight,\n\tpreserveAspectRatio = true,\n\tchildren,\n\t...worldObjectProps\n}) => {\n\tvalidateMapBounds(bounds);\n\n\tconst mapRect = useMemo(() => {\n\t\tif (!preserveAspectRatio) {\n\t\t\treturn { x: 0, y: 0, width, height };\n\t\t}\n\n\t\tconst mercatorWidth =\n\t\t\tlongitudeToMercatorX(bounds.east) - longitudeToMercatorX(bounds.west);\n\t\tconst mercatorHeight =\n\t\t\tlatitudeToMercatorY(bounds.south) - latitudeToMercatorY(bounds.north);\n\t\tconst mapAspect = mercatorWidth / mercatorHeight;\n\t\tconst worldAspect = width / height;\n\n\t\tif (!Number.isFinite(mapAspect) || mapAspect <= 0) {\n\t\t\treturn { x: 0, y: 0, width, height };\n\t\t}\n\n\t\tif (worldAspect > mapAspect) {\n\t\t\tconst fittedWidth = height * mapAspect;\n\t\t\treturn {\n\t\t\t\tx: (width - fittedWidth) / 2,\n\t\t\t\ty: 0,\n\t\t\t\twidth: fittedWidth,\n\t\t\t\theight,\n\t\t\t};\n\t\t}\n\n\t\tconst fittedHeight = width / mapAspect;\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: (height - fittedHeight) / 2,\n\t\t\twidth,\n\t\t\theight: fittedHeight,\n\t\t};\n\t}, [\n\t\tbounds.east,\n\t\tbounds.north,\n\t\tbounds.south,\n\t\tbounds.west,\n\t\theight,\n\t\tpreserveAspectRatio,\n\t\twidth,\n\t]);\n\n\tconst projection = useMemo(() => {\n\t\tconst baseProjection = createMapProjection({\n\t\t\tbounds,\n\t\t\twidth: mapRect.width,\n\t\t\theight: mapRect.height,\n\t\t});\n\n\t\treturn {\n\t\t\tlngLatToWorld(lng: number, lat: number) {\n\t\t\t\tconst world = baseProjection.lngLatToWorld(lng, lat);\n\t\t\t\treturn {\n\t\t\t\t\tx: world.x + mapRect.x,\n\t\t\t\t\ty: world.y + mapRect.y,\n\t\t\t\t};\n\t\t\t},\n\t\t\tworldToLngLat(x: number, y: number) {\n\t\t\t\treturn baseProjection.worldToLngLat(x - mapRect.x, y - mapRect.y);\n\t\t\t},\n\t\t\tlngLatBoundsToWorldRect(inputBounds: MapBounds) {\n\t\t\t\tconst rect = baseProjection.lngLatBoundsToWorldRect(inputBounds);\n\t\t\t\treturn {\n\t\t\t\t\tx: rect.x + mapRect.x,\n\t\t\t\t\ty: rect.y + mapRect.y,\n\t\t\t\t\twidth: rect.width,\n\t\t\t\t\theight: rect.height,\n\t\t\t\t};\n\t\t\t},\n\t\t\tworldRectToLngLatBounds(rect: {\n\t\t\t\tx: number;\n\t\t\t\ty: number;\n\t\t\t\twidth: number;\n\t\t\t\theight: number;\n\t\t\t}) {\n\t\t\t\treturn baseProjection.worldRectToLngLatBounds({\n\t\t\t\t\tx: rect.x - mapRect.x,\n\t\t\t\t\ty: rect.y - mapRect.y,\n\t\t\t\t\twidth: rect.width,\n\t\t\t\t\theight: rect.height,\n\t\t\t\t});\n\t\t\t},\n\t\t\tprojectRing(ring: Array<[number, number]>) {\n\t\t\t\treturn ring.map(([lng, lat]) => {\n\t\t\t\t\tconst point = baseProjection.lngLatToWorld(lng, lat);\n\t\t\t\t\treturn [point.x + mapRect.x, point.y + mapRect.y] as [number, number];\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}, [bounds, mapRect.height, mapRect.width, mapRect.x, mapRect.y]);\n\n\tconst contextValue = useMemo(\n\t\t() => ({\n\t\t\tbounds,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tmapRect,\n\t\t\tprojection,\n\t\t}),\n\t\t[bounds, height, mapRect, projection, width],\n\t);\n\n\treturn React.createElement(\n\t\tMapProjectionContext.Provider,\n\t\t{ value: contextValue },\n\t\tReact.createElement(\n\t\t\t\"world-object\",\n\t\t\t{ width, height, ...worldObjectProps },\n\t\t\tchildren,\n\t\t),\n\t);\n};\n","/* @refresh skip */\nimport React, { useMemo } from \"react\";\nimport type { CompositeResourceProps } from \"../../../spacial-content/composite-resource\";\nimport { estimateFiniteTileGridCoverage } from \"../../../spacial-content/map-tiled-image\";\nimport { DEFAULT_OSM_TILE_TEMPLATE } from \"../../maps/tile-source\";\nimport type { MapTileSource } from \"../../maps/types\";\nimport { useMapProjectionContext } from \"../hooks/use-map-projection\";\n\nexport type MapTileLayerProps = {\n\tid?: string;\n\ttileUrlTemplate?: string;\n\ttileSource?: MapTileSource;\n\tsubdomains?: string[];\n\ttileSize?: number;\n\tminZoom?: number;\n\tmaxZoom?: number;\n\tmaxQualityLevels?: number;\n\tmaxTilesPerLayer?: number;\n\tmaxTotalTiles?: number;\n\tuseDevicePixelRatio?: boolean;\n\trenderOptions?: CompositeResourceProps;\n};\n\nconst DEFAULT_MAX_TILES_PER_LAYER = 16000;\nconst DEFAULT_MAX_TOTAL_TILES = 120000;\nconst DEFAULT_MAX_QUALITY_LEVELS = 12;\n\nexport const MapTileLayer: React.FC<MapTileLayerProps> = ({\n\tid,\n\ttileUrlTemplate,\n\ttileSource,\n\tsubdomains,\n\ttileSize = 256,\n\tminZoom = 0,\n\tmaxZoom = 19,\n\tmaxQualityLevels = DEFAULT_MAX_QUALITY_LEVELS,\n\tmaxTilesPerLayer = DEFAULT_MAX_TILES_PER_LAYER,\n\tmaxTotalTiles = DEFAULT_MAX_TOTAL_TILES,\n\tuseDevicePixelRatio = false,\n\trenderOptions,\n}) => {\n\tconst map = useMapProjectionContext();\n\n\tconst normalizedMinZoom = Math.max(0, Math.floor(minZoom));\n\tconst normalizedMaxZoom = Math.max(normalizedMinZoom, Math.floor(maxZoom));\n\n\tconst source = tileSource || tileUrlTemplate || DEFAULT_OSM_TILE_TEMPLATE;\n\n\tconst zoomEntries = useMemo(() => {\n\t\tconst entries: Array<{\n\t\t\tzoom: number;\n\t\t\tcoverage: ReturnType<typeof estimateFiniteTileGridCoverage>;\n\t\t}> = [];\n\t\tlet totalTiles = 0;\n\t\tfor (let z = normalizedMinZoom; z <= normalizedMaxZoom; z++) {\n\t\t\tconst coverage = estimateFiniteTileGridCoverage({\n\t\t\t\tbounds: map.bounds,\n\t\t\t\tzoom: z,\n\t\t\t});\n\t\t\tif (\n\t\t\t\tcoverage.count > maxTilesPerLayer ||\n\t\t\t\ttotalTiles + coverage.count > maxTotalTiles\n\t\t\t) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttotalTiles += coverage.count;\n\t\t\tentries.push({ zoom: z, coverage });\n\t\t}\n\n\t\tif (!entries.length) {\n\t\t\tlet fallbackZoom = normalizedMinZoom;\n\t\t\twhile (fallbackZoom > 0) {\n\t\t\t\tconst coverage = estimateFiniteTileGridCoverage({\n\t\t\t\t\tbounds: map.bounds,\n\t\t\t\t\tzoom: fallbackZoom,\n\t\t\t\t});\n\t\t\t\tif (coverage.count <= maxTilesPerLayer) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfallbackZoom -= 1;\n\t\t\t}\n\t\t\tentries.push({\n\t\t\t\tzoom: fallbackZoom,\n\t\t\t\tcoverage: estimateFiniteTileGridCoverage({\n\t\t\t\t\tbounds: map.bounds,\n\t\t\t\t\tzoom: fallbackZoom,\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\n\t\tif (entries.length > maxQualityLevels) {\n\t\t\tconst lowest = entries[0];\n\t\t\tconst highest = entries[entries.length - 1];\n\t\t\tconst floorZoom = Math.max(\n\t\t\t\tlowest.zoom + 1,\n\t\t\t\thighest.zoom - (maxQualityLevels - 2),\n\t\t\t);\n\t\t\treturn [\n\t\t\t\tlowest,\n\t\t\t\t...entries.filter((entry) => entry.zoom >= floorZoom),\n\t\t\t].filter(\n\t\t\t\t(entry, index, arr) =>\n\t\t\t\t\tindex === 0 || entry.zoom !== arr[index - 1].zoom,\n\t\t\t);\n\t\t}\n\n\t\treturn entries;\n\t}, [\n\t\tmap.bounds,\n\t\tmaxQualityLevels,\n\t\tmaxTilesPerLayer,\n\t\tmaxTotalTiles,\n\t\tnormalizedMaxZoom,\n\t\tnormalizedMinZoom,\n\t]);\n\n\tconst resolvedRenderOptions = useMemo<CompositeResourceProps>(\n\t\t() => ({\n\t\t\tlayerPolicy: \"always-blend\",\n\t\t\trenderLayers: 2,\n\t\t\trenderSmallestFallback: true,\n\t\t\tprefetchRadius: 0,\n\t\t\tquality: 0.9,\n\t\t\tuseDevicePixelRatio,\n\t\t\tfadeInMs: 300,\n\t\t\tfadeFallbackTiles: true,\n\t\t\tfadeOnLayerChange: true,\n\t\t\tclipToBounds: true,\n\t\t\t...(renderOptions || {}),\n\t\t}),\n\t\t[renderOptions, useDevicePixelRatio],\n\t);\n\n\tconst sourceKey = typeof source === \"string\" ? source : \"function-source\";\n\tconst compositeId = id || `map-tile-layer-${map.width}x${map.height}`;\n\n\tconst tiles = zoomEntries.map(({ zoom, coverage }) => {\n\t\tconst sourceWidth = coverage.tileSpanX * tileSize;\n\t\tconst sourceHeight = coverage.tileSpanY * tileSize;\n\t\tconst scaleFactor = Math.max(\n\t\t\tmap.mapRect.width / sourceWidth,\n\t\t\tmap.mapRect.height / sourceHeight,\n\t\t);\n\t\treturn React.createElement(\"map-tiled-image\", {\n\t\t\tkey: `${compositeId}-${zoom}-${sourceKey}-${tileSize}`,\n\t\t\tid: `${compositeId}-z${zoom}`,\n\t\t\tbounds: map.bounds,\n\t\t\tworldWidth: map.mapRect.width,\n\t\t\tworldHeight: map.mapRect.height,\n\t\t\tzoom,\n\t\t\tscaleFactor,\n\t\t\ttileSize,\n\t\t\ttileSource: source,\n\t\t\tsubdomains,\n\t\t});\n\t});\n\n\tconst composite = React.createElement(\n\t\t\"composite-image\",\n\t\t{\n\t\t\tid: compositeId,\n\t\t\twidth: map.mapRect.width,\n\t\t\theight: map.mapRect.height,\n\t\t\trenderOptions: resolvedRenderOptions,\n\t\t},\n\t\ttiles,\n\t);\n\n\tif (map.mapRect.x === 0 && map.mapRect.y === 0) {\n\t\treturn composite;\n\t}\n\n\treturn React.createElement(\n\t\t\"world-object\",\n\t\t{\n\t\t\tid: `${compositeId}-frame`,\n\t\t\tx: map.mapRect.x,\n\t\t\ty: map.mapRect.y,\n\t\t\twidth: map.mapRect.width,\n\t\t\theight: map.mapRect.height,\n\t\t},\n\t\tcomposite,\n\t);\n};\n","import { supportedEventMap, SupportedEventNames } from '../../../events';\nimport { useEffect } from 'react';\nimport { useRuntime } from './use-runtime';\n\nexport const useWorldEvent = <Name extends SupportedEventNames>(name: Name, cb: (e: any) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n const world = runtime ? runtime.world : undefined;\n\n useEffect(() => {\n if (runtime) {\n const callback = cb;\n const realName = supportedEventMap[name];\n runtime.world.activatedEvents.push(realName);\n const ev = realName.slice(2).toLowerCase();\n runtime.world.addEventListener(ev as any, callback);\n\n return () => {\n runtime.world.removeEventListener(ev as any, callback);\n };\n }\n return () => {\n // no-op\n };\n }, [world, name, ...deps]);\n};\n","export function getRatio(a: number, b: number) {\n if (a === 0) {\n return [0, 1];\n }\n if (b === 0) {\n return [1, 0];\n }\n\n const ratio = Math.abs(a) / Math.abs(b);\n\n return [ratio, 1 - ratio];\n}\n","import { useLayoutEffect, useRef } from 'react';\n\nexport function useModifierKeys() {\n const modifierKeys = useRef({\n ctrl: false,\n shift: false,\n alt: false,\n });\n\n useLayoutEffect(() => {\n function keyDown(e: KeyboardEvent) {\n if (e.key === 'Shift') modifierKeys.current.shift = true;\n if (e.key === 'Control') modifierKeys.current.ctrl = true;\n if (e.key === 'Alt') modifierKeys.current.alt = true;\n }\n function keyUp(e: KeyboardEvent) {\n if (e.key === 'Shift') modifierKeys.current.shift = false;\n if (e.key === 'Control') modifierKeys.current.ctrl = false;\n if (e.key === 'Alt') modifierKeys.current.alt = false;\n }\n\n window.addEventListener('keydown', keyDown);\n window.addEventListener('keyup', keyUp);\n return () => {\n window.removeEventListener('keydown', keyDown);\n window.removeEventListener('keyup', keyUp);\n };\n }, []);\n\n return modifierKeys;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Box } from '../../../objects/box';\nimport { useMode } from './use-mode';\nimport { useWorldEvent } from './use-world-event';\nimport { useRuntime } from './use-runtime';\nimport { useFrame } from './use-frame';\nimport { useCanvasPosition } from './use-canvas-position';\nimport { getRatio } from '../utility/get-ratio';\nimport { useModifierKeys } from './use-modifier-keys';\n\nexport const useResizeWorldItem = (\n props: { x: number; y: number; width: number; height: number; maintainAspectRatio?: boolean; aspectRatio?: number },\n onSave: (item: { x: number; y: number; width: number; height: number }) => void\n) => {\n const mode = useMode();\n const runtime = useRuntime();\n const canvasPosition = useCanvasPosition();\n const resizeMode = useRef<string>();\n const portalRef = useRef<Box | null>(null);\n const mouseStart = useRef<{ x: number; y: number } | undefined>();\n const [isEditing, setIsEditing] = useState(false);\n const isEditingRef = useRef(false);\n\n const cardinalDeltas = useRef({ north: 0, south: 0, east: 0, west: 0 });\n const keys = useModifierKeys();\n\n const mouseEvent = useCallback(\n (direction: string) => (e: any) => {\n isEditingRef.current = true;\n setIsEditing(true);\n if (canvasPosition && runtime) {\n const { top, left } = canvasPosition;\n const current = runtime.viewerToWorld(e.pageX - left, e.pageY - top);\n mouseStart.current = { x: current.x, y: current.y };\n resizeMode.current = direction;\n }\n },\n [canvasPosition, runtime]\n );\n\n const aspectRatio = useMemo(() => {\n // Calculate aspect ratio.\n return props.width / props.height;\n }, [props.width, props.height]);\n\n const constrainToAspectRatio = useCallback(\n (deltas: { north: number; south: number; east: number; west: number }) => {\n const hasDeltas = Math.abs(deltas.north - deltas.south + (deltas.east - deltas.west));\n if (!hasDeltas) return;\n\n const xDelta = -deltas.west + deltas.east;\n const yDelta = -deltas.north + deltas.south;\n\n const originalWidth = props.width + xDelta;\n const originalHeight = props.height + yDelta;\n\n const newAspectRatio = originalWidth / originalHeight;\n\n if (newAspectRatio >= aspectRatio) {\n // too wide\n const width = originalHeight * aspectRatio;\n const margin = originalWidth - width; // reduce by this amount.\n const [eastRatio, westRatio] = getRatio(deltas.east, deltas.west);\n\n deltas.west = deltas.west + margin * westRatio;\n deltas.east = deltas.east - margin * eastRatio;\n } else {\n // too tall\n const height = originalWidth / aspectRatio;\n const margin = originalHeight - height; // reduce by this amount.\n const [northRatio, southRatio] = getRatio(deltas.north, deltas.south);\n\n deltas.north = deltas.north + margin * northRatio;\n deltas.south = deltas.south - margin * southRatio;\n }\n },\n [props.width, props.height, aspectRatio]\n );\n\n useFrame(() => {\n if (mouseStart && runtime) {\n runtime.updateNextFrame();\n }\n });\n\n useEffect(() => {\n if (runtime) {\n runtime.updateNextFrame();\n }\n }, [runtime, isEditing]);\n\n const onPointerMoveCallback = useCallback(\n (e: any) => {\n if (!runtime || !canvasPosition || runtime.mode !== 'sketch') return;\n\n const { top, left } = canvasPosition;\n const position = runtime.viewerToWorld(e.pageX - left, e.pageY - top);\n const box = portalRef.current;\n\n const alt = !props.maintainAspectRatio && keys.current.alt;\n const shift = !alt && keys.current.shift && resizeMode.current?.indexOf('-') !== -1;\n\n // Take co-ordinates, clamp constraints, update\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'east' ||\n resizeMode.current === 'north-east' ||\n resizeMode.current === 'south-east'\n ) {\n cardinalDeltas.current.east = position.x - (mouseStart.current ? mouseStart.current.x : 0);\n if (alt) {\n cardinalDeltas.current.west = -cardinalDeltas.current.east;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'west' ||\n resizeMode.current === 'north-west' ||\n resizeMode.current === 'south-west'\n ) {\n cardinalDeltas.current.west = position.x - (mouseStart.current ? mouseStart.current.x : 0);\n if (alt) {\n cardinalDeltas.current.east = -cardinalDeltas.current.west;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'north' ||\n resizeMode.current === 'north-east' ||\n resizeMode.current === 'north-west'\n ) {\n cardinalDeltas.current.north = position.y - (mouseStart.current ? mouseStart.current.y : 0);\n if (alt) {\n cardinalDeltas.current.south = -cardinalDeltas.current.north;\n }\n }\n if (\n resizeMode.current === 'translate' ||\n resizeMode.current === 'south' ||\n resizeMode.current === 'south-west' ||\n resizeMode.current === 'south-east'\n ) {\n cardinalDeltas.current.south = position.y - (mouseStart.current ? mouseStart.current.y : 0);\n if (alt) {\n cardinalDeltas.current.north = -cardinalDeltas.current.south;\n }\n }\n\n if (props.maintainAspectRatio || shift) {\n constrainToAspectRatio(cardinalDeltas.current);\n }\n\n if (box) {\n const dX1 = cardinalDeltas.current.west;\n const dY1 = cardinalDeltas.current.north;\n const dX2 = props.width + cardinalDeltas.current.east;\n const dY2 = props.height + cardinalDeltas.current.south;\n\n box.points[1] = Math.min(dX1, dX2);\n box.points[2] = Math.min(dY1, dY2);\n box.points[3] = Math.max(dX1, dX2);\n box.points[4] = Math.max(dY1, dY2);\n\n runtime.updateNextFrame();\n }\n },\n [runtime, props.width, props.height, props.maintainAspectRatio, canvasPosition]\n );\n\n useWorldEvent('mousemove', onPointerMoveCallback, [props.width, props.height, canvasPosition]);\n useWorldEvent('pointermove', onPointerMoveCallback, [props.width, props.height, canvasPosition]);\n\n const windowPointerUp = useRef<() => void>();\n\n useEffect(() => {\n windowPointerUp.current = () => {\n if (isEditingRef.current) {\n const dX1 = cardinalDeltas.current.west;\n const dY1 = cardinalDeltas.current.north;\n const dX2 = props.width + cardinalDeltas.current.east;\n const dY2 = props.height + cardinalDeltas.current.south;\n\n const x1 = Math.min(dX1, dX2);\n const y1 = Math.min(dY1, dY2);\n const x2 = Math.max(dX1, dX2);\n const y2 = Math.max(dY1, dY2);\n\n const realSize = {\n x: (props.x || 0) + x1,\n y: (props.y || 0) + y1,\n width: x2 - x1 || 1,\n height: y2 - y1 || 1,\n };\n if (props.maintainAspectRatio) {\n // @todo apply aspect ratio here.\n onSave(realSize);\n } else {\n onSave(realSize);\n }\n\n resizeMode.current = undefined;\n mouseStart.current = undefined;\n cardinalDeltas.current.east = 0;\n cardinalDeltas.current.west = 0;\n cardinalDeltas.current.north = 0;\n cardinalDeltas.current.south = 0;\n isEditingRef.current = false;\n setIsEditing(false);\n }\n };\n }, [onSave, props.height, props.width, props.x, props.y]);\n\n useEffect(() => {\n const cb = () => {\n if (windowPointerUp.current) {\n windowPointerUp.current();\n }\n };\n window.addEventListener('pointerup', cb);\n window.addEventListener('touchend', cb);\n return () => {\n window.removeEventListener('pointerup', cb);\n window.removeEventListener('touchend', cb);\n };\n }, []);\n\n return {\n portalRef,\n mode,\n mouseEvent,\n onPointerMoveCallback,\n isEditing,\n };\n};\n","import React, { CSSProperties, ReactNode, useMemo } from 'react';\nimport { useResizeWorldItem } from '../hooks/use-resize-world-item';\nimport { HTMLPortal } from './HTMLPortal';\n\ntype ResizeWorldItemProps = JSX.IntrinsicElements['worldObject'] & {\n handleSize?: number;\n resizable?: boolean;\n rotation?: number;\n onSave: (pos: Partial<{ x: number; y: number; width: number; height: number }>) => void;\n children?: ReactNode;\n maintainAspectRatio?: boolean;\n disableCardinalControls?: boolean;\n};\n\nexport function ResizeWorldItem({\n handleSize: _handleSize,\n resizable,\n onSave,\n children,\n maintainAspectRatio,\n disableCardinalControls,\n ...props\n}: ResizeWorldItemProps) {\n const handleSize = typeof _handleSize === 'undefined' ? (maintainAspectRatio ? 10 : 8) : _handleSize;\n const { portalRef, mode, mouseEvent, isEditing } = useResizeWorldItem(\n { x: props.x || 0, y: props.y || 0, width: props.width, height: props.height, maintainAspectRatio },\n onSave\n );\n const translate = useMemo(() => mouseEvent('translate'), [mouseEvent]);\n const east = useMemo(() => mouseEvent('east'), [mouseEvent]);\n const west = useMemo(() => mouseEvent('west'), [mouseEvent]);\n const south = useMemo(() => mouseEvent('south'), [mouseEvent]);\n const north = useMemo(() => mouseEvent('north'), [mouseEvent]);\n const southEast = useMemo(() => mouseEvent('south-east'), [mouseEvent]);\n const southWest = useMemo(() => mouseEvent('south-west'), [mouseEvent]);\n const northEast = useMemo(() => mouseEvent('north-east'), [mouseEvent]);\n const northWest = useMemo(() => mouseEvent('north-west'), [mouseEvent]);\n\n const inSketchMode = mode === 'sketch';\n const baseStyle: CSSProperties = {\n zIndex: 999,\n boxShadow: '0px 2px 3px 0 rgba(0,0,0,0.2)',\n border: '1px solid rgba(155,155,155,.7)',\n borderRadius: maintainAspectRatio || disableCardinalControls ? '50%' : 2,\n position: 'absolute',\n background: '#fff',\n pointerEvents: isEditing ? 'none' : inSketchMode ? 'initial' : 'none',\n };\n\n return (\n <>\n <world-object {...props}>\n {children}\n\n {inSketchMode && resizable ? (\n <HTMLPortal\n ref={portalRef}\n target={{ x: 0, y: 0, height: props.height, width: props.width }}\n relative={true}\n interactive={false}\n >\n {inSketchMode && resizable ? (\n <>\n <div\n onMouseDown={translate}\n onTouchStart={translate}\n style={{\n display: 'block',\n width: '100%',\n height: '100%',\n position: 'relative',\n border: '1px solid rgba(155,155,155, .7)',\n boxSizing: 'border-box',\n pointerEvents: isEditing ? 'none' : inSketchMode ? 'initial' : 'none',\n }}\n />\n\n {!maintainAspectRatio ? (\n <>\n <div\n title=\"east\"\n onTouchStart={east}\n onMouseDown={east}\n style={{\n ...baseStyle,\n cursor: 'e-resize',\n height: handleSize * 2,\n width: handleSize,\n right: 0,\n top: '50%',\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(${handleSize / 2}px, -${handleSize}px)`,\n }}\n />\n <div\n title=\"west\"\n onMouseDown={west}\n style={{\n ...baseStyle,\n cursor: 'w-resize',\n position: 'absolute',\n height: handleSize * 2,\n width: handleSize,\n left: 0,\n top: '50%',\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize / 2}px, -${handleSize}px)`,\n }}\n />\n\n <div\n title=\"north\"\n onMouseDown={north}\n style={{\n ...baseStyle,\n cursor: 'n-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize * 2,\n left: '50%',\n top: 0,\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize}px, -${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south\"\n onMouseDown={south}\n style={{\n ...baseStyle,\n cursor: 's-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize * 2,\n left: '50%',\n bottom: 0,\n opacity: disableCardinalControls ? 0 : 1,\n transform: `translate(-${handleSize}px, ${handleSize / 2}px)`,\n }}\n />\n </>\n ) : null}\n\n <div\n title=\"north-east\"\n onMouseDown={northEast}\n style={{\n ...baseStyle,\n cursor: 'ne-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n right: 0,\n top: 0,\n transform: `translate(${handleSize / 2}px, -${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south-east\"\n onMouseDown={southEast}\n style={{\n ...baseStyle,\n cursor: 'se-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n bottom: 0,\n right: 0,\n transform: `translate(${handleSize / 2}px, ${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"south-west\"\n onMouseDown={southWest}\n style={{\n ...baseStyle,\n cursor: 'sw-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n bottom: 0,\n left: 0,\n transform: `translate(-${handleSize / 2}px, ${handleSize / 2}px)`,\n }}\n />\n\n <div\n title=\"north-west\"\n onMouseDown={northWest}\n style={{\n ...baseStyle,\n cursor: 'nw-resize',\n position: 'absolute',\n height: handleSize,\n width: handleSize,\n top: 0,\n left: 0,\n transform: `translate(-${handleSize / 2}px, -${handleSize / 2}px)`,\n }}\n />\n </>\n ) : null}\n </HTMLPortal>\n ) : null}\n </world-object>\n </>\n );\n}\n","import React, { ReactNode, useCallback } from 'react';\nimport { ResizeWorldItem } from './ResizeWorldItem';\nimport { BoxStyle } from '../../../objects/box';\n\ntype RegionHighlightType = {\n id: any;\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nexport type RegionHighlightProps = {\n id?: string;\n region: RegionHighlightType;\n isEditing: boolean;\n rotation?: number;\n onSave: (annotation: RegionHighlightType) => void;\n onClick: (annotation: RegionHighlightType) => void;\n interactive?: boolean;\n maintainAspectRatio?: boolean;\n disableCardinalControls?: boolean;\n style?: BoxStyle;\n children?: ReactNode;\n};\n\nexport function RegionHighlight({\n interactive,\n region,\n onClick,\n onSave,\n maintainAspectRatio,\n disableCardinalControls,\n isEditing,\n rotation,\n style = { backgroundColor: 'rgba(0,0,0,.5)' },\n}: RegionHighlightProps) {\n const saveCallback = useCallback(\n (bounds: any) => {\n onSave({ id: region.id, x: region.x, y: region.y, height: region.height, width: region.width, ...bounds });\n },\n [onSave, region.id, region.x, region.y, region.height, region.width]\n );\n\n return (\n <ResizeWorldItem\n x={region.x}\n y={region.y}\n rotation={rotation}\n width={region.width}\n height={region.height}\n resizable={isEditing}\n onSave={saveCallback}\n maintainAspectRatio={maintainAspectRatio}\n disableCardinalControls={disableCardinalControls}\n >\n <box\n interactive={interactive}\n onContextMenu={(e) => {\n e.preventDefault();\n }}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n onClick(region);\n }}\n target={{ x: 0, y: 0, width: region.width, height: region.height }}\n style={style}\n />\n </ResizeWorldItem>\n );\n}\n","import { Paintable } from '../../../world-objects/paint';\nimport { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useAfterPaint = (callback: (paint: Paintable) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useAfterPaint', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { BrowserEventManager } from '../../browser-event-manager/browser-event-manager';\nimport { ReactAtlas } from '../reconciler';\nimport { Runtime, ViewerMode } from '../../../renderer/runtime';\nimport { CanvasRenderer } from '../../canvas-renderer/canvas-renderer';\nimport { popmotionController } from '../../popmotion-controller/popmotion-controller';\nimport { World } from '../../../world';\nimport { AtlasContext } from '../components/AtlasContext';\nimport { ModeContext } from './use-mode';\nimport { Preset } from '../presets/_types';\nimport { usePreset } from './use-preset';\nimport { useIsomorphicLayoutEffect } from '../utility/react';\n\ntype AtlasProps = {\n width: number;\n height: number;\n mode?: ViewerMode;\n onCreated?: (ctx: Preset) => void | Promise<void>;\n containerRef?: { current?: HTMLElement };\n cover?: boolean;\n resetWorldOnChange?: boolean;\n};\n\nexport const useAtlasImage: (\n children: any,\n options: AtlasProps\n) => { uri: string | undefined; loading?: boolean; imageError?: string } = (\n children,\n { onCreated, resetWorldOnChange = true, mode = 'explore', cover, containerRef, ...restProps }\n) => {\n const [ready, setReady] = useState(false);\n const [imageUrl, setImageUrl] = useState<string | undefined>(undefined);\n const [imageError, setError] = useState<string | undefined>(undefined);\n // Reference to the current HTML Canvas element\n // Set by React by passing <canvas ref={...} />\n // Used to instantiate the controller and viewer with the correct HTML element.\n const canvasRef = useRef<HTMLCanvasElement>();\n\n // This is an HTML element that sits above the Canvas element that is passed to the controller.\n // Additional non-canvas drawn elements can be placed here and positioned. CSS is applied to this\n // element by this component to absolutely position it. The overlay is updated if the \"bounds\" change\n // on the parent element and matches the size of it.\n const overlayRef = useRef<HTMLDivElement>();\n\n // This measures the height and width of the Atlas element.\n // const [ref, bounds] = useMeasure({ scroll: true });\n const bounds = useMemo(() => {\n return {\n width: restProps.width,\n height: restProps.height,\n };\n }, [restProps.width, restProps.height]);\n\n // This is a big messy global state of atlas that is updated outside of Reacts lifecycle.\n const [presetName, preset, viewport, refs] = usePreset(undefined, {\n width: restProps.width,\n height: restProps.height,\n });\n\n // Create our in memory canvas.\n useIsomorphicLayoutEffect(() => {\n const $cvs = document.createElement('canvas');\n $cvs.height = bounds.height;\n $cvs.width = bounds.width;\n canvasRef.current = $cvs;\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n const $cvs = canvasRef.current;\n if ($cvs) {\n $cvs.height = bounds.height;\n $cvs.width = bounds.width;\n }\n }, [bounds.width, bounds.height]);\n\n useEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n return runtime.registerHook('useAfterFrame', () => {\n if (canvasRef.current) {\n try {\n setImageUrl(canvasRef.current.toDataURL());\n } catch (e) {\n if (e instanceof Error) {\n setError(e.message);\n }\n }\n }\n });\n }\n return () => {\n // no-op\n };\n }, []);\n\n useEffect(() => {\n if (preset) {\n const runtime = preset.runtime;\n return runtime.world.addLayoutSubscriber((type) => {\n if (type === 'ready') {\n setReady(true);\n }\n });\n }\n return () => {\n // no-op\n };\n }, []);\n\n // This changes the mutable state object with the position (top/left/width/height) of the\n // canvas element on the page. This is used in the editing tools such as BoxDraw for comparing\n // positions.\n useEffect(() => {\n if (preset && preset.em) {\n preset.em.updateBounds();\n }\n }, [bounds]);\n\n // This changes the mode in the state object when the prop passed in changes. This will\n // be picked up by the renderer on the next method. There is not current way to detect this change.\n // @todo create a mode change event.\n useEffect(() => {\n if (preset) {\n preset.runtime.mode = mode;\n }\n }, [mode]);\n\n // When the width and height change this will resize the viewer and then reset the view to fit the element.\n // @todo improve or make configurable.\n // @todo resize event.\n useEffect(() => {\n if (preset) {\n const rt: Runtime = preset.runtime;\n\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n if (cover) {\n rt.cover();\n } else {\n rt.goHome();\n }\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n }\n }, [restProps.width, restProps.height]);\n\n // When the bounds of the container change, we need to reflect those changes in the overlay.\n // @todo move to canvas.\n useIsomorphicLayoutEffect(() => {\n const overlay = overlayRef.current;\n if (!overlay) return;\n overlay.style.width = `${bounds.width}px`;\n overlay.style.height = `${bounds.height}px`;\n overlay.style.pointerEvents = 'none';\n overlay.style.overflow = 'hidden';\n }, [bounds.height, bounds.width]);\n\n // When the window resizes we need to recalculate the width.\n // @todo possibly move to controller.\n useIsomorphicLayoutEffect(() => {\n const windowResizeCallback = () => {\n if (preset && preset.runtime) {\n const rt: Runtime = preset.runtime;\n\n rt.resize(viewport.current.width, restProps.width, viewport.current.height, restProps.height);\n viewport.current.width = restProps.width;\n viewport.current.height = restProps.height;\n rt.updateNextFrame();\n }\n };\n\n window.addEventListener('resize', windowResizeCallback);\n\n return () => window.removeEventListener('resize', windowResizeCallback);\n }, [preset, restProps.height, restProps.width]);\n\n const Canvas = useCallback(\n function Canvas(props: { children: React.ReactElement }): JSX.Element {\n const activate = () => {\n if (preset) {\n preset.ready = true;\n }\n };\n\n useEffect(() => {\n if (preset) {\n const result = onCreated && onCreated(preset);\n return void (result && result.then ? result.then(activate) : activate());\n }\n return () => {\n // no-op\n };\n }, []);\n\n return props.children;\n },\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [preset]\n );\n\n useEffect(() => {\n if (preset && preset.runtime) {\n const rt = preset.runtime;\n if (resetWorldOnChange) {\n return rt.world.addLayoutSubscriber((type) => {\n if (type === 'recalculate-world-size') {\n rt.goHome({ cover });\n }\n });\n }\n }\n return () => {\n // no-op\n };\n }, [preset, cover, resetWorldOnChange]);\n\n useIsomorphicLayoutEffect(() => {\n if (preset) {\n ReactAtlas.render(\n <Canvas>\n <ModeContext.Provider value={mode}>\n <AtlasContext.Provider value={preset}>{children}</AtlasContext.Provider>\n </ModeContext.Provider>\n </Canvas>,\n preset.runtime\n );\n }\n }, [preset, mode, children]);\n\n return {\n loading: !imageUrl && ready,\n uri: imageUrl,\n imageError,\n };\n};\n","import { useRuntime } from './use-runtime';\nimport { useEffect } from 'react';\n\nexport const useBeforeFrame = (callback: (time: number) => void, deps: any[] = []) => {\n const runtime = useRuntime();\n\n useEffect(() => {\n if (runtime) {\n return runtime.registerHook('useBeforeFrame', callback);\n }\n return () => {\n // no-op\n };\n }, deps);\n};\n","import { useCallback, useState } from 'react';\nimport { nanoid } from 'nanoid';\n\nexport const useControlledAnnotationList = (\n initialList: Array<{ x: number; y: number; width: number; height: number; id: any }> = []\n) => {\n const [annotations, setAnnotations] =\n useState<Array<{ x: number; y: number; width: number; height: number; id: any }>>(initialList);\n const [isEditing, setIsEditing] = useState(false);\n const [selectedAnnotation, setSelectedAnnotation] = useState<string | undefined>();\n\n const addNewAnnotation = useCallback(() => {\n setIsEditing(true);\n setSelectedAnnotation(undefined);\n }, []);\n\n const editAnnotation = useCallback((id: string) => {\n setIsEditing(true);\n setSelectedAnnotation(id);\n }, []);\n\n const onUpdateAnnotation = (newAnno: any) => {\n setAnnotations((val) =>\n val.map((ann) => {\n if (ann.id === newAnno.id) {\n return newAnno;\n }\n return ann;\n })\n );\n };\n\n const onCreateNewAnnotation = useCallback((bounds: { x: number; y: number; width: number; height: number }) => {\n const id = nanoid();\n setAnnotations((a) => [...a, { id, ...bounds }]);\n setIsEditing(false);\n setSelectedAnnotation(undefined);\n }, []);\n\n const onDeselect = useCallback(() => {\n setIsEditing(false);\n setSelectedAnnotation(undefined);\n }, []);\n\n return {\n isEditing,\n onDeselect,\n selectedAnnotation,\n onCreateNewAnnotation,\n annotations,\n onUpdateAnnotation,\n setIsEditing,\n setSelectedAnnotation,\n editAnnotation,\n addNewAnnotation,\n };\n};\n","import { useCallback, useEffect, useState } from 'react';\nimport type { RuntimeZoneState } from '../../../renderer/runtime';\nimport { useAfterFrame } from './use-after-frame';\nimport { useRuntime } from './use-runtime';\n\nfunction getDefaultZoneRuntimeState(zoneId: string): RuntimeZoneState {\n return {\n zoneId,\n exists: false,\n active: false,\n visibleInViewport: false,\n };\n}\n\nexport const useZoneRuntimeState = (zoneId: string): RuntimeZoneState => {\n const runtime = useRuntime();\n const [state, setState] = useState<RuntimeZoneState>(() => getDefaultZoneRuntimeState(zoneId));\n\n const update = useCallback(() => {\n const next = runtime ? runtime.getZoneRuntimeState(zoneId) : getDefaultZoneRuntimeState(zoneId);\n setState((prev) => {\n if (\n prev.zoneId === next.zoneId &&\n prev.exists === next.exists &&\n prev.active === next.active &&\n prev.visibleInViewport === next.visibleInViewport\n ) {\n return prev;\n }\n return next;\n });\n }, [runtime, zoneId]);\n\n useAfterFrame(update, [runtime, update]);\n\n useEffect(() => {\n update();\n if (!runtime) {\n return () => {\n // no-op\n };\n }\n return runtime.world.addLayoutSubscriber((type) => {\n if (type === 'zone-changed' || type === 'goto-region' || type === 'recalculate-world-size') {\n update();\n }\n });\n }, [runtime, update]);\n\n return state;\n};\n","import { ViewerMode } from '../../../renderer/runtime';\n\nexport function canDrag(ref: { current: ViewerMode }) {\n return ref.current === 'sketch';\n}\n","import { BoxStyle } from '../objects/box';\n\nexport function mergeStyles(defaultStyle?: BoxStyle, style?: BoxStyle): BoxStyle | undefined {\n if (!defaultStyle) {\n return style;\n }\n if (!style) {\n return defaultStyle;\n }\n return {\n ...defaultStyle,\n ...(style || {}),\n ':hover': defaultStyle[':hover']\n ? Object.assign(defaultStyle[':hover'] || {}, style[':hover'] || {})\n : style[':hover'],\n ':active': defaultStyle[':active']\n ? Object.assign(defaultStyle[':active'] || {}, style[':active'] || {})\n : style[':hover'],\n };\n}\n","import { WorldObject } from './world-object';\nimport { SingleImage } from '../spacial-content';\n\nexport function fromImage(image: {\n src: string;\n height: number;\n width: number;\n target?: { width: number; height: number };\n}): WorldObject {\n const { src, target } = image;\n const width = target ? target.width : image.width;\n const height = target ? target.height : image.height;\n\n return new WorldObject({\n id: src,\n height,\n width,\n layers: [SingleImage.fromImage(src, { height, width }, { width: image.width, height: image.height })],\n });\n}\n"],"x_google_ignoreList":[3,4,5,36,37,38,39,40],"mappings":"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"}
|