@ai-matrx/alchemy 0.17.5 → 0.19.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 (84) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/core.cjs +3 -3
  3. package/dist/core.cjs.map +1 -1
  4. package/dist/core.d.cts +1 -0
  5. package/dist/core.d.ts +1 -0
  6. package/dist/core.js +3 -3
  7. package/dist/core.js.map +1 -1
  8. package/dist/index.cjs +3 -3
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +1 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +3 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/operate-capture.cjs +1 -1
  15. package/dist/operate-capture.cjs.map +1 -1
  16. package/dist/operate-capture.d.cts +13 -56
  17. package/dist/operate-capture.d.ts +13 -56
  18. package/dist/operate-capture.js +1 -1
  19. package/dist/operate-capture.js.map +1 -1
  20. package/dist/operate-document.cjs +1 -1
  21. package/dist/operate-document.cjs.map +1 -1
  22. package/dist/operate-document.d.cts +1 -0
  23. package/dist/operate-document.d.ts +1 -0
  24. package/dist/operate-document.js +1 -1
  25. package/dist/operate-document.js.map +1 -1
  26. package/dist/operate-pptx.cjs +2 -2
  27. package/dist/operate-pptx.js +2 -2
  28. package/dist/operate-read.cjs +1 -5
  29. package/dist/operate-read.cjs.map +1 -1
  30. package/dist/operate-read.d.cts +7 -50
  31. package/dist/operate-read.d.ts +7 -50
  32. package/dist/operate-read.js +1 -5
  33. package/dist/operate-read.js.map +1 -1
  34. package/dist/operate-rich-html.cjs +1 -1
  35. package/dist/operate-rich-html.cjs.map +1 -1
  36. package/dist/operate-rich-html.d.cts +1 -0
  37. package/dist/operate-rich-html.d.ts +1 -0
  38. package/dist/operate-rich-html.js +1 -1
  39. package/dist/operate-rich-html.js.map +1 -1
  40. package/dist/operate-server.cjs +1 -1
  41. package/dist/operate-server.cjs.map +1 -1
  42. package/dist/operate-server.js +1 -1
  43. package/dist/operate-server.js.map +1 -1
  44. package/dist/operate-xlsx.cjs +3 -4
  45. package/dist/operate-xlsx.cjs.map +1 -1
  46. package/dist/operate-xlsx.d.cts +3 -2
  47. package/dist/operate-xlsx.d.ts +3 -2
  48. package/dist/operate-xlsx.js +3 -4
  49. package/dist/operate-xlsx.js.map +1 -1
  50. package/dist/operate-zip.cjs +1 -1
  51. package/dist/operate-zip.cjs.map +1 -1
  52. package/dist/operate-zip.d.cts +10 -27
  53. package/dist/operate-zip.d.ts +10 -27
  54. package/dist/operate-zip.js +1 -1
  55. package/dist/operate-zip.js.map +1 -1
  56. package/dist/operate.cjs +3 -3
  57. package/dist/operate.cjs.map +1 -1
  58. package/dist/operate.d.cts +1 -0
  59. package/dist/operate.d.ts +1 -0
  60. package/dist/operate.js +3 -3
  61. package/dist/operate.js.map +1 -1
  62. package/dist/react-bar.cjs +1 -1
  63. package/dist/react-bar.cjs.map +1 -1
  64. package/dist/react-bar.js +1 -1
  65. package/dist/react-bar.js.map +1 -1
  66. package/dist/react-menu.cjs +1 -1
  67. package/dist/react-menu.cjs.map +1 -1
  68. package/dist/react-menu.js +1 -1
  69. package/dist/react-menu.js.map +1 -1
  70. package/dist/react-overflow.cjs +1 -1
  71. package/dist/react-overflow.cjs.map +1 -1
  72. package/dist/react-overflow.js +1 -1
  73. package/dist/react-overflow.js.map +1 -1
  74. package/dist/react-selection.cjs +1 -1
  75. package/dist/react-selection.cjs.map +1 -1
  76. package/dist/react-selection.js +1 -1
  77. package/dist/react-selection.js.map +1 -1
  78. package/dist/react-sheet.cjs.map +1 -1
  79. package/dist/react-sheet.js.map +1 -1
  80. package/dist/react-workspace.cjs +2 -2
  81. package/dist/react-workspace.cjs.map +1 -1
  82. package/dist/react-workspace.js +2 -2
  83. package/dist/react-workspace.js.map +1 -1
  84. package/package.json +7 -8
@@ -1,2 +1,2 @@
1
- "use strict";var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod)),__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var operate_capture_exports={};__export(operate_capture_exports,{canvasToBlob:()=>canvasToBlob,captureElement:()=>captureElement,elementToImage:()=>elementToImage,elementsToPdf:()=>elementsToPdf,pagesToPdf:()=>pagesToPdf,renderElement:()=>renderElement,renderElementToDataUrl:()=>renderElementToDataUrl});module.exports=__toCommonJS(operate_capture_exports);var UNSAFE_COLOR=/\b(oklch|oklab|lab|lch|color)\s*\(/i;function safeColor(value,prop,dark){if(!UNSAFE_COLOR.test(value))return value;let p=prop.toLowerCase();return p.includes("background")?dark?"#1f2937":"#ffffff":p==="color"?dark?"#f3f4f6":"#111827":p.includes("border")||p.includes("outline")?dark?"#4b5563":"#d1d5db":p==="fill"||p==="stroke"?dark?"#9ca3af":"#374151":"#6b7280"}function patchComputedStyle(dark){let original=window.getComputedStyle,bound=original.bind(window);return window.getComputedStyle=function(elt,pseudo){let computed=bound(elt,pseudo);return new Proxy(computed,{get(target,prop){let value=target[prop];return typeof prop=="string"&&typeof value=="string"&&value&&UNSAFE_COLOR.test(value)?safeColor(value,prop,dark):prop==="getPropertyValue"?p=>{let raw=target.getPropertyValue(p);return raw&&UNSAFE_COLOR.test(raw)?safeColor(raw,p,dark):raw}:typeof value=="function"?value.bind(target):value}})},()=>{window.getComputedStyle=original}}var prefersDark=()=>typeof document<"u"&&(document.documentElement.classList.contains("dark")||typeof window.matchMedia=="function"&&window.matchMedia("(prefers-color-scheme: dark)").matches);async function captureElement(element,options={}){let{safeColors,...rest}=options,{default:html2canvas}=await import("html2canvas"),restore=safeColors?patchComputedStyle(typeof safeColors=="object"?safeColors.dark:prefersDark()):()=>{};try{return await html2canvas(element,{scale:2,logging:!1,useCORS:!0,...rest})}finally{restore()}}async function canvasToBlob(canvas,type="image/png",quality){let blob=await new Promise(resolve=>canvas.toBlob(resolve,type,quality));if(!blob)throw new Error("The image could not be encoded.");return blob}async function elementToImage(element,options={}){let{type,quality,...capture}=options;return canvasToBlob(await captureElement(element,capture),type,quality)}async function renderElement(element,options={}){let{toCanvas}=await import("html-to-image");return toCanvas(element,options)}async function renderElementToDataUrl(element,options={}){let{toPng}=await import("html-to-image");return toPng(element,options)}async function pagesToPdf(pages,options={}){let{jsPDF}=await import("jspdf"),doc=new jsPDF({orientation:options.orientation??"portrait",unit:options.unit??"pt",format:options.format??"a4"});return pages.forEach((page,index)=>{index>0&&doc.addPage();let pageW=doc.internal.pageSize.getWidth(),pageH=doc.internal.pageSize.getHeight();page.header&&(doc.setFontSize(page.header.fontSize??12),doc.text(page.header.text,page.header.x,page.header.y));let type=page.imageType??"PNG",data=type==="JPEG"?page.image.toDataURL("image/jpeg",page.quality??.92):page.image.toDataURL("image/png"),placement=page.placement??"fill",x=0,y=0,w=pageW,h=pageH;if(placement!=="fill"){let availW=pageW-placement.left-placement.right,availH=pageH-placement.top-placement.bottom,scale=Math.min(availW/page.image.width,availH/page.image.height);x=placement.left,y=placement.top,w=page.image.width*scale,h=page.image.height*scale}page.compression?doc.addImage(data,type,x,y,w,h,void 0,page.compression):doc.addImage(data,type,x,y,w,h)}),doc.output("blob")}async function elementsToPdf(elements,options={}){let pages=[];for(let element of elements)pages.push({...options.page,image:await captureElement(element,options.capture)});return pagesToPdf(pages,options)}
1
+ "use strict";var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod)),__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var operate_capture_exports={};__export(operate_capture_exports,{canvasToBlob:()=>canvasToBlob,captureElement:()=>captureElement,elementToImage:()=>elementToImage,elementsToPdf:()=>elementsToPdf,pagesToPdf:()=>pagesToPdf,renderElement:()=>renderElement,renderElementToDataUrl:()=>renderElementToDataUrl});module.exports=__toCommonJS(operate_capture_exports);async function captureElement(element,options={}){let{captureCanvas}=await import("@ai-matrx/print/pdf");return captureCanvas(element,options)}async function canvasToBlob(canvas,type="image/png",quality){let blob=await new Promise(resolve=>canvas.toBlob(resolve,type,quality));if(!blob)throw new Error("The image could not be encoded.");return blob}async function elementToImage(element,options={}){let{type,quality,...capture}=options;return canvasToBlob(await captureElement(element,capture),type,quality)}async function renderElement(element,options={}){let{toCanvas}=await import("html-to-image");return toCanvas(element,options)}async function renderElementToDataUrl(element,options={}){let{toPng}=await import("html-to-image");return toPng(element,options)}async function pagesToPdf(pages,options={}){let{pagesToPdf:layOut}=await import("@ai-matrx/print/pdf");return layOut(pages,options)}async function elementsToPdf(elements,options={}){let pages=[];for(let element of elements)pages.push({...options.page,image:await captureElement(element,options.capture)});return pagesToPdf(pages,options)}
2
2
  //# sourceMappingURL=operate-capture.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/operate-capture.ts","../src/operate/capture.ts"],"sourcesContent":["/** `@ai-matrx/alchemy/operate/capture` — the one DOM capture engine (element → image / PDF). html2canvas, html-to-image and jsPDF load on first use. */\nexport {\n canvasToBlob,\n captureElement,\n elementToImage,\n elementsToPdf,\n pagesToPdf,\n renderElement,\n renderElementToDataUrl,\n type CaptureOptions,\n type PdfDocumentOptions,\n type PdfMargins,\n type PdfPage,\n type RenderOptions,\n} from \"./operate/capture\";\n","/**\n * `@ai-matrx/alchemy/operate/capture` — THE DOM capture engine (ALC-19 T11): an element on screen →\n * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. Both libraries\n * load on first use (`import()`), so a page that never exports never downloads them.\n *\n * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per\n * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.\n */\n\nexport type CaptureOptions = {\n /** Device-pixel scale of the capture (default 2 — legible when scaled in a deck or print). */\n scale?: number;\n /** Canvas background; null keeps transparency. */\n backgroundColor?: string | null;\n useCORS?: boolean;\n allowTaint?: boolean;\n logging?: boolean;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n scrollX?: number;\n scrollY?: number;\n windowWidth?: number;\n windowHeight?: number;\n ignoreElements?(element: Element): boolean;\n onclone?(document: Document, element: HTMLElement): void | Promise<void>;\n /** Replace unparseable modern colour functions while capturing (`{ dark }` picks the palette). */\n safeColors?: boolean | { dark: boolean };\n};\n\nconst UNSAFE_COLOR = /\\b(oklch|oklab|lab|lch|color)\\s*\\(/i;\n\nfunction safeColor(value: string, prop: string, dark: boolean): string {\n if (!UNSAFE_COLOR.test(value)) return value;\n const p = prop.toLowerCase();\n if (p.includes(\"background\")) return dark ? \"#1f2937\" : \"#ffffff\";\n if (p === \"color\") return dark ? \"#f3f4f6\" : \"#111827\";\n if (p.includes(\"border\") || p.includes(\"outline\")) return dark ? \"#4b5563\" : \"#d1d5db\";\n if (p === \"fill\" || p === \"stroke\") return dark ? \"#9ca3af\" : \"#374151\";\n return \"#6b7280\";\n}\n\n/** Patch `getComputedStyle` so the capture never reads an unsafe colour; returns the restore. */\nfunction patchComputedStyle(dark: boolean): () => void {\n const original = window.getComputedStyle;\n const bound = original.bind(window);\n window.getComputedStyle = function (elt: Element, pseudo?: string | null) {\n const computed = bound(elt, pseudo);\n return new Proxy(computed, {\n get(target, prop: string | symbol) {\n const value = (target as unknown as Record<string | symbol, unknown>)[prop];\n if (typeof prop === \"string\" && typeof value === \"string\" && value && UNSAFE_COLOR.test(value)) return safeColor(value, prop, dark);\n if (prop === \"getPropertyValue\")\n return (p: string) => {\n const raw = target.getPropertyValue(p);\n return raw && UNSAFE_COLOR.test(raw) ? safeColor(raw, p, dark) : raw;\n };\n if (typeof value === \"function\") return (value as CallableFunction).bind(target);\n return value;\n },\n });\n } as typeof window.getComputedStyle;\n return () => {\n window.getComputedStyle = original;\n };\n}\n\nconst prefersDark = () =>\n typeof document !== \"undefined\" &&\n (document.documentElement.classList.contains(\"dark\") || (typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches));\n\n/** Rasterise a live element to a canvas (what the person sees, at `scale`). */\nexport async function captureElement(element: HTMLElement, options: CaptureOptions = {}): Promise<HTMLCanvasElement> {\n const { safeColors, ...rest } = options;\n const { default: html2canvas } = await import(\"html2canvas\");\n const restore = safeColors ? patchComputedStyle(typeof safeColors === \"object\" ? safeColors.dark : prefersDark()) : () => {};\n try {\n return await html2canvas(element, { scale: 2, logging: false, useCORS: true, ...rest } as Parameters<typeof html2canvas>[1]);\n } finally {\n restore();\n }\n}\n\n/** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */\nexport async function canvasToBlob(canvas: HTMLCanvasElement, type: \"image/png\" | \"image/jpeg\" | \"image/webp\" = \"image/png\", quality?: number): Promise<Blob> {\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (!blob) throw new Error(\"The image could not be encoded.\");\n return blob;\n}\n\n/** Capture an element straight to an image Blob. */\nexport async function elementToImage(\n element: HTMLElement,\n options: CaptureOptions & { type?: \"image/png\" | \"image/jpeg\" | \"image/webp\"; quality?: number } = {},\n): Promise<Blob> {\n const { type, quality, ...capture } = options;\n return canvasToBlob(await captureElement(element, capture), type, quality);\n}\n\n/** Options for `renderElement` (html-to-image): the SVG foreignObject renderer. */\nexport type RenderOptions = {\n /** Device-pixel ratio (default 1). */\n pixelRatio?: number;\n width?: number;\n height?: number;\n /** Final canvas size; the render is scaled to it. */\n canvasWidth?: number;\n canvasHeight?: number;\n backgroundColor?: string;\n /** Inline style applied to the cloned root (e.g. a translate to pad the chart). */\n style?: Partial<CSSStyleDeclaration>;\n /** Return false to leave a node out of the picture. */\n filter?(node: HTMLElement): boolean;\n skipFonts?: boolean;\n /** Bust the image cache so a CORS fetch is fresh. */\n cacheBust?: boolean;\n /** Data URL drawn instead of an image that fails to load. */\n imagePlaceholder?: string;\n onImageErrorHandler?(...args: unknown[]): void;\n};\n\n/**\n * Render a live element to a canvas through the SVG foreignObject renderer (html-to-image). It keeps\n * the browser's own layout and fonts where html2canvas re-implements them, and it takes a `filter`\n * and a root `style` override — the right tool for a transformed or panned surface. Loads on first use.\n */\nexport async function renderElement(element: HTMLElement, options: RenderOptions = {}): Promise<HTMLCanvasElement> {\n const { toCanvas } = await import(\"html-to-image\");\n return toCanvas(element, options as Parameters<typeof toCanvas>[1]);\n}\n\n/** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */\nexport async function renderElementToDataUrl(element: HTMLElement, options: RenderOptions = {}): Promise<string> {\n const { toPng } = await import(\"html-to-image\");\n return toPng(element, options as Parameters<typeof toPng>[1]);\n}\n\nexport type PdfMargins = { top: number; right: number; bottom: number; left: number };\nexport type PdfPage = {\n image: HTMLCanvasElement;\n /** \"JPEG\" (default 0.92 quality) keeps a flat chart an order of magnitude smaller than a PNG embed. */\n imageType?: \"PNG\" | \"JPEG\";\n quality?: number;\n compression?: \"NONE\" | \"FAST\" | \"MEDIUM\" | \"SLOW\";\n /** \"fill\": the image covers the page. Margins: the image is scaled to fit inside them, never cropped. */\n placement?: \"fill\" | PdfMargins;\n /** A line of text drawn on the page (e.g. the as-of date a chart is true of). */\n header?: { text: string; x: number; y: number; fontSize?: number };\n};\nexport type PdfDocumentOptions = {\n orientation?: \"portrait\" | \"landscape\";\n unit?: \"pt\" | \"mm\" | \"cm\" | \"in\" | \"px\";\n format?: string | [number, number];\n};\n\n/** Lay canvases out as PDF pages (one page each) and answer the PDF Blob. */\nexport async function pagesToPdf(pages: readonly PdfPage[], options: PdfDocumentOptions = {}): Promise<Blob> {\n const { jsPDF } = await import(\"jspdf\");\n const doc = new jsPDF({ orientation: options.orientation ?? \"portrait\", unit: options.unit ?? \"pt\", format: options.format ?? \"a4\" });\n pages.forEach((page, index) => {\n if (index > 0) doc.addPage();\n const pageW = doc.internal.pageSize.getWidth();\n const pageH = doc.internal.pageSize.getHeight();\n if (page.header) {\n doc.setFontSize(page.header.fontSize ?? 12);\n doc.text(page.header.text, page.header.x, page.header.y);\n }\n const type = page.imageType ?? \"PNG\";\n const data = type === \"JPEG\" ? page.image.toDataURL(\"image/jpeg\", page.quality ?? 0.92) : page.image.toDataURL(\"image/png\");\n const placement = page.placement ?? \"fill\";\n let x = 0, y = 0, w = pageW, h = pageH;\n if (placement !== \"fill\") {\n const availW = pageW - placement.left - placement.right;\n const availH = pageH - placement.top - placement.bottom;\n const scale = Math.min(availW / page.image.width, availH / page.image.height);\n x = placement.left;\n y = placement.top;\n w = page.image.width * scale;\n h = page.image.height * scale;\n }\n if (page.compression) doc.addImage(data, type, x, y, w, h, undefined, page.compression);\n else doc.addImage(data, type, x, y, w, h);\n });\n return doc.output(\"blob\");\n}\n\n/** Capture each element and lay them out one per PDF page. */\nexport async function elementsToPdf(\n elements: readonly HTMLElement[],\n options: PdfDocumentOptions & { capture?: CaptureOptions; page?: Omit<PdfPage, \"image\"> } = {},\n): Promise<Blob> {\n const pages: PdfPage[] = [];\n for (const element of elements) pages.push({ ...options.page, image: await captureElement(element, options.capture) });\n return pagesToPdf(pages, options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/operate-capture.ts","../src/operate/capture.ts"],"sourcesContent":["/** `@ai-matrx/alchemy/operate/capture` — the one DOM capture engine (element → image / PDF). html2canvas, html-to-image and jsPDF load on first use. */\nexport {\n canvasToBlob,\n captureElement,\n elementToImage,\n elementsToPdf,\n pagesToPdf,\n renderElement,\n renderElementToDataUrl,\n type CaptureOptions,\n type PdfDocumentOptions,\n type PdfMargins,\n type PdfPage,\n type RenderOptions,\n} from \"./operate/capture\";\n","/**\n * `@ai-matrx/alchemy/operate/capture` — THE DOM capture door (ALC-19 T11): an element on screen →\n * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. The html2canvas +\n * jsPDF engine itself is `@ai-matrx/print/pdf` (`captureCanvas`, `pagesToPdf`), loaded on first use\n * (`import()`), so a page that never exports never downloads it; html-to-image (`renderElement`) is\n * this module's own.\n *\n * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per\n * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.\n */\n\n// THE one html2canvas + jsPDF engine is print's (AP-2 engine ruling: print sits below alchemy, so\n// alchemy loads it — never a second copy here). Type-only imports; the module loads on first use.\nimport type { CanvasCaptureOptions, PdfDocumentOptions, PdfPage } from \"@ai-matrx/print/pdf\";\nexport type { CanvasCaptureOptions as CaptureOptions, PdfDocumentOptions, PdfMargins, PdfPage } from \"@ai-matrx/print/pdf\";\ntype CaptureOptions = CanvasCaptureOptions;\n\n/** Rasterise a live element to a canvas (what the person sees, at `scale`) — print's `captureCanvas`. */\nexport async function captureElement(element: HTMLElement, options: CaptureOptions = {}): Promise<HTMLCanvasElement> {\n const { captureCanvas } = await import(\"@ai-matrx/print/pdf\");\n return captureCanvas(element, options);\n}\n\n/** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */\nexport async function canvasToBlob(canvas: HTMLCanvasElement, type: \"image/png\" | \"image/jpeg\" | \"image/webp\" = \"image/png\", quality?: number): Promise<Blob> {\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (!blob) throw new Error(\"The image could not be encoded.\");\n return blob;\n}\n\n/** Capture an element straight to an image Blob. */\nexport async function elementToImage(\n element: HTMLElement,\n options: CaptureOptions & { type?: \"image/png\" | \"image/jpeg\" | \"image/webp\"; quality?: number } = {},\n): Promise<Blob> {\n const { type, quality, ...capture } = options;\n return canvasToBlob(await captureElement(element, capture), type, quality);\n}\n\n/** Options for `renderElement` (html-to-image): the SVG foreignObject renderer. */\nexport type RenderOptions = {\n /** Device-pixel ratio (default 1). */\n pixelRatio?: number;\n width?: number;\n height?: number;\n /** Final canvas size; the render is scaled to it. */\n canvasWidth?: number;\n canvasHeight?: number;\n backgroundColor?: string;\n /** Inline style applied to the cloned root (e.g. a translate to pad the chart). */\n style?: Partial<CSSStyleDeclaration>;\n /** Return false to leave a node out of the picture. */\n filter?(node: HTMLElement): boolean;\n skipFonts?: boolean;\n /** Bust the image cache so a CORS fetch is fresh. */\n cacheBust?: boolean;\n /** Data URL drawn instead of an image that fails to load. */\n imagePlaceholder?: string;\n onImageErrorHandler?(...args: unknown[]): void;\n};\n\n/**\n * Render a live element to a canvas through the SVG foreignObject renderer (html-to-image). It keeps\n * the browser's own layout and fonts where html2canvas re-implements them, and it takes a `filter`\n * and a root `style` override — the right tool for a transformed or panned surface. Loads on first use.\n */\nexport async function renderElement(element: HTMLElement, options: RenderOptions = {}): Promise<HTMLCanvasElement> {\n const { toCanvas } = await import(\"html-to-image\");\n return toCanvas(element, options as Parameters<typeof toCanvas>[1]);\n}\n\n/** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */\nexport async function renderElementToDataUrl(element: HTMLElement, options: RenderOptions = {}): Promise<string> {\n const { toPng } = await import(\"html-to-image\");\n return toPng(element, options as Parameters<typeof toPng>[1]);\n}\n\n/** Lay canvases out as PDF pages (one page each) and answer the PDF Blob — print's `pagesToPdf`. */\nexport async function pagesToPdf(pages: readonly PdfPage[], options: PdfDocumentOptions = {}): Promise<Blob> {\n const { pagesToPdf: layOut } = await import(\"@ai-matrx/print/pdf\");\n return layOut(pages, options);\n}\n\n/** Capture each element and lay them out one per PDF page. */\nexport async function elementsToPdf(\n elements: readonly HTMLElement[],\n options: PdfDocumentOptions & { capture?: CaptureOptions; page?: Omit<PdfPage, \"image\"> } = {},\n): Promise<Blob> {\n const pages: PdfPage[] = [];\n for (const element of elements) pages.push({ ...options.page, image: await captureElement(element, options.capture) });\n return pagesToPdf(pages, options);\n}\n"],"mappings":"y5BAAA,sWCkBA,eAAsB,eAAe,QAAsB,QAA0B,CAAC,EAA+B,CACnH,GAAM,CAAE,aAAc,EAAI,KAAM,QAAO,qBAAqB,EAC5D,OAAO,cAAc,QAAS,OAAO,CACvC,CAGA,eAAsB,aAAa,OAA2B,KAAkD,YAAa,QAAiC,CAC5J,IAAM,KAAO,MAAM,IAAI,QAAsB,SAAY,OAAO,OAAO,QAAS,KAAM,OAAO,CAAC,EAC9F,GAAI,CAAC,KAAM,MAAM,IAAI,MAAM,iCAAiC,EAC5D,OAAO,IACT,CAGA,eAAsB,eACpB,QACA,QAAmG,CAAC,EACrF,CACf,GAAM,CAAE,KAAM,QAAS,GAAG,OAAQ,EAAI,QACtC,OAAO,aAAa,MAAM,eAAe,QAAS,OAAO,EAAG,KAAM,OAAO,CAC3E,CA6BA,eAAsB,cAAc,QAAsB,QAAyB,CAAC,EAA+B,CACjH,GAAM,CAAE,QAAS,EAAI,KAAM,QAAO,eAAe,EACjD,OAAO,SAAS,QAAS,OAAyC,CACpE,CAGA,eAAsB,uBAAuB,QAAsB,QAAyB,CAAC,EAAoB,CAC/G,GAAM,CAAE,KAAM,EAAI,KAAM,QAAO,eAAe,EAC9C,OAAO,MAAM,QAAS,OAAsC,CAC9D,CAGA,eAAsB,WAAW,MAA2B,QAA8B,CAAC,EAAkB,CAC3G,GAAM,CAAE,WAAY,MAAO,EAAI,KAAM,QAAO,qBAAqB,EACjE,OAAO,OAAO,MAAO,OAAO,CAC9B,CAGA,eAAsB,cACpB,SACA,QAA4F,CAAC,EAC9E,CACf,IAAM,MAAmB,CAAC,EAC1B,QAAW,WAAW,SAAU,MAAM,KAAK,CAAE,GAAG,QAAQ,KAAM,MAAO,MAAM,eAAe,QAAS,QAAQ,OAAO,CAAE,CAAC,EACrH,OAAO,WAAW,MAAO,OAAO,CAClC","names":[]}
@@ -1,35 +1,19 @@
1
+ import { CanvasCaptureOptions, PdfDocumentOptions, PdfPage } from '@ai-matrx/print/pdf';
2
+ export { CanvasCaptureOptions as CaptureOptions, PdfDocumentOptions, PdfMargins, PdfPage } from '@ai-matrx/print/pdf';
3
+
1
4
  /**
2
- * `@ai-matrx/alchemy/operate/capture` — THE DOM capture engine (ALC-19 T11): an element on screen →
3
- * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. Both libraries
4
- * load on first use (`import()`), so a page that never exports never downloads them.
5
+ * `@ai-matrx/alchemy/operate/capture` — THE DOM capture door (ALC-19 T11): an element on screen →
6
+ * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. The html2canvas +
7
+ * jsPDF engine itself is `@ai-matrx/print/pdf` (`captureCanvas`, `pagesToPdf`), loaded on first use
8
+ * (`import()`), so a page that never exports never downloads it; html-to-image (`renderElement`) is
9
+ * this module's own.
5
10
  *
6
11
  * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per
7
12
  * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.
8
13
  */
9
- type CaptureOptions = {
10
- /** Device-pixel scale of the capture (default 2 — legible when scaled in a deck or print). */
11
- scale?: number;
12
- /** Canvas background; null keeps transparency. */
13
- backgroundColor?: string | null;
14
- useCORS?: boolean;
15
- allowTaint?: boolean;
16
- logging?: boolean;
17
- width?: number;
18
- height?: number;
19
- x?: number;
20
- y?: number;
21
- scrollX?: number;
22
- scrollY?: number;
23
- windowWidth?: number;
24
- windowHeight?: number;
25
- ignoreElements?(element: Element): boolean;
26
- onclone?(document: Document, element: HTMLElement): void | Promise<void>;
27
- /** Replace unparseable modern colour functions while capturing (`{ dark }` picks the palette). */
28
- safeColors?: boolean | {
29
- dark: boolean;
30
- };
31
- };
32
- /** Rasterise a live element to a canvas (what the person sees, at `scale`). */
14
+
15
+ type CaptureOptions = CanvasCaptureOptions;
16
+ /** Rasterise a live element to a canvas (what the person sees, at `scale`) — print's `captureCanvas`. */
33
17
  declare function captureElement(element: HTMLElement, options?: CaptureOptions): Promise<HTMLCanvasElement>;
34
18
  /** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */
35
19
  declare function canvasToBlob(canvas: HTMLCanvasElement, type?: "image/png" | "image/jpeg" | "image/webp", quality?: number): Promise<Blob>;
@@ -67,34 +51,7 @@ type RenderOptions = {
67
51
  declare function renderElement(element: HTMLElement, options?: RenderOptions): Promise<HTMLCanvasElement>;
68
52
  /** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */
69
53
  declare function renderElementToDataUrl(element: HTMLElement, options?: RenderOptions): Promise<string>;
70
- type PdfMargins = {
71
- top: number;
72
- right: number;
73
- bottom: number;
74
- left: number;
75
- };
76
- type PdfPage = {
77
- image: HTMLCanvasElement;
78
- /** "JPEG" (default 0.92 quality) keeps a flat chart an order of magnitude smaller than a PNG embed. */
79
- imageType?: "PNG" | "JPEG";
80
- quality?: number;
81
- compression?: "NONE" | "FAST" | "MEDIUM" | "SLOW";
82
- /** "fill": the image covers the page. Margins: the image is scaled to fit inside them, never cropped. */
83
- placement?: "fill" | PdfMargins;
84
- /** A line of text drawn on the page (e.g. the as-of date a chart is true of). */
85
- header?: {
86
- text: string;
87
- x: number;
88
- y: number;
89
- fontSize?: number;
90
- };
91
- };
92
- type PdfDocumentOptions = {
93
- orientation?: "portrait" | "landscape";
94
- unit?: "pt" | "mm" | "cm" | "in" | "px";
95
- format?: string | [number, number];
96
- };
97
- /** Lay canvases out as PDF pages (one page each) and answer the PDF Blob. */
54
+ /** Lay canvases out as PDF pages (one page each) and answer the PDF Blob — print's `pagesToPdf`. */
98
55
  declare function pagesToPdf(pages: readonly PdfPage[], options?: PdfDocumentOptions): Promise<Blob>;
99
56
  /** Capture each element and lay them out one per PDF page. */
100
57
  declare function elementsToPdf(elements: readonly HTMLElement[], options?: PdfDocumentOptions & {
@@ -102,4 +59,4 @@ declare function elementsToPdf(elements: readonly HTMLElement[], options?: PdfDo
102
59
  page?: Omit<PdfPage, "image">;
103
60
  }): Promise<Blob>;
104
61
 
105
- export { type CaptureOptions, type PdfDocumentOptions, type PdfMargins, type PdfPage, type RenderOptions, canvasToBlob, captureElement, elementToImage, elementsToPdf, pagesToPdf, renderElement, renderElementToDataUrl };
62
+ export { type RenderOptions, canvasToBlob, captureElement, elementToImage, elementsToPdf, pagesToPdf, renderElement, renderElementToDataUrl };
@@ -1,35 +1,19 @@
1
+ import { CanvasCaptureOptions, PdfDocumentOptions, PdfPage } from '@ai-matrx/print/pdf';
2
+ export { CanvasCaptureOptions as CaptureOptions, PdfDocumentOptions, PdfMargins, PdfPage } from '@ai-matrx/print/pdf';
3
+
1
4
  /**
2
- * `@ai-matrx/alchemy/operate/capture` — THE DOM capture engine (ALC-19 T11): an element on screen →
3
- * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. Both libraries
4
- * load on first use (`import()`), so a page that never exports never downloads them.
5
+ * `@ai-matrx/alchemy/operate/capture` — THE DOM capture door (ALC-19 T11): an element on screen →
6
+ * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. The html2canvas +
7
+ * jsPDF engine itself is `@ai-matrx/print/pdf` (`captureCanvas`, `pagesToPdf`), loaded on first use
8
+ * (`import()`), so a page that never exports never downloads it; html-to-image (`renderElement`) is
9
+ * this module's own.
5
10
  *
6
11
  * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per
7
12
  * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.
8
13
  */
9
- type CaptureOptions = {
10
- /** Device-pixel scale of the capture (default 2 — legible when scaled in a deck or print). */
11
- scale?: number;
12
- /** Canvas background; null keeps transparency. */
13
- backgroundColor?: string | null;
14
- useCORS?: boolean;
15
- allowTaint?: boolean;
16
- logging?: boolean;
17
- width?: number;
18
- height?: number;
19
- x?: number;
20
- y?: number;
21
- scrollX?: number;
22
- scrollY?: number;
23
- windowWidth?: number;
24
- windowHeight?: number;
25
- ignoreElements?(element: Element): boolean;
26
- onclone?(document: Document, element: HTMLElement): void | Promise<void>;
27
- /** Replace unparseable modern colour functions while capturing (`{ dark }` picks the palette). */
28
- safeColors?: boolean | {
29
- dark: boolean;
30
- };
31
- };
32
- /** Rasterise a live element to a canvas (what the person sees, at `scale`). */
14
+
15
+ type CaptureOptions = CanvasCaptureOptions;
16
+ /** Rasterise a live element to a canvas (what the person sees, at `scale`) — print's `captureCanvas`. */
33
17
  declare function captureElement(element: HTMLElement, options?: CaptureOptions): Promise<HTMLCanvasElement>;
34
18
  /** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */
35
19
  declare function canvasToBlob(canvas: HTMLCanvasElement, type?: "image/png" | "image/jpeg" | "image/webp", quality?: number): Promise<Blob>;
@@ -67,34 +51,7 @@ type RenderOptions = {
67
51
  declare function renderElement(element: HTMLElement, options?: RenderOptions): Promise<HTMLCanvasElement>;
68
52
  /** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */
69
53
  declare function renderElementToDataUrl(element: HTMLElement, options?: RenderOptions): Promise<string>;
70
- type PdfMargins = {
71
- top: number;
72
- right: number;
73
- bottom: number;
74
- left: number;
75
- };
76
- type PdfPage = {
77
- image: HTMLCanvasElement;
78
- /** "JPEG" (default 0.92 quality) keeps a flat chart an order of magnitude smaller than a PNG embed. */
79
- imageType?: "PNG" | "JPEG";
80
- quality?: number;
81
- compression?: "NONE" | "FAST" | "MEDIUM" | "SLOW";
82
- /** "fill": the image covers the page. Margins: the image is scaled to fit inside them, never cropped. */
83
- placement?: "fill" | PdfMargins;
84
- /** A line of text drawn on the page (e.g. the as-of date a chart is true of). */
85
- header?: {
86
- text: string;
87
- x: number;
88
- y: number;
89
- fontSize?: number;
90
- };
91
- };
92
- type PdfDocumentOptions = {
93
- orientation?: "portrait" | "landscape";
94
- unit?: "pt" | "mm" | "cm" | "in" | "px";
95
- format?: string | [number, number];
96
- };
97
- /** Lay canvases out as PDF pages (one page each) and answer the PDF Blob. */
54
+ /** Lay canvases out as PDF pages (one page each) and answer the PDF Blob — print's `pagesToPdf`. */
98
55
  declare function pagesToPdf(pages: readonly PdfPage[], options?: PdfDocumentOptions): Promise<Blob>;
99
56
  /** Capture each element and lay them out one per PDF page. */
100
57
  declare function elementsToPdf(elements: readonly HTMLElement[], options?: PdfDocumentOptions & {
@@ -102,4 +59,4 @@ declare function elementsToPdf(elements: readonly HTMLElement[], options?: PdfDo
102
59
  page?: Omit<PdfPage, "image">;
103
60
  }): Promise<Blob>;
104
61
 
105
- export { type CaptureOptions, type PdfDocumentOptions, type PdfMargins, type PdfPage, type RenderOptions, canvasToBlob, captureElement, elementToImage, elementsToPdf, pagesToPdf, renderElement, renderElementToDataUrl };
62
+ export { type RenderOptions, canvasToBlob, captureElement, elementToImage, elementsToPdf, pagesToPdf, renderElement, renderElementToDataUrl };
@@ -1,2 +1,2 @@
1
- var UNSAFE_COLOR=/\b(oklch|oklab|lab|lch|color)\s*\(/i;function safeColor(value,prop,dark){if(!UNSAFE_COLOR.test(value))return value;let p=prop.toLowerCase();return p.includes("background")?dark?"#1f2937":"#ffffff":p==="color"?dark?"#f3f4f6":"#111827":p.includes("border")||p.includes("outline")?dark?"#4b5563":"#d1d5db":p==="fill"||p==="stroke"?dark?"#9ca3af":"#374151":"#6b7280"}function patchComputedStyle(dark){let original=window.getComputedStyle,bound=original.bind(window);return window.getComputedStyle=function(elt,pseudo){let computed=bound(elt,pseudo);return new Proxy(computed,{get(target,prop){let value=target[prop];return typeof prop=="string"&&typeof value=="string"&&value&&UNSAFE_COLOR.test(value)?safeColor(value,prop,dark):prop==="getPropertyValue"?p=>{let raw=target.getPropertyValue(p);return raw&&UNSAFE_COLOR.test(raw)?safeColor(raw,p,dark):raw}:typeof value=="function"?value.bind(target):value}})},()=>{window.getComputedStyle=original}}var prefersDark=()=>typeof document<"u"&&(document.documentElement.classList.contains("dark")||typeof window.matchMedia=="function"&&window.matchMedia("(prefers-color-scheme: dark)").matches);async function captureElement(element,options={}){let{safeColors,...rest}=options,{default:html2canvas}=await import("html2canvas"),restore=safeColors?patchComputedStyle(typeof safeColors=="object"?safeColors.dark:prefersDark()):()=>{};try{return await html2canvas(element,{scale:2,logging:!1,useCORS:!0,...rest})}finally{restore()}}async function canvasToBlob(canvas,type="image/png",quality){let blob=await new Promise(resolve=>canvas.toBlob(resolve,type,quality));if(!blob)throw new Error("The image could not be encoded.");return blob}async function elementToImage(element,options={}){let{type,quality,...capture}=options;return canvasToBlob(await captureElement(element,capture),type,quality)}async function renderElement(element,options={}){let{toCanvas}=await import("html-to-image");return toCanvas(element,options)}async function renderElementToDataUrl(element,options={}){let{toPng}=await import("html-to-image");return toPng(element,options)}async function pagesToPdf(pages,options={}){let{jsPDF}=await import("jspdf"),doc=new jsPDF({orientation:options.orientation??"portrait",unit:options.unit??"pt",format:options.format??"a4"});return pages.forEach((page,index)=>{index>0&&doc.addPage();let pageW=doc.internal.pageSize.getWidth(),pageH=doc.internal.pageSize.getHeight();page.header&&(doc.setFontSize(page.header.fontSize??12),doc.text(page.header.text,page.header.x,page.header.y));let type=page.imageType??"PNG",data=type==="JPEG"?page.image.toDataURL("image/jpeg",page.quality??.92):page.image.toDataURL("image/png"),placement=page.placement??"fill",x=0,y=0,w=pageW,h=pageH;if(placement!=="fill"){let availW=pageW-placement.left-placement.right,availH=pageH-placement.top-placement.bottom,scale=Math.min(availW/page.image.width,availH/page.image.height);x=placement.left,y=placement.top,w=page.image.width*scale,h=page.image.height*scale}page.compression?doc.addImage(data,type,x,y,w,h,void 0,page.compression):doc.addImage(data,type,x,y,w,h)}),doc.output("blob")}async function elementsToPdf(elements,options={}){let pages=[];for(let element of elements)pages.push({...options.page,image:await captureElement(element,options.capture)});return pagesToPdf(pages,options)}export{canvasToBlob,captureElement,elementToImage,elementsToPdf,pagesToPdf,renderElement,renderElementToDataUrl};
1
+ async function captureElement(element,options={}){let{captureCanvas}=await import("@ai-matrx/print/pdf");return captureCanvas(element,options)}async function canvasToBlob(canvas,type="image/png",quality){let blob=await new Promise(resolve=>canvas.toBlob(resolve,type,quality));if(!blob)throw new Error("The image could not be encoded.");return blob}async function elementToImage(element,options={}){let{type,quality,...capture}=options;return canvasToBlob(await captureElement(element,capture),type,quality)}async function renderElement(element,options={}){let{toCanvas}=await import("html-to-image");return toCanvas(element,options)}async function renderElementToDataUrl(element,options={}){let{toPng}=await import("html-to-image");return toPng(element,options)}async function pagesToPdf(pages,options={}){let{pagesToPdf:layOut}=await import("@ai-matrx/print/pdf");return layOut(pages,options)}async function elementsToPdf(elements,options={}){let pages=[];for(let element of elements)pages.push({...options.page,image:await captureElement(element,options.capture)});return pagesToPdf(pages,options)}export{canvasToBlob,captureElement,elementToImage,elementsToPdf,pagesToPdf,renderElement,renderElementToDataUrl};
2
2
  //# sourceMappingURL=operate-capture.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/operate/capture.ts"],"sourcesContent":["/**\n * `@ai-matrx/alchemy/operate/capture` — THE DOM capture engine (ALC-19 T11): an element on screen →\n * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. Both libraries\n * load on first use (`import()`), so a page that never exports never downloads them.\n *\n * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per\n * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.\n */\n\nexport type CaptureOptions = {\n /** Device-pixel scale of the capture (default 2 — legible when scaled in a deck or print). */\n scale?: number;\n /** Canvas background; null keeps transparency. */\n backgroundColor?: string | null;\n useCORS?: boolean;\n allowTaint?: boolean;\n logging?: boolean;\n width?: number;\n height?: number;\n x?: number;\n y?: number;\n scrollX?: number;\n scrollY?: number;\n windowWidth?: number;\n windowHeight?: number;\n ignoreElements?(element: Element): boolean;\n onclone?(document: Document, element: HTMLElement): void | Promise<void>;\n /** Replace unparseable modern colour functions while capturing (`{ dark }` picks the palette). */\n safeColors?: boolean | { dark: boolean };\n};\n\nconst UNSAFE_COLOR = /\\b(oklch|oklab|lab|lch|color)\\s*\\(/i;\n\nfunction safeColor(value: string, prop: string, dark: boolean): string {\n if (!UNSAFE_COLOR.test(value)) return value;\n const p = prop.toLowerCase();\n if (p.includes(\"background\")) return dark ? \"#1f2937\" : \"#ffffff\";\n if (p === \"color\") return dark ? \"#f3f4f6\" : \"#111827\";\n if (p.includes(\"border\") || p.includes(\"outline\")) return dark ? \"#4b5563\" : \"#d1d5db\";\n if (p === \"fill\" || p === \"stroke\") return dark ? \"#9ca3af\" : \"#374151\";\n return \"#6b7280\";\n}\n\n/** Patch `getComputedStyle` so the capture never reads an unsafe colour; returns the restore. */\nfunction patchComputedStyle(dark: boolean): () => void {\n const original = window.getComputedStyle;\n const bound = original.bind(window);\n window.getComputedStyle = function (elt: Element, pseudo?: string | null) {\n const computed = bound(elt, pseudo);\n return new Proxy(computed, {\n get(target, prop: string | symbol) {\n const value = (target as unknown as Record<string | symbol, unknown>)[prop];\n if (typeof prop === \"string\" && typeof value === \"string\" && value && UNSAFE_COLOR.test(value)) return safeColor(value, prop, dark);\n if (prop === \"getPropertyValue\")\n return (p: string) => {\n const raw = target.getPropertyValue(p);\n return raw && UNSAFE_COLOR.test(raw) ? safeColor(raw, p, dark) : raw;\n };\n if (typeof value === \"function\") return (value as CallableFunction).bind(target);\n return value;\n },\n });\n } as typeof window.getComputedStyle;\n return () => {\n window.getComputedStyle = original;\n };\n}\n\nconst prefersDark = () =>\n typeof document !== \"undefined\" &&\n (document.documentElement.classList.contains(\"dark\") || (typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-color-scheme: dark)\").matches));\n\n/** Rasterise a live element to a canvas (what the person sees, at `scale`). */\nexport async function captureElement(element: HTMLElement, options: CaptureOptions = {}): Promise<HTMLCanvasElement> {\n const { safeColors, ...rest } = options;\n const { default: html2canvas } = await import(\"html2canvas\");\n const restore = safeColors ? patchComputedStyle(typeof safeColors === \"object\" ? safeColors.dark : prefersDark()) : () => {};\n try {\n return await html2canvas(element, { scale: 2, logging: false, useCORS: true, ...rest } as Parameters<typeof html2canvas>[1]);\n } finally {\n restore();\n }\n}\n\n/** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */\nexport async function canvasToBlob(canvas: HTMLCanvasElement, type: \"image/png\" | \"image/jpeg\" | \"image/webp\" = \"image/png\", quality?: number): Promise<Blob> {\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (!blob) throw new Error(\"The image could not be encoded.\");\n return blob;\n}\n\n/** Capture an element straight to an image Blob. */\nexport async function elementToImage(\n element: HTMLElement,\n options: CaptureOptions & { type?: \"image/png\" | \"image/jpeg\" | \"image/webp\"; quality?: number } = {},\n): Promise<Blob> {\n const { type, quality, ...capture } = options;\n return canvasToBlob(await captureElement(element, capture), type, quality);\n}\n\n/** Options for `renderElement` (html-to-image): the SVG foreignObject renderer. */\nexport type RenderOptions = {\n /** Device-pixel ratio (default 1). */\n pixelRatio?: number;\n width?: number;\n height?: number;\n /** Final canvas size; the render is scaled to it. */\n canvasWidth?: number;\n canvasHeight?: number;\n backgroundColor?: string;\n /** Inline style applied to the cloned root (e.g. a translate to pad the chart). */\n style?: Partial<CSSStyleDeclaration>;\n /** Return false to leave a node out of the picture. */\n filter?(node: HTMLElement): boolean;\n skipFonts?: boolean;\n /** Bust the image cache so a CORS fetch is fresh. */\n cacheBust?: boolean;\n /** Data URL drawn instead of an image that fails to load. */\n imagePlaceholder?: string;\n onImageErrorHandler?(...args: unknown[]): void;\n};\n\n/**\n * Render a live element to a canvas through the SVG foreignObject renderer (html-to-image). It keeps\n * the browser's own layout and fonts where html2canvas re-implements them, and it takes a `filter`\n * and a root `style` override — the right tool for a transformed or panned surface. Loads on first use.\n */\nexport async function renderElement(element: HTMLElement, options: RenderOptions = {}): Promise<HTMLCanvasElement> {\n const { toCanvas } = await import(\"html-to-image\");\n return toCanvas(element, options as Parameters<typeof toCanvas>[1]);\n}\n\n/** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */\nexport async function renderElementToDataUrl(element: HTMLElement, options: RenderOptions = {}): Promise<string> {\n const { toPng } = await import(\"html-to-image\");\n return toPng(element, options as Parameters<typeof toPng>[1]);\n}\n\nexport type PdfMargins = { top: number; right: number; bottom: number; left: number };\nexport type PdfPage = {\n image: HTMLCanvasElement;\n /** \"JPEG\" (default 0.92 quality) keeps a flat chart an order of magnitude smaller than a PNG embed. */\n imageType?: \"PNG\" | \"JPEG\";\n quality?: number;\n compression?: \"NONE\" | \"FAST\" | \"MEDIUM\" | \"SLOW\";\n /** \"fill\": the image covers the page. Margins: the image is scaled to fit inside them, never cropped. */\n placement?: \"fill\" | PdfMargins;\n /** A line of text drawn on the page (e.g. the as-of date a chart is true of). */\n header?: { text: string; x: number; y: number; fontSize?: number };\n};\nexport type PdfDocumentOptions = {\n orientation?: \"portrait\" | \"landscape\";\n unit?: \"pt\" | \"mm\" | \"cm\" | \"in\" | \"px\";\n format?: string | [number, number];\n};\n\n/** Lay canvases out as PDF pages (one page each) and answer the PDF Blob. */\nexport async function pagesToPdf(pages: readonly PdfPage[], options: PdfDocumentOptions = {}): Promise<Blob> {\n const { jsPDF } = await import(\"jspdf\");\n const doc = new jsPDF({ orientation: options.orientation ?? \"portrait\", unit: options.unit ?? \"pt\", format: options.format ?? \"a4\" });\n pages.forEach((page, index) => {\n if (index > 0) doc.addPage();\n const pageW = doc.internal.pageSize.getWidth();\n const pageH = doc.internal.pageSize.getHeight();\n if (page.header) {\n doc.setFontSize(page.header.fontSize ?? 12);\n doc.text(page.header.text, page.header.x, page.header.y);\n }\n const type = page.imageType ?? \"PNG\";\n const data = type === \"JPEG\" ? page.image.toDataURL(\"image/jpeg\", page.quality ?? 0.92) : page.image.toDataURL(\"image/png\");\n const placement = page.placement ?? \"fill\";\n let x = 0, y = 0, w = pageW, h = pageH;\n if (placement !== \"fill\") {\n const availW = pageW - placement.left - placement.right;\n const availH = pageH - placement.top - placement.bottom;\n const scale = Math.min(availW / page.image.width, availH / page.image.height);\n x = placement.left;\n y = placement.top;\n w = page.image.width * scale;\n h = page.image.height * scale;\n }\n if (page.compression) doc.addImage(data, type, x, y, w, h, undefined, page.compression);\n else doc.addImage(data, type, x, y, w, h);\n });\n return doc.output(\"blob\");\n}\n\n/** Capture each element and lay them out one per PDF page. */\nexport async function elementsToPdf(\n elements: readonly HTMLElement[],\n options: PdfDocumentOptions & { capture?: CaptureOptions; page?: Omit<PdfPage, \"image\"> } = {},\n): Promise<Blob> {\n const pages: PdfPage[] = [];\n for (const element of elements) pages.push({ ...options.page, image: await captureElement(element, options.capture) });\n return pagesToPdf(pages, options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/operate/capture.ts"],"sourcesContent":["/**\n * `@ai-matrx/alchemy/operate/capture` — THE DOM capture door (ALC-19 T11): an element on screen →\n * an image or a PDF, with nothing else in the app importing html2canvas or jsPDF. The html2canvas +\n * jsPDF engine itself is `@ai-matrx/print/pdf` (`captureCanvas`, `pagesToPdf`), loaded on first use\n * (`import()`), so a page that never exports never downloads it; html-to-image (`renderElement`) is\n * this module's own.\n *\n * Tailwind 4 colours (oklch/lab/color()) are not parseable by html2canvas, which logs an error per\n * value; `safeColors` substitutes theme-appropriate hex values for the duration of the capture.\n */\n\n// THE one html2canvas + jsPDF engine is print's (AP-2 engine ruling: print sits below alchemy, so\n// alchemy loads it — never a second copy here). Type-only imports; the module loads on first use.\nimport type { CanvasCaptureOptions, PdfDocumentOptions, PdfPage } from \"@ai-matrx/print/pdf\";\nexport type { CanvasCaptureOptions as CaptureOptions, PdfDocumentOptions, PdfMargins, PdfPage } from \"@ai-matrx/print/pdf\";\ntype CaptureOptions = CanvasCaptureOptions;\n\n/** Rasterise a live element to a canvas (what the person sees, at `scale`) — print's `captureCanvas`. */\nexport async function captureElement(element: HTMLElement, options: CaptureOptions = {}): Promise<HTMLCanvasElement> {\n const { captureCanvas } = await import(\"@ai-matrx/print/pdf\");\n return captureCanvas(element, options);\n}\n\n/** Encode a canvas (PNG by default; JPEG/WebP take a 0–1 quality). Throws when the browser refuses. */\nexport async function canvasToBlob(canvas: HTMLCanvasElement, type: \"image/png\" | \"image/jpeg\" | \"image/webp\" = \"image/png\", quality?: number): Promise<Blob> {\n const blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, type, quality));\n if (!blob) throw new Error(\"The image could not be encoded.\");\n return blob;\n}\n\n/** Capture an element straight to an image Blob. */\nexport async function elementToImage(\n element: HTMLElement,\n options: CaptureOptions & { type?: \"image/png\" | \"image/jpeg\" | \"image/webp\"; quality?: number } = {},\n): Promise<Blob> {\n const { type, quality, ...capture } = options;\n return canvasToBlob(await captureElement(element, capture), type, quality);\n}\n\n/** Options for `renderElement` (html-to-image): the SVG foreignObject renderer. */\nexport type RenderOptions = {\n /** Device-pixel ratio (default 1). */\n pixelRatio?: number;\n width?: number;\n height?: number;\n /** Final canvas size; the render is scaled to it. */\n canvasWidth?: number;\n canvasHeight?: number;\n backgroundColor?: string;\n /** Inline style applied to the cloned root (e.g. a translate to pad the chart). */\n style?: Partial<CSSStyleDeclaration>;\n /** Return false to leave a node out of the picture. */\n filter?(node: HTMLElement): boolean;\n skipFonts?: boolean;\n /** Bust the image cache so a CORS fetch is fresh. */\n cacheBust?: boolean;\n /** Data URL drawn instead of an image that fails to load. */\n imagePlaceholder?: string;\n onImageErrorHandler?(...args: unknown[]): void;\n};\n\n/**\n * Render a live element to a canvas through the SVG foreignObject renderer (html-to-image). It keeps\n * the browser's own layout and fonts where html2canvas re-implements them, and it takes a `filter`\n * and a root `style` override — the right tool for a transformed or panned surface. Loads on first use.\n */\nexport async function renderElement(element: HTMLElement, options: RenderOptions = {}): Promise<HTMLCanvasElement> {\n const { toCanvas } = await import(\"html-to-image\");\n return toCanvas(element, options as Parameters<typeof toCanvas>[1]);\n}\n\n/** `renderElement` answering a PNG data URL (what a chat attachment preview needs besides the Blob). */\nexport async function renderElementToDataUrl(element: HTMLElement, options: RenderOptions = {}): Promise<string> {\n const { toPng } = await import(\"html-to-image\");\n return toPng(element, options as Parameters<typeof toPng>[1]);\n}\n\n/** Lay canvases out as PDF pages (one page each) and answer the PDF Blob — print's `pagesToPdf`. */\nexport async function pagesToPdf(pages: readonly PdfPage[], options: PdfDocumentOptions = {}): Promise<Blob> {\n const { pagesToPdf: layOut } = await import(\"@ai-matrx/print/pdf\");\n return layOut(pages, options);\n}\n\n/** Capture each element and lay them out one per PDF page. */\nexport async function elementsToPdf(\n elements: readonly HTMLElement[],\n options: PdfDocumentOptions & { capture?: CaptureOptions; page?: Omit<PdfPage, \"image\"> } = {},\n): Promise<Blob> {\n const pages: PdfPage[] = [];\n for (const element of elements) pages.push({ ...options.page, image: await captureElement(element, options.capture) });\n return pagesToPdf(pages, options);\n}\n"],"mappings":"AAkBA,eAAsB,eAAe,QAAsB,QAA0B,CAAC,EAA+B,CACnH,GAAM,CAAE,aAAc,EAAI,KAAM,QAAO,qBAAqB,EAC5D,OAAO,cAAc,QAAS,OAAO,CACvC,CAGA,eAAsB,aAAa,OAA2B,KAAkD,YAAa,QAAiC,CAC5J,IAAM,KAAO,MAAM,IAAI,QAAsB,SAAY,OAAO,OAAO,QAAS,KAAM,OAAO,CAAC,EAC9F,GAAI,CAAC,KAAM,MAAM,IAAI,MAAM,iCAAiC,EAC5D,OAAO,IACT,CAGA,eAAsB,eACpB,QACA,QAAmG,CAAC,EACrF,CACf,GAAM,CAAE,KAAM,QAAS,GAAG,OAAQ,EAAI,QACtC,OAAO,aAAa,MAAM,eAAe,QAAS,OAAO,EAAG,KAAM,OAAO,CAC3E,CA6BA,eAAsB,cAAc,QAAsB,QAAyB,CAAC,EAA+B,CACjH,GAAM,CAAE,QAAS,EAAI,KAAM,QAAO,eAAe,EACjD,OAAO,SAAS,QAAS,OAAyC,CACpE,CAGA,eAAsB,uBAAuB,QAAsB,QAAyB,CAAC,EAAoB,CAC/G,GAAM,CAAE,KAAM,EAAI,KAAM,QAAO,eAAe,EAC9C,OAAO,MAAM,QAAS,OAAsC,CAC9D,CAGA,eAAsB,WAAW,MAA2B,QAA8B,CAAC,EAAkB,CAC3G,GAAM,CAAE,WAAY,MAAO,EAAI,KAAM,QAAO,qBAAqB,EACjE,OAAO,OAAO,MAAO,OAAO,CAC9B,CAGA,eAAsB,cACpB,SACA,QAA4F,CAAC,EAC9E,CACf,IAAM,MAAmB,CAAC,EAC1B,QAAW,WAAW,SAAU,MAAM,KAAK,CAAE,GAAG,QAAQ,KAAM,MAAO,MAAM,eAAe,QAAS,QAAQ,OAAO,CAAE,CAAC,EACrH,OAAO,WAAW,MAAO,OAAO,CAClC","names":[]}
@@ -1,4 +1,4 @@
1
- "use strict";var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod)),__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var operate_document_exports={};__export(operate_document_exports,{documentEngine:()=>documentEngine,documentHtmlEngine:()=>documentHtmlEngine});module.exports=__toCommonJS(operate_document_exports);var import_download=require("@ai-matrx/kit/download"),import_json_format=require("@ai-matrx/kit/json-format"),import_html_escape=require("@ai-matrx/kit/html-escape"),import_transfer_json=require("@ai-matrx/kit/transfer-json"),import_transfer_json2=require("@ai-matrx/kit/transfer-json");function fencedCodeBlock(text,language){let runs=text.match(/`+/g)??[],fence="`".repeat(Math.max(3,...runs.map(run=>run.length+1)));return`${fence}${language}
1
+ "use strict";var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod)),__toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:!0}),mod);var operate_document_exports={};__export(operate_document_exports,{documentEngine:()=>documentEngine,documentHtmlEngine:()=>documentHtmlEngine});module.exports=__toCommonJS(operate_document_exports);var import_download=require("@ai-matrx/kit/download"),import_json_format=require("@ai-matrx/kit/json-format"),import_html_escape=require("@ai-matrx/kit/html-escape"),import_delimited=require("@ai-matrx/kit/delimited"),import_transfer_json=require("@ai-matrx/kit/transfer-json"),import_transfer_json2=require("@ai-matrx/kit/transfer-json");function fencedCodeBlock(text,language){let runs=text.match(/`+/g)??[],fence="`".repeat(Math.max(3,...runs.map(run=>run.length+1)));return`${fence}${language}
2
2
  ${text}${text.endsWith(`
3
3
  `)?"":`
4
4
  `}${fence}`}function deepFreeze(v){if(ArrayBuffer.isView(v))return v;if(v&&typeof v=="object"&&!Object.isFrozen(v)){Object.freeze(v);for(let x of Object.values(v))deepFreeze(x)}return v}function sealTransferArtifact(artifact){if(!artifact.file)return deepFreeze({...artifact,omissions:artifact.omissions.map(o=>({...o}))});let bytes=artifact.file.bytes.slice(),file={filename:artifact.file.filename,mime:artifact.file.mime,get bytes(){return bytes.slice()}};return deepFreeze({...artifact,file,omissions:artifact.omissions.map(o=>({...o}))})}var ENGINE=Symbol.for("ai-matrx.alchemy.operate.markdown-html-engine");async function loadMarkdownHtmlEngine(){let g=globalThis;return g[ENGINE]??=import("@ai-matrx/print/markdown-html").then(m=>m.createMarkdownHtmlEngine()),g[ENGINE]}var enc=new TextEncoder;function markdownOf(draft){let p=draft.payload;if(p.kind==="markdown")return p.text;if(p.kind==="text")return p.language?fencedCodeBlock(p.text,p.language):p.text;throw new import_transfer_json2.ContentTransferError("unsupported-format","A document needs text or Markdown content. Download it as JSON or CSV instead.")}var stem=filename=>filename?filename.replace(/\.[a-z0-9]+$/i,""):void 0,documentHtmlEngine={async build(draft,options,signal){if(signal.aborted)throw new DOMException("Cancelled","AbortError");let engine=await loadMarkdownHtmlEngine(),tree=await engine.parse(markdownOf(draft),{signal,...options.onNotice?{onNotice:options.onNotice}:{},...options.assets?{assets:options.assets}:{}}),page=engine.document(tree);return sealTransferArtifact({snapshotId:draft.snapshotId,draftRevision:draft.revision,format:"html",plainText:engine.plainText(tree),html:page,file:{filename:options.filename??"export.html",mime:"text/html;charset=utf-8",bytes:enc.encode(page)},omissions:draft.omissions.map(o=>({...o}))})}};function documentEngine(format){return{async build(draft,options,signal){if(signal.aborted)throw new DOMException("Cancelled","AbortError");let source=markdownOf(draft),{exportDocument}=await import("@ai-matrx/print/document"),name=stem(options.filename),out=await exportDocument(source,format,{...name?{fileName:name}:{},...options.onNotice?{onNotice:n=>options.onNotice?.({code:n.code,sentence:n.message,remedy:n.remedy})}:{}});if(signal.aborted)throw new DOMException("Cancelled","AbortError");return sealTransferArtifact({snapshotId:draft.snapshotId,draftRevision:draft.revision,format,plainText:source,file:{filename:out.fileName,mime:out.mime,bytes:out.bytes},omissions:draft.omissions.map(o=>({...o}))})}}}