web-annotation-renderer 0.1.4 → 0.3.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 (51) hide show
  1. package/README.md +176 -6
  2. package/ai-tools.js +11 -0
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +41 -25
  6. package/dist/index.js.map +1 -1
  7. package/dist/index12.cjs +1 -1
  8. package/dist/index12.cjs.map +1 -1
  9. package/dist/index12.js +118 -189
  10. package/dist/index12.js.map +1 -1
  11. package/dist/index13.cjs +1 -1
  12. package/dist/index13.cjs.map +1 -1
  13. package/dist/index13.js +200 -15
  14. package/dist/index13.js.map +1 -1
  15. package/dist/index14.cjs +1 -1
  16. package/dist/index14.cjs.map +1 -1
  17. package/dist/index14.js +15 -123
  18. package/dist/index14.js.map +1 -1
  19. package/dist/index15.cjs +1 -1
  20. package/dist/index15.cjs.map +1 -1
  21. package/dist/index15.js +123 -32
  22. package/dist/index15.js.map +1 -1
  23. package/dist/index16.cjs +2 -0
  24. package/dist/index16.cjs.map +1 -0
  25. package/dist/index16.js +219 -0
  26. package/dist/index16.js.map +1 -0
  27. package/dist/index17.cjs +2 -0
  28. package/dist/index17.cjs.map +1 -0
  29. package/dist/index17.js +44 -0
  30. package/dist/index17.js.map +1 -0
  31. package/dist/index18.cjs +2 -0
  32. package/dist/index18.cjs.map +1 -0
  33. package/dist/index18.js +40 -0
  34. package/dist/index18.js.map +1 -0
  35. package/dist/index19.cjs +2 -0
  36. package/dist/index19.cjs.map +1 -0
  37. package/dist/index19.js +41 -0
  38. package/dist/index19.js.map +1 -0
  39. package/dist/index20.cjs +2 -0
  40. package/dist/index20.cjs.map +1 -0
  41. package/dist/index20.js +50 -0
  42. package/dist/index20.js.map +1 -0
  43. package/dist/index21.cjs +2 -0
  44. package/dist/index21.cjs.map +1 -0
  45. package/dist/index21.js +35 -0
  46. package/dist/index21.js.map +1 -0
  47. package/dist/index22.cjs +2 -0
  48. package/dist/index22.cjs.map +1 -0
  49. package/dist/index22.js +8 -0
  50. package/dist/index22.js.map +1 -0
  51. package/package.json +10 -1
package/dist/index15.js CHANGED
@@ -1,35 +1,126 @@
1
- const o = {
2
- page: 1,
3
- start: 0,
4
- end: 0
5
- }, t = {
6
- mode: "quads",
7
- quads: [{ x: 0.1, y: 0.1, w: 0.8, h: 0.05 }],
8
- style: { color: "rgba(255, 255, 0, 0.3)" }
9
- }, s = {
10
- content: "[No content]",
11
- x: 0.1,
12
- y: 0.1,
13
- w: 0.3,
14
- h: 0.1,
15
- style: {
16
- bg: "rgba(255, 255, 255, 0.9)",
17
- color: "#000000"
18
- }
19
- }, e = {
20
- strokes: [{
21
- color: "#1f2937",
22
- size: 3,
23
- points: [
24
- { t: 0, x: 0.1, y: 0.1 },
25
- { t: 1, x: 0.2, y: 0.2 }
26
- ]
27
- }]
28
- };
1
+ import { jsxs as S, jsx as F } from "react/jsx-runtime";
2
+ import { useRef as u, useCallback as k, useEffect as c } from "react";
3
+ import { AnnotationRenderer as x } from "./index2.js";
4
+ function Q({
5
+ // Required props
6
+ pdfUrl: a,
7
+ // Optional props with defaults
8
+ page: i = 1,
9
+ scale: s = 1.5,
10
+ annotations: y = [],
11
+ currentTime: l = 0,
12
+ // Callbacks
13
+ onLoad: P,
14
+ onError: t,
15
+ onPageChange: h,
16
+ // Styling
17
+ className: v,
18
+ style: m,
19
+ canvasStyle: w
20
+ }) {
21
+ const f = u(null), d = u(null), r = u(null), A = u(Promise.resolve()), o = k((e) => {
22
+ A.current = A.current.then(e).catch((p) => {
23
+ console.error("AnnotPdf: Queued operation failed:", p);
24
+ });
25
+ }, []);
26
+ c(() => {
27
+ if (!(!f.current || !d.current)) {
28
+ try {
29
+ r.current = new x({
30
+ canvasElement: f.current,
31
+ container: d.current
32
+ });
33
+ } catch (e) {
34
+ console.error("AnnotPdf: Failed to initialize renderer:", e), t && t(e);
35
+ }
36
+ return () => {
37
+ r.current && (r.current.destroy(), r.current = null);
38
+ };
39
+ }
40
+ }, []), c(() => {
41
+ if (!r.current || !a)
42
+ return;
43
+ let e = !1;
44
+ return o(async () => {
45
+ try {
46
+ const n = await r.current.loadPDF(a);
47
+ if (e) return;
48
+ if (!n.success) {
49
+ console.error("AnnotPdf: Failed to load PDF:", n.error), t && t(new Error(n.error));
50
+ return;
51
+ }
52
+ P && P({ pageCount: n.pageCount });
53
+ } catch (n) {
54
+ if (e) return;
55
+ console.error("AnnotPdf: Failed to load PDF:", n), t && t(n);
56
+ }
57
+ }), () => {
58
+ e = !0;
59
+ };
60
+ }, [a, o]), c(() => {
61
+ !r.current || !i || typeof i != "number" || o(async () => {
62
+ try {
63
+ const e = await r.current.setPage(i);
64
+ if (!e.success) {
65
+ console.error("AnnotPdf: Failed to set page:", e.error), t && t(new Error(e.error));
66
+ return;
67
+ }
68
+ h && h(i);
69
+ } catch (e) {
70
+ console.error("AnnotPdf: Failed to set page:", e), t && t(e);
71
+ }
72
+ });
73
+ }, [i, o]), c(() => {
74
+ !r.current || !s || typeof s != "number" || o(async () => {
75
+ try {
76
+ const e = await r.current.setScale(s);
77
+ e.success || (console.error("AnnotPdf: Failed to set scale:", e.error), t && t(new Error(e.error)));
78
+ } catch (e) {
79
+ console.error("AnnotPdf: Failed to set scale:", e), t && t(e);
80
+ }
81
+ });
82
+ }, [s, o]), c(() => {
83
+ if (r.current)
84
+ try {
85
+ r.current.setAnnotations(y || []);
86
+ } catch (e) {
87
+ console.error("AnnotPdf: Failed to set annotations:", e), t && t(e);
88
+ }
89
+ }, [y]), c(() => {
90
+ if (!(!r.current || l === void 0 || l === null))
91
+ try {
92
+ r.current.setTime(l);
93
+ } catch (e) {
94
+ console.error("AnnotPdf: Failed to set time:", e), t && t(e);
95
+ }
96
+ }, [l]);
97
+ const b = {
98
+ position: "relative",
99
+ display: "inline-block",
100
+ lineHeight: 0,
101
+ // Remove extra space below canvas
102
+ ...m
103
+ // User styles override defaults
104
+ }, C = {
105
+ position: "absolute",
106
+ top: 0,
107
+ left: 0,
108
+ width: "100%",
109
+ height: "100%",
110
+ pointerEvents: "none",
111
+ // Allow clicks to pass through to canvas
112
+ overflow: "hidden"
113
+ }, R = {
114
+ display: "block",
115
+ ...w
116
+ // User styles override defaults
117
+ };
118
+ return /* @__PURE__ */ S("div", { className: v, style: b, children: [
119
+ /* @__PURE__ */ F("canvas", { ref: f, style: R }),
120
+ /* @__PURE__ */ F("div", { ref: d, style: C })
121
+ ] });
122
+ }
29
123
  export {
30
- o as BASE_DEFAULTS,
31
- t as HIGHLIGHT_DEFAULTS,
32
- e as INK_DEFAULTS,
33
- s as TEXT_DEFAULTS
124
+ Q as default
34
125
  };
35
126
  //# sourceMappingURL=index15.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index15.js","sources":["../src/types/defaults.js"],"sourcesContent":["/**\n * Default Values for Annotation Normalization\n *\n * This module defines default values used when annotation fields are missing\n * or invalid. These defaults ensure annotations render visibly and safely.\n *\n * @module types/defaults\n */\n\n/**\n * Default values for base annotation fields (common to all types)\n *\n * @constant {Object}\n * @property {number} page - Default page number (first page)\n * @property {number} start - Default start time (display immediately)\n * @property {number} end - Default end time (static display, no animation)\n */\nexport const BASE_DEFAULTS = {\n page: 1,\n start: 0,\n end: 0\n};\n\n/**\n * Default values for highlight annotations\n *\n * Creates a visible yellow highlight near the top of the page.\n *\n * @constant {Object}\n * @property {string} mode - Highlight mode (only 'quads' supported)\n * @property {Array<Object>} quads - Default rectangular regions\n * @property {Object} style - Default styling\n */\nexport const HIGHLIGHT_DEFAULTS = {\n mode: 'quads',\n quads: [{ x: 0.1, y: 0.1, w: 0.8, h: 0.05 }],\n style: { color: 'rgba(255, 255, 0, 0.3)' }\n};\n\n/**\n * Default values for text annotations\n *\n * Creates a visible text box in the top-left with placeholder content.\n *\n * @constant {Object}\n * @property {string} content - Placeholder text\n * @property {number} x - Normalized x position (10% from left)\n * @property {number} y - Normalized y position (10% from top)\n * @property {number} w - Normalized width (30% of page width)\n * @property {number} h - Normalized height (10% of page height)\n * @property {Object} style - Default styling with white background and black text\n */\nexport const TEXT_DEFAULTS = {\n content: '[No content]',\n x: 0.1,\n y: 0.1,\n w: 0.3,\n h: 0.1,\n style: {\n bg: 'rgba(255, 255, 255, 0.9)',\n color: '#000000'\n }\n};\n\n/**\n * Default values for ink annotations\n *\n * Creates a visible diagonal line in dark gray.\n *\n * @constant {Object}\n * @property {Array<Object>} strokes - Default stroke with two points\n */\nexport const INK_DEFAULTS = {\n strokes: [{\n color: '#1f2937',\n size: 3,\n points: [\n { t: 0, x: 0.1, y: 0.1 },\n { t: 1, x: 0.2, y: 0.2 }\n ]\n }]\n};\n"],"names":["BASE_DEFAULTS","HIGHLIGHT_DEFAULTS","TEXT_DEFAULTS","INK_DEFAULTS"],"mappings":"AAiBY,MAACA,IAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AACP,GAYaC,IAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO,CAAC,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM;AAAA,EAC3C,OAAO,EAAE,OAAO,yBAAwB;AAC1C,GAeaC,IAAgB;AAAA,EAC3B,SAAS;AAAA,EACT,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,EACX;AACA,GAUaC,IAAe;AAAA,EAC1B,SAAS,CAAC;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,IAAG;AAAA,MACtB,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,IAAG;AAAA,IAC5B;AAAA,EACA,CAAG;AACH;"}
1
+ {"version":3,"file":"index15.js","sources":["../src/adapters/AnnotPdf.jsx"],"sourcesContent":["// ============================================================================\n// SECTION 1: IMPORTS\n// ============================================================================\n\nimport { useRef, useEffect, useCallback } from 'react';\nimport { AnnotationRenderer } from '../core/AnnotationRenderer.js';\n\n// ============================================================================\n// SECTION 2: JSDOC DOCUMENTATION\n// ============================================================================\n\n/**\n * AnnotPdf - Declarative React component for PDF annotation rendering\n *\n * A React wrapper around the AnnotationRenderer core engine that provides\n * a declarative, props-based API for rendering PDF documents with\n * timeline-synchronized annotations.\n *\n * Features:\n * - Automatic lifecycle management (initialization and cleanup)\n * - Declarative prop-to-method synchronization\n * - PDF rendering with pdf.js\n * - Timeline-synchronized annotation display\n * - Support for highlight, text, and ink annotations\n * - Page navigation and zoom control\n *\n * @component\n * @example\n * // Basic usage\n * <AnnotPdf\n * pdfUrl=\"/document.pdf\"\n * page={1}\n * scale={1.5}\n * annotations={[]}\n * currentTime={0}\n * />\n *\n * @example\n * // With audio synchronization\n * const [currentTime, setCurrentTime] = useState(0);\n *\n * <div>\n * <AnnotPdf\n * pdfUrl=\"/lecture.pdf\"\n * page={1}\n * scale={1.5}\n * annotations={annotations}\n * currentTime={currentTime}\n * onLoad={({ pageCount }) => console.log('Loaded:', pageCount)}\n * />\n * <audio\n * src=\"/lecture.mp3\"\n * onTimeUpdate={(e) => setCurrentTime(e.target.currentTime)}\n * controls\n * />\n * </div>\n *\n * @param {Object} props - Component props\n * @param {string} props.pdfUrl - PDF document URL (required)\n * @param {number} [props.page=1] - Current page number (1-indexed)\n * @param {number} [props.scale=1.5] - Zoom scale factor\n * @param {Array} [props.annotations=[]] - Array of annotation objects\n * @param {number} [props.currentTime=0] - Timeline position in seconds\n * @param {Function} [props.onLoad] - Callback when PDF loads: ({pageCount}) => void\n * @param {Function} [props.onError] - Callback on error: (error) => void\n * @param {Function} [props.onPageChange] - Callback when page changes: (page) => void\n * @param {string} [props.className] - CSS class for container div\n * @param {Object} [props.style] - Inline styles for container div\n * @param {Object} [props.canvasStyle] - Inline styles for canvas element\n * @returns {JSX.Element} PDF viewer component with annotation layers\n */\n\n// ============================================================================\n// SECTION 3: COMPONENT DEFINITION\n// ============================================================================\n\nfunction AnnotPdf({\n // Required props\n pdfUrl,\n\n // Optional props with defaults\n page = 1,\n scale = 1.5,\n annotations = [],\n currentTime = 0,\n\n // Callbacks\n onLoad,\n onError,\n onPageChange,\n\n // Styling\n className,\n style,\n canvasStyle\n}) {\n\n // ==========================================================================\n // SECTION 4: REFS INITIALIZATION\n // ==========================================================================\n\n /**\n * Reference to the canvas element for PDF rendering\n * @type {React.RefObject<HTMLCanvasElement>}\n */\n const canvasRef = useRef(null);\n\n /**\n * Reference to the layer container div for annotation layers\n * @type {React.RefObject<HTMLDivElement>}\n */\n const layerContainerRef = useRef(null);\n\n /**\n * Reference to the AnnotationRenderer engine instance\n * Stored in ref to avoid triggering re-renders\n * @type {React.RefObject<AnnotationRenderer|null>}\n */\n const engineRef = useRef(null);\n\n /**\n * Reference to the render operation queue\n * Ensures sequential execution of async canvas operations\n * Prevents PDF.js race condition: \"Cannot use the same canvas during multiple render() operations\"\n * @type {React.RefObject<Promise<void>>}\n */\n const renderQueue = useRef(Promise.resolve());\n\n // ==========================================================================\n // SECTION 4.5: RENDER QUEUE HELPER\n // ==========================================================================\n\n /**\n * Queue a render operation to execute sequentially\n *\n * This helper ensures that async canvas operations (loadPDF, setPage, setScale)\n * execute one at a time, preventing concurrent access to the PDF.js canvas.\n * Uses Promise chaining to maintain operation order.\n *\n * @param {Function} operation - Async function returning a Promise\n * @returns {void}\n */\n const queueOperation = useCallback((operation) => {\n renderQueue.current = renderQueue.current\n .then(operation)\n .catch(error => {\n // Log errors but don't break the queue\n console.error('AnnotPdf: Queued operation failed:', error);\n });\n }, []);\n\n // ==========================================================================\n // SECTION 5: ENGINE INITIALIZATION AND CLEANUP\n // ==========================================================================\n\n /**\n * Initialize AnnotationRenderer on component mount\n * Cleanup on component unmount\n */\n useEffect(() => {\n // Guard: Wait for DOM elements to be ready\n if (!canvasRef.current || !layerContainerRef.current) {\n return;\n }\n\n // Initialize engine\n try {\n engineRef.current = new AnnotationRenderer({\n canvasElement: canvasRef.current,\n container: layerContainerRef.current\n });\n } catch (error) {\n console.error('AnnotPdf: Failed to initialize renderer:', error);\n if (onError) {\n onError(error);\n }\n }\n\n // Cleanup on unmount\n return () => {\n if (engineRef.current) {\n engineRef.current.destroy();\n engineRef.current = null;\n }\n };\n }, []); // Empty deps - run once on mount\n\n // ==========================================================================\n // SECTION 6: PDF LOADING SYNCHRONIZATION\n // ==========================================================================\n\n /**\n * Load PDF document when pdfUrl prop changes\n * Handles async operation with cancellation support\n * Uses render queue to prevent concurrent canvas operations\n */\n useEffect(() => {\n // Guard: Engine must exist and pdfUrl must be valid\n if (!engineRef.current || !pdfUrl) {\n return;\n }\n\n let cancelled = false;\n\n const loadPdf = async () => {\n try {\n const result = await engineRef.current.loadPDF(pdfUrl);\n\n // Check if component unmounted during async operation\n if (cancelled) return;\n\n // Check if load was successful\n if (!result.success) {\n console.error('AnnotPdf: Failed to load PDF:', result.error);\n if (onError) {\n onError(new Error(result.error));\n }\n return;\n }\n\n // Call onLoad callback with pageCount from result\n if (onLoad) {\n onLoad({ pageCount: result.pageCount });\n }\n } catch (error) {\n if (cancelled) return;\n\n console.error('AnnotPdf: Failed to load PDF:', error);\n if (onError) {\n onError(error);\n }\n }\n };\n\n // Queue the PDF loading operation to prevent race conditions\n queueOperation(loadPdf);\n\n // Cleanup: Prevent state updates if component unmounts during load\n return () => {\n cancelled = true;\n };\n }, [pdfUrl, queueOperation]);\n\n // ==========================================================================\n // SECTION 7: PAGE SYNCHRONIZATION\n // ==========================================================================\n\n /**\n * Sync page prop to engine.setPage() method\n * Uses render queue to prevent concurrent canvas operations\n */\n useEffect(() => {\n // Guard: Engine must exist and page must be valid\n if (!engineRef.current || !page || typeof page !== 'number') {\n return;\n }\n\n // Queue the page change operation to prevent race conditions\n queueOperation(async () => {\n try {\n const result = await engineRef.current.setPage(page);\n\n // Check if page change was successful\n if (!result.success) {\n console.error('AnnotPdf: Failed to set page:', result.error);\n if (onError) {\n onError(new Error(result.error));\n }\n return;\n }\n\n // Optional: Notify parent of successful page change\n if (onPageChange) {\n onPageChange(page);\n }\n } catch (error) {\n console.error('AnnotPdf: Failed to set page:', error);\n if (onError) {\n onError(error);\n }\n }\n });\n }, [page, queueOperation]);\n\n // ==========================================================================\n // SECTION 8: SCALE SYNCHRONIZATION\n // ==========================================================================\n\n /**\n * Sync scale prop to engine.setScale() method\n * Uses render queue to prevent concurrent canvas operations\n */\n useEffect(() => {\n // Guard: Engine must exist and scale must be valid\n if (!engineRef.current || !scale || typeof scale !== 'number') {\n return;\n }\n\n // Queue the scale change operation to prevent race conditions\n queueOperation(async () => {\n try {\n const result = await engineRef.current.setScale(scale);\n\n // Check if scale change was successful\n if (!result.success) {\n console.error('AnnotPdf: Failed to set scale:', result.error);\n if (onError) {\n onError(new Error(result.error));\n }\n }\n } catch (error) {\n console.error('AnnotPdf: Failed to set scale:', error);\n if (onError) {\n onError(error);\n }\n }\n });\n }, [scale, queueOperation]);\n\n // ==========================================================================\n // SECTION 9: ANNOTATIONS SYNCHRONIZATION\n // ==========================================================================\n\n /**\n * Sync annotations prop to engine.setAnnotations() method\n */\n useEffect(() => {\n // Guard: Engine must exist\n if (!engineRef.current) {\n return;\n }\n\n // Sync annotations to engine (default to empty array)\n try {\n engineRef.current.setAnnotations(annotations || []);\n } catch (error) {\n console.error('AnnotPdf: Failed to set annotations:', error);\n if (onError) {\n onError(error);\n }\n }\n }, [annotations]);\n\n // ==========================================================================\n // SECTION 10: TIMELINE SYNCHRONIZATION\n // ==========================================================================\n\n /**\n * Sync currentTime prop to engine.setTime() method\n */\n useEffect(() => {\n // Guard: Engine must exist and currentTime must be defined\n if (!engineRef.current || currentTime === undefined || currentTime === null) {\n return;\n }\n\n // Sync timeline to engine\n try {\n engineRef.current.setTime(currentTime);\n } catch (error) {\n console.error('AnnotPdf: Failed to set time:', error);\n if (onError) {\n onError(error);\n }\n }\n }, [currentTime]);\n\n // ==========================================================================\n // SECTION 11: STYLING DEFINITIONS\n // ==========================================================================\n\n /**\n * Default container styles\n * Merged with user-provided styles (user styles override defaults)\n */\n const defaultContainerStyle = {\n position: 'relative',\n display: 'inline-block',\n lineHeight: 0, // Remove extra space below canvas\n ...style // User styles override defaults\n };\n\n /**\n * Default layer container styles\n * Positions layer div absolutely over canvas\n */\n const defaultLayerStyle = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none', // Allow clicks to pass through to canvas\n overflow: 'hidden'\n };\n\n /**\n * Default canvas styles\n * Merged with user-provided canvasStyle\n */\n const defaultCanvasStyle = {\n display: 'block',\n ...canvasStyle // User styles override defaults\n };\n\n // ==========================================================================\n // SECTION 12: JSX RETURN\n // ==========================================================================\n\n return (\n <div className={className} style={defaultContainerStyle}>\n <canvas ref={canvasRef} style={defaultCanvasStyle} />\n <div ref={layerContainerRef} style={defaultLayerStyle} />\n </div>\n );\n}\n\n// ============================================================================\n// SECTION 13: EXPORT\n// ============================================================================\n\nexport default AnnotPdf;\n"],"names":["AnnotPdf","pdfUrl","page","scale","annotations","currentTime","onLoad","onError","onPageChange","className","style","canvasStyle","canvasRef","useRef","layerContainerRef","engineRef","renderQueue","queueOperation","useCallback","operation","error","useEffect","AnnotationRenderer","cancelled","result","defaultContainerStyle","defaultLayerStyle","defaultCanvasStyle","jsxs","jsx"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=[{type:"function",function:{name:"create_highlight_annotation",description:"Create a highlight annotation at specified coordinates on the PDF page. Use this to emphasize important text or regions. Highlights are rectangular regions that can span multiple lines.",parameters:{type:"object",properties:{quads:{type:"array",description:"Array of rectangular regions defining the highlight areas. Each quad is an object with normalized coordinates (0-1): {x, y, w, h}. Multiple quads can be used for multi-line highlights.",items:{type:"object",properties:{x:{type:"number",description:"Normalized x position (0 = left, 1 = right)",minimum:0,maximum:1},y:{type:"number",description:"Normalized y position (0 = top, 1 = bottom)",minimum:0,maximum:1},w:{type:"number",description:"Normalized width (0-1)",minimum:0,maximum:1},h:{type:"number",description:"Normalized height (0-1)",minimum:0,maximum:1}},required:["x","y","w","h"]},minItems:1},color:{type:"string",description:"Highlight color in rgba format (e.g., 'rgba(255, 255, 0, 0.3)'). Default is semi-transparent yellow. Use rgba for transparency control.",default:"rgba(255, 255, 0, 0.3)"},page:{type:"integer",description:"Page number (1-indexed) where the annotation appears",minimum:1},sentence_ref:{type:"string",description:"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",pattern:"^S\\d+$"}},required:["quads","page","sentence_ref"]}}},{type:"function",function:{name:"create_text_annotation",description:"Create a text box annotation with explanatory content. Use this to add clarifying notes, definitions, or explanations. Text boxes have background and appear as overlays.",parameters:{type:"object",properties:{content:{type:"string",description:"The text content of the annotation",minLength:1,maxLength:500},x:{type:"number",description:"Normalized x position (0 = left edge, 1 = right edge)",minimum:0,maximum:1},y:{type:"number",description:"Normalized y position (0 = top edge, 1 = bottom edge)",minimum:0,maximum:1},w:{type:"number",description:"Normalized width (0-1) of the text box",minimum:0,maximum:1},h:{type:"number",description:"Normalized height (0-1) of the text box",minimum:0,maximum:1},page:{type:"integer",description:"Page number (1-indexed) where the annotation appears",minimum:1},textColor:{type:"string",description:"Text color in hex format (e.g., '#000000' for black). Default is dark gray.",default:"#1f2937"},bgColor:{type:"string",description:"Background color in rgba format (e.g., 'rgba(255, 255, 255, 0.9)'). Default is semi-transparent white.",default:"rgba(255, 255, 255, 0.9)"},sentence_ref:{type:"string",description:"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",pattern:"^S\\d+$"}},required:["content","x","y","w","h","page","sentence_ref"]}}},{type:"function",function:{name:"create_ink_annotation",description:"Create a freehand drawing annotation with custom strokes. Use this to draw arrows, circles, underlines, or other visual markers. Each stroke can have its own color and width.",parameters:{type:"object",properties:{strokes:{type:"array",description:"Array of stroke objects. Each stroke defines a path with points that have time offsets for progressive drawing animation.",items:{type:"object",properties:{color:{type:"string",description:"Stroke color in hex format (e.g., '#FF0000' for red)",default:"#1f2937"},size:{type:"number",description:"Stroke width in pixels",minimum:1,maximum:10,default:3},points:{type:"array",description:"Array of points defining the stroke path. Each point has normalized coordinates (x, y) and a time offset (t) from 0 to stroke duration for progressive animation.",items:{type:"object",properties:{t:{type:"number",description:"Time offset in seconds from annotation start. Points are drawn progressively based on this value.",minimum:0},x:{type:"number",description:"Normalized x position (0-1)",minimum:0,maximum:1},y:{type:"number",description:"Normalized y position (0-1)",minimum:0,maximum:1}},required:["t","x","y"]},minItems:2}},required:["points"]},minItems:1},page:{type:"integer",description:"Page number (1-indexed) where the annotation appears",minimum:1},sentence_ref:{type:"string",description:"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",pattern:"^S\\d+$"}},required:["strokes","page","sentence_ref"]}}}];function o(e=[]){if(!Array.isArray(e)||e.length===0)return[];const n={highlight:"create_highlight_annotation",text:"create_text_annotation",ink:"create_ink_annotation"},r=e.map(t=>n[t]).filter(Boolean);return i.filter(t=>r.includes(t.function.name))}exports.annotationTools=i;exports.getAnnotationTools=o;
2
+ //# sourceMappingURL=index16.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index16.cjs","sources":["../src/ai-tools/openai/schemas.js"],"sourcesContent":["/**\n * OpenAI Tool Schemas for PDF Annotation Generation\n *\n * Provides OpenAI-compatible function calling schemas for creating PDF annotations.\n * These schemas define the structure and parameters for AI-generated annotations.\n * Compatible with web-annotation-renderer library format.\n *\n * @module ai-tools/openai/schemas\n */\n\n/**\n * Complete set of annotation tools for OpenAI function calling\n *\n * Export this array to the OpenAI API's `tools` parameter to enable\n * AI-generated annotations.\n *\n * @constant {Array<Object>}\n * @example\n * ```javascript\n * import { annotationTools } from 'web-annotation-renderer/ai-tools';\n *\n * const response = await openai.chat.completions.create({\n * model: \"gpt-4\",\n * messages: [...],\n * tools: annotationTools\n * });\n * ```\n */\nexport const annotationTools = [\n {\n type: \"function\",\n function: {\n name: \"create_highlight_annotation\",\n description: \"Create a highlight annotation at specified coordinates on the PDF page. Use this to emphasize important text or regions. Highlights are rectangular regions that can span multiple lines.\",\n parameters: {\n type: \"object\",\n properties: {\n quads: {\n type: \"array\",\n description: \"Array of rectangular regions defining the highlight areas. Each quad is an object with normalized coordinates (0-1): {x, y, w, h}. Multiple quads can be used for multi-line highlights.\",\n items: {\n type: \"object\",\n properties: {\n x: {\n type: \"number\",\n description: \"Normalized x position (0 = left, 1 = right)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0 = top, 1 = bottom)\",\n minimum: 0,\n maximum: 1\n },\n w: {\n type: \"number\",\n description: \"Normalized width (0-1)\",\n minimum: 0,\n maximum: 1\n },\n h: {\n type: \"number\",\n description: \"Normalized height (0-1)\",\n minimum: 0,\n maximum: 1\n }\n },\n required: [\"x\", \"y\", \"w\", \"h\"]\n },\n minItems: 1\n },\n color: {\n type: \"string\",\n description: \"Highlight color in rgba format (e.g., 'rgba(255, 255, 0, 0.3)'). Default is semi-transparent yellow. Use rgba for transparency control.\",\n default: \"rgba(255, 255, 0, 0.3)\"\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"quads\", \"page\", \"sentence_ref\"]\n }\n }\n },\n {\n type: \"function\",\n function: {\n name: \"create_text_annotation\",\n description: \"Create a text box annotation with explanatory content. Use this to add clarifying notes, definitions, or explanations. Text boxes have background and appear as overlays.\",\n parameters: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description: \"The text content of the annotation\",\n minLength: 1,\n maxLength: 500\n },\n x: {\n type: \"number\",\n description: \"Normalized x position (0 = left edge, 1 = right edge)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0 = top edge, 1 = bottom edge)\",\n minimum: 0,\n maximum: 1\n },\n w: {\n type: \"number\",\n description: \"Normalized width (0-1) of the text box\",\n minimum: 0,\n maximum: 1\n },\n h: {\n type: \"number\",\n description: \"Normalized height (0-1) of the text box\",\n minimum: 0,\n maximum: 1\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n textColor: {\n type: \"string\",\n description: \"Text color in hex format (e.g., '#000000' for black). Default is dark gray.\",\n default: \"#1f2937\"\n },\n bgColor: {\n type: \"string\",\n description: \"Background color in rgba format (e.g., 'rgba(255, 255, 255, 0.9)'). Default is semi-transparent white.\",\n default: \"rgba(255, 255, 255, 0.9)\"\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"content\", \"x\", \"y\", \"w\", \"h\", \"page\", \"sentence_ref\"]\n }\n }\n },\n {\n type: \"function\",\n function: {\n name: \"create_ink_annotation\",\n description: \"Create a freehand drawing annotation with custom strokes. Use this to draw arrows, circles, underlines, or other visual markers. Each stroke can have its own color and width.\",\n parameters: {\n type: \"object\",\n properties: {\n strokes: {\n type: \"array\",\n description: \"Array of stroke objects. Each stroke defines a path with points that have time offsets for progressive drawing animation.\",\n items: {\n type: \"object\",\n properties: {\n color: {\n type: \"string\",\n description: \"Stroke color in hex format (e.g., '#FF0000' for red)\",\n default: \"#1f2937\"\n },\n size: {\n type: \"number\",\n description: \"Stroke width in pixels\",\n minimum: 1,\n maximum: 10,\n default: 3\n },\n points: {\n type: \"array\",\n description: \"Array of points defining the stroke path. Each point has normalized coordinates (x, y) and a time offset (t) from 0 to stroke duration for progressive animation.\",\n items: {\n type: \"object\",\n properties: {\n t: {\n type: \"number\",\n description: \"Time offset in seconds from annotation start. Points are drawn progressively based on this value.\",\n minimum: 0\n },\n x: {\n type: \"number\",\n description: \"Normalized x position (0-1)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0-1)\",\n minimum: 0,\n maximum: 1\n }\n },\n required: [\"t\", \"x\", \"y\"]\n },\n minItems: 2\n }\n },\n required: [\"points\"]\n },\n minItems: 1\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"strokes\", \"page\", \"sentence_ref\"]\n }\n }\n }\n];\n\n/**\n * Get filtered annotation tools based on enabled types\n *\n * @param {Array<string>} enabledTypes - Array of enabled tool types: ['highlight', 'text', 'ink']\n * @returns {Array<Object>} Filtered annotation tools\n * @example\n * ```javascript\n * // Only enable highlights and text notes\n * const tools = getAnnotationTools(['highlight', 'text']);\n * ```\n */\nexport function getAnnotationTools(enabledTypes = []) {\n if (!Array.isArray(enabledTypes) || enabledTypes.length === 0) {\n return [];\n }\n\n const typeMap = {\n 'highlight': 'create_highlight_annotation',\n 'text': 'create_text_annotation',\n 'ink': 'create_ink_annotation'\n };\n\n const enabledFunctionNames = enabledTypes\n .map(type => typeMap[type])\n .filter(Boolean);\n\n return annotationTools.filter(tool =>\n enabledFunctionNames.includes(tool.function.name)\n );\n}\n"],"names":["annotationTools","getAnnotationTools","enabledTypes","typeMap","enabledFunctionNames","type","tool"],"mappings":"gFA4BY,MAACA,EAAkB,CAC7B,CACE,KAAM,WACN,SAAU,CACR,KAAM,8BACN,YAAa,4LACb,WAAY,CACV,KAAM,SACN,WAAY,CACV,MAAO,CACL,KAAM,QACN,YAAa,2LACb,MAAO,CACL,KAAM,SACN,WAAY,CACV,EAAG,CACD,KAAM,SACN,YAAa,8CACb,QAAS,EACT,QAAS,CAC3B,EACgB,EAAG,CACD,KAAM,SACN,YAAa,8CACb,QAAS,EACT,QAAS,CAC3B,EACgB,EAAG,CACD,KAAM,SACN,YAAa,yBACb,QAAS,EACT,QAAS,CAC3B,EACgB,EAAG,CACD,KAAM,SACN,YAAa,0BACb,QAAS,EACT,QAAS,CAC3B,CACA,EACc,SAAU,CAAC,IAAK,IAAK,IAAK,GAAG,CAC3C,EACY,SAAU,CACtB,EACU,MAAO,CACL,KAAM,SACN,YAAa,0IACb,QAAS,wBACrB,EACU,KAAM,CACJ,KAAM,UACN,YAAa,uDACb,QAAS,CACrB,EACU,aAAc,CACZ,KAAM,SACN,YAAa,6EACb,QAAS,SACrB,CACA,EACQ,SAAU,CAAC,QAAS,OAAQ,cAAc,CAClD,CACA,CACA,EACE,CACE,KAAM,WACN,SAAU,CACR,KAAM,yBACN,YAAa,4KACb,WAAY,CACV,KAAM,SACN,WAAY,CACV,QAAS,CACP,KAAM,SACN,YAAa,qCACb,UAAW,EACX,UAAW,GACvB,EACU,EAAG,CACD,KAAM,SACN,YAAa,wDACb,QAAS,EACT,QAAS,CACrB,EACU,EAAG,CACD,KAAM,SACN,YAAa,wDACb,QAAS,EACT,QAAS,CACrB,EACU,EAAG,CACD,KAAM,SACN,YAAa,yCACb,QAAS,EACT,QAAS,CACrB,EACU,EAAG,CACD,KAAM,SACN,YAAa,0CACb,QAAS,EACT,QAAS,CACrB,EACU,KAAM,CACJ,KAAM,UACN,YAAa,uDACb,QAAS,CACrB,EACU,UAAW,CACT,KAAM,SACN,YAAa,8EACb,QAAS,SACrB,EACU,QAAS,CACP,KAAM,SACN,YAAa,yGACb,QAAS,0BACrB,EACU,aAAc,CACZ,KAAM,SACN,YAAa,6EACb,QAAS,SACrB,CACA,EACQ,SAAU,CAAC,UAAW,IAAK,IAAK,IAAK,IAAK,OAAQ,cAAc,CACxE,CACA,CACA,EACE,CACE,KAAM,WACN,SAAU,CACR,KAAM,wBACN,YAAa,iLACb,WAAY,CACV,KAAM,SACN,WAAY,CACV,QAAS,CACP,KAAM,QACN,YAAa,4HACb,MAAO,CACL,KAAM,SACN,WAAY,CACV,MAAO,CACL,KAAM,SACN,YAAa,uDACb,QAAS,SAC3B,EACgB,KAAM,CACJ,KAAM,SACN,YAAa,yBACb,QAAS,EACT,QAAS,GACT,QAAS,CAC3B,EACgB,OAAQ,CACN,KAAM,QACN,YAAa,oKACb,MAAO,CACL,KAAM,SACN,WAAY,CACV,EAAG,CACD,KAAM,SACN,YAAa,oGACb,QAAS,CACjC,EACsB,EAAG,CACD,KAAM,SACN,YAAa,8BACb,QAAS,EACT,QAAS,CACjC,EACsB,EAAG,CACD,KAAM,SACN,YAAa,8BACb,QAAS,EACT,QAAS,CACjC,CACA,EACoB,SAAU,CAAC,IAAK,IAAK,GAAG,CAC5C,EACkB,SAAU,CAC5B,CACA,EACc,SAAU,CAAC,QAAQ,CACjC,EACY,SAAU,CACtB,EACU,KAAM,CACJ,KAAM,UACN,YAAa,uDACb,QAAS,CACrB,EACU,aAAc,CACZ,KAAM,SACN,YAAa,6EACb,QAAS,SACrB,CACA,EACQ,SAAU,CAAC,UAAW,OAAQ,cAAc,CACpD,CACA,CACA,CACA,EAaO,SAASC,EAAmBC,EAAe,GAAI,CACpD,GAAI,CAAC,MAAM,QAAQA,CAAY,GAAKA,EAAa,SAAW,EAC1D,MAAO,CAAA,EAGT,MAAMC,EAAU,CACd,UAAa,8BACb,KAAQ,yBACR,IAAO,uBACX,EAEQC,EAAuBF,EAC1B,IAAIG,GAAQF,EAAQE,CAAI,CAAC,EACzB,OAAO,OAAO,EAEjB,OAAOL,EAAgB,OAAOM,GAC5BF,EAAqB,SAASE,EAAK,SAAS,IAAI,CACpD,CACA"}
@@ -0,0 +1,219 @@
1
+ const r = [
2
+ {
3
+ type: "function",
4
+ function: {
5
+ name: "create_highlight_annotation",
6
+ description: "Create a highlight annotation at specified coordinates on the PDF page. Use this to emphasize important text or regions. Highlights are rectangular regions that can span multiple lines.",
7
+ parameters: {
8
+ type: "object",
9
+ properties: {
10
+ quads: {
11
+ type: "array",
12
+ description: "Array of rectangular regions defining the highlight areas. Each quad is an object with normalized coordinates (0-1): {x, y, w, h}. Multiple quads can be used for multi-line highlights.",
13
+ items: {
14
+ type: "object",
15
+ properties: {
16
+ x: {
17
+ type: "number",
18
+ description: "Normalized x position (0 = left, 1 = right)",
19
+ minimum: 0,
20
+ maximum: 1
21
+ },
22
+ y: {
23
+ type: "number",
24
+ description: "Normalized y position (0 = top, 1 = bottom)",
25
+ minimum: 0,
26
+ maximum: 1
27
+ },
28
+ w: {
29
+ type: "number",
30
+ description: "Normalized width (0-1)",
31
+ minimum: 0,
32
+ maximum: 1
33
+ },
34
+ h: {
35
+ type: "number",
36
+ description: "Normalized height (0-1)",
37
+ minimum: 0,
38
+ maximum: 1
39
+ }
40
+ },
41
+ required: ["x", "y", "w", "h"]
42
+ },
43
+ minItems: 1
44
+ },
45
+ color: {
46
+ type: "string",
47
+ description: "Highlight color in rgba format (e.g., 'rgba(255, 255, 0, 0.3)'). Default is semi-transparent yellow. Use rgba for transparency control.",
48
+ default: "rgba(255, 255, 0, 0.3)"
49
+ },
50
+ page: {
51
+ type: "integer",
52
+ description: "Page number (1-indexed) where the annotation appears",
53
+ minimum: 1
54
+ },
55
+ sentence_ref: {
56
+ type: "string",
57
+ description: "Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",
58
+ pattern: "^S\\d+$"
59
+ }
60
+ },
61
+ required: ["quads", "page", "sentence_ref"]
62
+ }
63
+ }
64
+ },
65
+ {
66
+ type: "function",
67
+ function: {
68
+ name: "create_text_annotation",
69
+ description: "Create a text box annotation with explanatory content. Use this to add clarifying notes, definitions, or explanations. Text boxes have background and appear as overlays.",
70
+ parameters: {
71
+ type: "object",
72
+ properties: {
73
+ content: {
74
+ type: "string",
75
+ description: "The text content of the annotation",
76
+ minLength: 1,
77
+ maxLength: 500
78
+ },
79
+ x: {
80
+ type: "number",
81
+ description: "Normalized x position (0 = left edge, 1 = right edge)",
82
+ minimum: 0,
83
+ maximum: 1
84
+ },
85
+ y: {
86
+ type: "number",
87
+ description: "Normalized y position (0 = top edge, 1 = bottom edge)",
88
+ minimum: 0,
89
+ maximum: 1
90
+ },
91
+ w: {
92
+ type: "number",
93
+ description: "Normalized width (0-1) of the text box",
94
+ minimum: 0,
95
+ maximum: 1
96
+ },
97
+ h: {
98
+ type: "number",
99
+ description: "Normalized height (0-1) of the text box",
100
+ minimum: 0,
101
+ maximum: 1
102
+ },
103
+ page: {
104
+ type: "integer",
105
+ description: "Page number (1-indexed) where the annotation appears",
106
+ minimum: 1
107
+ },
108
+ textColor: {
109
+ type: "string",
110
+ description: "Text color in hex format (e.g., '#000000' for black). Default is dark gray.",
111
+ default: "#1f2937"
112
+ },
113
+ bgColor: {
114
+ type: "string",
115
+ description: "Background color in rgba format (e.g., 'rgba(255, 255, 255, 0.9)'). Default is semi-transparent white.",
116
+ default: "rgba(255, 255, 255, 0.9)"
117
+ },
118
+ sentence_ref: {
119
+ type: "string",
120
+ description: "Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",
121
+ pattern: "^S\\d+$"
122
+ }
123
+ },
124
+ required: ["content", "x", "y", "w", "h", "page", "sentence_ref"]
125
+ }
126
+ }
127
+ },
128
+ {
129
+ type: "function",
130
+ function: {
131
+ name: "create_ink_annotation",
132
+ description: "Create a freehand drawing annotation with custom strokes. Use this to draw arrows, circles, underlines, or other visual markers. Each stroke can have its own color and width.",
133
+ parameters: {
134
+ type: "object",
135
+ properties: {
136
+ strokes: {
137
+ type: "array",
138
+ description: "Array of stroke objects. Each stroke defines a path with points that have time offsets for progressive drawing animation.",
139
+ items: {
140
+ type: "object",
141
+ properties: {
142
+ color: {
143
+ type: "string",
144
+ description: "Stroke color in hex format (e.g., '#FF0000' for red)",
145
+ default: "#1f2937"
146
+ },
147
+ size: {
148
+ type: "number",
149
+ description: "Stroke width in pixels",
150
+ minimum: 1,
151
+ maximum: 10,
152
+ default: 3
153
+ },
154
+ points: {
155
+ type: "array",
156
+ description: "Array of points defining the stroke path. Each point has normalized coordinates (x, y) and a time offset (t) from 0 to stroke duration for progressive animation.",
157
+ items: {
158
+ type: "object",
159
+ properties: {
160
+ t: {
161
+ type: "number",
162
+ description: "Time offset in seconds from annotation start. Points are drawn progressively based on this value.",
163
+ minimum: 0
164
+ },
165
+ x: {
166
+ type: "number",
167
+ description: "Normalized x position (0-1)",
168
+ minimum: 0,
169
+ maximum: 1
170
+ },
171
+ y: {
172
+ type: "number",
173
+ description: "Normalized y position (0-1)",
174
+ minimum: 0,
175
+ maximum: 1
176
+ }
177
+ },
178
+ required: ["t", "x", "y"]
179
+ },
180
+ minItems: 2
181
+ }
182
+ },
183
+ required: ["points"]
184
+ },
185
+ minItems: 1
186
+ },
187
+ page: {
188
+ type: "integer",
189
+ description: "Page number (1-indexed) where the annotation appears",
190
+ minimum: 1
191
+ },
192
+ sentence_ref: {
193
+ type: "string",
194
+ description: "Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization",
195
+ pattern: "^S\\d+$"
196
+ }
197
+ },
198
+ required: ["strokes", "page", "sentence_ref"]
199
+ }
200
+ }
201
+ }
202
+ ];
203
+ function o(e = []) {
204
+ if (!Array.isArray(e) || e.length === 0)
205
+ return [];
206
+ const i = {
207
+ highlight: "create_highlight_annotation",
208
+ text: "create_text_annotation",
209
+ ink: "create_ink_annotation"
210
+ }, n = e.map((t) => i[t]).filter(Boolean);
211
+ return r.filter(
212
+ (t) => n.includes(t.function.name)
213
+ );
214
+ }
215
+ export {
216
+ r as annotationTools,
217
+ o as getAnnotationTools
218
+ };
219
+ //# sourceMappingURL=index16.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index16.js","sources":["../src/ai-tools/openai/schemas.js"],"sourcesContent":["/**\n * OpenAI Tool Schemas for PDF Annotation Generation\n *\n * Provides OpenAI-compatible function calling schemas for creating PDF annotations.\n * These schemas define the structure and parameters for AI-generated annotations.\n * Compatible with web-annotation-renderer library format.\n *\n * @module ai-tools/openai/schemas\n */\n\n/**\n * Complete set of annotation tools for OpenAI function calling\n *\n * Export this array to the OpenAI API's `tools` parameter to enable\n * AI-generated annotations.\n *\n * @constant {Array<Object>}\n * @example\n * ```javascript\n * import { annotationTools } from 'web-annotation-renderer/ai-tools';\n *\n * const response = await openai.chat.completions.create({\n * model: \"gpt-4\",\n * messages: [...],\n * tools: annotationTools\n * });\n * ```\n */\nexport const annotationTools = [\n {\n type: \"function\",\n function: {\n name: \"create_highlight_annotation\",\n description: \"Create a highlight annotation at specified coordinates on the PDF page. Use this to emphasize important text or regions. Highlights are rectangular regions that can span multiple lines.\",\n parameters: {\n type: \"object\",\n properties: {\n quads: {\n type: \"array\",\n description: \"Array of rectangular regions defining the highlight areas. Each quad is an object with normalized coordinates (0-1): {x, y, w, h}. Multiple quads can be used for multi-line highlights.\",\n items: {\n type: \"object\",\n properties: {\n x: {\n type: \"number\",\n description: \"Normalized x position (0 = left, 1 = right)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0 = top, 1 = bottom)\",\n minimum: 0,\n maximum: 1\n },\n w: {\n type: \"number\",\n description: \"Normalized width (0-1)\",\n minimum: 0,\n maximum: 1\n },\n h: {\n type: \"number\",\n description: \"Normalized height (0-1)\",\n minimum: 0,\n maximum: 1\n }\n },\n required: [\"x\", \"y\", \"w\", \"h\"]\n },\n minItems: 1\n },\n color: {\n type: \"string\",\n description: \"Highlight color in rgba format (e.g., 'rgba(255, 255, 0, 0.3)'). Default is semi-transparent yellow. Use rgba for transparency control.\",\n default: \"rgba(255, 255, 0, 0.3)\"\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"quads\", \"page\", \"sentence_ref\"]\n }\n }\n },\n {\n type: \"function\",\n function: {\n name: \"create_text_annotation\",\n description: \"Create a text box annotation with explanatory content. Use this to add clarifying notes, definitions, or explanations. Text boxes have background and appear as overlays.\",\n parameters: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description: \"The text content of the annotation\",\n minLength: 1,\n maxLength: 500\n },\n x: {\n type: \"number\",\n description: \"Normalized x position (0 = left edge, 1 = right edge)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0 = top edge, 1 = bottom edge)\",\n minimum: 0,\n maximum: 1\n },\n w: {\n type: \"number\",\n description: \"Normalized width (0-1) of the text box\",\n minimum: 0,\n maximum: 1\n },\n h: {\n type: \"number\",\n description: \"Normalized height (0-1) of the text box\",\n minimum: 0,\n maximum: 1\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n textColor: {\n type: \"string\",\n description: \"Text color in hex format (e.g., '#000000' for black). Default is dark gray.\",\n default: \"#1f2937\"\n },\n bgColor: {\n type: \"string\",\n description: \"Background color in rgba format (e.g., 'rgba(255, 255, 255, 0.9)'). Default is semi-transparent white.\",\n default: \"rgba(255, 255, 255, 0.9)\"\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"content\", \"x\", \"y\", \"w\", \"h\", \"page\", \"sentence_ref\"]\n }\n }\n },\n {\n type: \"function\",\n function: {\n name: \"create_ink_annotation\",\n description: \"Create a freehand drawing annotation with custom strokes. Use this to draw arrows, circles, underlines, or other visual markers. Each stroke can have its own color and width.\",\n parameters: {\n type: \"object\",\n properties: {\n strokes: {\n type: \"array\",\n description: \"Array of stroke objects. Each stroke defines a path with points that have time offsets for progressive drawing animation.\",\n items: {\n type: \"object\",\n properties: {\n color: {\n type: \"string\",\n description: \"Stroke color in hex format (e.g., '#FF0000' for red)\",\n default: \"#1f2937\"\n },\n size: {\n type: \"number\",\n description: \"Stroke width in pixels\",\n minimum: 1,\n maximum: 10,\n default: 3\n },\n points: {\n type: \"array\",\n description: \"Array of points defining the stroke path. Each point has normalized coordinates (x, y) and a time offset (t) from 0 to stroke duration for progressive animation.\",\n items: {\n type: \"object\",\n properties: {\n t: {\n type: \"number\",\n description: \"Time offset in seconds from annotation start. Points are drawn progressively based on this value.\",\n minimum: 0\n },\n x: {\n type: \"number\",\n description: \"Normalized x position (0-1)\",\n minimum: 0,\n maximum: 1\n },\n y: {\n type: \"number\",\n description: \"Normalized y position (0-1)\",\n minimum: 0,\n maximum: 1\n }\n },\n required: [\"t\", \"x\", \"y\"]\n },\n minItems: 2\n }\n },\n required: [\"points\"]\n },\n minItems: 1\n },\n page: {\n type: \"integer\",\n description: \"Page number (1-indexed) where the annotation appears\",\n minimum: 1\n },\n sentence_ref: {\n type: \"string\",\n description: \"Reference to sentence marker (e.g., 'S1', 'S2') for timing synchronization\",\n pattern: \"^S\\\\d+$\"\n }\n },\n required: [\"strokes\", \"page\", \"sentence_ref\"]\n }\n }\n }\n];\n\n/**\n * Get filtered annotation tools based on enabled types\n *\n * @param {Array<string>} enabledTypes - Array of enabled tool types: ['highlight', 'text', 'ink']\n * @returns {Array<Object>} Filtered annotation tools\n * @example\n * ```javascript\n * // Only enable highlights and text notes\n * const tools = getAnnotationTools(['highlight', 'text']);\n * ```\n */\nexport function getAnnotationTools(enabledTypes = []) {\n if (!Array.isArray(enabledTypes) || enabledTypes.length === 0) {\n return [];\n }\n\n const typeMap = {\n 'highlight': 'create_highlight_annotation',\n 'text': 'create_text_annotation',\n 'ink': 'create_ink_annotation'\n };\n\n const enabledFunctionNames = enabledTypes\n .map(type => typeMap[type])\n .filter(Boolean);\n\n return annotationTools.filter(tool =>\n enabledFunctionNames.includes(tool.function.name)\n );\n}\n"],"names":["annotationTools","getAnnotationTools","enabledTypes","typeMap","enabledFunctionNames","type","tool"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./index18.cjs"),c=require("./index19.cjs"),l=require("./index20.cjs");function o(r){if(!r||typeof r!="object")throw new Error("Invalid tool call: must be an object");if(!r.function||typeof r.function!="object")throw new Error("Invalid tool call: missing function property");const{name:t,arguments:n}=r.function;if(!t||typeof t!="string")throw new Error("Invalid tool call: missing or invalid function name");let e;try{e=typeof n=="string"?JSON.parse(n):n}catch(a){throw new Error(`Failed to parse tool call arguments: ${a.message}`)}switch(t){case"create_highlight_annotation":return i.createHighlight(e);case"create_text_annotation":return c.createText(e);case"create_ink_annotation":return l.createInk(e);default:throw new Error(`Unknown tool: ${t}. Supported tools: create_highlight_annotation, create_text_annotation, create_ink_annotation`)}}function s(r){if(!Array.isArray(r))throw new Error("Tool calls must be an array");return r.map((t,n)=>{try{return o(t)}catch(e){throw new Error(`Error processing tool call at index ${n}: ${e.message}`)}})}exports.handleToolCall=o;exports.handleToolCalls=s;
2
+ //# sourceMappingURL=index17.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index17.cjs","sources":["../src/ai-tools/openai/handler.js"],"sourcesContent":["/**\n * OpenAI Tool Call Handler\n *\n * Processes OpenAI function calling responses and converts them into\n * valid annotation objects.\n *\n * @module ai-tools/openai/handler\n */\n\nimport { createHighlight } from '../creators/createHighlight.js';\nimport { createText } from '../creators/createText.js';\nimport { createInk } from '../creators/createInk.js';\n\n/**\n * Handle an OpenAI tool call and convert it to a valid annotation\n *\n * @param {Object} toolCall - Tool call object from OpenAI API response\n * @param {Object} toolCall.function - Function call details\n * @param {string} toolCall.function.name - Function name\n * @param {string} toolCall.function.arguments - JSON string of arguments\n * @returns {Object} Valid annotation object\n * @throws {Error} If tool call is invalid or unsupported\n * @example\n * ```javascript\n * import { handleToolCall } from 'web-annotation-renderer/ai-tools';\n *\n * const response = await openai.chat.completions.create({\n * model: \"gpt-4\",\n * messages: [...],\n * tools: annotationTools\n * });\n *\n * const annotations = [];\n * if (response.choices[0].message.tool_calls) {\n * for (const toolCall of response.choices[0].message.tool_calls) {\n * const annotation = handleToolCall(toolCall);\n * annotations.push(annotation);\n * }\n * }\n * ```\n */\nexport function handleToolCall(toolCall) {\n // Validate tool call structure\n if (!toolCall || typeof toolCall !== 'object') {\n throw new Error('Invalid tool call: must be an object');\n }\n\n if (!toolCall.function || typeof toolCall.function !== 'object') {\n throw new Error('Invalid tool call: missing function property');\n }\n\n const { name, arguments: argsString } = toolCall.function;\n\n if (!name || typeof name !== 'string') {\n throw new Error('Invalid tool call: missing or invalid function name');\n }\n\n // Parse arguments\n let args;\n try {\n args = typeof argsString === 'string' ? JSON.parse(argsString) : argsString;\n } catch (error) {\n throw new Error(`Failed to parse tool call arguments: ${error.message}`);\n }\n\n // Route to appropriate creator function\n switch (name) {\n case 'create_highlight_annotation':\n return createHighlight(args);\n\n case 'create_text_annotation':\n return createText(args);\n\n case 'create_ink_annotation':\n return createInk(args);\n\n default:\n throw new Error(`Unknown tool: ${name}. Supported tools: create_highlight_annotation, create_text_annotation, create_ink_annotation`);\n }\n}\n\n/**\n * Process multiple tool calls from an OpenAI response\n *\n * @param {Array<Object>} toolCalls - Array of tool call objects from OpenAI\n * @returns {Array<Object>} Array of valid annotation objects\n * @example\n * ```javascript\n * const annotations = handleToolCalls(response.choices[0].message.tool_calls);\n * ```\n */\nexport function handleToolCalls(toolCalls) {\n if (!Array.isArray(toolCalls)) {\n throw new Error('Tool calls must be an array');\n }\n\n return toolCalls.map((toolCall, index) => {\n try {\n return handleToolCall(toolCall);\n } catch (error) {\n throw new Error(`Error processing tool call at index ${index}: ${error.message}`);\n }\n });\n}\n"],"names":["handleToolCall","toolCall","name","argsString","args","error","createHighlight","createText","createInk","handleToolCalls","toolCalls","index"],"mappings":"uKAyCO,SAASA,EAAeC,EAAU,CAEvC,GAAI,CAACA,GAAY,OAAOA,GAAa,SACnC,MAAM,IAAI,MAAM,sCAAsC,EAGxD,GAAI,CAACA,EAAS,UAAY,OAAOA,EAAS,UAAa,SACrD,MAAM,IAAI,MAAM,8CAA8C,EAGhE,KAAM,CAAE,KAAAC,EAAM,UAAWC,CAAU,EAAKF,EAAS,SAEjD,GAAI,CAACC,GAAQ,OAAOA,GAAS,SAC3B,MAAM,IAAI,MAAM,qDAAqD,EAIvE,IAAIE,EACJ,GAAI,CACFA,EAAO,OAAOD,GAAe,SAAW,KAAK,MAAMA,CAAU,EAAIA,CACnE,OAASE,EAAO,CACd,MAAM,IAAI,MAAM,wCAAwCA,EAAM,OAAO,EAAE,CACzE,CAGA,OAAQH,EAAI,CACV,IAAK,8BACH,OAAOI,EAAAA,gBAAgBF,CAAI,EAE7B,IAAK,yBACH,OAAOG,EAAAA,WAAWH,CAAI,EAExB,IAAK,wBACH,OAAOI,EAAAA,UAAUJ,CAAI,EAEvB,QACE,MAAM,IAAI,MAAM,iBAAiBF,CAAI,+FAA+F,CAC1I,CACA,CAYO,SAASO,EAAgBC,EAAW,CACzC,GAAI,CAAC,MAAM,QAAQA,CAAS,EAC1B,MAAM,IAAI,MAAM,6BAA6B,EAG/C,OAAOA,EAAU,IAAI,CAACT,EAAUU,IAAU,CACxC,GAAI,CACF,OAAOX,EAAeC,CAAQ,CAChC,OAASI,EAAO,CACd,MAAM,IAAI,MAAM,uCAAuCM,CAAK,KAAKN,EAAM,OAAO,EAAE,CAClF,CACF,CAAC,CACH"}
@@ -0,0 +1,44 @@
1
+ import { createHighlight as a } from "./index18.js";
2
+ import { createText as i } from "./index19.js";
3
+ import { createInk as c } from "./index20.js";
4
+ function s(r) {
5
+ if (!r || typeof r != "object")
6
+ throw new Error("Invalid tool call: must be an object");
7
+ if (!r.function || typeof r.function != "object")
8
+ throw new Error("Invalid tool call: missing function property");
9
+ const { name: t, arguments: e } = r.function;
10
+ if (!t || typeof t != "string")
11
+ throw new Error("Invalid tool call: missing or invalid function name");
12
+ let n;
13
+ try {
14
+ n = typeof e == "string" ? JSON.parse(e) : e;
15
+ } catch (o) {
16
+ throw new Error(`Failed to parse tool call arguments: ${o.message}`);
17
+ }
18
+ switch (t) {
19
+ case "create_highlight_annotation":
20
+ return a(n);
21
+ case "create_text_annotation":
22
+ return i(n);
23
+ case "create_ink_annotation":
24
+ return c(n);
25
+ default:
26
+ throw new Error(`Unknown tool: ${t}. Supported tools: create_highlight_annotation, create_text_annotation, create_ink_annotation`);
27
+ }
28
+ }
29
+ function g(r) {
30
+ if (!Array.isArray(r))
31
+ throw new Error("Tool calls must be an array");
32
+ return r.map((t, e) => {
33
+ try {
34
+ return s(t);
35
+ } catch (n) {
36
+ throw new Error(`Error processing tool call at index ${e}: ${n.message}`);
37
+ }
38
+ });
39
+ }
40
+ export {
41
+ s as handleToolCall,
42
+ g as handleToolCalls
43
+ };
44
+ //# sourceMappingURL=index17.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index17.js","sources":["../src/ai-tools/openai/handler.js"],"sourcesContent":["/**\n * OpenAI Tool Call Handler\n *\n * Processes OpenAI function calling responses and converts them into\n * valid annotation objects.\n *\n * @module ai-tools/openai/handler\n */\n\nimport { createHighlight } from '../creators/createHighlight.js';\nimport { createText } from '../creators/createText.js';\nimport { createInk } from '../creators/createInk.js';\n\n/**\n * Handle an OpenAI tool call and convert it to a valid annotation\n *\n * @param {Object} toolCall - Tool call object from OpenAI API response\n * @param {Object} toolCall.function - Function call details\n * @param {string} toolCall.function.name - Function name\n * @param {string} toolCall.function.arguments - JSON string of arguments\n * @returns {Object} Valid annotation object\n * @throws {Error} If tool call is invalid or unsupported\n * @example\n * ```javascript\n * import { handleToolCall } from 'web-annotation-renderer/ai-tools';\n *\n * const response = await openai.chat.completions.create({\n * model: \"gpt-4\",\n * messages: [...],\n * tools: annotationTools\n * });\n *\n * const annotations = [];\n * if (response.choices[0].message.tool_calls) {\n * for (const toolCall of response.choices[0].message.tool_calls) {\n * const annotation = handleToolCall(toolCall);\n * annotations.push(annotation);\n * }\n * }\n * ```\n */\nexport function handleToolCall(toolCall) {\n // Validate tool call structure\n if (!toolCall || typeof toolCall !== 'object') {\n throw new Error('Invalid tool call: must be an object');\n }\n\n if (!toolCall.function || typeof toolCall.function !== 'object') {\n throw new Error('Invalid tool call: missing function property');\n }\n\n const { name, arguments: argsString } = toolCall.function;\n\n if (!name || typeof name !== 'string') {\n throw new Error('Invalid tool call: missing or invalid function name');\n }\n\n // Parse arguments\n let args;\n try {\n args = typeof argsString === 'string' ? JSON.parse(argsString) : argsString;\n } catch (error) {\n throw new Error(`Failed to parse tool call arguments: ${error.message}`);\n }\n\n // Route to appropriate creator function\n switch (name) {\n case 'create_highlight_annotation':\n return createHighlight(args);\n\n case 'create_text_annotation':\n return createText(args);\n\n case 'create_ink_annotation':\n return createInk(args);\n\n default:\n throw new Error(`Unknown tool: ${name}. Supported tools: create_highlight_annotation, create_text_annotation, create_ink_annotation`);\n }\n}\n\n/**\n * Process multiple tool calls from an OpenAI response\n *\n * @param {Array<Object>} toolCalls - Array of tool call objects from OpenAI\n * @returns {Array<Object>} Array of valid annotation objects\n * @example\n * ```javascript\n * const annotations = handleToolCalls(response.choices[0].message.tool_calls);\n * ```\n */\nexport function handleToolCalls(toolCalls) {\n if (!Array.isArray(toolCalls)) {\n throw new Error('Tool calls must be an array');\n }\n\n return toolCalls.map((toolCall, index) => {\n try {\n return handleToolCall(toolCall);\n } catch (error) {\n throw new Error(`Error processing tool call at index ${index}: ${error.message}`);\n }\n });\n}\n"],"names":["handleToolCall","toolCall","name","argsString","args","error","createHighlight","createText","createInk","handleToolCalls","toolCalls","index"],"mappings":";;;AAyCO,SAASA,EAAeC,GAAU;AAEvC,MAAI,CAACA,KAAY,OAAOA,KAAa;AACnC,UAAM,IAAI,MAAM,sCAAsC;AAGxD,MAAI,CAACA,EAAS,YAAY,OAAOA,EAAS,YAAa;AACrD,UAAM,IAAI,MAAM,8CAA8C;AAGhE,QAAM,EAAE,MAAAC,GAAM,WAAWC,EAAU,IAAKF,EAAS;AAEjD,MAAI,CAACC,KAAQ,OAAOA,KAAS;AAC3B,UAAM,IAAI,MAAM,qDAAqD;AAIvE,MAAIE;AACJ,MAAI;AACF,IAAAA,IAAO,OAAOD,KAAe,WAAW,KAAK,MAAMA,CAAU,IAAIA;AAAA,EACnE,SAASE,GAAO;AACd,UAAM,IAAI,MAAM,wCAAwCA,EAAM,OAAO,EAAE;AAAA,EACzE;AAGA,UAAQH,GAAI;AAAA,IACV,KAAK;AACH,aAAOI,EAAgBF,CAAI;AAAA,IAE7B,KAAK;AACH,aAAOG,EAAWH,CAAI;AAAA,IAExB,KAAK;AACH,aAAOI,EAAUJ,CAAI;AAAA,IAEvB;AACE,YAAM,IAAI,MAAM,iBAAiBF,CAAI,+FAA+F;AAAA,EAC1I;AACA;AAYO,SAASO,EAAgBC,GAAW;AACzC,MAAI,CAAC,MAAM,QAAQA,CAAS;AAC1B,UAAM,IAAI,MAAM,6BAA6B;AAG/C,SAAOA,EAAU,IAAI,CAACT,GAAUU,MAAU;AACxC,QAAI;AACF,aAAOX,EAAeC,CAAQ;AAAA,IAChC,SAASI,GAAO;AACd,YAAM,IAAI,MAAM,uCAAuCM,CAAK,KAAKN,EAAM,OAAO,EAAE;AAAA,IAClF;AAAA,EACF,CAAC;AACH;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index22.cjs");function h(e){if(!e.quads||!Array.isArray(e.quads)||e.quads.length===0)throw new Error("Highlight annotation requires at least one quad");if(!e.page||typeof e.page!="number"||e.page<1)throw new Error("Highlight annotation requires a valid page number (>= 1)");if(!e.sentence_ref||typeof e.sentence_ref!="string")throw new Error("Highlight annotation requires a sentence_ref for timing");e.quads.forEach((r,o)=>{if(typeof r!="object"||r===null||Array.isArray(r))throw new Error(`Quad at index ${o} must be an object with {x, y, w, h} properties`);const i=["x","y","w","h"];for(const t of i){if(typeof r[t]!="number")throw new Error(`Quad at index ${o} is missing required property '${t}' or it's not a number`);if(r[t]<0||r[t]>1)throw new Error(`Quad property '${t}' at index ${o} must be between 0 and 1 (got ${r[t]})`)}});const n=e.color||"rgba(255, 255, 0, 0.3)";return{id:a.generateId("highlight"),type:"highlight",mode:"quads",page:e.page,quads:e.quads,style:{color:n},sentence_ref:e.sentence_ref}}exports.createHighlight=h;
2
+ //# sourceMappingURL=index18.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index18.cjs","sources":["../src/ai-tools/creators/createHighlight.js"],"sourcesContent":["/**\n * Highlight Annotation Creator\n *\n * Converts AI-generated tool call arguments into valid highlight annotation objects\n * compatible with web-annotation-renderer library format.\n *\n * @module ai-tools/creators/createHighlight\n */\n\nimport { generateId } from '../../utils/idGenerator.js';\n\n/**\n * Create a highlight annotation from tool call arguments\n *\n * @param {Object} args - Tool call arguments from AI\n * @param {Array<Object>} args.quads - Rectangle objects with {x, y, w, h} (normalized 0-1)\n * @param {string} [args.color='rgba(255, 255, 0, 0.3)'] - Highlight color in rgba format\n * @param {number} args.page - Page number (1-indexed)\n * @param {string} args.sentence_ref - Sentence reference for timing (e.g., 'S1')\n * @returns {Object} Valid highlight annotation object\n * @example\n * ```javascript\n * const highlight = createHighlight({\n * quads: [{x: 0.1, y: 0.2, w: 0.8, h: 0.05}],\n * color: 'rgba(255, 255, 0, 0.3)',\n * page: 1,\n * sentence_ref: 'S2'\n * });\n * ```\n */\nexport function createHighlight(args) {\n // Validate required fields\n if (!args.quads || !Array.isArray(args.quads) || args.quads.length === 0) {\n throw new Error('Highlight annotation requires at least one quad');\n }\n\n if (!args.page || typeof args.page !== 'number' || args.page < 1) {\n throw new Error('Highlight annotation requires a valid page number (>= 1)');\n }\n\n if (!args.sentence_ref || typeof args.sentence_ref !== 'string') {\n throw new Error('Highlight annotation requires a sentence_ref for timing');\n }\n\n // Validate quad format - each quad must be an object with {x, y, w, h}\n args.quads.forEach((quad, index) => {\n if (typeof quad !== 'object' || quad === null || Array.isArray(quad)) {\n throw new Error(`Quad at index ${index} must be an object with {x, y, w, h} properties`);\n }\n\n const requiredProps = ['x', 'y', 'w', 'h'];\n for (const prop of requiredProps) {\n if (typeof quad[prop] !== 'number') {\n throw new Error(`Quad at index ${index} is missing required property '${prop}' or it's not a number`);\n }\n if (quad[prop] < 0 || quad[prop] > 1) {\n throw new Error(`Quad property '${prop}' at index ${index} must be between 0 and 1 (got ${quad[prop]})`);\n }\n }\n });\n\n // Validate color format (should be rgba)\n const color = args.color || 'rgba(255, 255, 0, 0.3)';\n\n // Create annotation object matching library format\n return {\n id: generateId('highlight'),\n type: 'highlight',\n mode: 'quads', // Required by HighlightLayer\n page: args.page,\n quads: args.quads, // Array of {x, y, w, h} objects\n style: {\n color: color // Color wrapped in style object\n },\n sentence_ref: args.sentence_ref,\n // Note: start/end will be added during timing sync phase\n };\n}\n"],"names":["createHighlight","args","quad","index","requiredProps","prop","color","generateId"],"mappings":"iHA8BO,SAASA,EAAgBC,EAAM,CAEpC,GAAI,CAACA,EAAK,OAAS,CAAC,MAAM,QAAQA,EAAK,KAAK,GAAKA,EAAK,MAAM,SAAW,EACrE,MAAM,IAAI,MAAM,iDAAiD,EAGnE,GAAI,CAACA,EAAK,MAAQ,OAAOA,EAAK,MAAS,UAAYA,EAAK,KAAO,EAC7D,MAAM,IAAI,MAAM,0DAA0D,EAG5E,GAAI,CAACA,EAAK,cAAgB,OAAOA,EAAK,cAAiB,SACrD,MAAM,IAAI,MAAM,yDAAyD,EAI3EA,EAAK,MAAM,QAAQ,CAACC,EAAMC,IAAU,CAClC,GAAI,OAAOD,GAAS,UAAYA,IAAS,MAAQ,MAAM,QAAQA,CAAI,EACjE,MAAM,IAAI,MAAM,iBAAiBC,CAAK,iDAAiD,EAGzF,MAAMC,EAAgB,CAAC,IAAK,IAAK,IAAK,GAAG,EACzC,UAAWC,KAAQD,EAAe,CAChC,GAAI,OAAOF,EAAKG,CAAI,GAAM,SACxB,MAAM,IAAI,MAAM,iBAAiBF,CAAK,kCAAkCE,CAAI,wBAAwB,EAEtG,GAAIH,EAAKG,CAAI,EAAI,GAAKH,EAAKG,CAAI,EAAI,EACjC,MAAM,IAAI,MAAM,kBAAkBA,CAAI,cAAcF,CAAK,iCAAiCD,EAAKG,CAAI,CAAC,GAAG,CAE3G,CACF,CAAC,EAGD,MAAMC,EAAQL,EAAK,OAAS,yBAG5B,MAAO,CACL,GAAIM,EAAAA,WAAW,WAAW,EAC1B,KAAM,YACN,KAAM,QACN,KAAMN,EAAK,KACX,MAAOA,EAAK,MACZ,MAAO,CACL,MAAOK,CACb,EACI,aAAcL,EAAK,YAEvB,CACA"}
@@ -0,0 +1,40 @@
1
+ import { generateId as h } from "./index22.js";
2
+ function p(e) {
3
+ if (!e.quads || !Array.isArray(e.quads) || e.quads.length === 0)
4
+ throw new Error("Highlight annotation requires at least one quad");
5
+ if (!e.page || typeof e.page != "number" || e.page < 1)
6
+ throw new Error("Highlight annotation requires a valid page number (>= 1)");
7
+ if (!e.sentence_ref || typeof e.sentence_ref != "string")
8
+ throw new Error("Highlight annotation requires a sentence_ref for timing");
9
+ e.quads.forEach((r, o) => {
10
+ if (typeof r != "object" || r === null || Array.isArray(r))
11
+ throw new Error(`Quad at index ${o} must be an object with {x, y, w, h} properties`);
12
+ const i = ["x", "y", "w", "h"];
13
+ for (const t of i) {
14
+ if (typeof r[t] != "number")
15
+ throw new Error(`Quad at index ${o} is missing required property '${t}' or it's not a number`);
16
+ if (r[t] < 0 || r[t] > 1)
17
+ throw new Error(`Quad property '${t}' at index ${o} must be between 0 and 1 (got ${r[t]})`);
18
+ }
19
+ });
20
+ const n = e.color || "rgba(255, 255, 0, 0.3)";
21
+ return {
22
+ id: h("highlight"),
23
+ type: "highlight",
24
+ mode: "quads",
25
+ // Required by HighlightLayer
26
+ page: e.page,
27
+ quads: e.quads,
28
+ // Array of {x, y, w, h} objects
29
+ style: {
30
+ color: n
31
+ // Color wrapped in style object
32
+ },
33
+ sentence_ref: e.sentence_ref
34
+ // Note: start/end will be added during timing sync phase
35
+ };
36
+ }
37
+ export {
38
+ p as createHighlight
39
+ };
40
+ //# sourceMappingURL=index18.js.map