presenter 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/3d/index.d.ts +17 -0
  2. package/dist/3d/objects/ThreeBox.d.ts +9 -0
  3. package/dist/3d/objects/ThreeCameraType.d.ts +5 -0
  4. package/dist/3d/objects/ThreeMesh.d.ts +30 -0
  5. package/dist/3d/objects/ThreeModel.d.ts +18 -0
  6. package/dist/3d/objects/ThreeModelMaterial.d.ts +11 -0
  7. package/dist/3d/objects/ThreeModelNode.d.ts +24 -0
  8. package/dist/3d/objects/ThreeModelTarget.d.ts +9 -0
  9. package/dist/3d/objects/ThreeObjectType.d.ts +10 -0
  10. package/dist/3d/objects/ThreePresenterGroup.d.ts +13 -0
  11. package/dist/3d/objects/ThreeScene.d.ts +39 -0
  12. package/dist/3d/objects/ThreeSphere.d.ts +9 -0
  13. package/dist/3d/renderers/getThreeObjectRenderers.d.ts +6 -0
  14. package/dist/3d/renderers/renderThreeSceneFallback.d.ts +3 -0
  15. package/dist/3d/renderers/renderThreeScenePowerPointFallback.d.ts +3 -0
  16. package/dist/3d/renderers/threeFallbackRenderers.d.ts +5 -0
  17. package/dist/3d/types/ThreeModules.d.ts +10 -0
  18. package/dist/3d/utils/colorToThreeHex.d.ts +2 -0
  19. package/dist/3d/utils/inspectThreeModel.d.ts +4 -0
  20. package/dist/3d/utils/installThreeSceneCaptureApi.d.ts +21 -0
  21. package/dist/3d/utils/loadThreeModules.d.ts +2 -0
  22. package/dist/3d/utils/modelCache.d.ts +6 -0
  23. package/dist/3d/utils/modelInspection.d.ts +23 -0
  24. package/dist/3d/utils/modelInspection.test.d.ts +1 -0
  25. package/dist/3d/utils/modelPaths.d.ts +14 -0
  26. package/dist/3d/utils/modelPaths.test.d.ts +1 -0
  27. package/dist/3d.js +2 -0
  28. package/dist/3d.js.map +1 -0
  29. package/dist/3d.mjs +1055 -0
  30. package/dist/3d.mjs.map +1 -0
  31. package/dist/export/browser-image-renderer/BrowserImageRenderer.d.ts +7 -0
  32. package/dist/export/browser-image-renderer/types/BrowserImageRendererProps.d.ts +36 -0
  33. package/dist/export/browser.d.ts +2 -0
  34. package/dist/export/image-renderer/ImageRenderer.d.ts +1 -1
  35. package/dist/export/index.d.ts +2 -0
  36. package/dist/export/utils/getImageExportFrames.d.ts +14 -0
  37. package/dist/export/utils/getImageExportFrames.test.d.ts +1 -0
  38. package/dist/export-browser.js +6 -0
  39. package/dist/export-browser.js.map +1 -0
  40. package/dist/export-browser.mjs +2231 -0
  41. package/dist/export-browser.mjs.map +1 -0
  42. package/dist/export.js +74 -72
  43. package/dist/export.js.map +1 -1
  44. package/dist/export.mjs +5443 -4333
  45. package/dist/export.mjs.map +1 -1
  46. package/dist/objects/Image.d.ts +2 -1
  47. package/dist/presenter.js +5 -5
  48. package/dist/presenter.js.map +1 -1
  49. package/dist/presenter.mjs +1820 -1794
  50. package/dist/presenter.mjs.map +1 -1
  51. package/dist/renderer/browser-canvas/types/BrowserCanvasObjectRenderer.d.ts +8 -1
  52. package/dist/renderer/browser-canvas/utils/text/getTextLayout.d.ts +4 -11
  53. package/dist/renderer/browser-canvas/utils/text/getTextUnitMeasurements.d.ts +9 -0
  54. package/dist/utils/presentation/getImagePathUrlById.d.ts +2 -0
  55. package/dist/utils/presentation/getObjectChildren.d.ts +1 -1
  56. package/package.json +23 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"3d.mjs","sources":["../src/types/ObjectType.ts","../src/types/SlideObject.ts","../src/types/Color.ts","../src/3d/objects/ThreeMesh.ts","../src/3d/objects/ThreeObjectType.ts","../src/3d/objects/ThreeBox.ts","../src/3d/objects/ThreeCameraType.ts","../src/3d/objects/ThreeModel.ts","../src/3d/objects/ThreeModelMaterial.ts","../src/3d/objects/ThreeModelNode.ts","../src/3d/objects/ThreePresenterGroup.ts","../src/types/Anchor.ts","../src/3d/objects/ThreeScene.ts","../src/3d/objects/ThreeSphere.ts","../src/renderer/browser-canvas/types/UnifiedCanvasContext.ts","../src/types/Position.ts","../src/types/Size.ts","../src/utils/color/getAlphaForColor.ts","../src/types/BoundingBox.ts","../src/utils/core/assertNever.ts","../src/utils/layout/getBoundingBox.ts","../src/3d/utils/colorToThreeHex.ts","../src/3d/utils/loadThreeModules.ts","../src/utils/presentation/getObjectChildren.ts","../src/3d/utils/modelPaths.ts","../src/3d/utils/modelInspection.ts","../src/3d/utils/modelCache.ts","../src/3d/renderers/getThreeObjectRenderers.ts","../src/objects/Image.ts","../src/utils/objects/rectangle/getRoundedRectanglePath.ts","../src/renderer/browser-canvas/types/UnifiedImage.ts","../src/renderer/browser-canvas/types/UnifiedPath2D.ts","../src/renderer/browser-canvas/objects/renderImage.ts","../src/3d/renderers/renderThreeSceneFallback.ts","../src/export/powerpoint-renderer/utils/getTransformedBoundingBox.ts","../src/export/powerpoint-renderer/utils/getUnitsFromPixels.ts","../src/export/powerpoint-renderer/objects/renderImage.ts","../src/3d/renderers/renderThreeScenePowerPointFallback.ts","../src/3d/renderers/threeFallbackRenderers.ts","../src/3d/utils/inspectThreeModel.ts","../src/3d/utils/installThreeSceneCaptureApi.ts"],"sourcesContent":["export const ObjectType = {\n ARROW: \"Arrow\",\n CIRCLE: \"Circle\",\n GROUP: \"Group\",\n IMAGE: \"Image\",\n LINE: \"Line\",\n MASK: \"Mask\",\n PATH: \"Path\",\n POLYGON: \"Polygon\",\n RECTANGLE: \"Rectangle\",\n SLIDE_OBJECT: \"SlideObject\",\n SPOTLIGHT: \"Spotlight\",\n SVG: \"SVG\",\n TEXT: \"Text\",\n} as const;\n\nexport type ObjectType = (typeof ObjectType)[keyof typeof ObjectType];\n","import { ObjectType } from \"./ObjectType\";\n\nexport interface SlideObject {\n /** A screen-reader description included while the object is visible. */\n readonly description: string | null;\n readonly objectType: string;\n readonly opacity: number;\n}\n\nexport function SlideObject<T>(props: Partial<SlideObject> & T): SlideObject & T {\n return {\n description: null,\n objectType: ObjectType.SLIDE_OBJECT,\n opacity: 1,\n ...props,\n };\n}\n","export interface Color {\n /** Red channel, in [0, 255] */\n red: number;\n\n /** Green channel, in [0, 255] */\n green: number;\n\n /** Blue channel, in [0, 255] */\n blue: number;\n\n /** Alpha channel, in [0, 1] */\n alpha: number;\n}\n\nexport function Color(color: Partial<Color> | string): Color;\nexport function Color(red: number, green: number, blue: number, alpha?: number): Color;\nexport function Color(\n color: Partial<Color> | string | number,\n green: number = 0,\n blue: number = 0,\n alpha: number = 1,\n): Color {\n if (typeof color === \"string\") {\n const hexString = color.replace(\"#\", \"\");\n const hex = parseInt(hexString, 16);\n\n if (isNaN(hex)) {\n console.warn(\"Invalid hex color format:\", color);\n return DEFAULT_COLOR;\n }\n\n if (hexString.length === 6) {\n return {\n red: (hex >> 16) & 255,\n green: (hex >> 8) & 255,\n blue: hex & 255,\n alpha: 1,\n };\n } else if (hexString.length === 8) {\n return {\n red: (hex >> 24) & 255,\n green: (hex >> 16) & 255,\n blue: (hex >> 8) & 255,\n alpha: (hex & 255) / 255,\n };\n } else {\n console.warn(\"Invalid hex color format:\", color);\n return DEFAULT_COLOR;\n }\n } else if (typeof color === \"number\") {\n return {\n red: color,\n green: green ?? 0,\n blue: blue ?? 0,\n alpha: alpha ?? 1,\n };\n }\n\n return {\n red: 0,\n green: 0,\n blue: 0,\n alpha: 1,\n ...color,\n };\n}\n\nColor.BLACK = Color(0, 0, 0);\nColor.BLUE = Color(0, 0, 255);\nColor.GREEN = Color(0, 255, 0);\nColor.RED = Color(255, 0, 0);\nColor.TRANSPARENT = Color(0, 0, 0, 0);\nColor.WHITE = Color(255, 255, 255);\n\nexport const DEFAULT_COLOR: Color = { red: 0, green: 0, blue: 0, alpha: 1 };\n","import { Color } from \"../../types/Color\";\nimport { SlideObject } from \"../../types/SlideObject\";\n\nexport interface ThreeMesh extends SlideObject {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n readonly rotationX: number;\n readonly rotationY: number;\n readonly rotationZ: number;\n readonly scale: number;\n readonly scaleX: number;\n readonly scaleY: number;\n readonly scaleZ: number;\n readonly color: Color;\n readonly wireframe: boolean;\n}\n\nexport const THREE_MESH_DEFAULTS = {\n x: 0,\n y: 0,\n z: 0,\n rotationX: 0,\n rotationY: 0,\n rotationZ: 0,\n scale: 1,\n scaleX: 1,\n scaleY: 1,\n scaleZ: 1,\n color: Color.WHITE,\n wireframe: false,\n} as const;\n","export const ThreeObjectType = {\n BOX: \"ThreeBox\",\n MODEL: \"ThreeModel\",\n MODEL_MATERIAL: \"ThreeModelMaterial\",\n MODEL_NODE: \"ThreeModelNode\",\n PRESENTER_GROUP: \"ThreePresenterGroup\",\n SCENE: \"ThreeScene\",\n SPHERE: \"ThreeSphere\",\n} as const;\n\nexport type ThreeObjectType = (typeof ThreeObjectType)[keyof typeof ThreeObjectType];\n","import { SlideObject } from \"../../types/SlideObject\";\nimport { THREE_MESH_DEFAULTS, ThreeMesh } from \"./ThreeMesh\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeBox extends ThreeMesh {\n readonly objectType: typeof ThreeObjectType.BOX;\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n}\n\nexport function ThreeBox(props: Partial<ThreeBox> | null = null): ThreeBox {\n return SlideObject({\n objectType: ThreeObjectType.BOX,\n ...THREE_MESH_DEFAULTS,\n width: 1,\n height: 1,\n depth: 1,\n ...props,\n });\n}\n","export const ThreeCameraType = {\n ORTHOGRAPHIC: \"Orthographic\",\n PERSPECTIVE: \"Perspective\",\n} as const;\n\nexport type ThreeCameraType = (typeof ThreeCameraType)[keyof typeof ThreeCameraType];\n","import { Color } from \"../../types/Color\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { THREE_MESH_DEFAULTS, ThreeMesh } from \"./ThreeMesh\";\nimport { ThreeModelMaterial } from \"./ThreeModelMaterial\";\nimport { ThreeModelNode } from \"./ThreeModelNode\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeModel extends ThreeMesh {\n readonly objectType: typeof ThreeObjectType.MODEL;\n readonly src: string;\n\n /** Overrides every material in the imported model. */\n readonly materialColor: Color | null;\n\n /** Animatable controls for named nodes inside the imported model. */\n readonly nodes: ThreeModelNode[];\n\n /** Animatable controls for named materials inside the imported model. */\n readonly materials: ThreeModelMaterial[];\n\n /** Logs available node and material names to the console once the model is loaded. */\n readonly debugNames: boolean;\n}\n\nexport function ThreeModel(props: Partial<ThreeModel> | null = null): ThreeModel {\n return SlideObject({\n objectType: ThreeObjectType.MODEL,\n ...THREE_MESH_DEFAULTS,\n src: \"\",\n materialColor: null,\n nodes: [],\n materials: [],\n debugNames: false,\n ...props,\n });\n}\n","import { Color } from \"../../types/Color\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { ThreeModelTarget } from \"./ThreeModelTarget\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeModelMaterial extends SlideObject, Omit<ThreeModelTarget, \"path\"> {\n readonly objectType: typeof ThreeObjectType.MODEL_MATERIAL;\n\n /** Overrides each matching material's color while preserving other material properties. */\n readonly materialColor: Color | null;\n readonly wireframe: boolean;\n}\n\nexport function ThreeModelMaterial(\n props: Partial<ThreeModelMaterial> | null = null,\n): ThreeModelMaterial {\n return SlideObject({\n objectType: ThreeObjectType.MODEL_MATERIAL,\n name: null,\n presenterId: null,\n materialColor: null,\n wireframe: false,\n ...props,\n });\n}\n","import { Color } from \"../../types/Color\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { THREE_MESH_DEFAULTS } from \"./ThreeMesh\";\nimport { ThreeModelTarget } from \"./ThreeModelTarget\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeModelNode extends SlideObject, ThreeModelTarget {\n readonly objectType: typeof ThreeObjectType.MODEL_NODE;\n\n /** Position offsets added to the matched node's exported local transform. */\n readonly x: number;\n readonly y: number;\n readonly z: number;\n\n /** Rotation offsets, in degrees, added to the matched node's exported local rotation. */\n readonly rotationX: number;\n readonly rotationY: number;\n readonly rotationZ: number;\n\n /** Scale multipliers applied to the matched node's exported local scale. */\n readonly scale: number;\n readonly scaleX: number;\n readonly scaleY: number;\n readonly scaleZ: number;\n\n /** Overrides descendant mesh materials under the matched node. */\n readonly materialColor: Color | null;\n readonly wireframe: boolean;\n}\n\nexport function ThreeModelNode(props: Partial<ThreeModelNode> | null = null): ThreeModelNode {\n return SlideObject({\n objectType: ThreeObjectType.MODEL_NODE,\n name: null,\n path: null,\n presenterId: null,\n x: THREE_MESH_DEFAULTS.x,\n y: THREE_MESH_DEFAULTS.y,\n z: THREE_MESH_DEFAULTS.z,\n rotationX: THREE_MESH_DEFAULTS.rotationX,\n rotationY: THREE_MESH_DEFAULTS.rotationY,\n rotationZ: THREE_MESH_DEFAULTS.rotationZ,\n scale: THREE_MESH_DEFAULTS.scale,\n scaleX: THREE_MESH_DEFAULTS.scaleX,\n scaleY: THREE_MESH_DEFAULTS.scaleY,\n scaleZ: THREE_MESH_DEFAULTS.scaleZ,\n materialColor: null,\n wireframe: THREE_MESH_DEFAULTS.wireframe,\n ...props,\n });\n}\n","import { SlideObject } from \"../../types/SlideObject\";\nimport { THREE_MESH_DEFAULTS, ThreeMesh } from \"./ThreeMesh\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreePresenterGroup extends ThreeMesh {\n readonly objectType: typeof ThreeObjectType.PRESENTER_GROUP;\n readonly objects: SlideObject[];\n readonly width: number;\n readonly height: number;\n // Width of coordinate system that the group is drawn into\n readonly textureWidth: number | null;\n // Height of coordinate system that the group is drawn into\n readonly textureHeight: number | null;\n readonly doubleSided: boolean;\n}\n\nexport function ThreePresenterGroup(\n objects: SlideObject[],\n props: Partial<Omit<ThreePresenterGroup, \"objects\">> | null = null,\n): ThreePresenterGroup {\n return SlideObject({\n objectType: ThreeObjectType.PRESENTER_GROUP,\n ...THREE_MESH_DEFAULTS,\n objects,\n width: 1,\n height: 1,\n textureWidth: null,\n textureHeight: null,\n doubleSided: true,\n ...props,\n });\n}\n","export const Anchor = {\n TOP_LEFT: \"TopLeft\",\n TOP: \"Top\",\n TOP_RIGHT: \"TopRight\",\n LEFT: \"Left\",\n CENTER: \"Center\",\n RIGHT: \"Right\",\n BOTTOM_LEFT: \"BottomLeft\",\n BOTTOM: \"Bottom\",\n BOTTOM_RIGHT: \"BottomRight\",\n} as const;\n\nexport type Anchor = (typeof Anchor)[keyof typeof Anchor];\n\nexport const DEFAULT_ANCHOR: Anchor = Anchor.TOP_LEFT;\n","import { Anchor, DEFAULT_ANCHOR } from \"../../types/Anchor\";\nimport { Color } from \"../../types/Color\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { ThreeCameraType } from \"./ThreeCameraType\";\nimport { ThreeMesh } from \"./ThreeMesh\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeScene extends SlideObject {\n readonly objectType: typeof ThreeObjectType.SCENE;\n readonly anchor: Anchor;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly meshes: ThreeMesh[];\n readonly fallbackImageId: string | null;\n readonly fallbackImagePath: string | null;\n readonly fallbackCornerRadius: number;\n readonly fallbackSmooth: boolean;\n readonly cameraType: ThreeCameraType;\n readonly cameraX: number;\n readonly cameraY: number;\n readonly cameraZ: number;\n readonly cameraFov: number;\n readonly cameraOrthographicHeight: number | null;\n readonly cameraNear: number;\n readonly cameraFar: number;\n readonly targetX: number;\n readonly targetY: number;\n readonly targetZ: number;\n readonly backgroundColor: Color | null;\n readonly ambientLightColor: Color;\n readonly ambientLightIntensity: number;\n readonly directionalLightColor: Color;\n readonly directionalLightIntensity: number;\n readonly directionalLightX: number;\n readonly directionalLightY: number;\n readonly directionalLightZ: number;\n}\n\nexport function ThreeScene(\n meshes: ThreeMesh[],\n props: Partial<Omit<ThreeScene, \"meshes\">> | null = null,\n): ThreeScene {\n return SlideObject({\n objectType: ThreeObjectType.SCENE,\n anchor: DEFAULT_ANCHOR,\n x: 0,\n y: 0,\n width: 100,\n height: 100,\n meshes,\n fallbackImageId: null,\n fallbackImagePath: null,\n fallbackCornerRadius: 0,\n fallbackSmooth: true,\n cameraType: ThreeCameraType.PERSPECTIVE,\n cameraX: 0,\n cameraY: 0,\n cameraZ: 5,\n cameraFov: 50,\n cameraOrthographicHeight: null,\n cameraNear: 0.1,\n cameraFar: 2000,\n targetX: 0,\n targetY: 0,\n targetZ: 0,\n backgroundColor: null,\n ambientLightColor: Color.WHITE,\n ambientLightIntensity: 1,\n directionalLightColor: Color.WHITE,\n directionalLightIntensity: 2,\n directionalLightX: 3,\n directionalLightY: 4,\n directionalLightZ: 5,\n ...props,\n });\n}\n","import { SlideObject } from \"../../types/SlideObject\";\nimport { THREE_MESH_DEFAULTS, ThreeMesh } from \"./ThreeMesh\";\nimport { ThreeObjectType } from \"./ThreeObjectType\";\n\nexport interface ThreeSphere extends ThreeMesh {\n readonly objectType: typeof ThreeObjectType.SPHERE;\n readonly radius: number;\n readonly widthSegments: number;\n readonly heightSegments: number;\n}\n\nexport function ThreeSphere(props: Partial<ThreeSphere> | null = null): ThreeSphere {\n return SlideObject({\n objectType: ThreeObjectType.SPHERE,\n ...THREE_MESH_DEFAULTS,\n radius: 1,\n widthSegments: 32,\n heightSegments: 16,\n ...props,\n });\n}\n","import { type CanvasRenderingContext2D as SkiaCanvasRenderingContext2D } from \"skia-canvas\";\n\nexport const CanvasContextType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type CanvasContextType = (typeof CanvasContextType)[keyof typeof CanvasContextType];\n\nexport interface BrowserCanvasContext {\n readonly type: typeof CanvasContextType.Browser;\n readonly context: CanvasRenderingContext2D;\n}\n\nexport interface NodeCanvasContext {\n readonly type: typeof CanvasContextType.Node;\n readonly context: SkiaCanvasRenderingContext2D;\n}\n\n/**\n * A unified CanvasRenderingContext2D type that works in both browser and Node.js environments.\n */\nexport type UnifiedCanvasContext = BrowserCanvasContext | NodeCanvasContext;\n","export interface Position {\n readonly x: number;\n readonly y: number;\n}\n\nexport function Position(props: Partial<Position> | null = null): Position {\n return {\n x: 0,\n y: 0,\n ...props,\n };\n}\n\nexport const DEFAULT_POSITION = Position();\n","export interface Size {\n readonly height: number;\n readonly width: number;\n}\n\nexport function Size(props: Partial<Size> | null = null): Size {\n return {\n height: 0,\n width: 0,\n ...props,\n };\n}\n\nexport const DEFAULT_SIZE: Size = Size({ width: 0, height: 0 });\n","import { Color } from \"../../types/Color\";\n\n/**\n * Returns the alpha value for a color in [0, 1], given the color and the overall opacity of a shape.\n * Combines the color's alpha and the overall opacity.\n */\nexport function getAlphaForColor(color: Color, opacity: number | null = null): number {\n return color.alpha * (opacity ?? 1);\n}\n","import { DEFAULT_POSITION, Position } from \"./Position\";\nimport { DEFAULT_SIZE, Size } from \"./Size\";\n\nexport interface BoundingBox {\n /** The position of the top-left corner of the bounding box */\n readonly origin: Position;\n\n /** The size of the bounding box */\n readonly size: Size;\n}\n\nexport function BoundingBox(props: Partial<BoundingBox> | null = null): BoundingBox {\n return {\n origin: DEFAULT_POSITION,\n size: DEFAULT_SIZE,\n ...props,\n };\n}\n\nexport const DEFAULT_BOUNDING_BOX: BoundingBox = BoundingBox();\n","export function assertNever(value: never, message?: string): never {\n throw new Error((message ?? \"Unexpected value\") + \": \" + value);\n}\n","import { Anchor } from \"../../types/Anchor\";\nimport { BoundingBox } from \"../../types/BoundingBox\";\nimport { Position } from \"../../types/Position\";\nimport { Size } from \"../../types/Size\";\nimport { assertNever } from \"../core/assertNever\";\n\nexport function getBoundingBox(position: Position, anchor: Anchor, size: Size): BoundingBox {\n const { x, y } = position;\n const { width, height } = size;\n\n switch (anchor) {\n case Anchor.TOP_LEFT:\n return BoundingBox({\n origin: Position({ x, y }),\n size,\n });\n case Anchor.TOP:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y }),\n size,\n });\n case Anchor.TOP_RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y }),\n size,\n });\n case Anchor.LEFT:\n return BoundingBox({\n origin: Position({ x, y: y - height / 2 }),\n size,\n });\n case Anchor.CENTER:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y: y - height / 2 }),\n size,\n });\n case Anchor.RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y: y - height / 2 }),\n size,\n });\n case Anchor.BOTTOM_LEFT:\n return BoundingBox({\n origin: Position({ x, y: y - height }),\n size,\n });\n case Anchor.BOTTOM:\n return BoundingBox({\n origin: Position({ x: x - width / 2, y: y - height }),\n size,\n });\n case Anchor.BOTTOM_RIGHT:\n return BoundingBox({\n origin: Position({ x: x - width, y: y - height }),\n size,\n });\n default:\n assertNever(anchor);\n }\n}\n","import { Color } from \"../../types/Color\";\n\nexport function colorToThreeHex(color: Color): number {\n return (color.red << 16) + (color.green << 8) + color.blue;\n}\n","import { ThreeModules } from \"../types/ThreeModules\";\n\nexport async function loadThreeModules(): Promise<ThreeModules> {\n try {\n const [THREE, loaderModule] = await Promise.all([\n import(\"three\"),\n import(\"three/examples/jsm/loaders/GLTFLoader.js\"),\n ]);\n return { THREE, GLTFLoader: loaderModule.GLTFLoader };\n } catch (error) {\n throw new Error(\n 'Presenter 3D rendering requires the \"three\" package. Install it with: npm install three',\n { cause: error },\n );\n }\n}\n","import { SlideObject } from \"../../types/SlideObject\";\n\n/**\n * Returns the children of a SlideObject if they exist.\n */\nexport function getObjectChildren(object: SlideObject): SlideObject[] {\n const children: SlideObject[] = [];\n const childContainers = object as SlideObject &\n Partial<Record<\"objects\" | \"meshes\" | \"nodes\" | \"materials\", unknown>>;\n\n for (const key of [\"objects\", \"meshes\", \"nodes\", \"materials\"] as const) {\n const value = childContainers[key];\n if (Array.isArray(value)) {\n children.push(...getSlideObjects(value));\n }\n }\n return children;\n}\n\nfunction getSlideObjects(objects: unknown[]): SlideObject[] {\n return objects.filter(\n (object): object is SlideObject =>\n typeof object === \"object\" && object !== null && \"objectType\" in object,\n );\n}\n","import type * as Three from \"three\";\n\nimport { ThreeModelPath, ThreeModelTarget } from \"../objects/ThreeModelTarget\";\n\nexport interface ObjectPath {\n readonly object: Three.Object3D;\n readonly path: readonly string[];\n}\n\nexport function collectObjectPaths(root: Three.Object3D): ObjectPath[] {\n const paths: ObjectPath[] = [];\n\n function visit(object: Three.Object3D, parentPath: readonly string[]) {\n const path = object === root && object.name === \"\" ? parentPath : [...parentPath, object.name];\n if (object !== root || object.name !== \"\") {\n paths.push({ object, path });\n }\n for (const child of object.children) {\n visit(child, path);\n }\n }\n\n visit(root, []);\n return paths;\n}\n\nexport function normalizeModelPath(path: ThreeModelPath): readonly string[] {\n return typeof path === \"string\" ? path.split(\"/\").filter((part) => part !== \"\") : path;\n}\n\nexport function modelPathToString(path: readonly string[]): string {\n return path.join(\"/\");\n}\n\nexport function modelTargetToString(target: ThreeModelTarget | Omit<ThreeModelTarget, \"path\">) {\n if (\"path\" in target && target.path !== null) {\n return `path \"${modelPathToString(normalizeModelPath(target.path))}\"`;\n }\n if (target.presenterId !== null) {\n return `presenterId \"${target.presenterId}\"`;\n }\n if (target.name !== null) {\n return `name \"${target.name}\"`;\n }\n return \"empty target\";\n}\n\nexport function objectPathMatches(path: readonly string[], targetPath: ThreeModelPath): boolean {\n const normalizedTargetPath = normalizeModelPath(targetPath);\n if (normalizedTargetPath.length > path.length) {\n return false;\n }\n\n const offset = path.length - normalizedTargetPath.length;\n return normalizedTargetPath.every((part, index) => path[offset + index] === part);\n}\n\nexport function getPresenterId(object: { userData?: Record<string, unknown> }): string | null {\n const id = object.userData?.presenterId ?? object.userData?.presenterID;\n return typeof id === \"string\" ? id : null;\n}\n","import type * as Three from \"three\";\n\nimport { collectObjectPaths, getPresenterId, modelPathToString } from \"./modelPaths\";\n\nexport interface ThreeModelNodeInfo {\n readonly name: string;\n readonly path: readonly string[];\n readonly pathString: string;\n readonly type: string;\n readonly isMesh: boolean;\n readonly isBone: boolean;\n readonly presenterId: string | null;\n readonly materialNames: readonly string[];\n}\n\nexport interface ThreeModelMaterialInfo {\n readonly name: string;\n readonly presenterId: string | null;\n readonly meshPaths: readonly string[];\n}\n\nexport interface ThreeModelInspection {\n readonly src: string;\n readonly nodes: readonly ThreeModelNodeInfo[];\n readonly materials: readonly ThreeModelMaterialInfo[];\n}\n\nexport function inspectThreeModelScene(src: string, scene: Three.Object3D): ThreeModelInspection {\n const materialInfoByMaterial = new Map<Three.Material, ThreeModelMaterialInfo>();\n\n const nodes = collectObjectPaths(scene).map(({ object, path }) => {\n const materials = isMesh(object)\n ? Array.isArray(object.material)\n ? object.material\n : [object.material]\n : [];\n const materialNames = materials.map((material) => material.name);\n\n for (const material of materials) {\n const existingInfo = materialInfoByMaterial.get(material);\n const meshPath = modelPathToString(path);\n if (existingInfo === undefined) {\n materialInfoByMaterial.set(material, {\n name: material.name,\n presenterId: getPresenterId(material),\n meshPaths: [meshPath],\n });\n } else {\n materialInfoByMaterial.set(material, {\n ...existingInfo,\n meshPaths: [...existingInfo.meshPaths, meshPath],\n });\n }\n }\n\n return {\n name: object.name,\n path,\n pathString: modelPathToString(path),\n type: object.type,\n isMesh: isMesh(object),\n isBone: isBone(object),\n presenterId: getPresenterId(object),\n materialNames,\n };\n });\n\n return {\n src,\n nodes,\n materials: [...materialInfoByMaterial.values()],\n };\n}\n\nexport function logThreeModelInspection(inspection: ThreeModelInspection): void {\n const title = `ThreeModel ${inspection.src}`;\n const logger = console.groupCollapsed ?? console.group;\n logger.call(console, title);\n console.table(\n inspection.nodes.map((node) => ({\n path: node.pathString,\n name: node.name,\n type: node.type,\n presenterId: node.presenterId,\n materials: node.materialNames.join(\", \"),\n })),\n );\n console.table(\n inspection.materials.map((material) => ({\n name: material.name,\n presenterId: material.presenterId,\n meshes: material.meshPaths.join(\", \"),\n })),\n );\n console.groupEnd?.();\n}\n\nfunction isMesh(object: Three.Object3D): object is Three.Mesh {\n return \"isMesh\" in object && object.isMesh === true;\n}\n\nfunction isBone(object: Three.Object3D): object is Three.Bone {\n return \"isBone\" in object && object.isBone === true;\n}\n","import type { Object3D } from \"three\";\n\nimport { Presentation } from \"../../types/Presentation\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { getObjectChildren } from \"../../utils/presentation/getObjectChildren\";\nimport { ThreeModel } from \"../objects/ThreeModel\";\nimport { ThreeObjectType } from \"../objects/ThreeObjectType\";\nimport { GLTFLoaderLike } from \"../types/ThreeModules\";\nimport { inspectThreeModelScene, logThreeModelInspection } from \"./modelInspection\";\n\ninterface LoadedModel {\n readonly status: \"loaded\";\n readonly scene: Object3D;\n}\n\ninterface LoadingModel {\n readonly status: \"loading\";\n readonly promise: Promise<void>;\n}\n\ntype ModelState = LoadedModel | LoadingModel;\n\ninterface ModelPreloadRequest {\n readonly src: string;\n readonly debugNames: boolean;\n}\n\n/**\n * Cache GLB/GLTF load state by source URL for the lifetime of the browser session.\n *\n * `getThreeObjectRenderers(presentation)` preloads every model before presentation rendering\n * starts. This cache deduplicates repeated model references across slides, lets multiple preload\n * calls share in-flight work during hot module replacement, and keeps already-parsed Three.js\n * scenes available when the renderer is recreated in the same JS session.\n */\nconst modelStateBySrc = new Map<string, ModelState>();\nconst loggedInspectionBySrc = new Set<string>();\n\nexport async function preloadThreeModels(\n loader: GLTFLoaderLike,\n presentation: Presentation,\n): Promise<void> {\n const modelRequests = new Map<string, ModelPreloadRequest>();\n\n for (const slide of presentation.slides) {\n for (const object of slide.objects) {\n collectModelSources(object, modelRequests);\n }\n }\n\n await Promise.all(\n [...modelRequests.values()].map(async (request) => {\n try {\n await loadThreeModel(loader, request.src);\n if (request.debugNames) {\n logLoadedModelInspection(request.src);\n }\n } catch (error) {\n throw new Error(`Failed to load 3D model: ${request.src}`, { cause: error });\n }\n }),\n );\n}\n\nexport function getLoadedModelScene(src: string): Object3D | null {\n const state = modelStateBySrc.get(src);\n return state?.status === \"loaded\" ? state.scene : null;\n}\n\nexport function loadThreeModel(loader: GLTFLoaderLike, src: string): Promise<void> {\n return loadModel(loader, src);\n}\n\nfunction collectModelSources(object: SlideObject, sources: Map<string, ModelPreloadRequest>): void {\n if (object.objectType === ThreeObjectType.MODEL) {\n const model = object as ThreeModel;\n if (model.src !== \"\") {\n const existingRequest = sources.get(model.src);\n sources.set(model.src, {\n src: model.src,\n debugNames: model.debugNames || existingRequest?.debugNames === true,\n });\n }\n }\n\n for (const childObject of getObjectChildren(object)) {\n collectModelSources(childObject, sources);\n }\n}\n\nfunction logLoadedModelInspection(src: string): void {\n if (loggedInspectionBySrc.has(src)) {\n return;\n }\n\n const scene = getLoadedModelScene(src);\n if (scene === null) {\n return;\n }\n\n loggedInspectionBySrc.add(src);\n logThreeModelInspection(inspectThreeModelScene(src, scene));\n}\n\nfunction loadModel(loader: GLTFLoaderLike, src: string): Promise<void> {\n const existingState = modelStateBySrc.get(src);\n if (existingState?.status === \"loaded\") {\n return Promise.resolve();\n }\n if (existingState?.status === \"loading\") {\n return existingState.promise;\n }\n\n const promise = new Promise<void>((resolve, reject) => {\n loader.load(\n src,\n (gltf) => {\n modelStateBySrc.set(src, { status: \"loaded\", scene: gltf.scene });\n resolve();\n },\n undefined,\n (error: unknown) => {\n modelStateBySrc.delete(src);\n reject(error);\n },\n );\n });\n\n modelStateBySrc.set(src, { status: \"loading\", promise });\n return promise;\n}\n","import type * as Three from \"three\";\n\nimport {\n BrowserCanvasObjectRenderer,\n BrowserCanvasObjectRendererArgs,\n} from \"../../renderer/browser-canvas/types/BrowserCanvasObjectRenderer\";\nimport { CanvasContextType } from \"../../renderer/browser-canvas/types/UnifiedCanvasContext\";\nimport { Color } from \"../../types/Color\";\nimport { Position } from \"../../types/Position\";\nimport { Presentation } from \"../../types/Presentation\";\nimport { Size } from \"../../types/Size\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { getAlphaForColor } from \"../../utils/color/getAlphaForColor\";\nimport { getBoundingBox } from \"../../utils/layout/getBoundingBox\";\nimport { ThreeBox } from \"../objects/ThreeBox\";\nimport { ThreeCameraType } from \"../objects/ThreeCameraType\";\nimport { ThreeMesh } from \"../objects/ThreeMesh\";\nimport { ThreeModel } from \"../objects/ThreeModel\";\nimport { ThreeModelMaterial } from \"../objects/ThreeModelMaterial\";\nimport { ThreeModelNode } from \"../objects/ThreeModelNode\";\nimport { ThreeModelTarget } from \"../objects/ThreeModelTarget\";\nimport { ThreeObjectType } from \"../objects/ThreeObjectType\";\nimport { ThreePresenterGroup } from \"../objects/ThreePresenterGroup\";\nimport { ThreeScene } from \"../objects/ThreeScene\";\nimport { ThreeSphere } from \"../objects/ThreeSphere\";\nimport { GLTFLoaderLike, ThreeModules } from \"../types/ThreeModules\";\nimport { colorToThreeHex } from \"../utils/colorToThreeHex\";\nimport { loadThreeModules } from \"../utils/loadThreeModules\";\nimport { getLoadedModelScene, preloadThreeModels } from \"../utils/modelCache\";\nimport {\n collectObjectPaths,\n getPresenterId,\n modelTargetToString,\n objectPathMatches,\n} from \"../utils/modelPaths\";\n\ninterface Runtime {\n readonly renderer: Three.WebGLRenderer;\n readonly scene: Three.Scene;\n camera: Three.PerspectiveCamera | Three.OrthographicCamera;\n cameraType: ThreeCameraType;\n readonly target: Three.Vector3;\n}\n\nconst runtimeByScene = new WeakMap<SlideObject, Runtime>();\nconst loggedTargetWarningKeys = new Set<string>();\n\nexport async function getThreeObjectRenderers(\n presentation: Presentation,\n): Promise<Record<string, BrowserCanvasObjectRenderer<SlideObject>>> {\n const modules = await loadThreeModules();\n const loader: GLTFLoaderLike = new modules.GLTFLoader();\n await preloadThreeModels(loader, presentation);\n\n return {\n [ThreeObjectType.SCENE]: createRenderThreeScene(\n modules,\n ) as BrowserCanvasObjectRenderer<SlideObject>,\n };\n}\n\nexport function getRenderedThreeSceneCanvas(scene: ThreeScene): HTMLCanvasElement | null {\n return runtimeByScene.get(scene)?.renderer.domElement ?? null;\n}\n\nfunction createRenderThreeScene({ THREE }: ThreeModules): BrowserCanvasObjectRenderer<ThreeScene> {\n return (args) => {\n const { ctx, object: sceneObject, opacity, originalObject, getCurrentObject } = args;\n\n if (ctx.type !== CanvasContextType.Browser) {\n return;\n }\n\n const targetOpacity = opacity * sceneObject.opacity;\n if (targetOpacity === 0 || sceneObject.width <= 0 || sceneObject.height <= 0) {\n return;\n }\n\n const runtime = getRuntime(THREE, sceneObject, originalObject);\n runtime.renderer.setPixelRatio(window.devicePixelRatio || 1);\n runtime.renderer.setSize(sceneObject.width, sceneObject.height, false);\n\n clearScene(runtime.scene);\n configureScene(THREE, runtime, sceneObject);\n\n const originalScene =\n originalObject.objectType === ThreeObjectType.SCENE\n ? (originalObject as ThreeScene)\n : sceneObject;\n\n for (const originalMesh of originalScene.meshes) {\n const currentMesh = getCurrentObject(originalMesh) as ThreeMesh | undefined;\n if (currentMesh === undefined || currentMesh.opacity === 0) {\n continue;\n }\n const object3d = createObject3D(THREE, currentMesh, originalMesh, args);\n if (object3d !== null) {\n applyMeshTransform(object3d, currentMesh);\n runtime.scene.add(object3d);\n }\n }\n\n configureCamera(THREE, runtime, sceneObject);\n runtime.camera.position.set(sceneObject.cameraX, sceneObject.cameraY, sceneObject.cameraZ);\n runtime.target.set(sceneObject.targetX, sceneObject.targetY, sceneObject.targetZ);\n runtime.camera.lookAt(runtime.target);\n runtime.camera.updateProjectionMatrix();\n\n runtime.renderer.render(runtime.scene, runtime.camera);\n\n const boundingBox = getBoundingBox(\n Position({ x: sceneObject.x, y: sceneObject.y }),\n sceneObject.anchor,\n Size({ width: sceneObject.width, height: sceneObject.height }),\n );\n\n ctx.context.save();\n ctx.context.globalAlpha = targetOpacity;\n ctx.context.drawImage(\n runtime.renderer.domElement,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n ctx.context.restore();\n };\n}\n\nfunction getRuntime(\n THREE: typeof Three,\n sceneObject: ThreeScene,\n originalObject: SlideObject,\n): Runtime {\n const runtimeKey =\n originalObject.objectType === ThreeObjectType.SCENE ? originalObject : sceneObject;\n const existingRuntime = runtimeByScene.get(runtimeKey);\n if (existingRuntime !== undefined) {\n return existingRuntime;\n }\n\n const canvas = document.createElement(\"canvas\");\n const renderer = new THREE.WebGLRenderer({\n alpha: true,\n antialias: true,\n canvas,\n preserveDrawingBuffer: true,\n });\n const runtime: Runtime = {\n renderer,\n scene: new THREE.Scene(),\n camera: createCamera(THREE, sceneObject),\n cameraType: sceneObject.cameraType,\n target: new THREE.Vector3(),\n };\n runtimeByScene.set(runtimeKey, runtime);\n return runtime;\n}\n\nfunction configureCamera(THREE: typeof Three, runtime: Runtime, sceneObject: ThreeScene): void {\n if (runtime.cameraType !== sceneObject.cameraType) {\n runtime.camera = createCamera(THREE, sceneObject);\n runtime.cameraType = sceneObject.cameraType;\n }\n\n switch (sceneObject.cameraType) {\n case ThreeCameraType.PERSPECTIVE: {\n const camera = runtime.camera as Three.PerspectiveCamera;\n camera.aspect = sceneObject.width / sceneObject.height;\n camera.fov = sceneObject.cameraFov;\n camera.near = sceneObject.cameraNear;\n camera.far = sceneObject.cameraFar;\n break;\n }\n case ThreeCameraType.ORTHOGRAPHIC: {\n const camera = runtime.camera as Three.OrthographicCamera;\n const height = getOrthographicHeight(sceneObject);\n const width = height * (sceneObject.width / sceneObject.height);\n camera.left = -width / 2;\n camera.right = width / 2;\n camera.top = height / 2;\n camera.bottom = -height / 2;\n camera.near = sceneObject.cameraNear;\n camera.far = sceneObject.cameraFar;\n break;\n }\n }\n}\n\nfunction createCamera(\n THREE: typeof Three,\n sceneObject: ThreeScene,\n): Three.PerspectiveCamera | Three.OrthographicCamera {\n switch (sceneObject.cameraType) {\n case ThreeCameraType.PERSPECTIVE:\n return new THREE.PerspectiveCamera(\n sceneObject.cameraFov,\n sceneObject.width / sceneObject.height,\n sceneObject.cameraNear,\n sceneObject.cameraFar,\n );\n case ThreeCameraType.ORTHOGRAPHIC:\n return createOrthographicCamera(THREE, sceneObject);\n }\n}\n\nfunction createOrthographicCamera(\n THREE: typeof Three,\n sceneObject: ThreeScene,\n): Three.OrthographicCamera {\n const height = getOrthographicHeight(sceneObject);\n const width = height * (sceneObject.width / sceneObject.height);\n return new THREE.OrthographicCamera(\n -width / 2,\n width / 2,\n height / 2,\n -height / 2,\n sceneObject.cameraNear,\n sceneObject.cameraFar,\n );\n}\n\nfunction getOrthographicHeight(sceneObject: ThreeScene): number {\n if (sceneObject.cameraOrthographicHeight !== null && sceneObject.cameraOrthographicHeight > 0) {\n return sceneObject.cameraOrthographicHeight;\n }\n\n const cameraDistance = Math.hypot(\n sceneObject.cameraX - sceneObject.targetX,\n sceneObject.cameraY - sceneObject.targetY,\n sceneObject.cameraZ - sceneObject.targetZ,\n );\n\n if (cameraDistance === 0) {\n return sceneObject.height;\n }\n\n return 2 * cameraDistance * Math.tan(degreesToRadians(sceneObject.cameraFov) / 2);\n}\n\nfunction configureScene(THREE: typeof Three, runtime: Runtime, sceneObject: ThreeScene): void {\n if (sceneObject.backgroundColor === null) {\n runtime.renderer.setClearColor(0x000000, 0);\n } else {\n runtime.renderer.setClearColor(\n colorToThreeHex(sceneObject.backgroundColor),\n getAlphaForColor(sceneObject.backgroundColor),\n );\n }\n\n const ambient = new THREE.AmbientLight(\n colorToThreeHex(sceneObject.ambientLightColor),\n sceneObject.ambientLightIntensity,\n );\n runtime.scene.add(ambient);\n\n const directional = new THREE.DirectionalLight(\n colorToThreeHex(sceneObject.directionalLightColor),\n sceneObject.directionalLightIntensity,\n );\n directional.position.set(\n sceneObject.directionalLightX,\n sceneObject.directionalLightY,\n sceneObject.directionalLightZ,\n );\n runtime.scene.add(directional);\n}\n\nfunction clearScene(scene: Three.Scene): void {\n while (scene.children.length > 0) {\n const child = scene.children[0];\n if (child !== undefined) {\n disposeRendererOwnedResources(child);\n scene.remove(child);\n }\n }\n}\n\nfunction createObject3D(\n THREE: typeof Three,\n mesh: ThreeMesh,\n originalMesh: ThreeMesh,\n renderArgs: BrowserCanvasObjectRendererArgs<ThreeScene>,\n): Three.Object3D | null {\n switch (mesh.objectType) {\n case ThreeObjectType.BOX:\n return createBox(THREE, mesh as ThreeBox);\n case ThreeObjectType.SPHERE:\n return createSphere(THREE, mesh as ThreeSphere);\n case ThreeObjectType.MODEL:\n return createModel(\n THREE,\n mesh as ThreeModel,\n originalMesh as ThreeModel,\n renderArgs.getCurrentObject,\n );\n case ThreeObjectType.PRESENTER_GROUP:\n return createPresenterGroup(THREE, mesh as ThreePresenterGroup, renderArgs);\n default:\n return null;\n }\n}\n\nfunction createBox(THREE: typeof Three, box: ThreeBox): Three.Mesh {\n const geometry = new THREE.BoxGeometry(box.width, box.height, box.depth);\n markRendererOwnedResource(geometry);\n\n return new THREE.Mesh(geometry, createMaterial(THREE, box));\n}\n\nfunction createSphere(THREE: typeof Three, sphere: ThreeSphere): Three.Mesh {\n const geometry = new THREE.SphereGeometry(\n sphere.radius,\n sphere.widthSegments,\n sphere.heightSegments,\n );\n markRendererOwnedResource(geometry);\n\n return new THREE.Mesh(geometry, createMaterial(THREE, sphere));\n}\n\nfunction createPresenterGroup(\n THREE: typeof Three,\n group: ThreePresenterGroup,\n renderArgs: BrowserCanvasObjectRendererArgs<ThreeScene>,\n): Three.Mesh | null {\n const textureWidth = group.textureWidth ?? renderArgs.slideSize.width;\n const textureHeight = group.textureHeight ?? renderArgs.slideSize.height;\n\n if (group.width <= 0 || group.height <= 0 || textureWidth <= 0 || textureHeight <= 0) {\n return null;\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.ceil(textureWidth);\n canvas.height = Math.ceil(textureHeight);\n\n const context = canvas.getContext(\"2d\");\n if (context === null) {\n return null;\n }\n\n context.clearRect(0, 0, canvas.width, canvas.height);\n const textureContext = {\n type: CanvasContextType.Browser,\n context,\n } as const;\n\n for (const object of group.objects) {\n renderArgs.renderObject(object, 1, textureContext);\n }\n\n const texture = new THREE.CanvasTexture(canvas);\n texture.colorSpace = THREE.SRGBColorSpace;\n markRendererOwnedResource(texture);\n\n const geometry = new THREE.PlaneGeometry(group.width, group.height);\n markRendererOwnedResource(geometry);\n\n const material = new THREE.MeshBasicMaterial({\n color: colorToThreeHex(group.color),\n map: texture,\n opacity: group.opacity * getAlphaForColor(group.color),\n side: group.doubleSided ? THREE.DoubleSide : THREE.FrontSide,\n transparent: true,\n wireframe: group.wireframe,\n });\n markRendererOwnedResource(material);\n\n return new THREE.Mesh(geometry, material);\n}\n\nfunction createModel(\n THREE: typeof Three,\n model: ThreeModel,\n originalModel: ThreeModel,\n getCurrentObject: <TObject extends SlideObject>(object: TObject) => TObject | undefined,\n): Three.Object3D | null {\n if (model.src === \"\") {\n return null;\n }\n\n const modelScene = getLoadedModelScene(model.src);\n if (modelScene === null) {\n console.warn(`3D model was not preloaded: ${model.src}`);\n return null;\n }\n\n const clonedScene = modelScene.clone(true);\n applyModelMaterialOverrides(clonedScene, model);\n applyModelMaterialTargetOverrides(clonedScene, model, originalModel, getCurrentObject);\n applyModelNodeOverrides(clonedScene, model, originalModel, getCurrentObject);\n return clonedScene;\n}\n\nfunction createMaterial(THREE: typeof Three, mesh: ThreeMesh): Three.MeshStandardMaterial {\n const material = new THREE.MeshStandardMaterial({\n color: colorToThreeHex(mesh.color),\n opacity: mesh.opacity * getAlphaForColor(mesh.color),\n transparent: mesh.opacity < 1 || getAlphaForColor(mesh.color) < 1,\n wireframe: mesh.wireframe,\n });\n markRendererOwnedResource(material);\n return material;\n}\n\nfunction applyModelMaterialOverrides(object: Three.Object3D, model: ThreeModel): void {\n if (!hasMaterialOverrides(model)) {\n return;\n }\n\n object.traverse((child) => {\n if (!isMesh(child)) {\n return;\n }\n updateMeshMaterials(child, model, () => true);\n });\n}\n\nfunction applyModelMaterialTargetOverrides(\n object: Three.Object3D,\n model: ThreeModel,\n originalModel: ThreeModel,\n getCurrentObject: <TObject extends SlideObject>(object: TObject) => TObject | undefined,\n): void {\n for (const originalMaterial of originalModel.materials) {\n const material = getCurrentObject(originalMaterial) ?? originalMaterial;\n if (!hasMaterialOverrides(material)) {\n continue;\n }\n\n let matchCount = 0;\n object.traverse((child) => {\n if (!isMesh(child)) {\n return;\n }\n\n updateMeshMaterials(child, material, (meshMaterial) => {\n const isMatch = materialMatchesTarget(meshMaterial, material);\n if (isMatch) {\n matchCount++;\n }\n return isMatch;\n });\n });\n warnForTargetMatchCount(model.src, \"material\", material, matchCount);\n }\n}\n\nfunction applyModelNodeOverrides(\n object: Three.Object3D,\n model: ThreeModel,\n originalModel: ThreeModel,\n getCurrentObject: <TObject extends SlideObject>(object: TObject) => TObject | undefined,\n): void {\n const objectPaths = collectObjectPaths(object);\n for (const originalNode of originalModel.nodes) {\n const node = getCurrentObject(originalNode) ?? originalNode;\n const matches = objectPaths.filter((objectPath) => nodeMatchesTarget(objectPath, node));\n warnForTargetMatchCount(model.src, \"node\", node, matches.length);\n\n for (const match of matches) {\n applyNodeTransform(match.object, node);\n if (hasMaterialOverrides(node)) {\n applyNodeMaterialOverrides(match.object, node);\n }\n }\n }\n}\n\nfunction applyNodeTransform(object: Three.Object3D, node: ThreeModelNode): void {\n object.position.set(\n object.position.x + node.x,\n object.position.y + node.y,\n object.position.z + node.z,\n );\n object.rotation.set(\n object.rotation.x + degreesToRadians(node.rotationX),\n object.rotation.y + degreesToRadians(node.rotationY),\n object.rotation.z + degreesToRadians(node.rotationZ),\n );\n object.scale.set(\n object.scale.x * node.scale * node.scaleX,\n object.scale.y * node.scale * node.scaleY,\n object.scale.z * node.scale * node.scaleZ,\n );\n}\n\nfunction applyNodeMaterialOverrides(object: Three.Object3D, node: ThreeModelNode): void {\n object.traverse((child) => {\n if (isMesh(child)) {\n updateMeshMaterials(child, node, () => true);\n }\n });\n}\n\nfunction nodeMatchesTarget(\n objectPath: { readonly object: Three.Object3D; readonly path: readonly string[] },\n target: ThreeModelNode,\n): boolean {\n if (target.path !== null) {\n return objectPathMatches(objectPath.path, target.path);\n }\n if (target.presenterId !== null) {\n return getPresenterId(objectPath.object) === target.presenterId;\n }\n if (target.name !== null) {\n return objectPath.object.name === target.name;\n }\n return false;\n}\n\nfunction materialMatchesTarget(material: Three.Material, target: ThreeModelMaterial): boolean {\n if (target.presenterId !== null) {\n return getPresenterId(material) === target.presenterId;\n }\n if (target.name !== null) {\n return material.name === target.name;\n }\n return false;\n}\n\nfunction warnForTargetMatchCount(\n src: string,\n targetType: \"material\" | \"node\",\n target: ThreeModelTarget | Omit<ThreeModelTarget, \"path\">,\n matchCount: number,\n): void {\n if (matchCount === 1 || (targetType === \"material\" && matchCount > 1)) {\n return;\n }\n\n const targetDescription = modelTargetToString(target);\n const key = `${src}:${targetType}:${targetDescription}:${matchCount}`;\n if (loggedTargetWarningKeys.has(key)) {\n return;\n }\n\n loggedTargetWarningKeys.add(key);\n const message =\n matchCount === 0\n ? `ThreeModel ${src} did not find ${targetType} target ${targetDescription}.`\n : `ThreeModel ${src} found ${matchCount} ${targetType} targets for ${targetDescription}. Use a path or presenterId to make the target unique.`;\n console.warn(message);\n}\n\nfunction updateMeshMaterials(\n mesh: Three.Mesh,\n state: MaterialOverrideState,\n predicate: (material: Three.Material) => boolean,\n): void {\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n let didUpdate = false;\n const updatedMaterials = materials.map((material) => {\n if (!predicate(material)) {\n return material;\n }\n didUpdate = true;\n const updatedMaterial = getWritableMaterial(material);\n applyMaterialOverride(updatedMaterial, state);\n return updatedMaterial;\n });\n\n if (!didUpdate) {\n return;\n }\n\n if (Array.isArray(mesh.material)) {\n mesh.material = updatedMaterials;\n } else {\n const updatedMaterial = updatedMaterials[0];\n if (updatedMaterial !== undefined) {\n mesh.material = updatedMaterial;\n }\n }\n}\n\nfunction getWritableMaterial(material: Three.Material): CustomizableMaterial {\n if (isRendererOwnedResource(material)) {\n return material as CustomizableMaterial;\n }\n\n const updatedMaterial = material.clone() as CustomizableMaterial;\n markRendererOwnedResource(updatedMaterial);\n return updatedMaterial;\n}\n\nfunction applyMaterialOverride(material: CustomizableMaterial, state: MaterialOverrideState): void {\n if (state.materialColor !== null && material.color !== undefined) {\n material.color.setHex(colorToThreeHex(state.materialColor));\n }\n\n const targetOpacity =\n material.opacity *\n state.opacity *\n (state.materialColor !== null ? getAlphaForColor(state.materialColor) : 1);\n if (targetOpacity !== material.opacity) {\n material.opacity = targetOpacity;\n material.transparent = true;\n }\n\n if (state.wireframe) {\n material.wireframe = true;\n }\n}\n\nfunction hasMaterialOverrides(state: MaterialOverrideState): boolean {\n return state.materialColor !== null || state.opacity !== 1 || state.wireframe;\n}\n\nfunction applyMeshTransform(object: Three.Object3D, mesh: ThreeMesh): void {\n object.position.set(mesh.x, mesh.y, mesh.z);\n object.rotation.set(\n degreesToRadians(mesh.rotationX),\n degreesToRadians(mesh.rotationY),\n degreesToRadians(mesh.rotationZ),\n );\n object.scale.set(mesh.scale * mesh.scaleX, mesh.scale * mesh.scaleY, mesh.scale * mesh.scaleZ);\n}\n\nfunction degreesToRadians(degrees: number): number {\n return (degrees * Math.PI) / 180;\n}\n\nfunction disposeRendererOwnedResources(object: Three.Object3D): void {\n object.traverse((child) => {\n if (!isMesh(child)) {\n return;\n }\n\n if (isRendererOwnedResource(child.geometry)) {\n child.geometry.dispose();\n }\n\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n for (const material of materials) {\n disposeMaterialTextures(material);\n if (isRendererOwnedResource(material)) {\n material.dispose();\n }\n }\n });\n}\n\nfunction isMesh(object: Three.Object3D): object is Three.Mesh {\n return \"isMesh\" in object && object.isMesh === true;\n}\n\ninterface MaterialOverrideState {\n readonly opacity: number;\n readonly materialColor: Color | null;\n readonly wireframe: boolean;\n}\n\ninterface CustomizableMaterial extends Three.Material {\n color?: Three.Color;\n map?: Three.Texture | null;\n wireframe?: boolean;\n}\n\nfunction disposeMaterialTextures(material: Three.Material): void {\n const maybeTexturedMaterial = material as CustomizableMaterial;\n if (\n maybeTexturedMaterial.map !== undefined &&\n maybeTexturedMaterial.map !== null &&\n isRendererOwnedResource(maybeTexturedMaterial.map)\n ) {\n maybeTexturedMaterial.map.dispose();\n }\n}\n\nfunction markRendererOwnedResource(resource: { userData: Record<string, unknown> }): void {\n resource.userData.presenterRendererOwned = true;\n}\n\nfunction isRendererOwnedResource(resource: { userData?: Record<string, unknown> }): boolean {\n return resource.userData?.presenterRendererOwned === true;\n}\n","import { Anchor, DEFAULT_ANCHOR } from \"../types/Anchor\";\nimport { ObjectType } from \"../types/ObjectType\";\nimport { SlideObject } from \"../types/SlideObject\";\n\nexport interface Image extends SlideObject {\n readonly objectType: typeof ObjectType.IMAGE;\n readonly anchor: Anchor;\n readonly height: number;\n readonly imageId: string | null;\n readonly imagePath: string | null;\n readonly cornerRadius: number;\n readonly smooth: boolean;\n readonly width: number;\n readonly x: number;\n readonly y: number;\n}\n\nexport function Image(props: Partial<Image> | null = null): Image {\n return SlideObject({\n objectType: ObjectType.IMAGE,\n anchor: DEFAULT_ANCHOR,\n cornerRadius: 0,\n height: 100,\n imageId: null,\n imagePath: null,\n smooth: true,\n width: 100,\n x: 0,\n y: 0,\n ...props,\n });\n}\n","import { UnifiedPath2D } from \"../../../renderer/browser-canvas/types/UnifiedPath2D\";\nimport { PathWithLength } from \"../../../types/PathWithLength\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\n\nexport function getRoundedRectanglePath(\n origin: Position,\n size: Size,\n cornerRadius: number,\n createPath: () => UnifiedPath2D,\n overshoot: number = 0,\n): PathWithLength {\n const path = createPath();\n\n path.path.moveTo(origin.x + cornerRadius, origin.y);\n path.path.lineTo(origin.x + size.width - cornerRadius, origin.y);\n path.path.arcTo(\n origin.x + size.width,\n origin.y,\n origin.x + size.width,\n origin.y + cornerRadius,\n cornerRadius,\n );\n path.path.lineTo(origin.x + size.width, origin.y + size.height - cornerRadius);\n path.path.arcTo(\n origin.x + size.width,\n origin.y + size.height,\n origin.x + size.width - cornerRadius,\n origin.y + size.height,\n cornerRadius,\n );\n path.path.lineTo(origin.x + cornerRadius, origin.y + size.height);\n path.path.arcTo(\n origin.x,\n origin.y + size.height,\n origin.x,\n origin.y + size.height - cornerRadius,\n cornerRadius,\n );\n path.path.lineTo(origin.x, origin.y + cornerRadius);\n path.path.arcTo(origin.x, origin.y, origin.x + cornerRadius, origin.y, cornerRadius);\n if (overshoot > 0) {\n path.path.lineTo(origin.x + cornerRadius + overshoot, origin.y);\n }\n\n const length =\n 2 * (size.width + size.height - 4 * cornerRadius) + 2 * Math.PI * cornerRadius + overshoot;\n return { path, length };\n}\n","import { type Image } from \"skia-canvas\";\n\nexport const ImageType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type ImageType = (typeof ImageType)[keyof typeof ImageType];\n\nexport interface BrowserImage {\n readonly type: typeof ImageType.Browser;\n readonly image: HTMLImageElement;\n}\n\nexport interface NodeImage {\n readonly type: typeof ImageType.Node;\n readonly image: Image;\n}\n\n/**\n * A unified Image type that works in both browser and Node.js environments.\n */\nexport type UnifiedImage = BrowserImage | NodeImage;\n","import { type Path2D as SkiaPath2D } from \"skia-canvas\";\n\nexport const Path2DType = {\n Browser: \"browser\",\n Node: \"node\",\n} as const;\n\nexport type Path2DType = (typeof Path2DType)[keyof typeof Path2DType];\n\nexport interface BrowserPath2D {\n readonly type: typeof Path2DType.Browser;\n readonly path: Path2D;\n}\n\nexport interface NodePath2D {\n readonly type: typeof Path2DType.Node;\n readonly path: SkiaPath2D;\n}\n\n/**\n * A unified Path2D type that works in both browser and Node.js environments.\n */\nexport type UnifiedPath2D = BrowserPath2D | NodePath2D;\n","import { Image } from \"../../../objects/Image\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { assertNever } from \"../../../utils/core/assertNever\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { getRoundedRectanglePath } from \"../../../utils/objects/rectangle/getRoundedRectanglePath\";\nimport { BrowserCanvasObjectRenderer } from \"../types/BrowserCanvasObjectRenderer\";\nimport { CanvasContextType } from \"../types/UnifiedCanvasContext\";\nimport { ImageType } from \"../types/UnifiedImage\";\nimport { Path2DType } from \"../types/UnifiedPath2D\";\n\nexport const renderImage: BrowserCanvasObjectRenderer<Image> = ({\n ctx,\n imageById,\n object: image,\n opacity,\n createPath2D,\n}) => {\n const boundingBox = getBoundingBox(\n Position({ x: image.x, y: image.y }),\n image.anchor,\n Size({ width: image.width, height: image.height }),\n );\n\n const imageId =\n image.imageId != null && image.imageId.length > 0 ? image.imageId : image.imagePath;\n if (imageId == null) {\n return;\n }\n\n const imageData = imageById[imageId];\n if (imageData === undefined) {\n return;\n }\n\n ctx.context.save();\n\n if (image.cornerRadius > 0) {\n const roundedRectPath = getRoundedRectanglePath(\n boundingBox.origin,\n boundingBox.size,\n image.cornerRadius,\n createPath2D,\n );\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (roundedRectPath.path.type === Path2DType.Browser) {\n ctx.context.clip(roundedRectPath.path.path);\n } else {\n console.warn(\"Attempted to use Node Path2D in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (roundedRectPath.path.type === Path2DType.Node) {\n ctx.context.clip(roundedRectPath.path.path);\n } else {\n console.warn(\"Attempted to use Browser Path2D in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n }\n\n ctx.context.globalAlpha = opacity * image.opacity;\n ctx.context.imageSmoothingEnabled = image.smooth;\n\n switch (ctx.type) {\n case CanvasContextType.Browser:\n if (imageData.type === ImageType.Browser) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n } else {\n console.warn(\"Attempted to use Node Image in Browser Canvas context\");\n }\n break;\n case CanvasContextType.Node:\n if (imageData.type === ImageType.Node) {\n ctx.context.drawImage(\n imageData.image,\n boundingBox.origin.x,\n boundingBox.origin.y,\n boundingBox.size.width,\n boundingBox.size.height,\n );\n } else {\n console.warn(\"Attempted to use Browser Image in Node Canvas context\");\n }\n break;\n default:\n assertNever(ctx);\n }\n\n // Restore opacity state\n ctx.context.restore();\n};\n","import { Image } from \"../../objects/Image\";\nimport { renderImage } from \"../../renderer/browser-canvas/objects/renderImage\";\nimport { BrowserCanvasObjectRenderer } from \"../../renderer/browser-canvas/types/BrowserCanvasObjectRenderer\";\nimport { ThreeScene } from \"../objects/ThreeScene\";\n\nexport const renderThreeSceneFallback: BrowserCanvasObjectRenderer<ThreeScene> = (args) => {\n const { object: scene } = args;\n if (scene.fallbackImageId == null && scene.fallbackImagePath == null) {\n return;\n }\n\n renderImage({\n ...args,\n object: Image({\n anchor: scene.anchor,\n cornerRadius: scene.fallbackCornerRadius,\n description: scene.description,\n height: scene.height,\n imageId: scene.fallbackImageId,\n imagePath: scene.fallbackImagePath,\n opacity: scene.opacity,\n smooth: scene.fallbackSmooth,\n width: scene.width,\n x: scene.x,\n y: scene.y,\n }),\n });\n};\n","import { Anchor } from \"../../../types/Anchor\";\nimport { BoundingBox } from \"../../../types/BoundingBox\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { getBoundingBox } from \"../../../utils/layout/getBoundingBox\";\nimport { ObjectTransform } from \"../types/ObjectTransform\";\n\nexport function getTransformedBoundingBox(\n position: Position,\n anchor: Anchor,\n size: Size,\n transform: ObjectTransform,\n): BoundingBox {\n return getBoundingBox(\n {\n x: position.x * transform.scale + transform.translateX,\n y: position.y * transform.scale + transform.translateY,\n },\n anchor,\n {\n width: size.width * transform.scale,\n height: size.height * transform.scale,\n },\n );\n}\n","/** PowerPoint file assumes 96 pixels per inch. */\nconst POWERPOINT_PIXELS_PER_INCH = 96;\nconst POWERPOINT_FONT_SIZE_SCALE = 69;\n\n/**\n * Gets inches from pixels.\n */\nexport function getInchesFromPixels(pixels: number, pixelsPerInch: number): number {\n return pixels / pixelsPerInch;\n}\n\n/**\n * Gets PowerPoint pixels from Presenter.js pixels.\n */\nexport function getPptxPixelsFromPixels(pixels: number, pixelsPerInch: number): number {\n return getInchesFromPixels(pixels, pixelsPerInch) * POWERPOINT_PIXELS_PER_INCH;\n}\n\nexport function getPptxFontSizeFromPixels(pixels: number, pixelsPerInch: number): number {\n return getInchesFromPixels(pixels, pixelsPerInch) * POWERPOINT_FONT_SIZE_SCALE;\n}\n","import { Image } from \"../../../objects/Image\";\nimport { Position } from \"../../../types/Position\";\nimport { Size } from \"../../../types/Size\";\nimport { PowerPointObjectRenderer } from \"../types/PowerPointObjectRenderer\";\nimport { getTransformedBoundingBox } from \"../utils/getTransformedBoundingBox\";\nimport { getInchesFromPixels } from \"../utils/getUnitsFromPixels\";\n\nexport const renderImage: PowerPointObjectRenderer<Image> = ({\n imagePathById,\n slide,\n object: image,\n opacity,\n pixelsPerInch,\n transform,\n}) => {\n const targetOpacity = image.opacity * opacity;\n if (targetOpacity === 0) {\n return;\n }\n\n const imageId =\n image.imageId != null && image.imageId.length > 0 ? image.imageId : image.imagePath;\n if (imageId == null) {\n return;\n }\n\n const path = imagePathById[imageId];\n if (path === undefined) {\n return;\n }\n\n const { origin, size } = getTransformedBoundingBox(\n Position({ x: image.x, y: image.y }),\n image.anchor,\n Size({ width: image.width, height: image.height }),\n transform,\n );\n\n slide.addImage({\n path,\n x: getInchesFromPixels(origin.x, pixelsPerInch),\n y: getInchesFromPixels(origin.y, pixelsPerInch),\n w: getInchesFromPixels(size.width, pixelsPerInch),\n h: getInchesFromPixels(size.height, pixelsPerInch),\n transparency: (1 - targetOpacity) * 100,\n });\n};\n","import { renderImage } from \"../../export/powerpoint-renderer/objects/renderImage\";\nimport { PowerPointObjectRenderer } from \"../../export/powerpoint-renderer/types/PowerPointObjectRenderer\";\nimport { Image } from \"../../objects/Image\";\nimport { ThreeScene } from \"../objects/ThreeScene\";\n\nexport const renderThreeScenePowerPointFallback: PowerPointObjectRenderer<ThreeScene> = (args) => {\n const { object: scene } = args;\n if (scene.fallbackImageId == null && scene.fallbackImagePath == null) {\n return;\n }\n\n renderImage({\n ...args,\n object: Image({\n anchor: scene.anchor,\n cornerRadius: scene.fallbackCornerRadius,\n description: scene.description,\n height: scene.height,\n imageId: scene.fallbackImageId,\n imagePath: scene.fallbackImagePath,\n opacity: scene.opacity,\n smooth: scene.fallbackSmooth,\n width: scene.width,\n x: scene.x,\n y: scene.y,\n }),\n });\n};\n","import { PowerPointObjectRenderer } from \"../../export/powerpoint-renderer/types/PowerPointObjectRenderer\";\nimport { BrowserCanvasObjectRenderer } from \"../../renderer/browser-canvas/types/BrowserCanvasObjectRenderer\";\nimport { SlideObject } from \"../../types/SlideObject\";\nimport { ThreeObjectType } from \"../objects/ThreeObjectType\";\nimport { renderThreeSceneFallback } from \"./renderThreeSceneFallback\";\nimport { renderThreeScenePowerPointFallback } from \"./renderThreeScenePowerPointFallback\";\n\nexport const THREE_FALLBACK_OBJECT_RENDERERS: Record<\n string,\n BrowserCanvasObjectRenderer<SlideObject>\n> = {\n [ThreeObjectType.SCENE]: renderThreeSceneFallback as BrowserCanvasObjectRenderer<SlideObject>,\n};\n\nexport const THREE_POWERPOINT_FALLBACK_OBJECT_RENDERERS: Record<\n string,\n PowerPointObjectRenderer<SlideObject>\n> = {\n [ThreeObjectType.SCENE]:\n renderThreeScenePowerPointFallback as PowerPointObjectRenderer<SlideObject>,\n};\n","import { GLTFLoaderLike } from \"../types/ThreeModules\";\nimport { loadThreeModules } from \"./loadThreeModules\";\nimport { getLoadedModelScene, loadThreeModel } from \"./modelCache\";\nimport {\n inspectThreeModelScene,\n logThreeModelInspection,\n type ThreeModelInspection,\n type ThreeModelMaterialInfo,\n type ThreeModelNodeInfo,\n} from \"./modelInspection\";\n\nexport type { ThreeModelInspection, ThreeModelMaterialInfo, ThreeModelNodeInfo };\n\nexport async function inspectThreeModel(src: string): Promise<ThreeModelInspection> {\n const modules = await loadThreeModules();\n const loader: GLTFLoaderLike = new modules.GLTFLoader();\n await loadThreeModel(loader, src);\n\n const scene = getLoadedModelScene(src);\n if (scene === null) {\n throw new Error(`3D model was not loaded: ${src}`);\n }\n\n return inspectThreeModelScene(src, scene);\n}\n\nexport async function logThreeModelParts(src: string): Promise<ThreeModelInspection> {\n const inspection = await inspectThreeModel(src);\n logThreeModelInspection(inspection);\n return inspection;\n}\n","import { ThreeScene } from \"../objects/ThreeScene\";\nimport { getRenderedThreeSceneCanvas } from \"../renderers/getThreeObjectRenderers\";\n\nexport interface ThreeSceneCaptureOptions {\n readonly filename?: string;\n readonly imageType?: string;\n readonly quality?: number;\n}\n\nexport interface InstallThreeSceneCaptureApiOptions {\n readonly scenes: Record<string, ThreeScene>;\n}\n\ndeclare global {\n interface Window {\n presenterCaptureThreeScene?: (\n sceneName: string,\n options?: ThreeSceneCaptureOptions,\n ) => string | null;\n }\n}\n\n/**\n * Installs a small console helper for saving fallback images while tuning a live\n * browser presentation. Register stable scene references in your app, view the\n * desired build in the browser, then run `presenterCaptureThreeScene(\"name\")`\n * in DevTools to download the most recently rendered WebGL canvas for that scene.\n */\nexport function installThreeSceneCaptureApi({ scenes }: InstallThreeSceneCaptureApiOptions): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.presenterCaptureThreeScene = (sceneName, options = {}) => {\n const scene = scenes[sceneName];\n if (scene === undefined) {\n console.warn(`No Presenter 3D scene registered with name \"${sceneName}\".`);\n return null;\n }\n\n const canvas = getRenderedThreeSceneCanvas(scene);\n if (canvas === null) {\n console.warn(`Presenter 3D scene \"${sceneName}\" has not been rendered yet.`);\n return null;\n }\n\n const imageType = options.imageType ?? \"image/png\";\n const dataUrl = canvas.toDataURL(imageType, options.quality);\n const link = document.createElement(\"a\");\n link.href = dataUrl;\n link.download = options.filename ?? `${sceneName}.${getImageExtension(imageType)}`;\n link.click();\n // Previously returned dataUrl, but download is sufficient, don't need console to know data URL\n return null;\n };\n}\n\nfunction getImageExtension(imageType: string): string {\n switch (imageType) {\n case \"image/jpeg\":\n return \"jpg\";\n case \"image/webp\":\n return \"webp\";\n default:\n return \"png\";\n }\n}\n"],"names":["ObjectType","SlideObject","props","Color","color","green","blue","alpha","hexString","hex","DEFAULT_COLOR","THREE_MESH_DEFAULTS","ThreeObjectType","ThreeBox","ThreeCameraType","ThreeModel","ThreeModelMaterial","ThreeModelNode","ThreePresenterGroup","objects","Anchor","DEFAULT_ANCHOR","ThreeScene","meshes","ThreeSphere","CanvasContextType","Position","DEFAULT_POSITION","Size","DEFAULT_SIZE","getAlphaForColor","opacity","BoundingBox","assertNever","value","message","getBoundingBox","position","anchor","size","x","y","width","height","colorToThreeHex","loadThreeModules","THREE","loaderModule","error","getObjectChildren","object","children","childContainers","key","getSlideObjects","collectObjectPaths","root","paths","visit","parentPath","path","child","normalizeModelPath","part","modelPathToString","modelTargetToString","target","objectPathMatches","targetPath","normalizedTargetPath","offset","index","getPresenterId","_a","_b","id","inspectThreeModelScene","src","scene","materialInfoByMaterial","nodes","materials","isMesh","materialNames","material","existingInfo","meshPath","isBone","logThreeModelInspection","inspection","title","node","modelStateBySrc","loggedInspectionBySrc","preloadThreeModels","loader","presentation","modelRequests","slide","collectModelSources","request","loadThreeModel","logLoadedModelInspection","getLoadedModelScene","state","loadModel","sources","model","existingRequest","childObject","existingState","promise","resolve","reject","gltf","runtimeByScene","loggedTargetWarningKeys","getThreeObjectRenderers","modules","createRenderThreeScene","getRenderedThreeSceneCanvas","args","ctx","sceneObject","originalObject","getCurrentObject","targetOpacity","runtime","getRuntime","clearScene","configureScene","originalScene","originalMesh","currentMesh","object3d","createObject3D","applyMeshTransform","configureCamera","boundingBox","runtimeKey","existingRuntime","canvas","createCamera","camera","getOrthographicHeight","createOrthographicCamera","cameraDistance","degreesToRadians","ambient","directional","disposeRendererOwnedResources","mesh","renderArgs","createBox","createSphere","createModel","createPresenterGroup","box","geometry","markRendererOwnedResource","createMaterial","sphere","group","textureWidth","textureHeight","context","textureContext","texture","originalModel","modelScene","clonedScene","applyModelMaterialOverrides","applyModelMaterialTargetOverrides","applyModelNodeOverrides","hasMaterialOverrides","updateMeshMaterials","originalMaterial","matchCount","meshMaterial","isMatch","materialMatchesTarget","warnForTargetMatchCount","objectPaths","originalNode","matches","objectPath","nodeMatchesTarget","match","applyNodeTransform","applyNodeMaterialOverrides","targetType","targetDescription","predicate","didUpdate","updatedMaterials","updatedMaterial","getWritableMaterial","applyMaterialOverride","isRendererOwnedResource","degrees","disposeMaterialTextures","maybeTexturedMaterial","resource","Image","getRoundedRectanglePath","origin","cornerRadius","createPath","overshoot","length","ImageType","Path2DType","renderImage","imageById","image","createPath2D","imageId","imageData","roundedRectPath","renderThreeSceneFallback","getTransformedBoundingBox","transform","getInchesFromPixels","pixels","pixelsPerInch","imagePathById","renderThreeScenePowerPointFallback","THREE_FALLBACK_OBJECT_RENDERERS","THREE_POWERPOINT_FALLBACK_OBJECT_RENDERERS","inspectThreeModel","logThreeModelParts","installThreeSceneCaptureApi","scenes","sceneName","options","imageType","dataUrl","link","getImageExtension"],"mappings":"AAAO,MAAMA,IAAa;AAAA,EAIxB,OAAO;AAAA,EAMP,cAAc;AAIhB;ACLO,SAASC,EAAeC,GAAkD;AAC/E,SAAO;AAAA,IACL,aAAa;AAAA,IACb,YAAYF,EAAW;AAAA,IACvB,SAAS;AAAA,IACT,GAAGE;AAAA,EAAA;AAEP;ACAO,SAASC,EACdC,GACAC,IAAgB,GAChBC,IAAe,GACfC,IAAgB,GACT;AACP,MAAI,OAAOH,KAAU,UAAU;AAC7B,UAAMI,IAAYJ,EAAM,QAAQ,KAAK,EAAE,GACjCK,IAAM,SAASD,GAAW,EAAE;AAElC,WAAI,MAAMC,CAAG,KACX,QAAQ,KAAK,6BAA6BL,CAAK,GACxCM,KAGLF,EAAU,WAAW,IAChB;AAAA,MACL,KAAMC,KAAO,KAAM;AAAA,MACnB,OAAQA,KAAO,IAAK;AAAA,MACpB,MAAMA,IAAM;AAAA,MACZ,OAAO;AAAA,IAAA,IAEAD,EAAU,WAAW,IACvB;AAAA,MACL,KAAMC,KAAO,KAAM;AAAA,MACnB,OAAQA,KAAO,KAAM;AAAA,MACrB,MAAOA,KAAO,IAAK;AAAA,MACnB,QAAQA,IAAM,OAAO;AAAA,IAAA,KAGvB,QAAQ,KAAK,6BAA6BL,CAAK,GACxCM;AAAA,EAEX,WAAW,OAAON,KAAU;AAC1B,WAAO;AAAA,MACL,KAAKA;AAAA,MACL,OAAOC,KAAS;AAAA,MAChB,MAAMC,KAAQ;AAAA,MACd,OAAOC,KAAS;AAAA,IAAA;AAIpB,SAAO;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,GAAGH;AAAA,EAAA;AAEP;AAEAD,EAAM,QAAQA,EAAM,GAAG,GAAG,CAAC;AAC3BA,EAAM,OAAOA,EAAM,GAAG,GAAG,GAAG;AAC5BA,EAAM,QAAQA,EAAM,GAAG,KAAK,CAAC;AAC7BA,EAAM,MAAMA,EAAM,KAAK,GAAG,CAAC;AAC3BA,EAAM,cAAcA,EAAM,GAAG,GAAG,GAAG,CAAC;AACpCA,EAAM,QAAQA,EAAM,KAAK,KAAK,GAAG;AAE1B,MAAMO,IAAuB,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,EAAA,GCxD3DC,IAAsB;AAAA,EACjC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAOR,EAAM;AAAA,EACb,WAAW;AACb,GC/BaS,IAAkB;AAAA,EAC7B,KAAK;AAAA,EACL,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,QAAQ;AACV;ACGO,SAASC,GAASX,IAAkC,MAAgB;AACzE,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,GAAGD;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,GAAGT;AAAA,EAAA,CACJ;AACH;ACpBO,MAAMY,IAAkB;AAAA,EAC7B,cAAc;AAAA,EACd,aAAa;AACf;ACqBO,SAASC,GAAWb,IAAoC,MAAkB;AAC/E,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,GAAGD;AAAA,IACH,KAAK;AAAA,IACL,eAAe;AAAA,IACf,OAAO,CAAA;AAAA,IACP,WAAW,CAAA;AAAA,IACX,YAAY;AAAA,IACZ,GAAGT;AAAA,EAAA,CACJ;AACH;ACtBO,SAASc,GACdd,IAA4C,MACxB;AACpB,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,MAAM;AAAA,IACN,aAAa;AAAA,IACb,eAAe;AAAA,IACf,WAAW;AAAA,IACX,GAAGV;AAAA,EAAA,CACJ;AACH;ACMO,SAASe,GAAef,IAAwC,MAAsB;AAC3F,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,GAAGD,EAAoB;AAAA,IACvB,GAAGA,EAAoB;AAAA,IACvB,GAAGA,EAAoB;AAAA,IACvB,WAAWA,EAAoB;AAAA,IAC/B,WAAWA,EAAoB;AAAA,IAC/B,WAAWA,EAAoB;AAAA,IAC/B,OAAOA,EAAoB;AAAA,IAC3B,QAAQA,EAAoB;AAAA,IAC5B,QAAQA,EAAoB;AAAA,IAC5B,QAAQA,EAAoB;AAAA,IAC5B,eAAe;AAAA,IACf,WAAWA,EAAoB;AAAA,IAC/B,GAAGT;AAAA,EAAA,CACJ;AACH;AClCO,SAASgB,GACdC,GACAjB,IAA8D,MACzC;AACrB,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,GAAGD;AAAA,IACH,SAAAQ;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,eAAe;AAAA,IACf,aAAa;AAAA,IACb,GAAGjB;AAAA,EAAA,CACJ;AACH;AC/BO,MAAMkB,IAAS;AAAA,EACpB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAChB,GAIaC,IAAyBD,EAAO;AC0BtC,SAASE,GACdC,GACArB,IAAoD,MACxC;AACZ,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,QAAQS;AAAA,IACR,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAAE;AAAA,IACA,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,YAAYT,EAAgB;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,0BAA0B;AAAA,IAC1B,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,mBAAmBX,EAAM;AAAA,IACzB,uBAAuB;AAAA,IACvB,uBAAuBA,EAAM;AAAA,IAC7B,2BAA2B;AAAA,IAC3B,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,GAAGD;AAAA,EAAA,CACJ;AACH;AClEO,SAASsB,GAAYtB,IAAqC,MAAmB;AAClF,SAAOD,EAAY;AAAA,IACjB,YAAYW,EAAgB;AAAA,IAC5B,GAAGD;AAAA,IACH,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,GAAGT;AAAA,EAAA,CACJ;AACH;AClBO,MAAMuB,IAAoB;AAAA,EAC/B,SAAS;AAAA,EACT,MAAM;AACR;ACAO,SAASC,EAASxB,IAAkC,MAAgB;AACzE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAGA;AAAA,EAAA;AAEP;AAEO,MAAMyB,KAAmBD,EAAA;ACRzB,SAASE,EAAK1B,IAA8B,MAAY;AAC7D,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,GAAGA;AAAA,EAAA;AAEP;AAEO,MAAM2B,KAAqBD,EAAK,EAAE,OAAO,GAAG,QAAQ,GAAG;ACPvD,SAASE,EAAiB1B,GAAc2B,IAAyB,MAAc;AACpF,SAAO3B,EAAM,SAAS2B,KAAW;AACnC;ACGO,SAASC,EAAY9B,IAAqC,MAAmB;AAClF,SAAO;AAAA,IACL,QAAQyB;AAAA,IACR,MAAME;AAAA,IACN,GAAG3B;AAAA,EAAA;AAEP;AAEiD8B,EAAA;ACnB1C,SAASC,EAAYC,GAAcC,GAAyB;AACjE,QAAM,IAAI,MAAkB,uBAA6BD,CAAK;AAChE;ACIO,SAASE,EAAeC,GAAoBC,GAAgBC,GAAyB;AAC1F,QAAM,EAAE,GAAAC,GAAG,GAAAC,EAAA,IAAMJ,GACX,EAAE,OAAAK,GAAO,QAAAC,EAAA,IAAWJ;AAE1B,UAAQD,GAAA;AAAA,IACN,KAAKlB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAAc,GAAG,GAAAC,GAAG;AAAA,QACzB,MAAAF;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,IAAQ,GAAG,GAAAD,GAAG;AAAA,QACxC,MAAAF;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,GAAO,GAAAD,GAAG;AAAA,QACpC,MAAAF;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAAc,GAAG,GAAGC,IAAIE,IAAS,GAAG;AAAA,QACzC,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,IAAQ,GAAG,GAAGD,IAAIE,IAAS,EAAA,CAAG;AAAA,QACxD,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,GAAO,GAAGD,IAAIE,IAAS,GAAG;AAAA,QACpD,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAAc,GAAG,GAAGC,IAAIE,GAAQ;AAAA,QACrC,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,IAAQ,GAAG,GAAGD,IAAIE,GAAQ;AAAA,QACpD,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH,KAAKnB,EAAO;AACV,aAAOY,EAAY;AAAA,QACjB,QAAQN,EAAS,EAAE,GAAGc,IAAIE,GAAO,GAAGD,IAAIE,GAAQ;AAAA,QAChD,MAAAJ;AAAA,MAAA,CACD;AAAA,IACH;AACE,MAAAN,EAAYK,CAAM;AAAA,EAAA;AAExB;ACzDO,SAASM,EAAgBxC,GAAsB;AACpD,UAAQA,EAAM,OAAO,OAAOA,EAAM,SAAS,KAAKA,EAAM;AACxD;ACFA,eAAsByC,IAA0C;AAC9D,MAAI;AACF,UAAM,CAACC,GAAOC,CAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC9C,OAAO,OAAO;AAAA,MACd,OAAO,0CAA0C;AAAA,IAAA,CAClD;AACD,WAAO,EAAE,OAAAD,GAAO,YAAYC,EAAa,WAAA;AAAA,EAC3C,SAASC,GAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,EAAE,OAAOA,EAAA;AAAA,IAAM;AAAA,EAEnB;AACF;ACVO,SAASC,GAAkBC,GAAoC;AACpE,QAAMC,IAA0B,CAAA,GAC1BC,IAAkBF;AAGxB,aAAWG,KAAO,CAAC,WAAW,UAAU,SAAS,WAAW,GAAY;AACtE,UAAMnB,IAAQkB,EAAgBC,CAAG;AACjC,IAAI,MAAM,QAAQnB,CAAK,KACrBiB,EAAS,KAAK,GAAGG,GAAgBpB,CAAK,CAAC;AAAA,EAE3C;AACA,SAAOiB;AACT;AAEA,SAASG,GAAgBnC,GAAmC;AAC1D,SAAOA,EAAQ;AAAA,IACb,CAAC+B,MACC,OAAOA,KAAW,YAAYA,MAAW,QAAQ,gBAAgBA;AAAA,EAAA;AAEvE;ACfO,SAASK,EAAmBC,GAAoC;AACrE,QAAMC,IAAsB,CAAA;AAE5B,WAASC,EAAMR,GAAwBS,GAA+B;AACpE,UAAMC,IAAOV,MAAWM,KAAQN,EAAO,SAAS,KAAKS,IAAa,CAAC,GAAGA,GAAYT,EAAO,IAAI;AAC7F,KAAIA,MAAWM,KAAQN,EAAO,SAAS,OACrCO,EAAM,KAAK,EAAE,QAAAP,GAAQ,MAAAU,EAAA,CAAM;AAE7B,eAAWC,KAASX,EAAO;AACzB,MAAAQ,EAAMG,GAAOD,CAAI;AAAA,EAErB;AAEA,SAAAF,EAAMF,GAAM,EAAE,GACPC;AACT;AAEO,SAASK,EAAmBF,GAAyC;AAC1E,SAAO,OAAOA,KAAS,WAAWA,EAAK,MAAM,GAAG,EAAE,OAAO,CAACG,MAASA,MAAS,EAAE,IAAIH;AACpF;AAEO,SAASI,EAAkBJ,GAAiC;AACjE,SAAOA,EAAK,KAAK,GAAG;AACtB;AAEO,SAASK,GAAoBC,GAA2D;AAC7F,SAAI,UAAUA,KAAUA,EAAO,SAAS,OAC/B,SAASF,EAAkBF,EAAmBI,EAAO,IAAI,CAAC,CAAC,MAEhEA,EAAO,gBAAgB,OAClB,gBAAgBA,EAAO,WAAW,MAEvCA,EAAO,SAAS,OACX,SAASA,EAAO,IAAI,MAEtB;AACT;AAEO,SAASC,GAAkBP,GAAyBQ,GAAqC;AAC9F,QAAMC,IAAuBP,EAAmBM,CAAU;AAC1D,MAAIC,EAAqB,SAAST,EAAK;AACrC,WAAO;AAGT,QAAMU,IAASV,EAAK,SAASS,EAAqB;AAClD,SAAOA,EAAqB,MAAM,CAACN,GAAMQ,MAAUX,EAAKU,IAASC,CAAK,MAAMR,CAAI;AAClF;AAEO,SAASS,EAAetB,GAA+D;AxBzDvF,MAAAuB,GAAAC;AwB0DL,QAAMC,MAAKF,IAAAvB,EAAO,aAAP,gBAAAuB,EAAiB,kBAAeC,IAAAxB,EAAO,aAAP,gBAAAwB,EAAiB;AAC5D,SAAO,OAAOC,KAAO,WAAWA,IAAK;AACvC;ACjCO,SAASC,EAAuBC,GAAaC,GAA6C;AAC/F,QAAMC,wBAA6B,IAAA,GAE7BC,IAAQzB,EAAmBuB,CAAK,EAAE,IAAI,CAAC,EAAE,QAAA5B,GAAQ,MAAAU,QAAW;AAChE,UAAMqB,IAAYC,EAAOhC,CAAM,IAC3B,MAAM,QAAQA,EAAO,QAAQ,IAC3BA,EAAO,WACP,CAACA,EAAO,QAAQ,IAClB,CAAA,GACEiC,IAAgBF,EAAU,IAAI,CAACG,MAAaA,EAAS,IAAI;AAE/D,eAAWA,KAAYH,GAAW;AAChC,YAAMI,IAAeN,EAAuB,IAAIK,CAAQ,GAClDE,IAAWtB,EAAkBJ,CAAI;AACvC,MAAIyB,MAAiB,SACnBN,EAAuB,IAAIK,GAAU;AAAA,QACnC,MAAMA,EAAS;AAAA,QACf,aAAaZ,EAAeY,CAAQ;AAAA,QACpC,WAAW,CAACE,CAAQ;AAAA,MAAA,CACrB,IAEDP,EAAuB,IAAIK,GAAU;AAAA,QACnC,GAAGC;AAAA,QACH,WAAW,CAAC,GAAGA,EAAa,WAAWC,CAAQ;AAAA,MAAA,CAChD;AAAA,IAEL;AAEA,WAAO;AAAA,MACL,MAAMpC,EAAO;AAAA,MACb,MAAAU;AAAA,MACA,YAAYI,EAAkBJ,CAAI;AAAA,MAClC,MAAMV,EAAO;AAAA,MACb,QAAQgC,EAAOhC,CAAM;AAAA,MACrB,QAAQqC,GAAOrC,CAAM;AAAA,MACrB,aAAasB,EAAetB,CAAM;AAAA,MAClC,eAAAiC;AAAA,IAAA;AAAA,EAEJ,CAAC;AAED,SAAO;AAAA,IACL,KAAAN;AAAA,IACA,OAAAG;AAAA,IACA,WAAW,CAAC,GAAGD,EAAuB,QAAQ;AAAA,EAAA;AAElD;AAEO,SAASS,EAAwBC,GAAwC;AzB1EzE,MAAAhB;AyB2EL,QAAMiB,IAAQ,cAAcD,EAAW,GAAG;AAE1C,GADe,QAAQ,kBAAkB,QAAQ,OAC1C,KAAK,SAASC,CAAK,GAC1B,QAAQ;AAAA,IACND,EAAW,MAAM,IAAI,CAACE,OAAU;AAAA,MAC9B,MAAMA,EAAK;AAAA,MACX,MAAMA,EAAK;AAAA,MACX,MAAMA,EAAK;AAAA,MACX,aAAaA,EAAK;AAAA,MAClB,WAAWA,EAAK,cAAc,KAAK,IAAI;AAAA,IAAA,EACvC;AAAA,EAAA,GAEJ,QAAQ;AAAA,IACNF,EAAW,UAAU,IAAI,CAACL,OAAc;AAAA,MACtC,MAAMA,EAAS;AAAA,MACf,aAAaA,EAAS;AAAA,MACtB,QAAQA,EAAS,UAAU,KAAK,IAAI;AAAA,IAAA,EACpC;AAAA,EAAA,IAEJX,IAAA,QAAQ,aAAR,QAAAA,EAAA;AACF;AAEA,SAASS,EAAOhC,GAA8C;AAC5D,SAAO,YAAYA,KAAUA,EAAO,WAAW;AACjD;AAEA,SAASqC,GAAOrC,GAA8C;AAC5D,SAAO,YAAYA,KAAUA,EAAO,WAAW;AACjD;ACpEA,MAAM0C,wBAAsB,IAAA,GACtBC,wBAA4B,IAAA;AAElC,eAAsBC,GACpBC,GACAC,GACe;AACf,QAAMC,wBAAoB,IAAA;AAE1B,aAAWC,KAASF,EAAa;AAC/B,eAAW9C,KAAUgD,EAAM;AACzB,MAAAC,GAAoBjD,GAAQ+C,CAAa;AAI7C,QAAM,QAAQ;AAAA,IACZ,CAAC,GAAGA,EAAc,OAAA,CAAQ,EAAE,IAAI,OAAOG,MAAY;AACjD,UAAI;AACF,cAAMC,EAAeN,GAAQK,EAAQ,GAAG,GACpCA,EAAQ,cACVE,GAAyBF,EAAQ,GAAG;AAAA,MAExC,SAASpD,GAAO;AACd,cAAM,IAAI,MAAM,4BAA4BoD,EAAQ,GAAG,IAAI,EAAE,OAAOpD,GAAO;AAAA,MAC7E;AAAA,IACF,CAAC;AAAA,EAAA;AAEL;AAEO,SAASuD,EAAoB1B,GAA8B;AAChE,QAAM2B,IAAQZ,EAAgB,IAAIf,CAAG;AACrC,UAAO2B,KAAA,gBAAAA,EAAO,YAAW,WAAWA,EAAM,QAAQ;AACpD;AAEO,SAASH,EAAeN,GAAwBlB,GAA4B;AACjF,SAAO4B,GAAUV,GAAQlB,CAAG;AAC9B;AAEA,SAASsB,GAAoBjD,GAAqBwD,GAAiD;AACjG,MAAIxD,EAAO,eAAetC,EAAgB,OAAO;AAC/C,UAAM+F,IAAQzD;AACd,QAAIyD,EAAM,QAAQ,IAAI;AACpB,YAAMC,IAAkBF,EAAQ,IAAIC,EAAM,GAAG;AAC7C,MAAAD,EAAQ,IAAIC,EAAM,KAAK;AAAA,QACrB,KAAKA,EAAM;AAAA,QACX,YAAYA,EAAM,eAAcC,KAAA,gBAAAA,EAAiB,gBAAe;AAAA,MAAA,CACjE;AAAA,IACH;AAAA,EACF;AAEA,aAAWC,KAAe5D,GAAkBC,CAAM;AAChD,IAAAiD,GAAoBU,GAAaH,CAAO;AAE5C;AAEA,SAASJ,GAAyBzB,GAAmB;AACnD,MAAIgB,EAAsB,IAAIhB,CAAG;AAC/B;AAGF,QAAMC,IAAQyB,EAAoB1B,CAAG;AACrC,EAAIC,MAAU,SAIde,EAAsB,IAAIhB,CAAG,GAC7BW,EAAwBZ,EAAuBC,GAAKC,CAAK,CAAC;AAC5D;AAEA,SAAS2B,GAAUV,GAAwBlB,GAA4B;AACrE,QAAMiC,IAAgBlB,EAAgB,IAAIf,CAAG;AAC7C,OAAIiC,KAAA,gBAAAA,EAAe,YAAW;AAC5B,WAAO,QAAQ,QAAA;AAEjB,OAAIA,KAAA,gBAAAA,EAAe,YAAW;AAC5B,WAAOA,EAAc;AAGvB,QAAMC,IAAU,IAAI,QAAc,CAACC,GAASC,MAAW;AACrD,IAAAlB,EAAO;AAAA,MACLlB;AAAA,MACA,CAACqC,MAAS;AACR,QAAAtB,EAAgB,IAAIf,GAAK,EAAE,QAAQ,UAAU,OAAOqC,EAAK,OAAO,GAChEF,EAAA;AAAA,MACF;AAAA,MACA;AAAA,MACA,CAAChE,MAAmB;AAClB,QAAA4C,EAAgB,OAAOf,CAAG,GAC1BoC,EAAOjE,CAAK;AAAA,MACd;AAAA,IAAA;AAAA,EAEJ,CAAC;AAED,SAAA4C,EAAgB,IAAIf,GAAK,EAAE,QAAQ,WAAW,SAAAkC,GAAS,GAChDA;AACT;ACtFA,MAAMI,wBAAqB,QAAA,GACrBC,wBAA8B,IAAA;AAEpC,eAAsBC,GACpBrB,GACmE;AACnE,QAAMsB,IAAU,MAAMzE,EAAA,GAChBkD,IAAyB,IAAIuB,EAAQ,WAAA;AAC3C,eAAMxB,GAAmBC,GAAQC,CAAY,GAEtC;AAAA,IACL,CAACpF,EAAgB,KAAK,GAAG2G;AAAA,MACvBD;AAAA,IAAA;AAAA,EACF;AAEJ;AAEO,SAASE,GAA4B1C,GAA6C;A3B7DlF,MAAAL;A2B8DL,WAAOA,IAAA0C,EAAe,IAAIrC,CAAK,MAAxB,gBAAAL,EAA2B,SAAS,eAAc;AAC3D;AAEA,SAAS8C,GAAuB,EAAE,OAAAzE,KAAgE;AAChG,SAAO,CAAC2E,MAAS;AACf,UAAM,EAAE,KAAAC,GAAK,QAAQC,GAAa,SAAA5F,GAAS,gBAAA6F,GAAgB,kBAAAC,MAAqBJ;AAEhF,QAAIC,EAAI,SAASjG,EAAkB;AACjC;AAGF,UAAMqG,IAAgB/F,IAAU4F,EAAY;AAC5C,QAAIG,MAAkB,KAAKH,EAAY,SAAS,KAAKA,EAAY,UAAU;AACzE;AAGF,UAAMI,IAAUC,GAAWlF,GAAO6E,GAAaC,CAAc;AAC7D,IAAAG,EAAQ,SAAS,cAAc,OAAO,oBAAoB,CAAC,GAC3DA,EAAQ,SAAS,QAAQJ,EAAY,OAAOA,EAAY,QAAQ,EAAK,GAErEM,GAAWF,EAAQ,KAAK,GACxBG,GAAepF,GAAOiF,GAASJ,CAAW;AAE1C,UAAMQ,IACJP,EAAe,eAAehH,EAAgB,QACzCgH,IACDD;AAEN,eAAWS,KAAgBD,EAAc,QAAQ;AAC/C,YAAME,IAAcR,EAAiBO,CAAY;AACjD,UAAIC,MAAgB,UAAaA,EAAY,YAAY;AACvD;AAEF,YAAMC,IAAWC,GAAezF,GAAOuF,GAAaD,GAAcX,CAAI;AACtE,MAAIa,MAAa,SACfE,GAAmBF,GAAUD,CAAW,GACxCN,EAAQ,MAAM,IAAIO,CAAQ;AAAA,IAE9B;AAEA,IAAAG,GAAgB3F,GAAOiF,GAASJ,CAAW,GAC3CI,EAAQ,OAAO,SAAS,IAAIJ,EAAY,SAASA,EAAY,SAASA,EAAY,OAAO,GACzFI,EAAQ,OAAO,IAAIJ,EAAY,SAASA,EAAY,SAASA,EAAY,OAAO,GAChFI,EAAQ,OAAO,OAAOA,EAAQ,MAAM,GACpCA,EAAQ,OAAO,uBAAA,GAEfA,EAAQ,SAAS,OAAOA,EAAQ,OAAOA,EAAQ,MAAM;AAErD,UAAMW,IAActG;AAAA,MAClBV,EAAS,EAAE,GAAGiG,EAAY,GAAG,GAAGA,EAAY,GAAG;AAAA,MAC/CA,EAAY;AAAA,MACZ/F,EAAK,EAAE,OAAO+F,EAAY,OAAO,QAAQA,EAAY,QAAQ;AAAA,IAAA;AAG/D,IAAAD,EAAI,QAAQ,KAAA,GACZA,EAAI,QAAQ,cAAcI,GAC1BJ,EAAI,QAAQ;AAAA,MACVK,EAAQ,SAAS;AAAA,MACjBW,EAAY,OAAO;AAAA,MACnBA,EAAY,OAAO;AAAA,MACnBA,EAAY,KAAK;AAAA,MACjBA,EAAY,KAAK;AAAA,IAAA,GAEnBhB,EAAI,QAAQ,QAAA;AAAA,EACd;AACF;AAEA,SAASM,GACPlF,GACA6E,GACAC,GACS;AACT,QAAMe,IACJf,EAAe,eAAehH,EAAgB,QAAQgH,IAAiBD,GACnEiB,IAAkBzB,EAAe,IAAIwB,CAAU;AACrD,MAAIC,MAAoB;AACtB,WAAOA;AAGT,QAAMC,IAAS,SAAS,cAAc,QAAQ,GAOxCd,IAAmB;AAAA,IACvB,UAPe,IAAIjF,EAAM,cAAc;AAAA,MACvC,OAAO;AAAA,MACP,WAAW;AAAA,MACX,QAAA+F;AAAA,MACA,uBAAuB;AAAA,IAAA,CACxB;AAAA,IAGC,OAAO,IAAI/F,EAAM,MAAA;AAAA,IACjB,QAAQgG,GAAahG,GAAO6E,CAAW;AAAA,IACvC,YAAYA,EAAY;AAAA,IACxB,QAAQ,IAAI7E,EAAM,QAAA;AAAA,EAAQ;AAE5B,SAAAqE,EAAe,IAAIwB,GAAYZ,CAAO,GAC/BA;AACT;AAEA,SAASU,GAAgB3F,GAAqBiF,GAAkBJ,GAA+B;AAM7F,UALII,EAAQ,eAAeJ,EAAY,eACrCI,EAAQ,SAASe,GAAahG,GAAO6E,CAAW,GAChDI,EAAQ,aAAaJ,EAAY,aAG3BA,EAAY,YAAA;AAAA,IAClB,KAAK7G,EAAgB,aAAa;AAChC,YAAMiI,IAAShB,EAAQ;AACvB,MAAAgB,EAAO,SAASpB,EAAY,QAAQA,EAAY,QAChDoB,EAAO,MAAMpB,EAAY,WACzBoB,EAAO,OAAOpB,EAAY,YAC1BoB,EAAO,MAAMpB,EAAY;AACzB;AAAA,IACF;AAAA,IACA,KAAK7G,EAAgB,cAAc;AACjC,YAAMiI,IAAShB,EAAQ,QACjBpF,IAASqG,GAAsBrB,CAAW,GAC1CjF,IAAQC,KAAUgF,EAAY,QAAQA,EAAY;AACxD,MAAAoB,EAAO,OAAO,CAACrG,IAAQ,GACvBqG,EAAO,QAAQrG,IAAQ,GACvBqG,EAAO,MAAMpG,IAAS,GACtBoG,EAAO,SAAS,CAACpG,IAAS,GAC1BoG,EAAO,OAAOpB,EAAY,YAC1BoB,EAAO,MAAMpB,EAAY;AACzB;AAAA,IACF;AAAA,EAAA;AAEJ;AAEA,SAASmB,GACPhG,GACA6E,GACoD;AACpD,UAAQA,EAAY,YAAA;AAAA,IAClB,KAAK7G,EAAgB;AACnB,aAAO,IAAIgC,EAAM;AAAA,QACf6E,EAAY;AAAA,QACZA,EAAY,QAAQA,EAAY;AAAA,QAChCA,EAAY;AAAA,QACZA,EAAY;AAAA,MAAA;AAAA,IAEhB,KAAK7G,EAAgB;AACnB,aAAOmI,GAAyBnG,GAAO6E,CAAW;AAAA,EAAA;AAExD;AAEA,SAASsB,GACPnG,GACA6E,GAC0B;AAC1B,QAAMhF,IAASqG,GAAsBrB,CAAW,GAC1CjF,IAAQC,KAAUgF,EAAY,QAAQA,EAAY;AACxD,SAAO,IAAI7E,EAAM;AAAA,IACf,CAACJ,IAAQ;AAAA,IACTA,IAAQ;AAAA,IACRC,IAAS;AAAA,IACT,CAACA,IAAS;AAAA,IACVgF,EAAY;AAAA,IACZA,EAAY;AAAA,EAAA;AAEhB;AAEA,SAASqB,GAAsBrB,GAAiC;AAC9D,MAAIA,EAAY,6BAA6B,QAAQA,EAAY,2BAA2B;AAC1F,WAAOA,EAAY;AAGrB,QAAMuB,IAAiB,KAAK;AAAA,IAC1BvB,EAAY,UAAUA,EAAY;AAAA,IAClCA,EAAY,UAAUA,EAAY;AAAA,IAClCA,EAAY,UAAUA,EAAY;AAAA,EAAA;AAGpC,SAAIuB,MAAmB,IACdvB,EAAY,SAGd,IAAIuB,IAAiB,KAAK,IAAIC,EAAiBxB,EAAY,SAAS,IAAI,CAAC;AAClF;AAEA,SAASO,GAAepF,GAAqBiF,GAAkBJ,GAA+B;AAC5F,EAAIA,EAAY,oBAAoB,OAClCI,EAAQ,SAAS,cAAc,GAAU,CAAC,IAE1CA,EAAQ,SAAS;AAAA,IACfnF,EAAgB+E,EAAY,eAAe;AAAA,IAC3C7F,EAAiB6F,EAAY,eAAe;AAAA,EAAA;AAIhD,QAAMyB,IAAU,IAAItG,EAAM;AAAA,IACxBF,EAAgB+E,EAAY,iBAAiB;AAAA,IAC7CA,EAAY;AAAA,EAAA;AAEd,EAAAI,EAAQ,MAAM,IAAIqB,CAAO;AAEzB,QAAMC,IAAc,IAAIvG,EAAM;AAAA,IAC5BF,EAAgB+E,EAAY,qBAAqB;AAAA,IACjDA,EAAY;AAAA,EAAA;AAEd,EAAA0B,EAAY,SAAS;AAAA,IACnB1B,EAAY;AAAA,IACZA,EAAY;AAAA,IACZA,EAAY;AAAA,EAAA,GAEdI,EAAQ,MAAM,IAAIsB,CAAW;AAC/B;AAEA,SAASpB,GAAWnD,GAA0B;AAC5C,SAAOA,EAAM,SAAS,SAAS,KAAG;AAChC,UAAMjB,IAAQiB,EAAM,SAAS,CAAC;AAC9B,IAAIjB,MAAU,WACZyF,GAA8BzF,CAAK,GACnCiB,EAAM,OAAOjB,CAAK;AAAA,EAEtB;AACF;AAEA,SAAS0E,GACPzF,GACAyG,GACAnB,GACAoB,GACuB;AACvB,UAAQD,EAAK,YAAA;AAAA,IACX,KAAK3I,EAAgB;AACnB,aAAO6I,GAAU3G,GAAOyG,CAAgB;AAAA,IAC1C,KAAK3I,EAAgB;AACnB,aAAO8I,GAAa5G,GAAOyG,CAAmB;AAAA,IAChD,KAAK3I,EAAgB;AACnB,aAAO+I;AAAA,QACL7G;AAAA,QACAyG;AAAA,QACAnB;AAAA,QACAoB,EAAW;AAAA,MAAA;AAAA,IAEf,KAAK5I,EAAgB;AACnB,aAAOgJ,GAAqB9G,GAAOyG,GAA6BC,CAAU;AAAA,IAC5E;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,SAASC,GAAU3G,GAAqB+G,GAA2B;AACjE,QAAMC,IAAW,IAAIhH,EAAM,YAAY+G,EAAI,OAAOA,EAAI,QAAQA,EAAI,KAAK;AACvE,SAAAE,EAA0BD,CAAQ,GAE3B,IAAIhH,EAAM,KAAKgH,GAAUE,GAAelH,GAAO+G,CAAG,CAAC;AAC5D;AAEA,SAASH,GAAa5G,GAAqBmH,GAAiC;AAC1E,QAAMH,IAAW,IAAIhH,EAAM;AAAA,IACzBmH,EAAO;AAAA,IACPA,EAAO;AAAA,IACPA,EAAO;AAAA,EAAA;AAET,SAAAF,EAA0BD,CAAQ,GAE3B,IAAIhH,EAAM,KAAKgH,GAAUE,GAAelH,GAAOmH,CAAM,CAAC;AAC/D;AAEA,SAASL,GACP9G,GACAoH,GACAV,GACmB;AACnB,QAAMW,IAAeD,EAAM,gBAAgBV,EAAW,UAAU,OAC1DY,IAAgBF,EAAM,iBAAiBV,EAAW,UAAU;AAElE,MAAIU,EAAM,SAAS,KAAKA,EAAM,UAAU,KAAKC,KAAgB,KAAKC,KAAiB;AACjF,WAAO;AAGT,QAAMvB,IAAS,SAAS,cAAc,QAAQ;AAC9C,EAAAA,EAAO,QAAQ,KAAK,KAAKsB,CAAY,GACrCtB,EAAO,SAAS,KAAK,KAAKuB,CAAa;AAEvC,QAAMC,IAAUxB,EAAO,WAAW,IAAI;AACtC,MAAIwB,MAAY;AACd,WAAO;AAGT,EAAAA,EAAQ,UAAU,GAAG,GAAGxB,EAAO,OAAOA,EAAO,MAAM;AACnD,QAAMyB,IAAiB;AAAA,IACrB,MAAM7I,EAAkB;AAAA,IACxB,SAAA4I;AAAA,EAAA;AAGF,aAAWnH,KAAUgH,EAAM;AACzB,IAAAV,EAAW,aAAatG,GAAQ,GAAGoH,CAAc;AAGnD,QAAMC,IAAU,IAAIzH,EAAM,cAAc+F,CAAM;AAC9C,EAAA0B,EAAQ,aAAazH,EAAM,gBAC3BiH,EAA0BQ,CAAO;AAEjC,QAAMT,IAAW,IAAIhH,EAAM,cAAcoH,EAAM,OAAOA,EAAM,MAAM;AAClE,EAAAH,EAA0BD,CAAQ;AAElC,QAAM1E,IAAW,IAAItC,EAAM,kBAAkB;AAAA,IAC3C,OAAOF,EAAgBsH,EAAM,KAAK;AAAA,IAClC,KAAKK;AAAA,IACL,SAASL,EAAM,UAAUpI,EAAiBoI,EAAM,KAAK;AAAA,IACrD,MAAMA,EAAM,cAAcpH,EAAM,aAAaA,EAAM;AAAA,IACnD,aAAa;AAAA,IACb,WAAWoH,EAAM;AAAA,EAAA,CAClB;AACD,SAAAH,EAA0B3E,CAAQ,GAE3B,IAAItC,EAAM,KAAKgH,GAAU1E,CAAQ;AAC1C;AAEA,SAASuE,GACP7G,GACA6D,GACA6D,GACA3C,GACuB;AACvB,MAAIlB,EAAM,QAAQ;AAChB,WAAO;AAGT,QAAM8D,IAAalE,EAAoBI,EAAM,GAAG;AAChD,MAAI8D,MAAe;AACjB,mBAAQ,KAAK,+BAA+B9D,EAAM,GAAG,EAAE,GAChD;AAGT,QAAM+D,IAAcD,EAAW,MAAM,EAAI;AACzC,SAAAE,GAA4BD,GAAa/D,CAAK,GAC9CiE,GAAkCF,GAAa/D,GAAO6D,GAAe3C,CAAgB,GACrFgD,GAAwBH,GAAa/D,GAAO6D,GAAe3C,CAAgB,GACpE6C;AACT;AAEA,SAASV,GAAelH,GAAqByG,GAA6C;AACxF,QAAMnE,IAAW,IAAItC,EAAM,qBAAqB;AAAA,IAC9C,OAAOF,EAAgB2G,EAAK,KAAK;AAAA,IACjC,SAASA,EAAK,UAAUzH,EAAiByH,EAAK,KAAK;AAAA,IACnD,aAAaA,EAAK,UAAU,KAAKzH,EAAiByH,EAAK,KAAK,IAAI;AAAA,IAChE,WAAWA,EAAK;AAAA,EAAA,CACjB;AACD,SAAAQ,EAA0B3E,CAAQ,GAC3BA;AACT;AAEA,SAASuF,GAA4BzH,GAAwByD,GAAyB;AACpF,EAAKmE,EAAqBnE,CAAK,KAI/BzD,EAAO,SAAS,CAACW,MAAU;AACzB,IAAKqB,EAAOrB,CAAK,KAGjBkH,EAAoBlH,GAAO8C,GAAO,MAAM,EAAI;AAAA,EAC9C,CAAC;AACH;AAEA,SAASiE,GACP1H,GACAyD,GACA6D,GACA3C,GACM;AACN,aAAWmD,KAAoBR,EAAc,WAAW;AACtD,UAAMpF,IAAWyC,EAAiBmD,CAAgB,KAAKA;AACvD,QAAI,CAACF,EAAqB1F,CAAQ;AAChC;AAGF,QAAI6F,IAAa;AACjB,IAAA/H,EAAO,SAAS,CAACW,MAAU;AACzB,MAAKqB,EAAOrB,CAAK,KAIjBkH,EAAoBlH,GAAOuB,GAAU,CAAC8F,MAAiB;AACrD,cAAMC,IAAUC,GAAsBF,GAAc9F,CAAQ;AAC5D,eAAI+F,KACFF,KAEKE;AAAA,MACT,CAAC;AAAA,IACH,CAAC,GACDE,GAAwB1E,EAAM,KAAK,YAAYvB,GAAU6F,CAAU;AAAA,EACrE;AACF;AAEA,SAASJ,GACP3H,GACAyD,GACA6D,GACA3C,GACM;AACN,QAAMyD,IAAc/H,EAAmBL,CAAM;AAC7C,aAAWqI,KAAgBf,EAAc,OAAO;AAC9C,UAAM7E,IAAOkC,EAAiB0D,CAAY,KAAKA,GACzCC,IAAUF,EAAY,OAAO,CAACG,MAAeC,GAAkBD,GAAY9F,CAAI,CAAC;AACtF,IAAA0F,GAAwB1E,EAAM,KAAK,QAAQhB,GAAM6F,EAAQ,MAAM;AAE/D,eAAWG,KAASH;AAClB,MAAAI,GAAmBD,EAAM,QAAQhG,CAAI,GACjCmF,EAAqBnF,CAAI,KAC3BkG,GAA2BF,EAAM,QAAQhG,CAAI;AAAA,EAGnD;AACF;AAEA,SAASiG,GAAmB1I,GAAwByC,GAA4B;AAC9E,EAAAzC,EAAO,SAAS;AAAA,IACdA,EAAO,SAAS,IAAIyC,EAAK;AAAA,IACzBzC,EAAO,SAAS,IAAIyC,EAAK;AAAA,IACzBzC,EAAO,SAAS,IAAIyC,EAAK;AAAA,EAAA,GAE3BzC,EAAO,SAAS;AAAA,IACdA,EAAO,SAAS,IAAIiG,EAAiBxD,EAAK,SAAS;AAAA,IACnDzC,EAAO,SAAS,IAAIiG,EAAiBxD,EAAK,SAAS;AAAA,IACnDzC,EAAO,SAAS,IAAIiG,EAAiBxD,EAAK,SAAS;AAAA,EAAA,GAErDzC,EAAO,MAAM;AAAA,IACXA,EAAO,MAAM,IAAIyC,EAAK,QAAQA,EAAK;AAAA,IACnCzC,EAAO,MAAM,IAAIyC,EAAK,QAAQA,EAAK;AAAA,IACnCzC,EAAO,MAAM,IAAIyC,EAAK,QAAQA,EAAK;AAAA,EAAA;AAEvC;AAEA,SAASkG,GAA2B3I,GAAwByC,GAA4B;AACtF,EAAAzC,EAAO,SAAS,CAACW,MAAU;AACzB,IAAIqB,EAAOrB,CAAK,KACdkH,EAAoBlH,GAAO8B,GAAM,MAAM,EAAI;AAAA,EAE/C,CAAC;AACH;AAEA,SAAS+F,GACPD,GACAvH,GACS;AACT,SAAIA,EAAO,SAAS,OACXC,GAAkBsH,EAAW,MAAMvH,EAAO,IAAI,IAEnDA,EAAO,gBAAgB,OAClBM,EAAeiH,EAAW,MAAM,MAAMvH,EAAO,cAElDA,EAAO,SAAS,OACXuH,EAAW,OAAO,SAASvH,EAAO,OAEpC;AACT;AAEA,SAASkH,GAAsBhG,GAA0BlB,GAAqC;AAC5F,SAAIA,EAAO,gBAAgB,OAClBM,EAAeY,CAAQ,MAAMlB,EAAO,cAEzCA,EAAO,SAAS,OACXkB,EAAS,SAASlB,EAAO,OAE3B;AACT;AAEA,SAASmH,GACPxG,GACAiH,GACA5H,GACA+G,GACM;AACN,MAAIA,MAAe,KAAMa,MAAe,cAAcb,IAAa;AACjE;AAGF,QAAMc,IAAoB9H,GAAoBC,CAAM,GAC9Cb,IAAM,GAAGwB,CAAG,IAAIiH,CAAU,IAAIC,CAAiB,IAAId,CAAU;AACnE,MAAI7D,EAAwB,IAAI/D,CAAG;AACjC;AAGF,EAAA+D,EAAwB,IAAI/D,CAAG;AAC/B,QAAMlB,IACJ8I,MAAe,IACX,cAAcpG,CAAG,iBAAiBiH,CAAU,WAAWC,CAAiB,MACxE,cAAclH,CAAG,UAAUoG,CAAU,IAAIa,CAAU,gBAAgBC,CAAiB;AAC1F,UAAQ,KAAK5J,CAAO;AACtB;AAEA,SAAS4I,EACPxB,GACA/C,GACAwF,GACM;AACN,QAAM/G,IAAY,MAAM,QAAQsE,EAAK,QAAQ,IAAIA,EAAK,WAAW,CAACA,EAAK,QAAQ;AAC/E,MAAI0C,IAAY;AAChB,QAAMC,IAAmBjH,EAAU,IAAI,CAACG,MAAa;AACnD,QAAI,CAAC4G,EAAU5G,CAAQ;AACrB,aAAOA;AAET,IAAA6G,IAAY;AACZ,UAAME,IAAkBC,GAAoBhH,CAAQ;AACpD,WAAAiH,GAAsBF,GAAiB3F,CAAK,GACrC2F;AAAA,EACT,CAAC;AAED,MAAKF;AAIL,QAAI,MAAM,QAAQ1C,EAAK,QAAQ;AAC7B,MAAAA,EAAK,WAAW2C;AAAA,SACX;AACL,YAAMC,IAAkBD,EAAiB,CAAC;AAC1C,MAAIC,MAAoB,WACtB5C,EAAK,WAAW4C;AAAA,IAEpB;AACF;AAEA,SAASC,GAAoBhH,GAAgD;AAC3E,MAAIkH,EAAwBlH,CAAQ;AAClC,WAAOA;AAGT,QAAM+G,IAAkB/G,EAAS,MAAA;AACjC,SAAA2E,EAA0BoC,CAAe,GAClCA;AACT;AAEA,SAASE,GAAsBjH,GAAgCoB,GAAoC;AACjG,EAAIA,EAAM,kBAAkB,QAAQpB,EAAS,UAAU,UACrDA,EAAS,MAAM,OAAOxC,EAAgB4D,EAAM,aAAa,CAAC;AAG5D,QAAMsB,IACJ1C,EAAS,UACToB,EAAM,WACLA,EAAM,kBAAkB,OAAO1E,EAAiB0E,EAAM,aAAa,IAAI;AAC1E,EAAIsB,MAAkB1C,EAAS,YAC7BA,EAAS,UAAU0C,GACnB1C,EAAS,cAAc,KAGrBoB,EAAM,cACRpB,EAAS,YAAY;AAEzB;AAEA,SAAS0F,EAAqBtE,GAAuC;AACnE,SAAOA,EAAM,kBAAkB,QAAQA,EAAM,YAAY,KAAKA,EAAM;AACtE;AAEA,SAASgC,GAAmBtF,GAAwBqG,GAAuB;AACzE,EAAArG,EAAO,SAAS,IAAIqG,EAAK,GAAGA,EAAK,GAAGA,EAAK,CAAC,GAC1CrG,EAAO,SAAS;AAAA,IACdiG,EAAiBI,EAAK,SAAS;AAAA,IAC/BJ,EAAiBI,EAAK,SAAS;AAAA,IAC/BJ,EAAiBI,EAAK,SAAS;AAAA,EAAA,GAEjCrG,EAAO,MAAM,IAAIqG,EAAK,QAAQA,EAAK,QAAQA,EAAK,QAAQA,EAAK,QAAQA,EAAK,QAAQA,EAAK,MAAM;AAC/F;AAEA,SAASJ,EAAiBoD,GAAyB;AACjD,SAAQA,IAAU,KAAK,KAAM;AAC/B;AAEA,SAASjD,GAA8BpG,GAA8B;AACnE,EAAAA,EAAO,SAAS,CAACW,MAAU;AACzB,QAAI,CAACqB,EAAOrB,CAAK;AACf;AAGF,IAAIyI,EAAwBzI,EAAM,QAAQ,KACxCA,EAAM,SAAS,QAAA;AAGjB,UAAMoB,IAAY,MAAM,QAAQpB,EAAM,QAAQ,IAAIA,EAAM,WAAW,CAACA,EAAM,QAAQ;AAClF,eAAWuB,KAAYH;AACrB,MAAAuH,GAAwBpH,CAAQ,GAC5BkH,EAAwBlH,CAAQ,KAClCA,EAAS,QAAA;AAAA,EAGf,CAAC;AACH;AAEA,SAASF,EAAOhC,GAA8C;AAC5D,SAAO,YAAYA,KAAUA,EAAO,WAAW;AACjD;AAcA,SAASsJ,GAAwBpH,GAAgC;AAC/D,QAAMqH,IAAwBrH;AAC9B,EACEqH,EAAsB,QAAQ,UAC9BA,EAAsB,QAAQ,QAC9BH,EAAwBG,EAAsB,GAAG,KAEjDA,EAAsB,IAAI,QAAA;AAE9B;AAEA,SAAS1C,EAA0B2C,GAAuD;AACxF,EAAAA,EAAS,SAAS,yBAAyB;AAC7C;AAEA,SAASJ,EAAwBI,GAA2D;A3BnqBrF,MAAAjI;A2BoqBL,WAAOA,IAAAiI,EAAS,aAAT,gBAAAjI,EAAmB,4BAA2B;AACvD;ACppBO,SAASkI,GAAMzM,IAA+B,MAAa;AAChE,SAAOD,EAAY;AAAA,IACjB,YAAYD,EAAW;AAAA,IACvB,QAAQqB;AAAA,IACR,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAGnB;AAAA,EAAA,CACJ;AACH;AC1BO,SAAS0M,GACdC,GACAtK,GACAuK,GACAC,GACAC,IAAoB,GACJ;AAChB,QAAMpJ,IAAOmJ,EAAA;AAEb,EAAAnJ,EAAK,KAAK,OAAOiJ,EAAO,IAAIC,GAAcD,EAAO,CAAC,GAClDjJ,EAAK,KAAK,OAAOiJ,EAAO,IAAItK,EAAK,QAAQuK,GAAcD,EAAO,CAAC,GAC/DjJ,EAAK,KAAK;AAAA,IACRiJ,EAAO,IAAItK,EAAK;AAAA,IAChBsK,EAAO;AAAA,IACPA,EAAO,IAAItK,EAAK;AAAA,IAChBsK,EAAO,IAAIC;AAAA,IACXA;AAAA,EAAA,GAEFlJ,EAAK,KAAK,OAAOiJ,EAAO,IAAItK,EAAK,OAAOsK,EAAO,IAAItK,EAAK,SAASuK,CAAY,GAC7ElJ,EAAK,KAAK;AAAA,IACRiJ,EAAO,IAAItK,EAAK;AAAA,IAChBsK,EAAO,IAAItK,EAAK;AAAA,IAChBsK,EAAO,IAAItK,EAAK,QAAQuK;AAAA,IACxBD,EAAO,IAAItK,EAAK;AAAA,IAChBuK;AAAA,EAAA,GAEFlJ,EAAK,KAAK,OAAOiJ,EAAO,IAAIC,GAAcD,EAAO,IAAItK,EAAK,MAAM,GAChEqB,EAAK,KAAK;AAAA,IACRiJ,EAAO;AAAA,IACPA,EAAO,IAAItK,EAAK;AAAA,IAChBsK,EAAO;AAAA,IACPA,EAAO,IAAItK,EAAK,SAASuK;AAAA,IACzBA;AAAA,EAAA,GAEFlJ,EAAK,KAAK,OAAOiJ,EAAO,GAAGA,EAAO,IAAIC,CAAY,GAClDlJ,EAAK,KAAK,MAAMiJ,EAAO,GAAGA,EAAO,GAAGA,EAAO,IAAIC,GAAcD,EAAO,GAAGC,CAAY,GAC/EE,IAAY,KACdpJ,EAAK,KAAK,OAAOiJ,EAAO,IAAIC,IAAeE,GAAWH,EAAO,CAAC;AAGhE,QAAMI,IACJ,KAAK1K,EAAK,QAAQA,EAAK,SAAS,IAAIuK,KAAgB,IAAI,KAAK,KAAKA,IAAeE;AACnF,SAAO,EAAE,MAAApJ,GAAM,QAAAqJ,EAAA;AACjB;AC9CO,MAAMC,IAAY;AAAA,EACvB,SAAS;AAAA,EACT,MAAM;AACR,GCHaC,IAAa;AAAA,EACxB,SAAS;AAAA,EACT,MAAM;AACR,GCMaC,KAAkD,CAAC;AAAA,EAC9D,KAAA1F;AAAA,EACA,WAAA2F;AAAA,EACA,QAAQC;AAAA,EACR,SAAAvL;AAAA,EACA,cAAAwL;AACF,MAAM;AACJ,QAAM7E,IAActG;AAAA,IAClBV,EAAS,EAAE,GAAG4L,EAAM,GAAG,GAAGA,EAAM,GAAG;AAAA,IACnCA,EAAM;AAAA,IACN1L,EAAK,EAAE,OAAO0L,EAAM,OAAO,QAAQA,EAAM,QAAQ;AAAA,EAAA,GAG7CE,IACJF,EAAM,WAAW,QAAQA,EAAM,QAAQ,SAAS,IAAIA,EAAM,UAAUA,EAAM;AAC5E,MAAIE,KAAW;AACb;AAGF,QAAMC,IAAYJ,EAAUG,CAAO;AACnC,MAAIC,MAAc,QAMlB;AAAA,QAFA/F,EAAI,QAAQ,KAAA,GAER4F,EAAM,eAAe,GAAG;AAC1B,YAAMI,IAAkBd;AAAA,QACtBlE,EAAY;AAAA,QACZA,EAAY;AAAA,QACZ4E,EAAM;AAAA,QACNC;AAAA,MAAA;AAGF,cAAQ7F,EAAI,MAAA;AAAA,QACV,KAAKjG,EAAkB;AACrB,UAAIiM,EAAgB,KAAK,SAASP,EAAW,UAC3CzF,EAAI,QAAQ,KAAKgG,EAAgB,KAAK,IAAI,IAE1C,QAAQ,KAAK,wDAAwD;AAEvE;AAAA,QACF,KAAKjM,EAAkB;AACrB,UAAIiM,EAAgB,KAAK,SAASP,EAAW,OAC3CzF,EAAI,QAAQ,KAAKgG,EAAgB,KAAK,IAAI,IAE1C,QAAQ,KAAK,wDAAwD;AAEvE;AAAA,QACF;AACE,UAAAzL,EAAYyF,CAAG;AAAA,MAAA;AAAA,IAErB;AAKA,YAHAA,EAAI,QAAQ,cAAc3F,IAAUuL,EAAM,SAC1C5F,EAAI,QAAQ,wBAAwB4F,EAAM,QAElC5F,EAAI,MAAA;AAAA,MACV,KAAKjG,EAAkB;AACrB,QAAIgM,EAAU,SAASP,EAAU,UAC/BxF,EAAI,QAAQ;AAAA,UACV+F,EAAU;AAAA,UACV/E,EAAY,OAAO;AAAA,UACnBA,EAAY,OAAO;AAAA,UACnBA,EAAY,KAAK;AAAA,UACjBA,EAAY,KAAK;AAAA,QAAA,IAGnB,QAAQ,KAAK,uDAAuD;AAEtE;AAAA,MACF,KAAKjH,EAAkB;AACrB,QAAIgM,EAAU,SAASP,EAAU,OAC/BxF,EAAI,QAAQ;AAAA,UACV+F,EAAU;AAAA,UACV/E,EAAY,OAAO;AAAA,UACnBA,EAAY,OAAO;AAAA,UACnBA,EAAY,KAAK;AAAA,UACjBA,EAAY,KAAK;AAAA,QAAA,IAGnB,QAAQ,KAAK,uDAAuD;AAEtE;AAAA,MACF;AACE,QAAAzG,EAAYyF,CAAG;AAAA,IAAA;AAInB,IAAAA,EAAI,QAAQ,QAAA;AAAA;AACd,GChGaiG,KAAoE,CAAClG,MAAS;AACzF,QAAM,EAAE,QAAQ3C,EAAA,IAAU2C;AAC1B,EAAI3C,EAAM,mBAAmB,QAAQA,EAAM,qBAAqB,QAIhEsI,GAAY;AAAA,IACV,GAAG3F;AAAA,IACH,QAAQkF,GAAM;AAAA,MACZ,QAAQ7H,EAAM;AAAA,MACd,cAAcA,EAAM;AAAA,MACpB,aAAaA,EAAM;AAAA,MACnB,QAAQA,EAAM;AAAA,MACd,SAASA,EAAM;AAAA,MACf,WAAWA,EAAM;AAAA,MACjB,SAASA,EAAM;AAAA,MACf,QAAQA,EAAM;AAAA,MACd,OAAOA,EAAM;AAAA,MACb,GAAGA,EAAM;AAAA,MACT,GAAGA,EAAM;AAAA,IAAA,CACV;AAAA,EAAA,CACF;AACH;ACpBO,SAAS8I,GACdvL,GACAC,GACAC,GACAsL,GACa;AACb,SAAOzL;AAAA,IACL;AAAA,MACE,GAAGC,EAAS,IAAIwL,EAAU,QAAQA,EAAU;AAAA,MAC5C,GAAGxL,EAAS,IAAIwL,EAAU,QAAQA,EAAU;AAAA,IAAA;AAAA,IAE9CvL;AAAA,IACA;AAAA,MACE,OAAOC,EAAK,QAAQsL,EAAU;AAAA,MAC9B,QAAQtL,EAAK,SAASsL,EAAU;AAAA,IAAA;AAAA,EAClC;AAEJ;ACjBO,SAASC,EAAoBC,GAAgBC,GAA+B;AACjF,SAAOD,IAASC;AAClB;ACFO,MAAMZ,KAA+C,CAAC;AAAA,EAC3D,eAAAa;AAAA,EACA,OAAA/H;AAAA,EACA,QAAQoH;AAAA,EACR,SAAAvL;AAAA,EACA,eAAAiM;AAAA,EACA,WAAAH;AACF,MAAM;AACJ,QAAM/F,IAAgBwF,EAAM,UAAUvL;AACtC,MAAI+F,MAAkB;AACpB;AAGF,QAAM0F,IACJF,EAAM,WAAW,QAAQA,EAAM,QAAQ,SAAS,IAAIA,EAAM,UAAUA,EAAM;AAC5E,MAAIE,KAAW;AACb;AAGF,QAAM5J,IAAOqK,EAAcT,CAAO;AAClC,MAAI5J,MAAS;AACX;AAGF,QAAM,EAAE,QAAAiJ,GAAQ,MAAAtK,EAAA,IAASqL;AAAA,IACvBlM,EAAS,EAAE,GAAG4L,EAAM,GAAG,GAAGA,EAAM,GAAG;AAAA,IACnCA,EAAM;AAAA,IACN1L,EAAK,EAAE,OAAO0L,EAAM,OAAO,QAAQA,EAAM,QAAQ;AAAA,IACjDO;AAAA,EAAA;AAGF,EAAA3H,EAAM,SAAS;AAAA,IACb,MAAAtC;AAAA,IACA,GAAGkK,EAAoBjB,EAAO,GAAGmB,CAAa;AAAA,IAC9C,GAAGF,EAAoBjB,EAAO,GAAGmB,CAAa;AAAA,IAC9C,GAAGF,EAAoBvL,EAAK,OAAOyL,CAAa;AAAA,IAChD,GAAGF,EAAoBvL,EAAK,QAAQyL,CAAa;AAAA,IACjD,eAAe,IAAIlG,KAAiB;AAAA,EAAA,CACrC;AACH,GCzCaoG,KAA2E,CAACzG,MAAS;AAChG,QAAM,EAAE,QAAQ3C,EAAA,IAAU2C;AAC1B,EAAI3C,EAAM,mBAAmB,QAAQA,EAAM,qBAAqB,QAIhEsI,GAAY;AAAA,IACV,GAAG3F;AAAA,IACH,QAAQkF,GAAM;AAAA,MACZ,QAAQ7H,EAAM;AAAA,MACd,cAAcA,EAAM;AAAA,MACpB,aAAaA,EAAM;AAAA,MACnB,QAAQA,EAAM;AAAA,MACd,SAASA,EAAM;AAAA,MACf,WAAWA,EAAM;AAAA,MACjB,SAASA,EAAM;AAAA,MACf,QAAQA,EAAM;AAAA,MACd,OAAOA,EAAM;AAAA,MACb,GAAGA,EAAM;AAAA,MACT,GAAGA,EAAM;AAAA,IAAA,CACV;AAAA,EAAA,CACF;AACH,GCpBaqJ,KAGT;AAAA,EACF,CAACvN,EAAgB,KAAK,GAAG+M;AAC3B,GAEaS,KAGT;AAAA,EACF,CAACxN,EAAgB,KAAK,GACpBsN;AACJ;ACPA,eAAsBG,GAAkBxJ,GAA4C;AAClF,QAAMyC,IAAU,MAAMzE,EAAA,GAChBkD,IAAyB,IAAIuB,EAAQ,WAAA;AAC3C,QAAMjB,EAAeN,GAAQlB,CAAG;AAEhC,QAAMC,IAAQyB,EAAoB1B,CAAG;AACrC,MAAIC,MAAU;AACZ,UAAM,IAAI,MAAM,4BAA4BD,CAAG,EAAE;AAGnD,SAAOD,EAAuBC,GAAKC,CAAK;AAC1C;AAEA,eAAsBwJ,GAAmBzJ,GAA4C;AACnF,QAAMY,IAAa,MAAM4I,GAAkBxJ,CAAG;AAC9C,SAAAW,EAAwBC,CAAU,GAC3BA;AACT;ACFO,SAAS8I,GAA4B,EAAE,QAAAC,KAAoD;AAChG,EAAI,OAAO,SAAW,QAItB,OAAO,6BAA6B,CAACC,GAAWC,IAAU,CAAA,MAAO;AAC/D,UAAM5J,IAAQ0J,EAAOC,CAAS;AAC9B,QAAI3J,MAAU;AACZ,qBAAQ,KAAK,+CAA+C2J,CAAS,IAAI,GAClE;AAGT,UAAM5F,IAASrB,GAA4B1C,CAAK;AAChD,QAAI+D,MAAW;AACb,qBAAQ,KAAK,uBAAuB4F,CAAS,8BAA8B,GACpE;AAGT,UAAME,IAAYD,EAAQ,aAAa,aACjCE,IAAU/F,EAAO,UAAU8F,GAAWD,EAAQ,OAAO,GACrDG,IAAO,SAAS,cAAc,GAAG;AACvC,WAAAA,EAAK,OAAOD,GACZC,EAAK,WAAWH,EAAQ,YAAY,GAAGD,CAAS,IAAIK,GAAkBH,CAAS,CAAC,IAChFE,EAAK,MAAA,GAEE;AAAA,EACT;AACF;AAEA,SAASC,GAAkBH,GAA2B;AACpD,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;"}
@@ -0,0 +1,7 @@
1
+ import { BrowserImageRendererProps } from './types/BrowserImageRendererProps';
2
+ export declare class BrowserImageRenderer {
3
+ props: BrowserImageRendererProps;
4
+ constructor(props: Partial<BrowserImageRendererProps>);
5
+ render(startImageIndex?: number): Promise<void>;
6
+ private renderFrame;
7
+ }
@@ -0,0 +1,36 @@
1
+ import { BrowserCanvasObjectRenderer } from '../../../renderer/browser-canvas/types/BrowserCanvasObjectRenderer';
2
+ import { Presentation } from '../../../types/Presentation';
3
+ import { SlideObject } from '../../../types/SlideObject';
4
+ import { ImageExportFrame } from '../../utils/getImageExportFrames';
5
+ export type BrowserImageFormat = "png" | "jpeg" | "webp";
6
+ export interface BrowserImageRendererImage extends ImageExportFrame {
7
+ readonly blob: Blob;
8
+ readonly filename: string;
9
+ }
10
+ export interface BrowserImageRendererProps {
11
+ readonly presentation: Presentation;
12
+ /**
13
+ * An animated export includes all frames of animation in the entire presentation.
14
+ * Non-animated exports only include key builds.
15
+ */
16
+ readonly isAnimatedExport: boolean;
17
+ /**
18
+ * The number of frames to hold for each animation step.
19
+ * Applies only to animated exports.
20
+ */
21
+ readonly animationHoldFrames: number;
22
+ /**
23
+ * The number of frames per second for animated exports.
24
+ */
25
+ readonly framesPerSecond: number;
26
+ readonly getFilenameForImage: (imageIndex: number) => string;
27
+ readonly imageFormat: BrowserImageFormat;
28
+ readonly imageQuality: number | undefined;
29
+ /** How frequently to log progress frame. */
30
+ readonly logFrequency: number;
31
+ readonly objectRenderers: Record<string, BrowserCanvasObjectRenderer<SlideObject>>;
32
+ readonly onRenderImage: (image: BrowserImageRendererImage) => void | Promise<void>;
33
+ readonly renderScale: number;
34
+ readonly resourcePathPrefix: string;
35
+ readonly waitForFonts: boolean;
36
+ }
@@ -0,0 +1,2 @@
1
+ export { BrowserImageRenderer } from './browser-image-renderer/BrowserImageRenderer';
2
+ export { type BrowserImageFormat, type BrowserImageRendererImage, type BrowserImageRendererProps, } from './browser-image-renderer/types/BrowserImageRendererProps';
@@ -5,5 +5,5 @@ export declare class ImageRenderer {
5
5
  state: ImageRendererState;
6
6
  constructor(props: Partial<ImageRendererProps>);
7
7
  save(directoryName: string, startImageIndex?: number): Promise<void>;
8
- renderImage(slideIndex: number, buildIndex: number, buildTime?: number | null): Promise<void>;
8
+ renderImage(slideIndex: number, buildIndex: number, buildTime?: number | null, targetImageIndex?: number | null): Promise<void>;
9
9
  }
@@ -1,3 +1,5 @@
1
+ export { BrowserImageRenderer } from './browser-image-renderer/BrowserImageRenderer';
2
+ export { type BrowserImageFormat, type BrowserImageRendererImage, type BrowserImageRendererProps, } from './browser-image-renderer/types/BrowserImageRendererProps';
1
3
  export { ImageRenderer } from './image-renderer/ImageRenderer';
2
4
  export { NotesRenderer } from './notes-renderer/NotesRenderer';
3
5
  export { PDFRenderer } from './pdf-renderer/PDFRenderer';
@@ -0,0 +1,14 @@
1
+ import { Presentation } from '../../types/Presentation';
2
+ export interface ImageExportFrame {
3
+ readonly imageIndex: number;
4
+ readonly slideIndex: number;
5
+ readonly buildIndex: number;
6
+ readonly buildTime: number | null;
7
+ }
8
+ export interface GetImageExportFramesProps {
9
+ readonly presentation: Presentation;
10
+ readonly isAnimatedExport: boolean;
11
+ readonly animationHoldFrames: number;
12
+ readonly framesPerSecond: number;
13
+ }
14
+ export declare function getImageExportFrames({ presentation, isAnimatedExport, animationHoldFrames, framesPerSecond, }: GetImageExportFramesProps): Generator<ImageExportFrame>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ (function(W,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(W=typeof globalThis<"u"?globalThis:W||self,_(W.PresenterBrowserExport={}))})(this,(function(W){"use strict";const _="presenter.navigator.state",D={open:!1,visibility:{slides:!0,current:!0,next:!0,notes:!1}};function q(){return typeof document>"u"?!1:Array.from(document.scripts).some(t=>t.src.includes("/@vite/client"))}function $t(){return q()?Q().open:!1}function Wt(){dt({...Q(),open:!0})}function ct(){var t;(t=Z())==null||t.removeItem(_)}function Q(){var t,e,n,r,i;if(!q())return D;try{const o=(t=Z())==null?void 0:t.getItem(_);if(o==null)return D;const s=JSON.parse(o);return{open:typeof s.open=="boolean"?s.open:D.open,visibility:{slides:typeof((e=s.visibility)==null?void 0:e.slides)=="boolean"?s.visibility.slides:D.visibility.slides,current:typeof((n=s.visibility)==null?void 0:n.current)=="boolean"?s.visibility.current:D.visibility.current,next:typeof((r=s.visibility)==null?void 0:r.next)=="boolean"?s.visibility.next:D.visibility.next,notes:typeof((i=s.visibility)==null?void 0:i.notes)=="boolean"?s.visibility.notes:D.visibility.notes}}}catch{return D}}function dt(t){var e;q()&&((e=Z())==null||e.setItem(_,JSON.stringify(t)))}function Z(){try{return window.sessionStorage}catch{return null}}function Ut(t=null){return{objects:[],animations:[],extras:[],description:null,isAllKey:!1,isEndKey:!0,isStartKey:!1,notes:null,shortcut:null,title:"",...t}}function ut(t){return t.altKey||t.ctrlKey||t.metaKey||t.shiftKey}function ht(t){var r,i;if(t===null)return!1;const e=t,n=(r=e.tagName)==null?void 0:r.toLowerCase();return n==="input"||n==="textarea"||n==="select"||n==="button"||e.isContentEditable?!0:(((i=e.closest)==null?void 0:i.call(e,"[contenteditable=''], [contenteditable='true']"))??null)!==null}function Gt(t){var r;const{slides:e}=t,n={s:{slideIndex:0,buildIndex:0},c:{slideIndex:null,buildIndex:0},e:{slideIndex:e.length-1,buildIndex:((r=e[e.length-1])==null?void 0:r.animations.length)??0}};for(let i=0;i<e.length;i++){const o=e[i];if(o===void 0)continue;const s=o.shortcut;tt(n,s,i,0);for(let a=0;a<o.animations.length;a++){const c=o.animations[a];if(c!==void 0)if(Array.isArray(c))for(const l of c)tt(n,l.shortcut,i,a+1);else tt(n,c.shortcut,i,a+1)}}return n}function tt(t,e,n,r){if(e!==null)if(Array.isArray(e))for(const i of e)t[i]={slideIndex:n,buildIndex:r};else t[e]={slideIndex:n,buildIndex:r}}function ft(t,e){const n=t[e];return n!==void 0?n:isNaN(Number(e))?null:{slideIndex:Number(e)-1,buildIndex:0}}function pt(t,e,n,{onNext:r,onPrevious:i,onRenderSlide:o,onShowNavigator:s},{focusOnPointerDown:a=!1,keyEventTarget:c=e,signal:l}={}){n.shortcuts=Gt(t);const d=l===void 0?void 0:{signal:l};a&&(e.hasAttribute("tabindex")||(e.tabIndex=-1),e.addEventListener("pointerdown",u=>{ht(u.target)||e.focus({preventScroll:!0})},d)),e.addEventListener("mousemove",()=>{e.style.cursor="auto"},d),c.addEventListener("keyup",u=>{const h=u;if(ht(h.target))return;if(h.code==="Escape"){n.textCommand=null;return}if(h.code==="ArrowRight"||h.code==="Space"){r(h.shiftKey);return}if(h.code==="ArrowLeft"){i(h.shiftKey);return}const p=Kt(h);if(p!==null){const g=ft(n.shortcuts,p);n.textCommand=null,g!==null&&(h.preventDefault(),o(g.slideIndex,g.buildIndex));return}if(n.textCommand!==null){if(h.code==="Enter"){const g=n.textCommand;n.textCommand=null;const m=ft(n.shortcuts,g);m!==null&&o(m.slideIndex,m.buildIndex);return}else h.code==="Backspace"?n.textCommand=n.textCommand.slice(0,-1):n.textCommand+=h.key;return}if(h.key==="g"){n.textCommand="";return}if(h.key==="`"&&!ut(h)){s();return}},d)}function Kt(t){return!t.altKey||t.ctrlKey||t.metaKey||t.shiftKey?null:t.code.startsWith("Key")&&t.code.length===4?t.code.slice(3).toLowerCase():t.code.startsWith("Digit")&&t.code.length===6?t.code.slice(5):t.code.startsWith("Numpad")&&t.code.length===7?t.code.slice(6):null}function Yt(t,e){for(let n=Math.min(e,t.animations.length);n>=0;n--){const r=Xt(t,n);if(r!==null)return r}return null}function Xt(t,e){if(e===0)return t.notes;const n=t.animations[e-1];return n===void 0?null:Jt(n)}function Jt(t){if(!Array.isArray(t))return t.notes;const e=t.map(({notes:n})=>n).filter(n=>n!==null);return e.length>0?e.join(`
2
+
3
+ `):null}let f=null,K=null,z=null;const gt="__presenterNavigatorInstanceId";let yt={width:700,height:680,left:20,top:50};function qt({presentation:t,shortcutState:e,onNavigateToSlide:n,onRenderSlide:r,onNext:i,onPrevious:o,forceRefresh:s=!1}){if(f!==null&&!f.closed&&(X(f),!s))return f.focus(),K;if((f===null||f.closed)&&(f=window.open("","Navigator",ne())),f===null)return console.error("Failed to open navigator window."),null;z==null||z();const a=ie(f),c=new AbortController;z=()=>c.abort();const l=Qt(t,n,i,a.isActive);return K=l,Wt(),f.document.title=t.title,f.document.body.replaceChildren(l.element),pt(t,l.element,e,{onNext:d=>{a.isActive()&&i(d)},onPrevious:d=>{a.isActive()&&o(d)},onRenderSlide:(d,u)=>{a.isActive()&&r(d,u)},onShowNavigator:()=>{a.isActive()&&et()}},{keyEventTarget:f,signal:c.signal}),f.addEventListener("resize",()=>X(f),{signal:c.signal}),f.addEventListener("beforeunload",()=>{X(f),ct()},{signal:c.signal}),f.addEventListener("keyup",d=>{a.isActive()&&(d.key==="Escape"||d.key==="`"&&!ut(d))&&et()},{signal:c.signal}),K}function Qt(t,e,n,r=()=>!0){const i=(f==null?void 0:f.document)??document,o=i.createElement("div");o.style.boxSizing="border-box",o.style.display="grid",o.style.gridTemplateColumns="260px 1fr",o.style.gap="18px",o.style.height="100vh",o.style.overflow="hidden",o.style.padding="18px",o.style.fontFamily='-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',o.style.backgroundColor="#f5f6f8",o.style.color="#1f2937",i.body.style.margin="0",i.body.style.overflow="hidden";const s=i.createElement("div");s.style.display="flex",s.style.flexDirection="column",s.style.gap="8px",s.style.minHeight="0",s.style.overflowY="auto",s.style.paddingRight="4px";const a=i.createElement("div");a.style.display="flex",a.style.flexDirection="column",a.style.gap="14px",a.style.minHeight="0",a.style.minWidth="0",a.style.overflow="hidden";const c=i.createElement("div");c.style.display="flex",c.style.gap="14px",c.style.alignItems="center",c.style.flexWrap="wrap",c.style.fontSize="13px",c.style.color="#4b5563";const l=i.createElement("div");l.style.display="flex",l.style.gap="14px",l.style.flex="1 1 auto",l.style.minHeight="0",l.style.minWidth="0",l.style.overflow="hidden";const d=mt("Current",t),u=mt("Next",t),h=Zt(),p=Q();u.container.style.cursor="pointer",u.container.addEventListener("click",()=>{r()&&n()});const g=t.slides.map((y,N)=>{const P=te(y,N);return P.style.cursor="pointer",P.addEventListener("click",k=>{r()&&(k.shiftKey&&et(),e(N))}),s.appendChild(P),P}),m=Y("Slides",s,p.visibility.slides),w=Y("Current",d.container,p.visibility.current),O=Y("Next",u.container,p.visibility.next),v=Y("Notes",h.container,p.visibility.notes),b=()=>{const y=w.input.checked&&O.input.checked&&T();o.style.gridTemplateColumns=m.input.checked?"260px 1fr":"1fr",l.style.flexDirection=y?"column":"row",d.container.style.flex="1 1 0",u.container.style.flex="1 1 0",requestAnimationFrame(()=>{d.resize(),u.resize()}),dt({...p,open:!0,visibility:{slides:m.input.checked,current:w.input.checked,next:O.input.checked,notes:v.input.checked}})};m.input.addEventListener("change",b),w.input.addEventListener("change",b),O.input.addEventListener("change",b),v.input.addEventListener("change",b),f==null||f.addEventListener("resize",b),c.appendChild(m.element),c.appendChild(w.element),c.appendChild(O.element),c.appendChild(v.element),l.appendChild(d.container),l.appendChild(u.container),a.appendChild(c),a.appendChild(l),a.appendChild(h.container),o.appendChild(s),o.appendChild(a);function S(y,N,P,k){r()&&(g.forEach(($,wn)=>{const lt=wn===y;$.style.backgroundColor=lt?"#dbeafe":"#ffffff",$.style.borderColor=lt?"#60a5fa":"#e5e7eb",$.style.color=lt?"#1e3a8a":"#1f2937"}),d.label.textContent=xt(t,y,N),u.label.textContent=xt(t,P,k),h.content.textContent=Yt(t.slides[y]??Ut(),N)??"",ee(g[y],s),b())}function T(){const y=f;if(y===null)return!1;const N=m.input.checked?278:0,P=y.innerWidth-36-N,k=y.innerHeight-36-c.offsetHeight-14;return P<=0||k<=0?!1:P/k<1.1}return{element:o,currentCanvas:d.canvas,nextCanvas:u.canvas,currentLabel:d.label,nextLabel:u.label,isOpen:()=>f!==null&&!f.closed,update:S}}function Zt(){const t=(f==null?void 0:f.document)??document,e=t.createElement("div");e.style.display="flex",e.style.flex="0 1 180px",e.style.flexDirection="column",e.style.minHeight="100px",e.style.maxHeight="30vh",e.style.overflow="hidden",e.style.backgroundColor="#ffffff",e.style.border="1px solid #e5e7eb",e.style.borderRadius="6px",e.style.boxShadow="0 1px 2px rgba(15, 23, 42, 0.06)";const n=t.createElement("div");n.textContent="Notes",n.style.padding="10px 12px 6px",n.style.fontSize="12px",n.style.fontWeight="700",n.style.textTransform="uppercase",n.style.color="#6b7280";const r=t.createElement("div");return r.style.flex="1 1 auto",r.style.minHeight="0",r.style.overflowY="auto",r.style.padding="4px 12px 12px",r.style.fontSize="16px",r.style.lineHeight="1.5",r.style.whiteSpace="pre-wrap",e.appendChild(n),e.appendChild(r),{container:e,content:r}}function te(t,e){const n=(f==null?void 0:f.document)??document,r=n.createElement("div");r.style.display="flex",r.style.alignItems="center",r.style.gap="10px",r.style.padding="8px 10px",r.style.backgroundColor="#ffffff",r.style.border="1px solid #e5e7eb",r.style.borderRadius="6px",r.style.boxShadow="0 1px 2px rgba(15, 23, 42, 0.06)",r.style.fontSize="14px",r.style.lineHeight="1",r.style.userSelect="none";const i=n.createElement("div");i.textContent=`${e+1}`,i.style.minWidth="24px",i.style.fontWeight="700",i.style.color="#6b7280";const o=n.createElement("div");return o.textContent=t.title.length>0?t.title:`Slide ${e+1}`,o.style.overflow="hidden",o.style.textOverflow="ellipsis",o.style.whiteSpace="nowrap",r.appendChild(i),r.appendChild(o),r}function mt(t,e){var d;const n=(f==null?void 0:f.document)??document,r=n.createElement("div");r.style.display="flex",r.style.alignItems="center",r.style.flexDirection="column",r.style.minHeight="0",r.style.minWidth="0";const i=n.createElement("div");i.textContent=t,i.style.marginBottom="4px",i.style.fontSize="12px",i.style.fontWeight="700",i.style.textAlign="center",i.style.textTransform="uppercase",i.style.color="#6b7280";const o=n.createElement("div");o.style.marginBottom="6px",o.style.fontSize="14px",o.style.fontWeight="600",o.style.textAlign="center";const s=n.createElement("div");s.style.flex="1 1 auto",s.style.display="flex",s.style.alignItems="flex-start",s.style.justifyContent="center",s.style.minHeight="0",s.style.width="100%",s.style.overflow="hidden";const a=n.createElement("canvas");a.style.display="block",a.style.width="0",a.style.height="0";function c(){const u=s.clientWidth,h=s.clientHeight;if(u<=0||h<=0)return;const p=e.size.width/e.size.height,g=Math.min(u,h*p),m=g/p;a.style.width=`${g}px`,a.style.height=`${m}px`}const l=(d=n.defaultView)==null?void 0:d.ResizeObserver;return l!==void 0&&new l(c).observe(s),f==null||f.addEventListener("resize",c),s.appendChild(a),r.appendChild(i),r.appendChild(o),r.appendChild(s),{container:r,label:o,canvas:a,resize:c}}function Y(t,e,n){const r=(f==null?void 0:f.document)??document,i=e.style.display||"block",o=r.createElement("label");o.style.display="inline-flex",o.style.alignItems="center",o.style.gap="6px",o.style.userSelect="none";const s=r.createElement("input");return s.type="checkbox",s.checked=n,e.style.display=n?i:"none",s.addEventListener("change",()=>{e.style.display=s.checked?i:"none"}),o.appendChild(s),o.appendChild(r.createTextNode(t)),{element:o,input:s}}function xt(t,e,n){if(e===null)return"End of presentation";const r=t.slides[e];return r===void 0?"No slide":`Slide ${e+1} of ${t.slides.length}, Build ${n+1} of ${r.animations.length+1}`}function ee(t,e){if(t===void 0)return;const n=t.offsetTop,r=n+t.offsetHeight,i=e.scrollTop,o=i+e.clientHeight;(n<i||r>o)&&t.scrollIntoView({block:"nearest"})}function et(){X(f),ct(),z==null||z(),f==null||f.close(),f=null,K=null,z=null}function ne(){const{width:t,height:e,left:n,top:r}=yt;return`width=${t},height=${e},left=${n},top=${r}`}function X(t){t===null||t.closed||(yt={width:t.outerWidth,height:t.outerHeight,left:t.screenX,top:t.screenY})}function ie(t){var r;const e=typeof((r=globalThis.crypto)==null?void 0:r.randomUUID)=="function"?globalThis.crypto.randomUUID():`${Date.now()}-${Math.random()}`,n=t;return n[gt]=e,{isActive:()=>!t.closed&&n[gt]===e}}function E(t,e=0,n=0,r=1){if(typeof t=="string"){const i=t.replace("#",""),o=parseInt(i,16);return isNaN(o)?(console.warn("Invalid hex color format:",t),bt):i.length===6?{red:o>>16&255,green:o>>8&255,blue:o&255,alpha:1}:i.length===8?{red:o>>24&255,green:o>>16&255,blue:o>>8&255,alpha:(o&255)/255}:(console.warn("Invalid hex color format:",t),bt)}else if(typeof t=="number")return{red:t,green:e??0,blue:n??0,alpha:r??1};return{red:0,green:0,blue:0,alpha:1,...t}}E.BLACK=E(0,0,0),E.BLUE=E(0,0,255),E.GREEN=E(0,255,0),E.RED=E(255,0,0),E.TRANSPARENT=E(0,0,0,0),E.WHITE=E(255,255,255);const bt={red:0,green:0,blue:0,alpha:1};function C(t=null){return{height:0,width:0,...t}}const oe=C({width:0,height:0});function wt(t=null){return{backgroundColor:E.WHITE,slides:[],title:"Presentation",size:C({width:3840,height:2160}),resources:{images:{}},...t}}const U={ANIMATE:"Animate",PAUSE:"Pause",UPDATE:"Update"};function B(t,e){throw new Error("Unexpected value: "+t)}function vt(t){const e=Array.isArray(t)?t:[t];let n=0,r=0;for(const i of e)switch(i.type){case U.PAUSE:n+=i.duration;break;case U.ANIMATE:r=Math.max(r,n+i.delay+i.duration),i.block&&(n+=i.delay+i.duration);break;case U.UPDATE:break;default:B(i)}return r}function St(t,e=null){return t.alpha*(e??1)}function nt(t,e=null){const{red:n,green:r,blue:i}=t,o=St(t,e);return`rgba(${n}, ${r}, ${i}, ${o})`}function Tt(t){return t===document.body}function re(t,e){const n=document.createElement("div");if(n.style.width="100%",n.style.aspectRatio=`${t.size.width} / ${t.size.height}`,n.style.position="relative",Tt(e)){n.style.top="50%",n.style.transform="translateY(-50%)",n.style.marginLeft="auto",n.style.marginRight="auto",n.style.overflowY="clip",document.title=t.title,document.documentElement.style.height="100%",document.body.style.margin="0",document.body.style.height="100%",document.body.style.width="100%",document.body.style.backgroundColor="#000000";const r=t.size.height/t.size.width;Ct(n,r),window.matchMedia(`(min-aspect-ratio: ${t.size.width} / ${t.size.height})`).addEventListener("change",()=>Ct(n,r))}return n}function Ct(t,e){window.innerHeight/window.innerWidth>e?(t.style.width="100%",t.style.height="auto"):(t.style.width="auto",t.style.height="100%")}function J(t){const e=[],n=t;for(const r of["objects","meshes","nodes","materials"]){const i=n[r];Array.isArray(i)&&e.push(...se(i))}return e}function se(t){return t.filter(e=>typeof e=="object"&&e!==null&&"objectType"in e)}function It(t){const e={};function n(i){i!=null&&i.length>0&&(e[i]=i)}function r(i){const o=i;n(o.imagePath),n(o.fallbackImagePath);for(const s of J(i))r(s)}for(const i of t.slides)for(const o of i.objects)r(o);return e}const Et=[{check:t=>typeof t=="number",interpolate:(t,e,n)=>t+(e-t)*n},{check:t=>typeof t=="object"&&t!==null&&typeof t.red=="number"&&typeof t.green=="number"&&typeof t.blue=="number"&&typeof t.alpha=="number",interpolate:(t,e,n)=>({red:Math.round(t.red+(e.red-t.red)*n),green:Math.round(t.green+(e.green-t.green)*n),blue:Math.round(t.blue+(e.blue-t.blue)*n),alpha:t.alpha+(e.alpha-t.alpha)*n})},{check:t=>!0,interpolate:(t,e)=>e}];function ae(t,e,n,r=null){if(n===0)return t;if(n===1)return{...t,...e};const i=r!=null?[...r,...Et]:Et,o={};for(const s in e){const a=t[s],c=e[s];for(const l of i)if(l.check(a,s)&&l.check(c,s)){o[s]=l.interpolate(a,c,n);break}}return{...t,...o}}function At(t,e,n=null){if(e===null)return;const r=Array.isArray(e)?e:[e];let i=0;for(const o of r){if(n!==null&&i>n)break;switch(o.type){case U.ANIMATE:{const s=t.get(o.object);if(s===void 0)break;const a=n!==null?n-i:null,c=Math.max(Math.min(a!==null?(a-o.delay)/o.duration:1,1),0);t.set(o.object,{...s,...ae(s,o.props,o.easing(c),o.interpolators)}),o.block&&(i+=o.delay+o.duration);break}case U.UPDATE:{const s=t.get(o.object);if(s===void 0)break;t.set(o.object,{...s,...o.props});break}case U.PAUSE:i+=o.duration;break;default:B(o)}}}function Pt({slide:t,buildIndex:e,buildTime:n}){const r=new Map;function i(s){r.set(s,s);for(const a of J(s))i(a)}for(const s of t.objects)i(s);const o=n===null?e:e-1;for(let s=0;s<o;s++){const a=t.animations[s]??null;At(r,a)}if(n!==null&&e>0){const s=t.animations[e-1]??null;At(r,s,n)}return r}const I={ARROW:"Arrow",CIRCLE:"Circle",GROUP:"Group",IMAGE:"Image",LINE:"Line",MASK:"Mask",PATH:"Path",POLYGON:"Polygon",RECTANGLE:"Rectangle",SLIDE_OBJECT:"SlideObject",SPOTLIGHT:"Spotlight",SVG:"SVG",TEXT:"Text"};function Ot(t){const e={};function n(r){if(r.objectType===I.SVG){const o=r.svg;o!==void 0&&o.length>0&&(e[o]=o)}const i=J(r);for(const o of i)n(o)}for(const r of t.slides)for(const i of r.objects)n(i);return e}const V="presenterState";function le(t,e){const n=localStorage.getItem(V);if(n===null)return null;if(e===null)return localStorage.removeItem(V),null;let r;try{r=JSON.parse(n)}catch(l){return console.error("Failed to parse presentation state from localStorage:",l),localStorage.removeItem(V),null}const{title:i,timestamp:o}=r;let{slideIndex:s,buildIndex:a}=r;if(typeof i!="string"||typeof s!="number"||typeof a!="number"||typeof o!="number"||i!==t.title||Date.now()-o>1e3*60*e)return localStorage.removeItem(V),null;s>t.slides.length-1&&(s=t.slides.length-1,a=0);const c=t.slides[s];return c===void 0?(localStorage.removeItem(V),null):(a>c.animations.length&&(a=c.animations.length),{title:i,slideIndex:s,buildIndex:a})}function Nt({title:t,slideIndex:e,buildIndex:n}){localStorage.setItem(V,JSON.stringify({title:t,slideIndex:e,buildIndex:n,timestamp:Date.now()}))}const Bt=Object.freeze({accessibleDescriptionElement:null,canvas:null,extrasContainer:null,mountedExtrasCleanups:[],slideIndex:0,buildIndex:0,currentAnimationId:null,imageById:{},shortcutState:{textCommand:null,shortcuts:{}}}),A={Browser:"browser",Node:"node"};function Rt(t){return typeof t=="string"?[[{text:t}]]:t.map(e=>e.map(n=>typeof n=="string"?{text:n}:n))}function ce(t){const e=document.createElement("div");return e.setAttribute("role","status"),e.setAttribute("aria-label",t),e.setAttribute("aria-atomic","true"),Object.assign(e.style,{position:"absolute",width:"1px",height:"1px",overflow:"hidden",clipPath:"inset(50%)",whiteSpace:"nowrap"}),e}function de(t,e){const n=t.description?[t.description]:[];function r(i,o){const s=e.get(i);if(s===void 0)return;const a=o*s.opacity;if(!ue(s,a))return;const c=he(s);c&&n.push(c);for(const l of J(i))r(l,a)}for(const i of t.objects)r(i,1);return n.join(`
4
+ `)}function ue(t,e){return e!==0&&(!("drawn"in t)||t.drawn!==0)}function he(t){return t.description!==null?t.description:fe(t)?pe(t):null}function fe(t){return t.objectType===I.TEXT}function pe(t){let e=t.length;return Rt(t.text).map(n=>n.map(r=>{if(e===null)return r.text;if(e<=0)return"";const i=r.text.slice(0,e);return e-=i.length,i}).join("")).join(`
5
+ `)}function ge(t,e){t.textContent!==e&&(t.textContent=e)}function ye(t,e){e.context.clearRect(0,0,t.width,t.height)}function Lt(t){const e=document.createElement("canvas");return e.setAttribute("width",t.width.toString()),e.setAttribute("height",t.height.toString()),e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width="100%",e}const M={Browser:"browser",Node:"node"};function me(t){const e=new Path2D(t);return{type:M.Browser,path:e}}function xe(t){const{drawn:e,startX:n,startY:r,endX:i,endY:o,arrowheadSize:s,isArrowheadFilled:a,isDrawnFromCenter:c}=t,l={x:n,y:r},d={x:i,y:o},u=Math.atan2(d.y-l.y,d.x-l.x),h={x:l.x+(d.x-l.x)/2,y:l.y+(d.y-l.y)/2},p=d.x-l.x,g=d.y-l.y,w=Math.hypot(p,g)*e,O=Math.cos(u),v=Math.sin(u),b=c?{x:h.x-O*w/2,y:h.y-v*w/2}:l,S=c?{x:h.x+O*w/2,y:h.y+v*w/2}:{x:l.x+O*w,y:l.y+v*w},T=a?Math.PI/6:Math.PI/4.5,y=w<s*2?w/2:s,N={x:S.x-y*Math.cos(u-T),y:S.y-y*Math.sin(u-T)},P={x:S.x-y*Math.cos(u+T),y:S.y-y*Math.sin(u+T)},k={x:b.x+y*Math.cos(u-T),y:b.y+y*Math.sin(u-T)},$={x:b.x+y*Math.cos(u+T),y:b.y+y*Math.sin(u+T)};return{arrowPoints:[b,S],arrowheadPoints:[N,S,P],doubledArrowheadPoints:[k,b,$]}}function it(t,e=null){const{red:n,green:r,blue:i}=t,o=n<<16|r<<8|i,s=Math.round(St(t,e)*255);return`#${o.toString(16).padStart(6,"0")}${s!==255?s.toString(16).padStart(2,"0"):""}`}function H({ctx:t,color:e,drawn:n=null,isDrawnFromCenter:r=!1,isRounded:i=!1,opacity:o=null,path:s,pathLength:a=null,width:c}){if(!(c===0||n===0)){if(n!==null&&a!==null&&n!==1){const l=a+(i?c:0),d=a*n;if(!r)t.context.setLineDash([d,l-d]),t.context.lineDashOffset=0;else{const u=l-d;t.context.setLineDash([d,u]),t.context.lineDashOffset=-u/2}}else t.context.setLineDash([]),t.context.lineDashOffset=0;if(t.context.lineWidth=c,t.context.strokeStyle=it(e,o),t.context.lineCap=i?"round":"butt",s===void 0){t.context.stroke();return}switch(t.type){case A.Browser:s.type===M.Browser?t.context.stroke(s.path):console.warn("Attempted to use Node Path2D in Browser Canvas context");break;case A.Node:s.type===M.Node?t.context.stroke(s.path):console.warn("Attempted to use Browser Path2D in Node Canvas context");break;default:B(t)}}}function F({ctx:t,path:e,color:n,opacity:r=null}){if(t.context.fillStyle=nt(n,r),e===void 0){t.context.fill();return}switch(t.type){case A.Browser:e.type===M.Browser?t.context.fill(e.path):console.warn("Attempted to use Node Path2D in Browser Canvas context");break;case A.Node:e.type===M.Node?t.context.fill(e.path):console.warn("Attempted to use Browser Path2D in Node Canvas context");break;default:B(t)}}function ot(t,e){const n=e(),r=t[0];if(r===void 0)return{path:n,length:0};n.path.moveTo(r.x,r.y);let i=0;for(let o=1;o<t.length;o++){const s=t[o],a=t[o-1];if(s===void 0||a===void 0)continue;const c=s.x-a.x,l=s.y-a.y;i+=Math.hypot(c,l),n.path.lineTo(s.x,s.y)}return{path:n,length:i}}const be=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0)return;const{arrowPoints:o,arrowheadPoints:s,doubledArrowheadPoints:a}=xe(e),{path:c}=ot(o,r),{path:l}=ot(s,r);if(H({color:e.color,ctx:t,path:c,opacity:i,width:e.width}),e.isArrowheadFilled&&(l.path.closePath(),F({ctx:t,path:l,color:e.color,opacity:i})),H({color:e.color,ctx:t,path:l,opacity:i,width:e.width}),e.isArrowheadDoubled){const{path:d}=ot(a,r);e.isArrowheadFilled&&(d.path.closePath(),F({ctx:t,path:d,color:e.color,opacity:i})),H({color:e.color,ctx:t,path:d,opacity:i,width:e.width})}};function we(t,e){const n=t.radius-t.strokeWidth/2;if(n<=0)return;const r=e(),i=-Math.PI/2;return r.path.arc(t.x,t.y,n,i,i+2*Math.PI),r}function ve(t,e){const n=e(),r=-Math.PI/2;n.path.arc(t.x,t.y,t.radius,r,r+2*Math.PI);const i=2*Math.PI*t.radius;return{path:n,length:i}}function kt(t,e){switch(t.type){case A.Browser:e.type===M.Browser?t.context.clip(e.path):console.warn("Attempted to use Node Path2D in Browser Canvas context");break;case A.Node:e.type===M.Node?t.context.clip(e.path):console.warn("Attempted to use Browser Path2D in Node Canvas context");break;default:B(t)}}const Se=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0&&e.fillColor.alpha===0)return;const{path:o,length:s}=ve(e,r);if(i<1&&e.strokeWidth>0){const a=we(e,r);a!==void 0&&(t.context.save(),kt(t,a),F({ctx:t,path:o,color:e.fillColor,opacity:i}),t.context.restore())}else F({ctx:t,path:o,color:e.fillColor,opacity:i});H({color:e.strokeColor,ctx:t,drawn:e.drawn,path:o,pathLength:s,opacity:i,width:e.strokeWidth})};function x(t=null){return{x:0,y:0,...t}}const Te=x(),j={TOP_LEFT:"TopLeft",TOP:"Top",TOP_RIGHT:"TopRight",LEFT:"Left",CENTER:"Center",RIGHT:"Right",BOTTOM_LEFT:"BottomLeft",BOTTOM:"Bottom",BOTTOM_RIGHT:"BottomRight"};function R(t=null){return{origin:Te,size:oe,...t}}R();function L(t,e,n){const{x:r,y:i}=t,{width:o,height:s}=n;switch(e){case j.TOP_LEFT:return R({origin:x({x:r,y:i}),size:n});case j.TOP:return R({origin:x({x:r-o/2,y:i}),size:n});case j.TOP_RIGHT:return R({origin:x({x:r-o,y:i}),size:n});case j.LEFT:return R({origin:x({x:r,y:i-s/2}),size:n});case j.CENTER:return R({origin:x({x:r-o/2,y:i-s/2}),size:n});case j.RIGHT:return R({origin:x({x:r-o,y:i-s/2}),size:n});case j.BOTTOM_LEFT:return R({origin:x({x:r,y:i-s}),size:n});case j.BOTTOM:return R({origin:x({x:r-o/2,y:i-s}),size:n});case j.BOTTOM_RIGHT:return R({origin:x({x:r-o,y:i-s}),size:n});default:B(e)}}const Ce=({ctx:t,object:e,renderObject:n,opacity:r})=>{const i=e.scale*e.scaleX,o=e.scale*e.scaleY,s=L(x({x:e.x,y:e.y}),e.anchor,C({width:e.width*Math.abs(i),height:e.height*Math.abs(o)})),{rotation:a,rotateOriginX:c,rotateOriginY:l,skewOriginX:d,skewOriginY:u,skewX:h,skewY:p}=e;if(!(i===0||o===0)){t.context.save(),t.context.translate(s.origin.x,s.origin.y),t.context.scale(i,o),t.context.translate(c,l),t.context.rotate(a*Math.PI/180),t.context.translate(-c,-l),t.context.translate(d,u),t.context.transform(1,Math.tan(p*Math.PI/180),Math.tan(h*Math.PI/180),1,0,0),t.context.translate(-d,-u);for(const g of e.objects)n(g,r*e.opacity);e.previewColor!==null&&(t.context.fillStyle=it(e.previewColor),t.context.fillRect(0,0,e.width,e.height)),e.rotateOriginPreviewSize>0&&(t.context.fillStyle="red",t.context.beginPath(),t.context.arc(c,l,e.rotateOriginPreviewSize,0,2*Math.PI),t.context.fill()),e.skewOriginPreviewSize>0&&(t.context.fillStyle="blue",t.context.beginPath(),t.context.arc(d,u,e.skewOriginPreviewSize,0,2*Math.PI),t.context.fill()),t.context.restore()}};function rt(t,e,n,r,i=0){const o=r();o.path.moveTo(t.x+n,t.y),o.path.lineTo(t.x+e.width-n,t.y),o.path.arcTo(t.x+e.width,t.y,t.x+e.width,t.y+n,n),o.path.lineTo(t.x+e.width,t.y+e.height-n),o.path.arcTo(t.x+e.width,t.y+e.height,t.x+e.width-n,t.y+e.height,n),o.path.lineTo(t.x+n,t.y+e.height),o.path.arcTo(t.x,t.y+e.height,t.x,t.y+e.height-n,n),o.path.lineTo(t.x,t.y+n),o.path.arcTo(t.x,t.y,t.x+n,t.y,n),i>0&&o.path.lineTo(t.x+n+i,t.y);const s=2*(e.width+e.height-4*n)+2*Math.PI*n+i;return{path:o,length:s}}const G={Browser:"browser",Node:"node"},Ie=({ctx:t,imageById:e,object:n,opacity:r,createPath2D:i})=>{const o=L(x({x:n.x,y:n.y}),n.anchor,C({width:n.width,height:n.height})),s=n.imageId!=null&&n.imageId.length>0?n.imageId:n.imagePath;if(s==null)return;const a=e[s];if(a!==void 0){if(t.context.save(),n.cornerRadius>0){const c=rt(o.origin,o.size,n.cornerRadius,i);switch(t.type){case A.Browser:c.path.type===M.Browser?t.context.clip(c.path.path):console.warn("Attempted to use Node Path2D in Browser Canvas context");break;case A.Node:c.path.type===M.Node?t.context.clip(c.path.path):console.warn("Attempted to use Browser Path2D in Node Canvas context");break;default:B(t)}}switch(t.context.globalAlpha=r*n.opacity,t.context.imageSmoothingEnabled=n.smooth,t.type){case A.Browser:a.type===G.Browser?t.context.drawImage(a.image,o.origin.x,o.origin.y,o.size.width,o.size.height):console.warn("Attempted to use Node Image in Browser Canvas context");break;case A.Node:a.type===G.Node?t.context.drawImage(a.image,o.origin.x,o.origin.y,o.size.width,o.size.height):console.warn("Attempted to use Browser Image in Node Canvas context");break;default:B(t)}t.context.restore()}};function Ee(t,e){const n=e();n.path.moveTo(t.startX,t.startY),n.path.lineTo(t.endX,t.endY);const r=Math.hypot(t.endX-t.startX,t.endY-t.startY);return{path:n,length:r}}const Ae=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0)return;const{path:o,length:s}=Ee(e,r);H({color:e.color,ctx:t,drawn:e.drawn,isDrawnFromCenter:e.isDrawnFromCenter,isRounded:e.isRounded,path:o,pathLength:s,opacity:i,width:e.width})},Pe=({ctx:t,object:e,opacity:n,renderObject:r})=>{t.context.save();const i=L(x({x:e.x,y:e.y}),e.anchor,C({width:e.width,height:e.height}));e.preview&&(t.context.lineWidth=4,t.context.strokeStyle=it(E.RED),t.context.rect(i.origin.x,i.origin.y,i.size.width,i.size.height),t.context.stroke()),t.context.beginPath(),t.context.rect(i.origin.x,i.origin.y,i.size.width,i.size.height),t.context.closePath(),t.context.clip();for(const o of e.objects)r(o,n*e.opacity);t.context.restore()},Oe=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0&&e.fillColor.alpha===0)return;const{origin:o}=L(x({x:e.x,y:e.y}),e.anchor,C({width:e.width,height:e.height})),s=r(e.path);t.context.save(),t.context.translate(o.x,o.y),t.context.scale(e.width/e.viewboxWidth,e.height/e.viewboxHeight),F({ctx:t,path:s,color:e.fillColor,opacity:i}),H({color:e.strokeColor,ctx:t,drawn:e.drawn,isRounded:e.isRounded,path:s,pathLength:e.pathLength,opacity:i,width:e.strokeWidth}),t.context.restore()};function Ne(t,e){const n=e(),r=t.points,i=r[0];if(i===void 0)return{path:n,length:0};n.path.moveTo(i.x,i.y);let o=0,s=i;for(let c=1;c<r.length;c++){const l=r[c];if(l===void 0)continue;n.path.lineTo(l.x,l.y);const d=Math.hypot(l.x-s.x,l.y-s.y);o+=d,s=l}n.path.closePath();const a=Math.hypot(i.x-s.x,i.y-s.y);return o+=a,{path:n,length:o}}const Be=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0&&e.fillColor.alpha===0)return;const{path:o,length:s}=Ne(e,r);F({ctx:t,path:o,color:e.fillColor,opacity:i}),H({color:e.strokeColor,ctx:t,drawn:e.drawn,path:o,pathLength:s,opacity:i,width:e.strokeWidth})};function Re(t,e){const n=t.strokeWidth/2,{origin:r,size:i}=L(x({x:t.x,y:t.y}),t.anchor,C({width:t.width,height:t.height})),o=i.width-t.strokeWidth,s=i.height-t.strokeWidth;if(o<=0||s<=0)return;const a=x({x:r.x+n,y:r.y+n}),c=C({width:o,height:s}),l=Math.max(0,Math.min(t.cornerRadius-n,Math.min(o,s)/2));if(l>0)return rt(a,c,l,e).path;const d=e();return d.path.moveTo(a.x,a.y),d.path.lineTo(a.x+o,a.y),d.path.lineTo(a.x+o,a.y+s),d.path.lineTo(a.x,a.y+s),d.path.closePath(),d}function Le(t,e){const{origin:n,size:r}=L(x({x:t.x,y:t.y}),t.anchor,C({width:t.width,height:t.height})),i=Math.max(0,Math.min(t.cornerRadius,Math.min(r.width,r.height)/2)),o=Math.min(t.strokeWidth*2,r.width-i);if(i>0)return rt(n,r,i,e,o);{const s=e();s.path.moveTo(n.x,n.y),s.path.lineTo(n.x+r.width,n.y),s.path.lineTo(n.x+r.width,n.y+r.height),s.path.lineTo(n.x,n.y+r.height),s.path.lineTo(n.x,n.y),s.path.lineTo(n.x+o,n.y);const a=2*(r.width+r.height)+o;return{path:s,length:a}}}const ke=({ctx:t,object:e,opacity:n,createPath2D:r})=>{const i=e.opacity*n;if(i===0||e.drawn===0&&e.fillColor.alpha===0)return;const{path:o,length:s}=Le(e,r);if(i<1&&e.strokeWidth>0){const a=Re(e,r);a!==void 0&&(t.context.save(),kt(t,a),F({ctx:t,path:o,color:e.fillColor,opacity:i}),t.context.restore())}else F({ctx:t,path:o,color:e.fillColor,opacity:i});H({color:e.strokeColor,ctx:t,drawn:e.drawn,path:o,pathLength:s,opacity:i,width:e.strokeWidth})};function Me(t){const{origin:e,size:n}=L(x({x:t.x,y:t.y}),t.anchor,C({width:t.width,height:t.height}));return{origin:e,size:n,cornerRadius:Math.max(0,Math.min(t.cornerRadius,Math.min(n.width,n.height)/2))}}function Fe(t,e,n,r={origin:x({x:0,y:0}),size:e}){const i=n(),{origin:o,size:s,cornerRadius:a}=Me(t),{origin:c,size:l}=r;return i.path.moveTo(c.x,c.y),i.path.lineTo(c.x+l.width,c.y),i.path.lineTo(c.x+l.width,c.y+l.height),i.path.lineTo(c.x,c.y+l.height),i.path.lineTo(c.x,c.y),a===0?(i.path.moveTo(o.x,o.y),i.path.lineTo(o.x,o.y+s.height),i.path.lineTo(o.x+s.width,o.y+s.height),i.path.lineTo(o.x+s.width,o.y),i.path.lineTo(o.x,o.y),i):(i.path.moveTo(o.x+a,o.y),i.path.arcTo(o.x,o.y,o.x,o.y+a,a),i.path.lineTo(o.x,o.y+s.height-a),i.path.arcTo(o.x,o.y+s.height,o.x+a,o.y+s.height,a),i.path.lineTo(o.x+s.width-a,o.y+s.height),i.path.arcTo(o.x+s.width,o.y+s.height,o.x+s.width,o.y+s.height-a,a),i.path.lineTo(o.x+s.width,o.y+a),i.path.arcTo(o.x+s.width,o.y,o.x+s.width-a,o.y,a),i.path.lineTo(o.x+a,o.y),i)}const je=({createPath2D:t,ctx:e,object:n,opacity:r,renderScale:i,slideSize:o})=>{const s=n.opacity*r;if(s===0||n.color.alpha===0)return;const a=C({width:o.width/i,height:o.height/i}),c=x({x:(o.width-a.width)/2,y:(o.height-a.height)/2}),l=Fe(n,o,t,{origin:c,size:a});F({ctx:e,path:l,color:n.color,opacity:s})},De=({ctx:t,imageById:e,object:n,opacity:r})=>{const i=n.opacity*r;if(i===0||!n.svg)return;const o=e[n.svg];if(o===void 0)return;const s=L(x({x:n.x,y:n.y}),n.anchor,C({width:n.width,height:n.height}));switch(t.context.save(),t.context.globalAlpha=i,t.type){case A.Browser:o.type===G.Browser&&t.context.drawImage(o.image,s.origin.x,s.origin.y,s.size.width,s.size.height);break;case A.Node:o.type===G.Node&&t.context.drawImage(o.image,s.origin.x,s.origin.y,s.size.width,s.size.height);break;default:B(t)}t.context.restore()},st={LEFT:"left",CENTER:"center",RIGHT:"right"};function ze(t){return{color:t.color,fontFamily:t.fontFamily,fontSize:t.fontSize,fontStyle:t.fontStyle,fontWeight:t.fontWeight,ligatures:t.ligatures,subscript:t.subscript,superscript:t.superscript}}function Ve(t){const e=Math.max(...t.map(r=>r.bottom),0),n=Math.max(...t.map(r=>r.top),0);return{bottom:e,height:n+e,lineAdvance:Math.max(...t.map(r=>r.lineAdvance),0),top:n,width:t.reduce((r,i)=>r+i.width,0)}}function He(t,e=1){const n=t.map(Ve);if(n.length===0)return{baselines:[],size:C()};let r=0,i,o=0,s=0;const a=[];for(const l of n){const u=(l.lineAdvance*e-l.height)/2,h=l.top+u;i===void 0?r=h:r+=i+h,a.push(r),o=Math.min(o,r-l.top),s=Math.max(s,r+l.bottom),i=l.bottom+u}const c=-o;return{baselines:a.map(l=>l+c),size:C({height:s-o,width:Math.max(...n.map(l=>l.width),0)})}}const _e=.7,$e=.3;function Mt(t){const e=t.superscript,n=t.subscript&&!e;return!e&&!n?{baselineShift:0,fontSize:t.fontSize,isSubscript:!1,isSuperscript:!1}:{baselineShift:t.fontSize*$e*(e?-1:1),fontSize:t.fontSize*_e,isSubscript:n,isSuperscript:e}}function Ft(t,e=0){return t??e}function We(t){const e=Ft(t.fontBoundingBoxAscent,t.actualBoundingBoxAscent),n=Ft(t.fontBoundingBoxDescent,t.actualBoundingBoxDescent);return{bottom:n,height:e+n,top:e,width:t.width}}function jt(t,e,n=1){const r=Mt(e);t.context.fillStyle=nt(e.color,n),t.context.font=`${e.fontStyle} ${e.fontWeight} ${r.fontSize}px ${e.fontFamily}`,t.type===A.Browser?t.context.textRendering=e.ligatures?"optimizeLegibility":"optimizeSpeed":t.context.fontVariant=e.ligatures?"common-ligatures":"no-common-ligatures"}function Ue(t,e,n){const r=[];for(const i of t){const o=[],s=i.length===0?[{text:""}]:i;for(const a of s){const{text:c,...l}=a,d={...e,...l};jt(n,d);const u=n.context.measureText(c),h=We(u),{baselineShift:p}=Mt(d),g=Math.max(0,h.top-p),m=Math.max(0,h.bottom+p);o.push({...h,baselineShift:p,bottom:m,height:g+m,lineAdvance:d.fontSize,top:g})}r.push(o)}return r}const Ge=({ctx:t,object:e,opacity:n})=>{const r=e.opacity*n;if(r===0)return;const{length:i}=e,o=Rt(e.text),s=ze(e),a=Ue(o,s,t),c=He(a,e.lineSpacing),l=L(x({x:e.x,y:e.y}),e.anchor,c.size);let d=l.origin.x,u=0;for(let h=0;h<o.length;h++){const p=o[h],g=a[h],m=c.baselines[h];if(p==null||g==null||m==null){console.error("Could not determine text units or sizes for line");continue}const w=g.reduce((v,b)=>v+b.width,0);switch(e.alignment){case st.LEFT:d=l.origin.x;break;case st.CENTER:d=l.origin.x+(l.size.width-w)/2;break;case st.RIGHT:d=l.origin.x+(l.size.width-w);break;default:B(e.alignment);break}const O=l.origin.y+m;for(let v=0;v<p.length&&!(i!==null&&u>=i);v++){const b=p[v],S=g[v];if(b==null||S==null){console.error("Could not determine text unit or size for unit");continue}const{text:T,...y}=b;let N;if(i!==null&&u+T.length>i){const $=i-u;N=T.slice(0,$)}const P=N??T;u+=P.length;const k={...s,...y};jt(t,k,r),t.context.fillText(P,d,O+S.baselineShift),d+=S.width}}},Ke={[I.ARROW]:be,[I.CIRCLE]:Se,[I.GROUP]:Ce,[I.IMAGE]:Ie,[I.LINE]:Ae,[I.MASK]:Pe,[I.PATH]:Oe,[I.POLYGON]:Be,[I.RECTANGLE]:ke,[I.SLIDE_OBJECT]:()=>{},[I.SPOTLIGHT]:je,[I.SVG]:De,[I.TEXT]:Ge};function Ye(t){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.setAttribute("viewBox",`0 0 ${t.width} ${t.height}`),e.style.backgroundColor="transparent",e.style.position="absolute",e.style.width="100%",e}function Xe(t,e){if(t===null)return null;const n=L(x({x:e.x,y:e.y}),e.anchor,C({width:e.width,height:e.height})),r=document.createElementNS("http://www.w3.org/2000/svg","foreignObject");r.setAttribute("x",n.origin.x.toString()),r.setAttribute("y",n.origin.y.toString()),r.setAttribute("width",e.width.toString()),r.setAttribute("height",e.height.toString());const i=e.content;i!==null&&r.appendChild(i),t.appendChild(r);let o=null;if(e.setup!==null){const s=e.setup(r);s!==void 0&&(o=s)}return()=>{o!==null&&o(),t.removeChild(r)}}async function Dt(t){if(Object.keys(t).length===0)return{};const e={},n=i=>new Promise((o,s)=>{const a=new Image;if(a.onload=()=>o(a),a.onerror=l=>s(l),i.includes("</svg>")){const l=i.replace(/<\?xml[^?]*\?>\s*/g,""),d=new Blob([l],{type:"image/svg+xml;charset=utf-8"}),u=URL.createObjectURL(d);a.src=u}else a.src=i}),r=Object.entries(t).map(async([i,o])=>{const s=await n(o);e[i]={type:G.Browser,image:s}});try{await Promise.all(r)}catch(i){console.error("Error loading images:",i)}return e}const zt="presenterPendingVariables:";function Je(t){const e=Qe();e!==null&&e.setItem(qe(),JSON.stringify({values:t}))}function qe(){return typeof window>"u"?zt:`${zt}${window.location.origin}${window.location.pathname}`}function Qe(){try{return typeof sessionStorage>"u"?null:sessionStorage}catch{return null}}const Ze=0,at=new Map;let Vt=new Map;function Ht(){return Array.from(at.values())}function _t(t){const e=at.get(t);return e===void 0?Ze:Vt.get(e.id)??e.default}function tn(t,e){const n=at.get(t);if(n===void 0)return e;const r=en(e,n);return Vt.set(n.id,r),r}function en(t,e){return nn(t,e.min,e.max)}function nn(t,e,n){return Math.max(e,Math.min(n,t))}function on({onCommit:t,onPreview:e}){const n=Ht();if(n.length===0)return null;const r=document.createElement("div");Object.assign(r.style,{position:"absolute",right:"16px",bottom:"16px",zIndex:"20",display:"flex",flexDirection:"column",gap:"8px",width:"min(360px, calc(100% - 32px))",padding:"10px",boxSizing:"border-box",border:"1px solid rgba(255, 255, 255, 0.18)",borderRadius:"8px",background:"rgba(16, 18, 22, 0.82)",color:"#ffffff",fontFamily:'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',fontSize:"12px",lineHeight:"1.25",pointerEvents:"auto",boxShadow:"0 12px 36px rgba(0, 0, 0, 0.28)",backdropFilter:"blur(10px)"});for(const i of n)r.appendChild(rn(i,e,t));return r}function rn(t,e,n){const r=document.createElement("div");r.dataset.presenterVariableId=t.id,r.dataset.presenterVariableName=t.name,Object.assign(r.style,{display:"grid",gridTemplateColumns:"72px minmax(0, 1fr) 74px",alignItems:"center",gap:"8px"});const i=document.createElement("div");i.textContent=t.name,i.title=t.name,Object.assign(i.style,{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"rgba(255, 255, 255, 0.86)",fontWeight:"600"});const o=document.createElement("input");o.type="range",o.min=t.min.toString(),o.max=t.max.toString(),o.step=t.increment.toString(),Object.assign(o.style,{width:"100%",minWidth:"0",accentColor:"#8bc7ff"});const s=document.createElement("input");s.type="number",s.min=t.min.toString(),s.max=t.max.toString(),s.step=t.increment.toString(),Object.assign(s.style,{width:"100%",boxSizing:"border-box",border:"1px solid rgba(255, 255, 255, 0.24)",borderRadius:"6px",padding:"4px 6px",background:"rgba(255, 255, 255, 0.1)",color:"#ffffff",font:"inherit"});let a=_t(t.id);const c=u=>{const h=sn(u);o.value=h,s.value=h},l=u=>{Number.isFinite(u)&&(a=e(t.id,u),c(a))},d=u=>{Number.isFinite(u)&&(u!==a&&l(u),n())};return o.addEventListener("input",()=>l(o.valueAsNumber)),o.addEventListener("change",()=>d(o.valueAsNumber)),s.addEventListener("change",()=>d(s.valueAsNumber)),c(a),r.appendChild(i),r.appendChild(o),r.appendChild(s),r}function sn(t){return Number.isInteger(t)?t.toString():parseFloat(t.toFixed(6)).toString()}function an({container:t,onCommit:e}){const n=on({onPreview:(r,i)=>{const o=tn(r,i);return Je(ln()),o},onCommit:e});n!==null&&t.appendChild(n)}function ln(){const t={};for(const e of Ht())t[e.id]=_t(e.id);return t}class cn{constructor(e){this.navigator=null;const{objectRenderers:n,scale:r=1,...i}=e;this.props={presentation:wt(),element:document.body,objectRenderers:{...Ke,...n},cacheDurationMinutes:15,scale:dn(r),...i},this.state={...Bt}}async present(){const{presentation:e,element:n,scale:r}=this.props;this.hideCursor();const i=ce(e.title),o=Lt(e.size),s=Ye(e.size);s.style.transformOrigin="center center",s.style.transform=`scale(${r})`,this.state={...Bt,accessibleDescriptionElement:i,imageById:await Dt({...It(e),...e.resources.images,...Ot(e)}),canvas:o,extrasContainer:s};const a=re(e,n),c=Tt(n),l=(h,p)=>{this.state.shortcutState.shortcuts.b={slideIndex:this.state.slideIndex,buildIndex:this.state.buildIndex},this.renderSlide(h??this.state.slideIndex,p)},d=(h=!1)=>{c&&(this.navigator=qt({presentation:e,shortcutState:this.state.shortcutState,onNavigateToSlide:p=>this.renderSlide(p),onRenderSlide:l,onNext:p=>this.next(p),onPrevious:p=>this.previous(p),forceRefresh:h}),this.updateNavigator())};pt(e,a,this.state.shortcutState,{onNext:h=>this.next(h),onPrevious:h=>this.previous(h),onRenderSlide:l,onShowNavigator:()=>d()},{focusOnPointerDown:!c,keyEventTarget:c?window:a}),n.replaceChildren(),a.appendChild(i),a.appendChild(o),a.appendChild(s),an({container:a,onCommit:()=>this.reloadAfterVariableChange()}),n.appendChild(a);const u=le(e,this.props.cacheDurationMinutes);u!==null?this.renderSlide(u.slideIndex,u.buildIndex):this.renderSlide(0),$t()&&d(!0)}reloadAfterVariableChange(){const{presentation:e}=this.props;this.state.currentAnimationId!==null&&(cancelAnimationFrame(this.state.currentAnimationId),this.state.currentAnimationId=null),Nt({title:e.title,slideIndex:this.state.slideIndex,buildIndex:this.state.buildIndex}),window.location.reload()}renderSlide(e,n=0,r=null){const{presentation:i}=this.props,{canvas:o}=this.state,s=this.state.slideIndex!==e;this.state.slideIndex=e,this.state.buildIndex=n,r===null&&Nt({title:i.title,slideIndex:e,buildIndex:n});const a=i.slides[e];if(!(a===void 0||o===null)){if(s||this.state.mountedExtrasCleanups.length===0&&a.extras.length>0){for(const c of this.state.mountedExtrasCleanups)c();this.state.mountedExtrasCleanups=[];for(const c of a.extras){const l=Xe(this.state.extrasContainer,c);l!==null&&this.state.mountedExtrasCleanups.push(l)}}if(this.renderCanvas(o,e,n,r,this.props.scale),r===null){if(this.state.accessibleDescriptionElement!==null){const c=Pt({slide:a,buildIndex:n,buildTime:r});ge(this.state.accessibleDescriptionElement,de(a,c))}this.updateNavigator()}}}renderCanvas(e,n,r=0,i=null,o=1){const{objectRenderers:s,presentation:a}=this.props,{imageById:c}=this.state;e.width=a.size.width,e.height=a.size.height;const l=e.getContext("2d");if(l===null)return;const d={type:A.Browser,context:l};ye(e,d);const u=a.slides[n];if(u===void 0)return;const h=Pt({slide:u,buildIndex:r,buildTime:i});d.context.fillStyle=nt(a.backgroundColor),d.context.fillRect(0,0,e.width,e.height);function p(m,w,O=d){const v=s[m.objectType],b=h.get(m);v===void 0||b===void 0||v({ctx:O,originalObject:m,imageById:c,object:b,opacity:w,renderScale:o,renderObject:(S,T,y=O)=>p(S,T,y),getCurrentObject:S=>h.get(S),createPath2D:me,slideSize:a.size})}const g=o!==1;g&&(d.context.save(),d.context.translate(e.width*(1-o)/2,e.height*(1-o)/2),d.context.scale(o,o));for(const m of u.objects)p(m,1);g&&d.context.restore()}updateNavigator(){const{navigator:e}=this;if(e===null)return;if(!e.isOpen()){this.navigator=null;return}const{slideIndex:n,buildIndex:r}=this.state,i=this.getNextSlideBuild(n,r);e.update(n,r,i.slideIndex,i.buildIndex),this.renderCanvas(e.currentCanvas,n,r),i.slideIndex===null?this.renderEndCanvas(e.nextCanvas):this.renderCanvas(e.nextCanvas,i.slideIndex,i.buildIndex)}getNextSlideBuild(e,n){const{presentation:r}=this.props,i=r.slides[e];return i===void 0?{slideIndex:e,buildIndex:n}:n<i.animations.length?{slideIndex:e,buildIndex:n+1}:e+1<r.slides.length?{slideIndex:e+1,buildIndex:0}:{slideIndex:null,buildIndex:0}}renderEndCanvas(e){const{presentation:n}=this.props;e.width=n.size.width,e.height=n.size.height;const r=e.getContext("2d");r!==null&&(r.fillStyle="#000000",r.fillRect(0,0,e.width,e.height))}next(e=!1){const{presentation:n}=this.props,{currentAnimationId:r,slideIndex:i,buildIndex:o}=this.state;this.hideCursor(),r!==null&&cancelAnimationFrame(r);const s=n.slides[i];if(s===void 0)return;const a=s.animations[o];if(a!==void 0&&!e){const c=performance.now(),l=vt(a),d=u=>{const h=u-c;h<l?(this.renderSlide(i,o+1,h),this.state.currentAnimationId=requestAnimationFrame(d)):this.renderSlide(i,o+1,null)};this.state.currentAnimationId=requestAnimationFrame(d)}else i+1<n.slides.length&&this.renderSlide(i+1)}previous(e=!1){const{currentAnimationId:n,slideIndex:r,buildIndex:i}=this.state;if(this.hideCursor(),n!==null&&cancelAnimationFrame(n),i>0)e?this.renderSlide(r,0):this.renderSlide(r,i-1);else if(r>0){const o=this.props.presentation.slides[r-1],s=e?0:(o==null?void 0:o.animations.length)??0;this.renderSlide(r-1,s)}else this.renderSlide(0,0)}hasNext(){const{presentation:e}=this.props,{slideIndex:n,buildIndex:r}=this.state,i=e.slides[n];return i===void 0?!1:i.animations[r]!==void 0?!0:n+1<e.slides.length}hasPrevious(){const{slideIndex:e,buildIndex:n}=this.state;return n>0||e>0}hideCursor(){var e,n;this.props.element.style.cursor="none",(n=(e=this.state.canvas)==null?void 0:e.parentElement)==null||n.style.setProperty("cursor","none")}}function dn(t){return t<=0||t>1?(console.warn(`BrowserCanvasRenderer scale must be positive and no greater than 1. Received ${t}; using 1 instead.`),1):t}function un(t){const e=[];if(t.isAllKey){for(let n=0;n<=t.animations.length;n++)e.push(n);return e}return t.isStartKey&&e.push(0),t.animations.forEach((n,r)=>{Array.isArray(n)?n.some(i=>i.isKey)&&e.push(r+1):n.isKey&&e.push(r+1)}),t.isEndKey&&e[e.length-1]!==t.animations.length&&e.push(t.animations.length),e}function*hn({presentation:t,isAnimatedExport:e,animationHoldFrames:n,framesPerSecond:r}){let i=0;for(let o=0;o<t.slides.length;o++){const s=t.slides[o];if(s!==void 0)if(e){for(let a=0;a<n;a++)yield{imageIndex:i++,slideIndex:o,buildIndex:0,buildTime:null};for(let a=0;a<s.animations.length;a++){const c=s.animations[a];if(c===void 0)continue;const l=vt(c),d=Math.ceil(l/1e3*r);for(let u=0;u<d;u++)yield{imageIndex:i++,slideIndex:o,buildIndex:a+1,buildTime:u*(l/d)};for(let u=0;u<n;u++)yield{imageIndex:i++,slideIndex:o,buildIndex:a+1,buildTime:null}}}else{const a=un(s);for(const c of a)yield{imageIndex:i++,slideIndex:o,buildIndex:c,buildTime:null}}}}class fn{constructor(e){const{imageFormat:n="png",...r}=e;this.props={presentation:wt(),imageFormat:n,imageQuality:void 0,animationHoldFrames:1,framesPerSecond:30,isAnimatedExport:!1,getFilenameForImage:i=>`${i.toString().padStart(4,"0")}.${n}`,logFrequency:0,objectRenderers:{},onRenderImage:()=>{},renderScale:1,resourcePathPrefix:"",waitForFonts:!0,...r}}async render(e=0){bn();const{presentation:n}=this.props,r=await Dt(yn({...It(n),...n.resources.images,...Ot(n)},this.props.resourcePathPrefix));this.props.waitForFonts&&await document.fonts.ready;const i=Lt(n.size),o=new cn({presentation:n,objectRenderers:this.props.objectRenderers,scale:this.props.renderScale,element:document.createElement("div")});o.state={...o.state,imageById:r};for(const s of hn(this.props))s.imageIndex<e||await this.renderFrame(o,i,s)}async renderFrame(e,n,r){const{getFilenameForImage:i,imageFormat:o,imageQuality:s,logFrequency:a,onRenderImage:c}=this.props;e.renderCanvas(n,r.slideIndex,r.buildIndex,r.buildTime,this.props.renderScale);const l=await pn(n,gn(o),s),d=i(r.imageIndex),u={...r,blob:l,filename:d};await c(u),a>0&&r.imageIndex%a===0&&console.log(`Rendered image ${r.imageIndex}: ${d}`)}}function pn(t,e,n){return new Promise((r,i)=>{t.toBlob(o=>{if(o===null){i(new Error("Unable to encode browser image export frame."));return}r(o)},e,n)})}function gn(t){switch(t){case"jpeg":return"image/jpeg";case"webp":return"image/webp";case"png":return"image/png"}}function yn(t,e){if(e==="")return t;const n={};for(const[r,i]of Object.entries(t))n[r]=mn(i)?xn(e,i):i;return n}function mn(t){return!t.includes("</svg>")&&!t.startsWith("/")&&!t.startsWith("data:")&&!t.startsWith("blob:")&&!/^[a-z][a-z0-9+.-]*:\/\//i.test(t)}function xn(t,e){return`${t.replace(/\/$/,"")}/${e.replace(/^\//,"")}`}function bn(){if(typeof document>"u")throw new Error("BrowserImageRenderer must run in a browser environment.")}W.BrowserImageRenderer=fn,Object.defineProperty(W,Symbol.toStringTag,{value:"Module"})}));
6
+ //# sourceMappingURL=export-browser.js.map