@atlas-viewer/atlas 3.0.4 → 3.0.5
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 +8 -8
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -10
- 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/utility/to-box.ts","../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?: number;\n nudge?: boolean;\n immediate?: boolean;\n }) {\n this.trigger('goto-region', data);\n }\n\n goHome(immediate = false) {\n this.trigger('go-home', {\n immediate,\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 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 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\n setHomePosition(position?: Projection) {\n this.homePosition.set(DnaFactory.projection(position ? position : this.world));\n this.pendingUpdate = true;\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 goHome(options: { cover?: boolean; position?: Strand } = {}) {\n if (this.world.width <= 0 || this.world.height <= 0) return;\n\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 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({ target, padding: panPadding });\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 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 // 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 /**\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 this.ctx.fillStyle = this.canvas.dataset.background ?? 'rgb(0, 0, 0)';\n this.ctx.fillRect(0, 0, canvas.width, canvas.height);\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","import { Projection, Strand } from '@atlas-viewer/dna';\n\nexport function toBox(strand: Strand): Projection {\n return {\n x: strand[1],\n y: strand[2],\n width: strand[3] - strand[1],\n height: strand[4] - strand[2],\n };\n}\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 runtime.transitionManager.goToRegion(toBox(runtime.homePosition), { transition });\n }\n if (type === 'goto-region' && data) {\n const transition = data.immediate ? { duration: 0 } : {};\n runtime.transitionManager.goToRegion(data, { transition });\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\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 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\n// @ts-ignore DefinitelyTyped is not up to date\nreconciler.injectIntoDevTools();\n\nexport function unmountComponentAtNode(runtime: Runtime, callback?: (runtime: any) => void) {\n const root = roots.get(runtime);\n if (root) {\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 (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 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 ...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 // 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":["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/utility/to-box.ts","../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?: number;\n nudge?: boolean;\n immediate?: boolean;\n }) {\n this.trigger('goto-region', data);\n }\n\n goHome(immediate = false) {\n this.trigger('go-home', {\n immediate,\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 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 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\n setHomePosition(position?: Projection) {\n this.homePosition.set(DnaFactory.projection(position ? position : this.world));\n this.pendingUpdate = true;\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 goHome(options: { cover?: boolean; position?: Strand } = {}) {\n if (this.world.width <= 0 || this.world.height <= 0) return;\n\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 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({ target, padding: panPadding });\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 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 // 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 /**\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 this.ctx.fillStyle = this.canvas.dataset.background ?? 'rgb(0, 0, 0)';\n this.ctx.fillRect(0, 0, canvas.width, canvas.height);\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","import { Projection, Strand } from '@atlas-viewer/dna';\n\nexport function toBox(strand: Strand): Projection {\n return {\n x: strand[1],\n y: strand[2],\n width: strand[3] - strand[1],\n height: strand[4] - strand[2],\n };\n}\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 runtime.transitionManager.goToRegion(toBox(runtime.homePosition), { transition });\n }\n if (type === 'goto-region' && data) {\n const transition = data.immediate ? { duration: 0 } : {};\n runtime.transitionManager.goToRegion(data, { transition });\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 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 ...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 // 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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"}
|