{"version":3,"file":"index.cjs","sources":["../src/types/annotation.ts","../src/types/config.ts","../src/utils/logger.ts","../src/utils/coordinates.ts","../src/utils/colors.ts","../src/utils/svg.ts","../src/utils/validation.ts","../src/utils/performance.ts","../src/adapters/storage/ApiStorage.ts","../src/adapters/storage/LocalStorage.ts","../src/adapters/collaboration/SocketIOAdapter.ts","../src/adapters/collaboration/NoOpAdapter.ts","../src/adapters/renderer/ReactPDFAdapter.ts","../src/adapters/renderer/GenericAdapter.ts","../src/store/annotationsSlice.ts","../src/store/uiSlice.ts","../src/store/documentSlice.ts","../src/store/commentsSlice.ts","../src/store/historySlice.ts","../src/store/store.ts","../src/store/hooks.ts","../src/components/AnnotationProvider/AnnotationContext.tsx","../src/hooks/useAnnotations.ts","../src/hooks/useAnnotationDraw.ts","../src/hooks/useDocument.ts","../src/hooks/useCollaboration.ts","../src/hooks/useViewport.ts","../src/utils/mentionParser.ts","../src/hooks/useComments.ts","../src/utils/historyTracking.ts","../src/hooks/useHistory.ts","../src/hooks/useKeyboardShortcuts.ts","../src/components/AnnotationProvider/AnnotationProvider.tsx","../src/components/AnnotationLayer/AnnotationElement.tsx","../src/components/AnnotationLayer/AnnotationLayer.tsx","../src/components/AnnotationCanvas/AnnotationCanvas.tsx","../node_modules/lucide-react/dist/esm/shared/src/utils.js","../node_modules/lucide-react/dist/esm/defaultAttributes.js","../node_modules/lucide-react/dist/esm/Icon.js","../node_modules/lucide-react/dist/esm/createLucideIcon.js","../node_modules/lucide-react/dist/esm/icons/arrow-right.js","../node_modules/lucide-react/dist/esm/icons/check.js","../node_modules/lucide-react/dist/esm/icons/circle.js","../node_modules/lucide-react/dist/esm/icons/ellipsis-vertical.js","../node_modules/lucide-react/dist/esm/icons/highlighter.js","../node_modules/lucide-react/dist/esm/icons/mouse-pointer.js","../node_modules/lucide-react/dist/esm/icons/pen-line.js","../node_modules/lucide-react/dist/esm/icons/pencil.js","../node_modules/lucide-react/dist/esm/icons/search.js","../node_modules/lucide-react/dist/esm/icons/square.js","../node_modules/lucide-react/dist/esm/icons/sticky-note.js","../node_modules/lucide-react/dist/esm/icons/trash-2.js","../node_modules/lucide-react/dist/esm/icons/x.js","../src/components/AnnotationToolbar/AnnotationToolbar.tsx","../src/components/NotesPanel/NoteCard.tsx","../src/components/NotesPanel/NoteInlineEditor.tsx","../src/components/NotesPanel/NotesPanel.tsx","../src/components/ErrorBoundary/ErrorBoundary.tsx","../src/components/CommentThread/CommentThread.tsx","../src/components/HistoryPanel/HistoryPanel.tsx","../src/components/AnnotationsListPanel.tsx","../src/components/InlineCommentInput.tsx"],"sourcesContent":["// Annotation Types\nexport enum AnnotationType {\n  HIGHLIGHT = 'highlight',\n  DRAWING = 'drawing',\n  NOTE = 'note',\n  SHAPE = 'shape',\n}\n\n// Position Data Interfaces\nexport interface NormalizedPosition {\n  x: number; // 0-1 normalized coordinate\n  y: number; // 0-1 normalized coordinate\n  width: number; // 0-1 normalized width\n  height: number; // 0-1 normalized height\n}\n\nexport interface DrawingPosition extends NormalizedPosition {\n  path?: string; // SVG path string\n  strokeWidth?: number;\n}\n\nexport interface ShapePosition extends NormalizedPosition {\n  type?: 'rectangle' | 'circle' | 'arrow';\n}\n\n// Main Annotation Interface\nexport interface Annotation {\n  id: string;\n  documentVersionId: string;\n  userId: string;\n  annotationType: AnnotationType;\n  pageNumber: number;\n  positionData: NormalizedPosition | DrawingPosition | ShapePosition;\n  content?: string | null;\n  color: string;\n  carriedFromVersionId?: string | null;\n  createdAt: string;\n  updatedAt: string;\n  isDeleted: boolean;\n  isResolved?: boolean; // For NOTE-type annotations\n}\n\n// DTOs\nexport interface CreateAnnotationDto {\n  documentVersionId: string;\n  userId: string;\n  annotationType: AnnotationType;\n  pageNumber: number;\n  positionData: NormalizedPosition | DrawingPosition | ShapePosition;\n  content?: string;\n  color: string;\n  tempId?: string; // For optimistic updates\n}\n\nexport interface UpdateAnnotationDto {\n  positionData?: NormalizedPosition | DrawingPosition | ShapePosition;\n  content?: string;\n  color?: string;\n}\n\n// UI State\nexport enum AnnotationTool {\n  SELECT = 'select',\n  HIGHLIGHT = 'highlight',\n  DRAW = 'draw',\n  RECTANGLE = 'rectangle',\n  CIRCLE = 'circle',\n  ARROW = 'arrow',\n  NOTE = 'note',\n}\n","import { AnnotationTool } from './annotation';\n\n// Configuration Types\nexport interface AnnotationConfig {\n  // Available annotation tools\n  tools?: AnnotationTool[];\n\n  // Default tool on mount\n  defaultTool?: AnnotationTool;\n\n  // Default annotation color\n  defaultColor?: string;\n\n  // Available colors for user selection\n  colorPalette?: string[];\n\n  // UI customization\n  ui?: {\n    showToolbar?: boolean;\n    showNotesPanel?: boolean;\n    toolbarPosition?: 'top' | 'bottom' | 'left' | 'right';\n    notesPanelPosition?: 'left' | 'right';\n    theme?: 'light' | 'dark' | 'auto';\n  };\n\n  // Behavior settings\n  behavior?: {\n    autoSave?: boolean;\n    autoSaveDelay?: number; // ms\n    enableUndo?: boolean;\n    maxUndoSteps?: number;\n    enableKeyboardShortcuts?: boolean;\n    selectAfterCreate?: boolean;\n    autoCreateCommentOnAnnotation?: boolean; // Auto-create comment entry when annotation is added\n  };\n\n  // Permissions\n  permissions?: {\n    canCreate?: boolean;\n    canEdit?: boolean;\n    canDelete?: boolean;\n    canEditOthers?: boolean; // Edit annotations from other users\n  };\n\n  // Callbacks\n  callbacks?: {\n    onAnnotationCreate?: (annotation: any) => void;\n    onAnnotationUpdate?: (annotation: any) => void;\n    onAnnotationDelete?: (annotationId: string) => void;\n    onCommentCreate?: (comment: any) => void;\n    onCommentUpdate?: (comment: any) => void;\n    onCommentDelete?: (commentId: string) => void;\n    onToolChange?: (tool: AnnotationTool) => void;\n    onError?: (error: Error) => void;\n  };\n\n  // User info (for comments and history)\n  userId?: string;\n  userName?: string;\n  userAvatar?: string;\n}\n\nexport const DEFAULT_CONFIG: AnnotationConfig = {\n  tools: [\n    AnnotationTool.SELECT,\n    AnnotationTool.HIGHLIGHT,\n    AnnotationTool.DRAW,\n    AnnotationTool.RECTANGLE,\n    AnnotationTool.CIRCLE,\n    AnnotationTool.ARROW,\n    AnnotationTool.NOTE,\n  ],\n  defaultTool: AnnotationTool.SELECT,\n  defaultColor: '#FFEB3B',\n  colorPalette: ['#FFEB3B', '#FF5722', '#4CAF50', '#2196F3', '#9C27B0'],\n  ui: {\n    showToolbar: true,\n    showNotesPanel: true,\n    toolbarPosition: 'top',\n    notesPanelPosition: 'right',\n    theme: 'light',\n  },\n  behavior: {\n    autoSave: true,\n    autoSaveDelay: 500,\n    enableUndo: true,\n    maxUndoSteps: 50,\n    enableKeyboardShortcuts: true,\n    selectAfterCreate: true,\n    autoCreateCommentOnAnnotation: true,\n  },\n  permissions: {\n    canCreate: true,\n    canEdit: true,\n    canDelete: true,\n    canEditOthers: false,\n  },\n};\n","/**\n * Logging utility for react-annotations library\n * Provides structured logging with different log levels\n */\n\nexport enum LogLevel {\n  DEBUG = 0,\n  INFO = 1,\n  WARN = 2,\n  ERROR = 3,\n  NONE = 4,\n}\n\nexport interface LoggerConfig {\n  level: LogLevel;\n  prefix?: string;\n  enabled?: boolean;\n  onLog?: (level: LogLevel, message: string, data?: unknown) => void;\n}\n\nexport class Logger {\n  private config: LoggerConfig;\n\n  constructor(config: Partial<LoggerConfig> = {}) {\n    // Check if we're in production by looking for common production indicators\n    const isProduction =\n      typeof window !== 'undefined' &&\n      (window.location?.hostname === 'localhost' || window.location?.hostname === '127.0.0.1')\n        ? false\n        : true;\n\n    this.config = {\n      level: isProduction ? LogLevel.WARN : LogLevel.DEBUG,\n      prefix: '[react-annotations]',\n      enabled: true,\n      ...config,\n    };\n  }\n\n  /**\n   * Configure logger settings\n   */\n  configure(config: Partial<LoggerConfig>): void {\n    this.config = { ...this.config, ...config };\n  }\n\n  /**\n   * Debug level logging\n   */\n  debug(message: string, data?: unknown): void {\n    this.log(LogLevel.DEBUG, message, data);\n  }\n\n  /**\n   * Info level logging\n   */\n  info(message: string, data?: unknown): void {\n    this.log(LogLevel.INFO, message, data);\n  }\n\n  /**\n   * Warning level logging\n   */\n  warn(message: string, data?: unknown): void {\n    this.log(LogLevel.WARN, message, data);\n  }\n\n  /**\n   * Error level logging\n   */\n  error(message: string, data?: unknown): void {\n    this.log(LogLevel.ERROR, message, data);\n  }\n\n  /**\n   * Internal logging method\n   */\n  private log(level: LogLevel, message: string, data?: unknown): void {\n    if (!this.config.enabled || level < this.config.level) {\n      return;\n    }\n\n    const prefix = this.config.prefix ? `${this.config.prefix} ` : '';\n    const fullMessage = `${prefix}${message}`;\n\n    // Call custom log handler if provided\n    if (this.config.onLog) {\n      this.config.onLog(level, fullMessage, data);\n      return;\n    }\n\n    // Default console logging\n    switch (level) {\n      case LogLevel.DEBUG:\n      case LogLevel.INFO:\n        if (data !== undefined) {\n          console.info(fullMessage, data);\n        } else {\n          console.info(fullMessage);\n        }\n        break;\n      case LogLevel.WARN:\n        if (data !== undefined) {\n          console.warn(fullMessage, data);\n        } else {\n          console.warn(fullMessage);\n        }\n        break;\n      case LogLevel.ERROR:\n        if (data !== undefined) {\n          console.error(fullMessage, data);\n        } else {\n          console.error(fullMessage);\n        }\n        break;\n    }\n  }\n}\n\n// Create default logger instance\nexport const logger = new Logger();\n\n/**\n * Create a namespaced logger\n */\nexport function createLogger(namespace: string, config?: Partial<LoggerConfig>): Logger {\n  return new Logger({\n    ...config,\n    prefix: `[react-annotations:${namespace}]`,\n  });\n}\n","import { NormalizedPosition } from '../types';\nimport { createLogger } from './logger';\n\nconst logger = createLogger('coordinates');\n\n/**\n * Convert normalized coordinates (0-1) to pixel coordinates\n * @param normalized - Normalized position data (0-1 range)\n * @param pageWidth - Page width in pixels\n * @param pageHeight - Page height in pixels\n * @returns Pixel coordinates\n */\nexport function normalizedToPixels(\n  normalized: NormalizedPosition,\n  pageWidth: number,\n  pageHeight: number\n): { x: number; y: number; width: number; height: number } {\n  logger.debug('normalizedToPixels', { normalized, pageWidth, pageHeight });\n\n  // Validate inputs\n  if (!pageWidth || !pageHeight || pageWidth <= 0 || pageHeight <= 0) {\n    logger.error('Invalid page dimensions', { pageWidth, pageHeight });\n    return { x: 0, y: 0, width: 0, height: 0 };\n  }\n\n  const result = {\n    x: normalized.x * pageWidth,\n    y: normalized.y * pageHeight,\n    width: normalized.width * pageWidth,\n    height: normalized.height * pageHeight,\n  };\n\n  logger.debug('Result:', result);\n  return result;\n}\n\n/**\n * Convert pixel coordinates to normalized (0-1) coordinates\n * @param pixels - Pixel position data\n * @param pageWidth - Page width in pixels\n * @param pageHeight - Page height in pixels\n * @returns Normalized position (0-1 range)\n */\nexport function pixelsToNormalized(\n  pixels: { x: number; y: number; width: number; height: number },\n  pageWidth: number,\n  pageHeight: number\n): NormalizedPosition {\n  return {\n    x: pixels.x / pageWidth,\n    y: pixels.y / pageHeight,\n    width: pixels.width / pageWidth,\n    height: pixels.height / pageHeight,\n  };\n}\n\n/**\n * Get bounding box from text selection\n * @param selection - DOM Selection object\n * @param container - Container element for coordinate calculation\n * @returns Bounding box in pixel coordinates relative to container\n */\nexport function getSelectionBounds(\n  selection: Selection,\n  container: HTMLElement\n): { x: number; y: number; width: number; height: number } | null {\n  if (!selection.rangeCount) return null;\n\n  const range = selection.getRangeAt(0);\n  const rects = range.getClientRects();\n  if (rects.length === 0) return null;\n\n  const containerRect = container.getBoundingClientRect();\n  const rect = rects[0];\n\n  if (!rect) return null;\n\n  return {\n    x: rect.left - containerRect.left,\n    y: rect.top - containerRect.top,\n    width: rect.width,\n    height: rect.height,\n  };\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n  return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Normalize a bounding box to ensure width/height are positive\n */\nexport function normalizeBounds(bounds: { x: number; y: number; width: number; height: number }): {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n} {\n  return {\n    x: bounds.width >= 0 ? bounds.x : bounds.x + bounds.width,\n    y: bounds.height >= 0 ? bounds.y : bounds.y + bounds.height,\n    width: Math.abs(bounds.width),\n    height: Math.abs(bounds.height),\n  };\n}\n","/**\n * Default color palette for user assignments\n */\nexport const USER_COLORS = [\n  '#FF6B6B', // Red\n  '#4ECDC4', // Teal\n  '#45B7D1', // Blue\n  '#FFA07A', // Light Salmon\n  '#98D8C8', // Mint\n  '#F7DC6F', // Yellow\n  '#BB8FCE', // Purple\n  '#85C1E2', // Sky Blue\n  '#F8B739', // Orange\n  '#52C41A', // Green\n];\n\n/**\n * Default annotation color palette\n */\nexport const ANNOTATION_COLORS = [\n  '#FFD700', // Highlight Yellow\n  '#FF6900', // Orange (Draw / Warning tone)\n  '#00A650', // Green (Shape / Success tone)\n  '#0066CC', // Blue (Note / Primary)\n  '#FFB6C1', // Pink\n  '#87CEEB', // Sky Blue\n  '#90EE90', // Light Green\n  '#FFA500', // Orange\n];\n\n/**\n * Simple hash function to convert string to number\n */\nfunction hashCode(str: string): number {\n  let hash = 0;\n  for (let i = 0; i < str.length; i++) {\n    const char = str.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash; // Convert to 32-bit integer\n  }\n  return Math.abs(hash);\n}\n\n/**\n * Get a consistent color for a user ID\n * @param userId - User identifier\n * @returns Hex color code\n */\nexport function getUserColor(userId: string): string {\n  const hash = hashCode(userId);\n  const color = USER_COLORS[hash % USER_COLORS.length];\n  if (!color) {\n    return USER_COLORS[0] ?? '#FF6B6B';\n  }\n  return color;\n}\n\n/**\n * Determine if a color is light or dark\n * @param color - Hex color code (e.g., '#FFFFFF')\n * @returns true if light, false if dark\n */\nexport function isColorLight(color: string): boolean {\n  // Convert hex to RGB\n  const hex = color.replace('#', '');\n  const r = parseInt(hex.substring(0, 2), 16);\n  const g = parseInt(hex.substring(2, 4), 16);\n  const b = parseInt(hex.substring(4, 6), 16);\n\n  // Calculate luminance using ITU-R BT.709 coefficients\n  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n  return luminance > 0.5;\n}\n\n/**\n * Get contrasting text color (black or white) for a background color\n * @param backgroundColor - Hex color code\n * @returns '#000000' or '#FFFFFF'\n */\nexport function getContrastColor(backgroundColor: string): string {\n  return isColorLight(backgroundColor) ? '#000000' : '#FFFFFF';\n}\n\n/**\n * Convert RGB to hex\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n  return (\n    '#' +\n    [r, g, b]\n      .map((x) => {\n        const hex = x.toString(16);\n        return hex.length === 1 ? '0' + hex : hex;\n      })\n      .join('')\n  );\n}\n\n/**\n * Convert hex to RGB\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n  const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n  if (!result || !result[1] || !result[2] || !result[3]) {\n    return null;\n  }\n  return {\n    r: parseInt(result[1], 16),\n    g: parseInt(result[2], 16),\n    b: parseInt(result[3], 16),\n  };\n}\n\n/**\n * Adjust color opacity\n */\nexport function withOpacity(color: string, opacity: number): string {\n  const rgb = hexToRgb(color);\n  if (!rgb) return color;\n  return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity})`;\n}\n","/**\n * SVG path utilities for drawing annotations\n */\n\n/**\n * Create an SVG path from an array of points\n * @param points - Array of {x, y} coordinates\n * @returns SVG path string\n */\nexport function pointsToPath(points: Array<{ x: number; y: number }>): string {\n  if (points.length === 0) return '';\n\n  const [first, ...rest] = points;\n  if (!first) return '';\n\n  const path = [`M ${first.x} ${first.y}`];\n\n  for (const point of rest) {\n    path.push(`L ${point.x} ${point.y}`);\n  }\n\n  return path.join(' ');\n}\n\n/**\n * Smooth a path using quadratic bezier curves\n * @param points - Array of {x, y} coordinates\n * @returns Smoothed SVG path string\n */\nexport function pointsToSmoothPath(points: Array<{ x: number; y: number }>): string {\n  if (points.length === 0) return '';\n\n  const first = points[0];\n  if (!first) return '';\n\n  if (points.length === 1) return `M ${first.x} ${first.y}`;\n\n  const second = points[1];\n  if (points.length === 2 && second) {\n    return `M ${first.x} ${first.y} L ${second.x} ${second.y}`;\n  }\n\n  const path: string[] = [`M ${first.x} ${first.y}`];\n\n  for (let i = 1; i < points.length - 1; i++) {\n    const curr = points[i];\n    const next = points[i + 1];\n\n    if (!curr || !next) continue;\n\n    const midX = (curr.x + next.x) / 2;\n    const midY = (curr.y + next.y) / 2;\n\n    path.push(`Q ${curr.x} ${curr.y} ${midX} ${midY}`);\n  }\n\n  const last = points[points.length - 1];\n  if (last) {\n    path.push(`L ${last.x} ${last.y}`);\n  }\n\n  return path.join(' ');\n}\n\n/**\n * Create an arrow marker definition\n */\nexport function createArrowMarker(id: string, color: string): string {\n  return `\n    <defs>\n      <marker\n        id=\"${id}\"\n        markerWidth=\"10\"\n        markerHeight=\"10\"\n        refX=\"9\"\n        refY=\"3\"\n        orient=\"auto\"\n        markerUnits=\"strokeWidth\"\n      >\n        <path d=\"M0,0 L0,6 L9,3 z\" fill=\"${color}\" />\n      </marker>\n    </defs>\n  `;\n}\n\n/**\n * Calculate arrow path with arrowhead\n */\nexport function createArrowPath(\n  startX: number,\n  startY: number,\n  endX: number,\n  endY: number\n): string {\n  return `M ${startX} ${startY} L ${endX} ${endY}`;\n}\n","import { NormalizedPosition, AnnotationType } from '../types';\n\n/**\n * Validate normalized position values are in 0-1 range\n */\nexport function isValidNormalizedPosition(position: NormalizedPosition): boolean {\n  return (\n    position.x >= 0 &&\n    position.x <= 1 &&\n    position.y >= 0 &&\n    position.y <= 1 &&\n    position.width >= 0 &&\n    position.width <= 1 &&\n    position.height >= 0 &&\n    position.height <= 1\n  );\n}\n\n/**\n * Validate hex color format\n */\nexport function isValidHexColor(color: string): boolean {\n  return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n}\n\n/**\n * Validate annotation type\n */\nexport function isValidAnnotationType(type: string): type is AnnotationType {\n  return Object.values(AnnotationType).includes(type as AnnotationType);\n}\n\n/**\n * Validate page number\n */\nexport function isValidPageNumber(page: number, totalPages: number): boolean {\n  return Number.isInteger(page) && page >= 1 && page <= totalPages;\n}\n\n/**\n * Sanitize user input string\n */\nexport function sanitizeString(input: string, maxLength: number = 1000): string {\n  return input.slice(0, maxLength).trim();\n}\n","/**\n * Performance utilities for optimizing react-annotations\n */\n\n/**\n * Debounce a function call\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n  func: T,\n  wait: number\n): (...args: Parameters<T>) => void {\n  let timeout: ReturnType<typeof setTimeout> | null = null;\n\n  return function executedFunction(...args: Parameters<T>) {\n    const later = () => {\n      timeout = null;\n      func(...args);\n    };\n\n    if (timeout) {\n      clearTimeout(timeout);\n    }\n    timeout = setTimeout(later, wait);\n  };\n}\n\n/**\n * Throttle a function call\n */\nexport function throttle<T extends (...args: unknown[]) => unknown>(\n  func: T,\n  limit: number\n): (...args: Parameters<T>) => void {\n  let inThrottle: boolean;\n  let lastResult: ReturnType<T>;\n\n  return function executedFunction(...args: Parameters<T>) {\n    if (!inThrottle) {\n      lastResult = func(...args) as ReturnType<T>;\n      inThrottle = true;\n\n      setTimeout(() => {\n        inThrottle = false;\n      }, limit);\n    }\n\n    return lastResult;\n  };\n}\n\n/**\n * Request animation frame throttle\n */\nexport function rafThrottle<T extends (...args: unknown[]) => unknown>(\n  func: T\n): (...args: Parameters<T>) => void {\n  let rafId: number | null = null;\n\n  return function executedFunction(...args: Parameters<T>) {\n    if (rafId) {\n      return;\n    }\n\n    rafId = requestAnimationFrame(() => {\n      func(...args);\n      rafId = null;\n    });\n  };\n}\n\n/**\n * Memoize a function result\n */\nexport function memoize<T extends (...args: unknown[]) => unknown>(\n  func: T,\n  keyGenerator?: (...args: Parameters<T>) => string\n): T {\n  const cache = new Map<string, ReturnType<T>>();\n\n  return ((...args: Parameters<T>) => {\n    const key = keyGenerator ? keyGenerator(...args) : JSON.stringify(args);\n\n    if (cache.has(key)) {\n      return cache.get(key);\n    }\n\n    const result = func(...args) as ReturnType<T>;\n    cache.set(key, result);\n    return result;\n  }) as T;\n}\n\n/**\n * Batch multiple calls into a single execution\n */\nexport function batchCalls<T>(callback: (items: T[]) => void, delay = 0): (item: T) => void {\n  let items: T[] = [];\n  let timeout: ReturnType<typeof setTimeout> | null = null;\n\n  return (item: T) => {\n    items.push(item);\n\n    if (timeout) {\n      clearTimeout(timeout);\n    }\n\n    timeout = setTimeout(() => {\n      callback(items);\n      items = [];\n      timeout = null;\n    }, delay);\n  };\n}\n\n/**\n * Create a queue with concurrency limit\n */\nclass TaskQueue<T> {\n  private queue: Array<() => Promise<T>> = [];\n  private running = 0;\n\n  constructor(private concurrency = 1) {}\n\n  add(task: () => Promise<T>): Promise<T> {\n    return new Promise((resolve, reject) => {\n      this.queue.push(async () => {\n        try {\n          const result = await task();\n          resolve(result);\n          return result;\n        } catch (error) {\n          reject(error);\n          throw error;\n        }\n      });\n\n      this.process();\n    });\n  }\n\n  private async process(): Promise<void> {\n    if (this.running >= this.concurrency || this.queue.length === 0) {\n      return;\n    }\n\n    this.running++;\n    const task = this.queue.shift();\n\n    if (task) {\n      try {\n        await task();\n      } finally {\n        this.running--;\n        this.process();\n      }\n    }\n  }\n\n  get size(): number {\n    return this.queue.length;\n  }\n\n  get isIdle(): boolean {\n    return this.queue.length === 0 && this.running === 0;\n  }\n}\n\n// Provide typings for a hybrid callable/constructable export\nexport interface QueueInstance<T> {\n  add(task: () => Promise<T>): Promise<T>;\n  readonly size: number;\n  readonly isIdle: boolean;\n}\nexport interface QueueConstructor {\n  new <T>(concurrency?: number): QueueInstance<T>;\n  <T>(concurrency?: number): QueueInstance<T>;\n}\n\n// Export Queue so it works with or without \"new\"\nexport const Queue: QueueConstructor = function Queue<T>(\n  this: unknown,\n  concurrency = 1\n): QueueInstance<T> {\n  return new TaskQueue<T>(concurrency);\n} as unknown as QueueConstructor;\n\n// Optional named export of the underlying class if needed elsewhere\nexport { TaskQueue as QueueClass };\n","import axios, { AxiosInstance, AxiosError } from 'axios';\nimport { StorageAdapter, Annotation, CreateAnnotationDto, ApiResponse } from '../../types';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('ApiStorage');\n\nexport interface ApiStorageConfig {\n  baseUrl: string;\n  documentId: string;\n  versionId?: string;\n  headers?: Record<string, string>;\n}\n\n/**\n * API Storage Adapter for NestJS backend\n * Implements the StorageAdapter interface using REST API\n */\nexport class ApiStorage implements StorageAdapter {\n  private api: AxiosInstance;\n  private documentId: string;\n  private versionId?: string;\n\n  constructor(config: ApiStorageConfig) {\n    this.documentId = config.documentId;\n    this.versionId = config.versionId;\n\n    this.api = axios.create({\n      baseURL: config.baseUrl,\n      headers: {\n        'Content-Type': 'application/json',\n        ...config.headers,\n      },\n    });\n\n    // Response interceptor for error handling\n    this.api.interceptors.response.use(\n      (response) => response,\n      (error: AxiosError<ApiResponse>) => {\n        const message = error.response?.data?.message || error.message;\n        logger.error('API Error', { message, status: error.response?.status });\n        return Promise.reject(new Error(message));\n      }\n    );\n  }\n\n  async fetchAnnotations(documentId?: string, versionId?: string): Promise<Annotation[]> {\n    const docId = documentId || this.documentId;\n    const verId = versionId || this.versionId;\n\n    if (!verId) {\n      throw new Error('Version ID is required to fetch annotations');\n    }\n\n    const { data } = await this.api.get<ApiResponse<Annotation[]>>(\n      `/documents/${docId}/versions/${verId}/annotations`\n    );\n\n    const annotations = data.data || [];\n\n    // Parse positionData if it's a string (coming from database as JSON string)\n    return annotations.map((annotation) => ({\n      ...annotation,\n      positionData:\n        typeof annotation.positionData === 'string'\n          ? JSON.parse(annotation.positionData)\n          : annotation.positionData,\n    }));\n  }\n\n  async createAnnotation(annotation: CreateAnnotationDto): Promise<Annotation> {\n    const verId = this.versionId || annotation.documentVersionId;\n\n    if (!verId) {\n      throw new Error('Version ID is required to create annotation');\n    }\n\n    const { data } = await this.api.post<ApiResponse<Annotation>>(\n      `/documents/${this.documentId}/versions/${verId}/annotations`,\n      annotation\n    );\n\n    if (!data.data) {\n      throw new Error('Failed to create annotation');\n    }\n\n    // Parse positionData if it's a string\n    const created = data.data;\n    return {\n      ...created,\n      positionData:\n        typeof created.positionData === 'string'\n          ? JSON.parse(created.positionData)\n          : created.positionData,\n    };\n  }\n\n  async updateAnnotation(annotationId: string, updates: Partial<Annotation>): Promise<Annotation> {\n    logger.debug('Updating annotation', { annotationId, updates });\n    const { data } = await this.api.put<ApiResponse<Annotation>>(\n      `/annotations/${annotationId}`,\n      updates\n    );\n\n    if (!data.data) {\n      throw new Error('Failed to update annotation');\n    }\n\n    // Parse positionData if it's a string\n    const updated = data.data;\n    const result = {\n      ...updated,\n      positionData:\n        typeof updated.positionData === 'string'\n          ? JSON.parse(updated.positionData)\n          : updated.positionData,\n    };\n\n    logger.debug('Update result', { result });\n    return result;\n  }\n\n  async deleteAnnotation(annotationId: string): Promise<void> {\n    logger.debug('Deleting annotation', { annotationId });\n    try {\n      await this.api.delete(`/annotations/${annotationId}`);\n      logger.debug('Delete successful', { annotationId });\n    } catch (error) {\n      logger.error('Delete failed', { annotationId, error });\n      throw error;\n    }\n  }\n\n  async toggleResolve(annotationId: string): Promise<Annotation> {\n    logger.debug('Toggling resolve status', { annotationId });\n    const { data } = await this.api.post<ApiResponse<Annotation>>(\n      `/annotations/${annotationId}/toggle-resolve`\n    );\n\n    if (!data.data) {\n      throw new Error('Failed to toggle resolve status');\n    }\n\n    // Parse positionData if it's a string\n    const updated = data.data;\n    return {\n      ...updated,\n      positionData:\n        typeof updated.positionData === 'string'\n          ? JSON.parse(updated.positionData)\n          : updated.positionData,\n    };\n  }\n\n  async batchCreate(annotations: CreateAnnotationDto[]): Promise<Annotation[]> {\n    const results: Annotation[] = [];\n\n    for (const annotation of annotations) {\n      const created = await this.createAnnotation(annotation);\n      results.push(created);\n    }\n\n    return results;\n  }\n\n  async batchUpdate(\n    updates: Array<{ id: string; data: Partial<Annotation> }>\n  ): Promise<Annotation[]> {\n    const results: Annotation[] = [];\n\n    for (const update of updates) {\n      const updated = await this.updateAnnotation(update.id, update.data);\n      results.push(updated);\n    }\n\n    return results;\n  }\n}\n\n/**\n * Factory function to create ApiStorage adapter\n */\nexport function createApiStorage(config: ApiStorageConfig): StorageAdapter {\n  return new ApiStorage(config);\n}\n","import { StorageAdapter, Annotation, CreateAnnotationDto } from '../../types';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('LocalStorage');\n\nexport interface LocalStorageConfig {\n  storageKey?: string;\n  documentId: string;\n  versionId?: string;\n}\n\n/**\n * LocalStorage Adapter for offline annotation storage\n * Implements the StorageAdapter interface using browser localStorage\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n  private storageKey: string;\n  private documentId: string;\n  private versionId?: string;\n\n  constructor(config: LocalStorageConfig) {\n    this.documentId = config.documentId;\n    this.versionId = config.versionId;\n    this.storageKey = config.storageKey || `annotations_${this.documentId}`;\n  }\n\n  private getKey(): string {\n    return this.versionId ? `${this.storageKey}_${this.versionId}` : this.storageKey;\n  }\n\n  private loadAnnotations(): Annotation[] {\n    try {\n      const stored = localStorage.getItem(this.getKey());\n      return stored ? JSON.parse(stored) : [];\n    } catch (error) {\n      logger.error('Failed to load annotations from localStorage', { error });\n      return [];\n    }\n  }\n\n  private saveAnnotations(annotations: Annotation[]): void {\n    try {\n      localStorage.setItem(this.getKey(), JSON.stringify(annotations));\n    } catch (error) {\n      logger.error('Failed to save annotations to localStorage', { error });\n      throw new Error('Storage quota exceeded');\n    }\n  }\n\n  async fetchAnnotations(documentId?: string, versionId?: string): Promise<Annotation[]> {\n    // If specific document/version requested, use those\n    if (documentId && documentId !== this.documentId) {\n      const key = versionId\n        ? `annotations_${documentId}_${versionId}`\n        : `annotations_${documentId}`;\n      const stored = localStorage.getItem(key);\n      return stored ? JSON.parse(stored) : [];\n    }\n\n    return this.loadAnnotations();\n  }\n\n  async createAnnotation(annotation: CreateAnnotationDto): Promise<Annotation> {\n    const annotations = this.loadAnnotations();\n\n    const newAnnotation: Annotation = {\n      ...annotation,\n      id: annotation.tempId ?? `local_${Date.now()}_${Math.random()}`,\n      createdAt: new Date().toISOString(),\n      updatedAt: new Date().toISOString(),\n      isDeleted: false,\n    };\n\n    annotations.push(newAnnotation);\n    this.saveAnnotations(annotations);\n\n    return newAnnotation;\n  }\n\n  async updateAnnotation(annotationId: string, updates: Partial<Annotation>): Promise<Annotation> {\n    const annotations = this.loadAnnotations();\n    const index = annotations.findIndex((a) => a.id === annotationId);\n\n    if (index === -1) {\n      throw new Error(`Annotation ${annotationId} not found`);\n    }\n\n    const existing = annotations[index];\n    if (!existing) {\n      throw new Error(`Annotation ${annotationId} not found`);\n    }\n\n    const updated: Annotation = {\n      ...existing,\n      ...updates,\n      id: existing.id,\n      documentVersionId: updates.documentVersionId ?? existing.documentVersionId,\n      userId: updates.userId ?? existing.userId,\n      annotationType: updates.annotationType ?? existing.annotationType,\n      pageNumber: updates.pageNumber ?? existing.pageNumber,\n      positionData: updates.positionData ?? existing.positionData,\n      color: updates.color ?? existing.color,\n      createdAt: existing.createdAt,\n      updatedAt: new Date().toISOString(),\n      isDeleted: updates.isDeleted ?? existing.isDeleted,\n    };\n\n    annotations[index] = updated;\n    this.saveAnnotations(annotations);\n\n    return updated;\n  }\n\n  async deleteAnnotation(annotationId: string): Promise<void> {\n    const annotations = this.loadAnnotations();\n    const filtered = annotations.filter((a) => a.id !== annotationId);\n\n    if (filtered.length === annotations.length) {\n      throw new Error(`Annotation ${annotationId} not found`);\n    }\n\n    this.saveAnnotations(filtered);\n  }\n\n  async batchCreate(annotations: CreateAnnotationDto[]): Promise<Annotation[]> {\n    const existing = this.loadAnnotations();\n\n    const newAnnotations: Annotation[] = annotations.map((dto) => ({\n      ...dto,\n      id: dto.tempId ?? `local_${Date.now()}_${Math.random()}`,\n      createdAt: new Date().toISOString(),\n      updatedAt: new Date().toISOString(),\n      isDeleted: false,\n    }));\n\n    existing.push(...newAnnotations);\n    this.saveAnnotations(existing);\n\n    return newAnnotations;\n  }\n\n  async batchUpdate(\n    updates: Array<{ id: string; data: Partial<Annotation> }>\n  ): Promise<Annotation[]> {\n    const annotations = this.loadAnnotations();\n    const results: Annotation[] = [];\n\n    for (const update of updates) {\n      const index = annotations.findIndex((a) => a.id === update.id);\n      if (index !== -1) {\n        const existing = annotations[index];\n        if (!existing) {\n          continue;\n        }\n        const updated: Annotation = {\n          ...existing,\n          ...update.data,\n          id: existing.id,\n          documentVersionId: update.data.documentVersionId ?? existing.documentVersionId,\n          userId: update.data.userId ?? existing.userId,\n          annotationType: update.data.annotationType ?? existing.annotationType,\n          pageNumber: update.data.pageNumber ?? existing.pageNumber,\n          positionData: update.data.positionData ?? existing.positionData,\n          color: update.data.color ?? existing.color,\n          createdAt: existing.createdAt,\n          updatedAt: new Date().toISOString(),\n          isDeleted: update.data.isDeleted ?? existing.isDeleted,\n        };\n        annotations[index] = updated;\n        results.push(updated);\n      }\n    }\n\n    this.saveAnnotations(annotations);\n    return results;\n  }\n\n  /**\n   * Clear all annotations for this document\n   */\n  clear(): void {\n    localStorage.removeItem(this.getKey());\n  }\n\n  /**\n   * Export annotations as JSON\n   */\n  export(): string {\n    const annotations = this.loadAnnotations();\n    return JSON.stringify(annotations, null, 2);\n  }\n\n  /**\n   * Import annotations from JSON\n   */\n  import(json: string): void {\n    try {\n      const annotations = JSON.parse(json);\n      if (Array.isArray(annotations)) {\n        this.saveAnnotations(annotations);\n      } else {\n        throw new Error('Invalid JSON format');\n      }\n    } catch (error) {\n      if (error instanceof Error && error.message === 'Invalid JSON format') {\n        throw error;\n      }\n      throw new Error('Failed to import annotations');\n    }\n  }\n}\n\n/**\n * Factory function to create LocalStorage adapter\n */\nexport function createLocalStorage(config: LocalStorageConfig): StorageAdapter {\n  return new LocalStorageAdapter(config);\n}\n","import * as socketio from 'socket.io-client';\nconst io = (socketio as any).io || socketio;\ntype Socket = any;\nimport { CollaborationAdapter, CollaborationEvent } from '../../types';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('SocketIOAdapter');\n\nexport interface SocketIOConfig {\n  url: string;\n  documentId: string;\n  versionId?: string;\n  userId: string;\n  options?: {\n    transports?: string[];\n    reconnection?: boolean;\n    reconnectionDelay?: number;\n    reconnectionAttempts?: number;\n  };\n}\n\n/**\n * Socket.IO Collaboration Adapter\n * Implements real-time collaboration using Socket.IO\n */\nexport class SocketIOAdapter implements CollaborationAdapter {\n  private socket: Socket | null = null;\n  private listeners: Map<string, Array<(data: unknown) => void>> = new Map();\n  private config: SocketIOConfig;\n\n  constructor(config: SocketIOConfig) {\n    this.config = config;\n  }\n\n  connect(): void {\n    if (this.socket?.connected) return;\n\n    const options = this.config.options || {};\n\n    this.socket = io(this.config.url, {\n      transports: options.transports || ['websocket'],\n      reconnection: options.reconnection !== false,\n      reconnectionDelay: options.reconnectionDelay || 1000,\n      reconnectionAttempts: options.reconnectionAttempts || 5,\n    });\n\n    // Connection events\n    this.socket.on('connect', () => {\n      logger.info('Connected', { socketId: this.socket?.id });\n    });\n\n    this.socket.on('disconnect', () => {\n      logger.info('Disconnected');\n    });\n\n    this.socket.on('connect_error', (error: any) => {\n      logger.error('Connection error', { error });\n    });\n\n    // Set up annotation event listeners\n    this.socket.on('annotationCreated', (data: any) => {\n      this.emitToListeners('annotationCreated', data);\n    });\n\n    this.socket.on('annotationUpdated', (data: any) => {\n      this.emitToListeners('annotationUpdated', data);\n    });\n\n    this.socket.on('annotationDeleted', (data: any) => {\n      this.emitToListeners('annotationDeleted', data);\n    });\n\n    this.socket.on('annotationError', (data: any) => {\n      this.emitToListeners('annotationError', data);\n    });\n\n    this.socket.on('annotationSaved', (data: any) => {\n      this.emitToListeners('annotationSaved', data);\n    });\n  }\n\n  disconnect(): void {\n    if (this.socket) {\n      this.socket.disconnect();\n      this.socket = null;\n      this.listeners.clear();\n    }\n  }\n\n  joinDocument(documentId?: string, versionId?: string): void {\n    if (!this.socket) {\n      logger.warn('Cannot join document: not connected');\n      return;\n    }\n\n    const docId = documentId || this.config.documentId;\n    const verId = versionId || this.config.versionId;\n\n    this.socket.emit('joinDocument', {\n      documentId: docId,\n      versionId: verId,\n    });\n\n    logger.info('Joined document', { documentId: docId, versionId: verId });\n  }\n\n  leaveDocument(documentId?: string, versionId?: string): void {\n    if (!this.socket) return;\n\n    const docId = documentId || this.config.documentId;\n    const verId = versionId || this.config.versionId;\n\n    this.socket.emit('leaveDocument', {\n      documentId: docId,\n      versionId: verId,\n    });\n\n    logger.info('Left document', { documentId: docId, versionId: verId });\n  }\n\n  emit(event: CollaborationEvent): void {\n    if (!this.socket) {\n      logger.warn('Cannot emit event: not connected');\n      return;\n    }\n\n    const { documentId, versionId } = this.config;\n\n    switch (event.type) {\n      case 'annotation:created':\n        this.socket.emit('createAnnotation', {\n          documentId,\n          versionId,\n          annotation: event.annotation,\n        });\n        break;\n\n      case 'annotation:updated':\n        this.socket.emit('updateAnnotation', {\n          documentId,\n          versionId,\n          annotationId: event.annotationId,\n          userId: this.config.userId,\n          updates: event.updates,\n        });\n        break;\n\n      case 'annotation:deleted':\n        this.socket.emit('deleteAnnotation', {\n          documentId,\n          versionId,\n          annotationId: event.annotationId,\n          userId: this.config.userId,\n        });\n        break;\n\n      default:\n        logger.warn('Unknown event type', { event });\n    }\n  }\n\n  on(event: string, handler: (data: any) => void): void {\n    if (!this.listeners.has(event)) {\n      this.listeners.set(event, []);\n    }\n    this.listeners.get(event)!.push(handler);\n  }\n\n  off(event: string, handler: (data: any) => void): void {\n    const handlers = this.listeners.get(event);\n    if (handlers) {\n      const index = handlers.indexOf(handler);\n      if (index > -1) {\n        handlers.splice(index, 1);\n      }\n    }\n  }\n\n  isConnected(): boolean {\n    return this.socket?.connected || false;\n  }\n\n  private emitToListeners(event: string, data: any): void {\n    const handlers = this.listeners.get(event);\n    if (handlers) {\n      handlers.forEach((handler) => handler(data));\n    }\n  }\n\n  /**\n   * Get the underlying Socket.IO socket instance\n   * (for advanced use cases)\n   */\n  getSocket(): Socket | null {\n    return this.socket;\n  }\n}\n\n/**\n * Factory function to create SocketIO adapter\n */\nexport function createSocketIOCollaboration(config: SocketIOConfig): CollaborationAdapter {\n  return new SocketIOAdapter(config);\n}\n","import { CollaborationAdapter, CollaborationEvent } from '../../types';\n\n/**\n * No-Op Collaboration Adapter\n * Disables real-time collaboration (single-user mode)\n */\nexport class NoOpAdapter implements CollaborationAdapter {\n  connect(): void {\n    // No-op\n  }\n\n  disconnect(): void {\n    // No-op\n  }\n\n  joinDocument(_documentId?: string, _versionId?: string): void {\n    // No-op\n  }\n\n  leaveDocument(_documentId?: string, _versionId?: string): void {\n    // No-op\n  }\n\n  emit(_event: CollaborationEvent): void {\n    // No-op\n  }\n\n  on(_event: string, _handler: (data: any) => void): void {\n    // No-op\n  }\n\n  off(_event: string, _handler: (data: any) => void): void {\n    // No-op\n  }\n\n  isConnected(): boolean {\n    return false;\n  }\n}\n\n/**\n * Factory function to create NoOp adapter\n */\nexport function createNoOpCollaboration(): CollaborationAdapter {\n  return new NoOpAdapter();\n}\n","import { RefObject } from 'react';\nimport { RendererAdapter } from '../../types';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('ReactPDFAdapter');\n\nexport interface ReactPDFAdapterConfig {\n  containerRef: RefObject<HTMLElement>;\n  getCurrentPage: () => number;\n  getTotalPages: () => number;\n  getScale: () => number;\n  goToPage?: (page: number) => void;\n  setScale?: (scale: number) => void;\n}\n\n/**\n * React-PDF Renderer Adapter\n * Integrates with react-pdf library\n */\nexport class ReactPDFAdapter implements RendererAdapter {\n  private config: ReactPDFAdapterConfig;\n  private defaultPageDimensions = { width: 595, height: 842 }; // A4 at 72 DPI\n\n  constructor(config: ReactPDFAdapterConfig) {\n    this.config = config;\n  }\n\n  getPageDimensions(_pageNumber: number): { width: number; height: number } {\n    const container = this.config.containerRef.current;\n    logger.debug('getPageDimensions - container:', container);\n\n    if (!container) {\n      logger.warn('No container found, using defaults');\n      return this.defaultPageDimensions;\n    }\n\n    // Try to find the PDF canvas element - use offsetWidth/offsetHeight for displayed size\n    const canvas = container.querySelector('canvas.react-pdf__Page__canvas') as HTMLCanvasElement;\n    logger.debug('Found canvas:', canvas);\n\n    if (canvas) {\n      const dims = {\n        width: canvas.offsetWidth || canvas.clientWidth,\n        height: canvas.offsetHeight || canvas.clientHeight,\n      };\n      logger.debug('Canvas dimensions:', {\n        ...dims,\n        offsetWidth: canvas.offsetWidth,\n        offsetHeight: canvas.offsetHeight,\n        clientWidth: canvas.clientWidth,\n        clientHeight: canvas.clientHeight,\n      });\n      return dims;\n    }\n\n    // Fallback: look for the page div\n    const pageDiv = container.querySelector('.react-pdf__Page') as HTMLElement;\n    logger.debug('Found pageDiv:', pageDiv);\n\n    if (pageDiv) {\n      const dims = {\n        width: pageDiv.offsetWidth || pageDiv.clientWidth,\n        height: pageDiv.offsetHeight || pageDiv.clientHeight,\n      };\n      logger.debug('PageDiv dimensions:', dims);\n      return dims;\n    }\n\n    logger.warn('No PDF elements found, using defaults');\n    return this.defaultPageDimensions;\n  }\n\n  getCurrentPage(): number {\n    return this.config.getCurrentPage();\n  }\n\n  getTotalPages(): number {\n    return this.config.getTotalPages();\n  }\n\n  getScale(): number {\n    return this.config.getScale();\n  }\n\n  goToPage(pageNumber: number): void {\n    if (this.config.goToPage) {\n      this.config.goToPage(pageNumber);\n    }\n  }\n\n  setScale(scale: number): void {\n    if (this.config.setScale) {\n      this.config.setScale(scale);\n    }\n  }\n\n  getContainerElement(): HTMLElement | null {\n    return this.config.containerRef.current;\n  }\n}\n\n/**\n * Factory function to create ReactPDF adapter\n */\nexport function createReactPDFAdapter(config: ReactPDFAdapterConfig): RendererAdapter {\n  return new ReactPDFAdapter(config);\n}\n","import { RefObject } from 'react';\nimport { RendererAdapter } from '../../types';\n\nexport interface GenericRendererConfig {\n  containerRef: RefObject<HTMLElement>;\n  pageWidth: number;\n  pageHeight: number;\n  currentPage?: number;\n  totalPages?: number;\n  scale?: number;\n  onPageChange?: (page: number) => void;\n  onScaleChange?: (scale: number) => void;\n}\n\n/**\n * Generic Renderer Adapter\n * Works with any PDF viewer or document renderer\n */\nexport class GenericAdapter implements RendererAdapter {\n  private config: GenericRendererConfig;\n  private currentPage: number;\n  private totalPages: number;\n  private scale: number;\n\n  constructor(config: GenericRendererConfig) {\n    this.config = config;\n    this.currentPage = config.currentPage || 1;\n    this.totalPages = config.totalPages || 1;\n    this.scale = config.scale || 1.0;\n  }\n\n  getPageDimensions(_pageNumber: number): { width: number; height: number } {\n    return {\n      width: this.config.pageWidth * this.scale,\n      height: this.config.pageHeight * this.scale,\n    };\n  }\n\n  getCurrentPage(): number {\n    return this.currentPage;\n  }\n\n  getTotalPages(): number {\n    return this.totalPages;\n  }\n\n  getScale(): number {\n    return this.scale;\n  }\n\n  goToPage(pageNumber: number): void {\n    this.currentPage = pageNumber;\n    if (this.config.onPageChange) {\n      this.config.onPageChange(pageNumber);\n    }\n  }\n\n  setScale(scale: number): void {\n    this.scale = scale;\n    if (this.config.onScaleChange) {\n      this.config.onScaleChange(scale);\n    }\n  }\n\n  getContainerElement(): HTMLElement | null {\n    return this.config.containerRef.current;\n  }\n\n  /**\n   * Update configuration dynamically\n   */\n  updateConfig(updates: Partial<GenericRendererConfig>): void {\n    if (updates.pageWidth !== undefined) {\n      this.config.pageWidth = updates.pageWidth;\n    }\n    if (updates.pageHeight !== undefined) {\n      this.config.pageHeight = updates.pageHeight;\n    }\n    if (updates.currentPage !== undefined) {\n      this.currentPage = updates.currentPage;\n    }\n    if (updates.totalPages !== undefined) {\n      this.totalPages = updates.totalPages;\n    }\n    if (updates.scale !== undefined) {\n      this.scale = updates.scale;\n    }\n  }\n}\n\n/**\n * Factory function to create Generic adapter\n */\nexport function createGenericAdapter(config: GenericRendererConfig): RendererAdapter {\n  return new GenericAdapter(config);\n}\n","import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';\nimport { Annotation, CreateAnnotationDto, UpdateAnnotationDto, StorageAdapter } from '../types';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('annotationsSlice');\n\nexport interface AnnotationsState {\n  list: Annotation[];\n  creating: Annotation | null; // In-progress annotation\n  selected: Annotation | null;\n  loading: boolean;\n  error: string | null;\n}\n\nconst initialState: AnnotationsState = {\n  list: [],\n  creating: null,\n  selected: null,\n  loading: false,\n  error: null,\n};\n\n// Async thunks that use the storage adapter\nexport const fetchAnnotations = createAsyncThunk(\n  'annotations/fetchAnnotations',\n  async ({\n    documentId,\n    versionId,\n    adapter,\n  }: {\n    documentId: string;\n    versionId?: string;\n    adapter: StorageAdapter;\n  }) => {\n    const annotations = await adapter.fetchAnnotations(documentId, versionId);\n    return annotations || [];\n  }\n);\n\nexport const createAnnotation = createAsyncThunk(\n  'annotations/create',\n  async ({ annotation, adapter }: { annotation: CreateAnnotationDto; adapter: StorageAdapter }) => {\n    const result = await adapter.createAnnotation(annotation);\n    return result;\n  }\n);\n\nexport const updateAnnotation = createAsyncThunk(\n  'annotations/update',\n  async ({\n    annotationId,\n    updates,\n    adapter,\n  }: {\n    annotationId: string;\n    updates: UpdateAnnotationDto;\n    adapter: StorageAdapter;\n  }) => {\n    const result = await adapter.updateAnnotation(annotationId, updates);\n    return result;\n  }\n);\n\nexport const deleteAnnotation = createAsyncThunk(\n  'annotations/delete',\n  async ({ annotationId, adapter }: { annotationId: string; adapter: StorageAdapter }) => {\n    await adapter.deleteAnnotation(annotationId);\n    return annotationId;\n  }\n);\n\nexport const toggleResolveAnnotation = createAsyncThunk(\n  'annotations/toggleResolve',\n  async ({ annotationId, adapter }: { annotationId: string; adapter: StorageAdapter }) => {\n    // Use the toggleResolve method if available, otherwise fall back to update\n    if (adapter.toggleResolve) {\n      return await adapter.toggleResolve(annotationId);\n    }\n    // Fallback: just return the annotation as-is\n    throw new Error('Toggle resolve not supported by adapter');\n  }\n);\n\n// Slice\nconst annotationsSlice = createSlice({\n  name: 'annotations',\n  initialState,\n  reducers: {\n    // Add annotation optimistically (before backend confirmation)\n    addAnnotationOptimistic(state, action: PayloadAction<Annotation>) {\n      state.list.push(action.payload);\n    },\n    // Update annotation from WebSocket/Collaboration\n    updateAnnotationFromWS(state, action: PayloadAction<Annotation>) {\n      const index = state.list.findIndex((a) => a.id === action.payload.id);\n      if (index !== -1) {\n        state.list[index] = action.payload;\n      }\n    },\n    // Remove annotation from WebSocket/Collaboration\n    removeAnnotationFromWS(state, action: PayloadAction<string>) {\n      state.list = state.list.filter((a) => a.id !== action.payload);\n    },\n    // Set creating annotation (in-progress)\n    setCreatingAnnotation(state, action: PayloadAction<Annotation | null>) {\n      state.creating = action.payload;\n    },\n    // Select annotation\n    selectAnnotation(state, action: PayloadAction<Annotation | null>) {\n      logger.debug('selectAnnotation', {\n        selectedId: action.payload?.id,\n        type: action.payload?.annotationType,\n      });\n      state.selected = action.payload;\n    },\n    // Clear all annotations\n    clearAnnotations(state) {\n      state.list = [];\n      state.creating = null;\n      state.selected = null;\n    },\n    // Clear error\n    clearError(state) {\n      state.error = null;\n    },\n  },\n  extraReducers: (builder) => {\n    // Fetch annotations\n    builder.addCase(fetchAnnotations.pending, (state) => {\n      state.loading = true;\n      state.error = null;\n    });\n    builder.addCase(fetchAnnotations.fulfilled, (state, action) => {\n      state.loading = false;\n      state.list = action.payload;\n    });\n    builder.addCase(fetchAnnotations.rejected, (state, action) => {\n      state.loading = false;\n      state.error = action.error.message || 'Failed to fetch annotations';\n    });\n\n    // Create annotation\n    builder.addCase(createAnnotation.fulfilled, (state, action) => {\n      // Replace optimistic annotation with real one\n      if (action.payload) {\n        const tempIndex = state.list.findIndex(\n          (a) => (a as any).tempId === (action.meta.arg.annotation as any).tempId\n        );\n        if (tempIndex !== -1) {\n          state.list[tempIndex] = action.payload;\n        } else {\n          state.list.push(action.payload);\n        }\n      }\n    });\n    builder.addCase(createAnnotation.rejected, (state, action) => {\n      state.error = action.error.message || 'Failed to create annotation';\n    });\n\n    // Update annotation\n    builder.addCase(updateAnnotation.fulfilled, (state, action) => {\n      logger.debug('updateAnnotation.fulfilled', { payload: action.payload });\n      if (action.payload) {\n        const index = state.list.findIndex((a) => a.id === action.payload!.id);\n        logger.debug('Found annotation at index', { index });\n        if (index !== -1) {\n          state.list[index] = action.payload;\n          logger.debug('Updated annotation in state');\n        }\n      }\n    });\n    builder.addCase(updateAnnotation.rejected, (state, action) => {\n      logger.error('updateAnnotation.rejected', { error: action.error });\n      state.error = action.error.message || 'Failed to update annotation';\n    });\n\n    // Delete annotation\n    builder.addCase(deleteAnnotation.fulfilled, (state, action) => {\n      logger.debug('deleteAnnotation.fulfilled', { annotationId: action.payload });\n      state.list = state.list.filter((a) => a.id !== action.payload);\n      if (state.selected?.id === action.payload) {\n        state.selected = null;\n      }\n      logger.debug('Annotation deleted from state');\n    });\n    builder.addCase(deleteAnnotation.rejected, (state, action) => {\n      logger.error('deleteAnnotation.rejected', { error: action.error });\n      state.error = action.error.message || 'Failed to delete annotation';\n    });\n\n    // Toggle resolve annotation\n    builder.addCase(toggleResolveAnnotation.fulfilled, (state, action) => {\n      logger.debug('toggleResolveAnnotation.fulfilled', { payload: action.payload });\n      if (action.payload) {\n        const index = state.list.findIndex((a) => a.id === action.payload!.id);\n        if (index !== -1) {\n          state.list[index] = action.payload;\n          // Update selected annotation if it's the same one\n          if (state.selected?.id === action.payload.id) {\n            state.selected = action.payload;\n          }\n        }\n      }\n    });\n    builder.addCase(toggleResolveAnnotation.rejected, (state, action) => {\n      logger.error('toggleResolveAnnotation.rejected', { error: action.error });\n      state.error = action.error.message || 'Failed to toggle resolve status';\n    });\n  },\n});\n\nexport const {\n  addAnnotationOptimistic,\n  updateAnnotationFromWS,\n  removeAnnotationFromWS,\n  setCreatingAnnotation,\n  selectAnnotation,\n  clearAnnotations,\n  clearError,\n} = annotationsSlice.actions;\n\nexport default annotationsSlice.reducer;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { AnnotationTool, ViewState } from '../types';\n\nexport interface UIState {\n  currentTool: AnnotationTool;\n  annotationColor: string;\n  viewState: ViewState;\n  sidebarOpen: boolean;\n  notesPanelOpen: boolean;\n}\n\nconst initialState: UIState = {\n  currentTool: AnnotationTool.SELECT,\n  annotationColor: '#FFEB3B',\n  viewState: {\n    scale: 1.0,\n    currentPage: 1,\n    totalPages: 0,\n  },\n  sidebarOpen: true,\n  notesPanelOpen: true,\n};\n\nconst uiSlice = createSlice({\n  name: 'ui',\n  initialState,\n  reducers: {\n    setCurrentTool(state, action: PayloadAction<AnnotationTool>) {\n      state.currentTool = action.payload;\n    },\n    setAnnotationColor(state, action: PayloadAction<string>) {\n      state.annotationColor = action.payload;\n    },\n    setScale(state, action: PayloadAction<number>) {\n      state.viewState.scale = action.payload;\n    },\n    setCurrentPage(state, action: PayloadAction<number>) {\n      state.viewState.currentPage = action.payload;\n    },\n    setTotalPages(state, action: PayloadAction<number>) {\n      state.viewState.totalPages = action.payload;\n    },\n    setViewState(state, action: PayloadAction<Partial<ViewState>>) {\n      state.viewState = { ...state.viewState, ...action.payload };\n    },\n    toggleSidebar(state) {\n      state.sidebarOpen = !state.sidebarOpen;\n    },\n    setSidebarOpen(state, action: PayloadAction<boolean>) {\n      state.sidebarOpen = action.payload;\n    },\n    toggleNotesPanel(state) {\n      state.notesPanelOpen = !state.notesPanelOpen;\n    },\n    setNotesPanelOpen(state, action: PayloadAction<boolean>) {\n      state.notesPanelOpen = action.payload;\n    },\n    resetUI() {\n      return initialState;\n    },\n  },\n});\n\nexport const {\n  setCurrentTool,\n  setAnnotationColor,\n  setScale,\n  setCurrentPage,\n  setTotalPages,\n  setViewState,\n  toggleSidebar,\n  setSidebarOpen,\n  toggleNotesPanel,\n  setNotesPanelOpen,\n  resetUI,\n} = uiSlice.actions;\n\nexport default uiSlice.reducer;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { DocumentVersion } from '../types';\n\nexport interface DocumentState {\n  currentDocument: DocumentVersion | null;\n  documentId: string | null;\n  versionId: string | null;\n  loading: boolean;\n  error: string | null;\n}\n\nconst initialState: DocumentState = {\n  currentDocument: null,\n  documentId: null,\n  versionId: null,\n  loading: false,\n  error: null,\n};\n\nconst documentSlice = createSlice({\n  name: 'document',\n  initialState,\n  reducers: {\n    setCurrentDocument(state, action: PayloadAction<DocumentVersion>) {\n      state.currentDocument = action.payload;\n      state.documentId = action.payload.documentId;\n      state.versionId = action.payload.id;\n      state.error = null;\n    },\n    setDocumentIds(state, action: PayloadAction<{ documentId: string; versionId?: string }>) {\n      state.documentId = action.payload.documentId;\n      state.versionId = action.payload.versionId || null;\n    },\n    setLoading(state, action: PayloadAction<boolean>) {\n      state.loading = action.payload;\n    },\n    setError(state, action: PayloadAction<string | null>) {\n      state.error = action.payload;\n    },\n    clearDocument(state) {\n      state.currentDocument = null;\n      state.documentId = null;\n      state.versionId = null;\n      state.error = null;\n    },\n  },\n});\n\nexport const { setCurrentDocument, setDocumentIds, setLoading, setError, clearDocument } =\n  documentSlice.actions;\n\nexport default documentSlice.reducer;\n","import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';\nimport { Comment, CreateCommentDto, UpdateCommentDto } from '../types/comment';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('commentsSlice');\n\nexport interface CommentsState {\n  comments: Record<string, Comment[]>; // Keyed by annotationId\n  loading: boolean;\n  error: string | null;\n}\n\nconst initialState: CommentsState = {\n  comments: {},\n  loading: false,\n  error: null,\n};\n\n// Async thunks (to be implemented with storage adapter)\nexport const fetchComments = createAsyncThunk(\n  'comments/fetch',\n  async ({ annotationId }: { annotationId: string }) => {\n    // This will be implemented by the storage adapter\n    logger.debug('Fetching comments', { annotationId });\n    return { annotationId, comments: [] as Comment[] };\n  }\n);\n\nexport const createComment = createAsyncThunk('comments/create', async (dto: CreateCommentDto) => {\n  logger.debug('Creating comment', { dto });\n\n  const comment: Comment = {\n    id: `comment_${Date.now()}_${Math.random()}`,\n    annotationId: dto.annotationId,\n    userId: dto.userId,\n    userName: dto.userName,\n    content: dto.content,\n    mentions: dto.mentions || [],\n    parentCommentId: dto.parentCommentId || null,\n    createdAt: new Date().toISOString(),\n    updatedAt: new Date().toISOString(),\n    isDeleted: false,\n    isEdited: false,\n    isResolved: false,\n  };\n\n  return comment;\n});\n\nexport const updateComment = createAsyncThunk(\n  'comments/update',\n  async ({ commentId, updates }: { commentId: string; updates: UpdateCommentDto }) => {\n    logger.debug('Updating comment', { commentId, updates });\n    return { commentId, updates };\n  }\n);\n\nexport const deleteComment = createAsyncThunk(\n  'comments/delete',\n  async ({ commentId }: { commentId: string }) => {\n    logger.debug('Deleting comment', { commentId });\n    return commentId;\n  }\n);\n\nexport const resolveComment = createAsyncThunk(\n  'comments/resolve',\n  async ({\n    commentId,\n    userId,\n    resolved,\n  }: {\n    commentId: string;\n    userId: string;\n    resolved: boolean;\n  }) => {\n    logger.debug('Resolving comment', { commentId, resolved });\n    return {\n      commentId,\n      resolved,\n      resolvedBy: resolved ? userId : undefined,\n      resolvedAt: resolved ? new Date().toISOString() : undefined,\n    };\n  }\n);\n\nconst commentsSlice = createSlice({\n  name: 'comments',\n  initialState,\n  reducers: {\n    addCommentOptimistic(state, action: PayloadAction<Comment>) {\n      const { annotationId } = action.payload;\n      if (!state.comments[annotationId]) {\n        state.comments[annotationId] = [];\n      }\n      state.comments[annotationId].push(action.payload);\n      logger.debug('Comment added optimistically', { commentId: action.payload.id });\n    },\n\n    updateCommentLocal(\n      state,\n      action: PayloadAction<{ commentId: string; updates: Partial<Comment> }>\n    ) {\n      const { commentId, updates } = action.payload;\n\n      // Find and update comment across all annotations\n      Object.values(state.comments).forEach((comments) => {\n        const comment = comments?.find((c) => c.id === commentId);\n        if (comment) {\n          Object.assign(comment, updates, {\n            updatedAt: new Date().toISOString(),\n            isEdited: true,\n          });\n        }\n      });\n    },\n\n    removeCommentLocal(state, action: PayloadAction<string>) {\n      const commentId = action.payload;\n\n      Object.values(state.comments).forEach((comments) => {\n        const index = comments.findIndex((c) => c.id === commentId);\n        if (index !== -1) {\n          comments.splice(index, 1);\n        }\n      });\n    },\n\n    resolveCommentLocal(\n      state,\n      action: PayloadAction<{\n        commentId: string;\n        resolved: boolean;\n        resolvedBy?: string;\n        resolvedAt?: string;\n      }>\n    ) {\n      const { commentId, resolved, resolvedBy, resolvedAt } = action.payload;\n\n      Object.values(state.comments).forEach((comments) => {\n        const comment = comments?.find((c) => c.id === commentId);\n        if (comment) {\n          comment.isResolved = resolved;\n          comment.resolvedBy = resolvedBy;\n          comment.resolvedAt = resolvedAt;\n          comment.updatedAt = new Date().toISOString();\n        }\n      });\n    },\n\n    clearComments(state, action: PayloadAction<string>) {\n      delete state.comments[action.payload];\n    },\n\n    clearAllComments(state) {\n      state.comments = {};\n    },\n  },\n\n  extraReducers: (builder) => {\n    // Fetch comments\n    builder.addCase(fetchComments.pending, (state) => {\n      state.loading = true;\n      state.error = null;\n    });\n    builder.addCase(fetchComments.fulfilled, (state, action) => {\n      const { annotationId, comments } = action.payload;\n      state.comments[annotationId] = comments;\n      state.loading = false;\n    });\n    builder.addCase(fetchComments.rejected, (state, action) => {\n      state.loading = false;\n      state.error = action.error.message || 'Failed to fetch comments';\n      logger.error('Failed to fetch comments', { error: action.error });\n    });\n\n    // Create comment\n    builder.addCase(createComment.fulfilled, (state, action) => {\n      const comment = action.payload;\n      if (!state.comments[comment.annotationId]) {\n        state.comments[comment.annotationId] = [];\n      }\n      const commentsArray = state.comments[comment.annotationId];\n      if (commentsArray) {\n        commentsArray.push(comment);\n      }\n    });\n\n    // Update comment\n    builder.addCase(updateComment.fulfilled, (state, action) => {\n      const { commentId, updates } = action.payload;\n\n      Object.values(state.comments).forEach((comments) => {\n        const comment = comments.find((c) => c.id === commentId);\n        if (comment) {\n          Object.assign(comment, updates, {\n            updatedAt: new Date().toISOString(),\n            isEdited: true,\n          });\n        }\n      });\n    });\n\n    // Delete comment\n    builder.addCase(deleteComment.fulfilled, (state, action) => {\n      const commentId = action.payload;\n\n      Object.values(state.comments).forEach((comments) => {\n        const comment = comments.find((c) => c.id === commentId);\n        if (comment) {\n          comment.isDeleted = true;\n        }\n      });\n    });\n\n    // Resolve comment\n    builder.addCase(resolveComment.fulfilled, (state, action) => {\n      const { commentId, resolved, resolvedBy, resolvedAt } = action.payload;\n\n      Object.values(state.comments).forEach((comments) => {\n        const comment = comments.find((c) => c.id === commentId);\n        if (comment) {\n          comment.isResolved = resolved;\n          comment.resolvedBy = resolvedBy;\n          comment.resolvedAt = resolvedAt;\n          comment.updatedAt = new Date().toISOString();\n        }\n      });\n    });\n  },\n});\n\nexport const {\n  addCommentOptimistic,\n  updateCommentLocal,\n  removeCommentLocal,\n  resolveCommentLocal,\n  clearComments,\n  clearAllComments,\n} = commentsSlice.actions;\n\nexport default commentsSlice.reducer;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { HistoryEntry, HistoryFilter } from '../types/history';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('historySlice');\n\nexport interface HistoryState {\n  entries: HistoryEntry[];\n  loading: boolean;\n  error: string | null;\n  filter: HistoryFilter | null;\n}\n\nconst initialState: HistoryState = {\n  entries: [],\n  loading: false,\n  error: null,\n  filter: null,\n};\n\nconst historySlice = createSlice({\n  name: 'history',\n  initialState,\n  reducers: {\n    recordHistoryEntry(state, action: PayloadAction<Omit<HistoryEntry, 'id' | 'timestamp'>>) {\n      const entry: HistoryEntry = {\n        ...action.payload,\n        id: `history_${Date.now()}_${Math.random()}`,\n        timestamp: new Date().toISOString(),\n      };\n\n      state.entries.unshift(entry); // Add to beginning\n\n      // Keep only last 1000 entries\n      if (state.entries.length > 1000) {\n        state.entries = state.entries.slice(0, 1000);\n      }\n\n      logger.debug('History entry recorded', {\n        action: entry.action,\n        entityType: entry.entityType,\n        entityId: entry.entityId,\n      });\n    },\n\n    setHistoryFilter(state, action: PayloadAction<HistoryFilter | null>) {\n      state.filter = action.payload;\n    },\n\n    clearHistory(state, action: PayloadAction<{ entityId?: string; entityType?: string }>) {\n      if (action.payload.entityId) {\n        state.entries = state.entries.filter((entry) => entry.entityId !== action.payload.entityId);\n      } else if (action.payload.entityType) {\n        state.entries = state.entries.filter(\n          (entry) => entry.entityType !== action.payload.entityType\n        );\n      } else {\n        state.entries = [];\n      }\n    },\n\n    setLoading(state, action: PayloadAction<boolean>) {\n      state.loading = action.payload;\n    },\n\n    setError(state, action: PayloadAction<string | null>) {\n      state.error = action.payload;\n    },\n  },\n});\n\nexport const { recordHistoryEntry, setHistoryFilter, clearHistory, setLoading, setError } =\n  historySlice.actions;\n\nexport default historySlice.reducer;\n\n// Selectors\nexport const selectFilteredHistory = (state: { history: HistoryState }) => {\n  const { entries, filter } = state.history;\n\n  if (!filter) return entries;\n\n  return entries.filter((entry) => {\n    if (filter.entityType && entry.entityType !== filter.entityType) return false;\n    if (filter.entityId && entry.entityId !== filter.entityId) return false;\n    if (filter.userId && entry.userId !== filter.userId) return false;\n    if (filter.action && entry.action !== filter.action) return false;\n\n    if (filter.dateRange) {\n      const entryDate = new Date(entry.timestamp);\n      const start = new Date(filter.dateRange.start);\n      const end = new Date(filter.dateRange.end);\n\n      if (entryDate < start || entryDate > end) return false;\n    }\n\n    return true;\n  });\n};\n\nexport const selectHistoryByEntity = (\n  state: { history: HistoryState },\n  entityType: string,\n  entityId: string\n) => {\n  return state.history.entries.filter(\n    (entry) => entry.entityType === entityType && entry.entityId === entityId\n  );\n};\n","import { configureStore, Middleware, ThunkAction, UnknownAction } from '@reduxjs/toolkit';\nimport annotationsReducer from './annotationsSlice';\nimport uiReducer from './uiSlice';\nimport documentReducer from './documentSlice';\nimport commentsReducer from './commentsSlice';\nimport historyReducer from './historySlice';\nimport { StorageAdapter, CollaborationAdapter } from '../types';\n\nexport interface StoreAdapters {\n  storage?: StorageAdapter;\n  collaboration?: CollaborationAdapter;\n}\n\n// Define RootState first based on reducers\nexport type RootState = {\n  annotations: ReturnType<typeof annotationsReducer>;\n  ui: ReturnType<typeof uiReducer>;\n  document: ReturnType<typeof documentReducer>;\n  comments: ReturnType<typeof commentsReducer>;\n  history: ReturnType<typeof historyReducer>;\n};\n\nexport interface CreateStoreOptions {\n  adapters?: StoreAdapters;\n  middleware?: Middleware[];\n  preloadedState?: Partial<RootState>;\n}\n\nexport const createAnnotationStore = (options: CreateStoreOptions = {}) => {\n  const { adapters = {}, middleware: extraMiddleware = [], preloadedState } = options;\n\n  const store = configureStore({\n    reducer: {\n      annotations: annotationsReducer,\n      ui: uiReducer,\n      document: documentReducer,\n      comments: commentsReducer,\n      history: historyReducer,\n    },\n    middleware: (getDefaultMiddleware: any) => {\n      const middleware = getDefaultMiddleware({\n        serializableCheck: {\n          // Ignore these action types\n          ignoredActions: ['annotations/setCreatingAnnotation'],\n          // Ignore these paths in the state\n          ignoredPaths: ['annotations.creating'],\n        },\n      });\n      return middleware.concat(extraMiddleware) as any;\n    },\n    preloadedState: preloadedState as any,\n  } as any);\n\n  // Attach adapters to the store for easy access\n  return Object.assign(store, { adapters });\n};\n\n// Type helpers\nexport type AnnotationStore = ReturnType<typeof createAnnotationStore>;\nexport type AppDispatch = AnnotationStore['dispatch'];\nexport type AppThunk<ReturnType = void> = ThunkAction<\n  ReturnType,\n  RootState,\n  unknown,\n  UnknownAction\n>;\n\n// Helper to get adapters from store\nexport const getAdapters = (store: AnnotationStore): StoreAdapters => {\n  return store.adapters;\n};\n","import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux';\nimport type { RootState, AppDispatch } from './store';\n\n// Use throughout your app instead of plain `useDispatch` and `useSelector`\nexport const useAppDispatch = () => useDispatch<AppDispatch>();\nexport const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;\n\n// Additional convenience hooks\nexport const useAnnotations = () => {\n  return useAppSelector((state) => state.annotations);\n};\n\nexport const useUI = () => {\n  return useAppSelector((state) => state.ui);\n};\n\nexport const useDocument = () => {\n  return useAppSelector((state) => state.document);\n};\n\nexport const useSelectedAnnotation = () => {\n  return useAppSelector((state) => state.annotations.selected);\n};\n\nexport const useCurrentTool = () => {\n  return useAppSelector((state) => state.ui.currentTool);\n};\n\nexport const useAnnotationColor = () => {\n  return useAppSelector((state) => state.ui.annotationColor);\n};\n\nexport const useViewState = () => {\n  return useAppSelector((state) => state.ui.viewState);\n};\n\nexport const useCreatingAnnotation = () => {\n  return useAppSelector((state) => state.annotations.creating);\n};\n","import { createContext, useContext } from 'react';\nimport {\n  StorageAdapter,\n  CollaborationAdapter,\n  RendererAdapter,\n  AnnotationConfig,\n} from '../../types';\n\nexport interface AnnotationContextValue {\n  config: AnnotationConfig;\n  adapters: {\n    storage?: StorageAdapter;\n    collaboration?: CollaborationAdapter;\n    renderer?: RendererAdapter;\n  };\n  documentId?: string;\n  versionId?: string;\n  userId?: string;\n}\n\nexport const AnnotationContext = createContext<AnnotationContextValue | null>(null);\n\nexport const useAnnotationContext = () => {\n  const context = useContext(AnnotationContext);\n  if (!context) {\n    throw new Error('useAnnotationContext must be used within AnnotationProvider');\n  }\n  return context;\n};\n","import { useCallback } from 'react';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport { useAnnotationContext } from '../components/AnnotationProvider/AnnotationContext';\nimport {\n  addAnnotationOptimistic,\n  updateAnnotationFromWS,\n  removeAnnotationFromWS,\n  selectAnnotation,\n  clearAnnotations,\n} from '../store/annotationsSlice';\nimport { createComment } from '../store/commentsSlice';\nimport { recordHistoryEntry } from '../store/historySlice';\nimport { Annotation, CreateAnnotationDto } from '../types';\nimport { AnnotationType } from '../types/annotation';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('useAnnotations');\n\n/**\n * Helper function to get human-readable annotation type label\n */\nfunction getAnnotationTypeLabel(type: AnnotationType): string {\n  switch (type) {\n    case AnnotationType.HIGHLIGHT:\n      return 'Highlight';\n    case AnnotationType.DRAWING:\n      return 'Drawing';\n    case AnnotationType.NOTE:\n      return 'Note';\n    case AnnotationType.SHAPE:\n      return 'Shape';\n    default:\n      return 'Annotation';\n  }\n}\n\n/**\n * Hook for managing annotations\n * Provides high-level API for annotation CRUD operations\n */\nexport function useAnnotations() {\n  const dispatch = useAppDispatch();\n  const { adapters, config } = useAnnotationContext();\n  const annotations = useAppSelector((state) => state.annotations.list);\n  const loading = useAppSelector((state) => state.annotations.loading);\n  const error = useAppSelector((state) => state.annotations.error);\n  const selected = useAppSelector((state) => state.annotations.selected);\n  const creating = useAppSelector((state) => state.annotations.creating);\n\n  const createAnnotation = useCallback(\n    async (dto: CreateAnnotationDto) => {\n      if (!adapters.storage) {\n        throw new Error('Storage adapter not configured');\n      }\n\n      try {\n        // Optimistic update\n        const tempAnnotation: Annotation = {\n          ...dto,\n          id: dto.tempId || `temp_${Date.now()}`,\n          createdAt: new Date().toISOString(),\n          updatedAt: new Date().toISOString(),\n          isDeleted: false,\n        };\n\n        dispatch(addAnnotationOptimistic(tempAnnotation));\n\n        // Auto-create comment entry if enabled\n        if (config?.behavior?.autoCreateCommentOnAnnotation !== false && config?.userId) {\n          const annotationTypeLabel = getAnnotationTypeLabel(dto.annotationType);\n          const commentContent = `${annotationTypeLabel} annotation created on page ${dto.pageNumber}`;\n\n          try {\n            const commentResult = await dispatch(\n              createComment({\n                annotationId: tempAnnotation.id,\n                userId: config.userId,\n                userName: config.userName,\n                content: commentContent,\n                mentions: [],\n              })\n            ).unwrap();\n\n            // Record history for the auto-created comment\n            dispatch(\n              recordHistoryEntry({\n                entityType: 'comment',\n                entityId: commentResult.id,\n                action: 'created',\n                userId: config.userId,\n                userName: config.userName,\n                metadata: {\n                  annotationId: tempAnnotation.id,\n                  autoCreated: true,\n                },\n              })\n            );\n\n            logger.debug('Auto-created comment for annotation', {\n              annotationId: tempAnnotation.id,\n              commentId: commentResult.id,\n            });\n          } catch (commentErr) {\n            logger.error('Failed to auto-create comment', { error: commentErr });\n            // Don't fail the annotation creation if comment creation fails\n          }\n        }\n\n        // Emit to collaboration\n        if (adapters.collaboration?.isConnected()) {\n          adapters.collaboration.emit({\n            type: 'annotation:created',\n            annotation: dto,\n          });\n        }\n\n        // Call callback\n        config?.callbacks?.onAnnotationCreate?.(tempAnnotation);\n\n        return tempAnnotation;\n      } catch (err) {\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [adapters, dispatch, config]\n  );\n\n  const updateAnnotation = useCallback(\n    async (annotationId: string, updates: Partial<Annotation>) => {\n      if (!adapters.storage) {\n        throw new Error('Storage adapter not configured');\n      }\n\n      try {\n        const updated = await adapters.storage.updateAnnotation(annotationId, updates);\n        dispatch(updateAnnotationFromWS(updated));\n\n        // Emit to collaboration\n        if (adapters.collaboration?.isConnected()) {\n          adapters.collaboration.emit({\n            type: 'annotation:updated',\n            annotationId,\n            updates: updates as any,\n          });\n        }\n\n        config?.callbacks?.onAnnotationUpdate?.(updated);\n        return updated;\n      } catch (err) {\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [adapters, dispatch, config]\n  );\n\n  const deleteAnnotation = useCallback(\n    async (annotationId: string) => {\n      if (!adapters.storage) {\n        throw new Error('Storage adapter not configured');\n      }\n\n      try {\n        await adapters.storage.deleteAnnotation(annotationId);\n        dispatch(removeAnnotationFromWS(annotationId));\n\n        // Emit to collaboration\n        if (adapters.collaboration?.isConnected()) {\n          adapters.collaboration.emit({\n            type: 'annotation:deleted',\n            annotationId,\n          });\n        }\n\n        config?.callbacks?.onAnnotationDelete?.(annotationId);\n      } catch (err) {\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [adapters, dispatch, config]\n  );\n\n  const selectAnnotationById = useCallback(\n    (annotation: Annotation | null) => {\n      dispatch(selectAnnotation(annotation));\n    },\n    [dispatch]\n  );\n\n  const clearAllAnnotations = useCallback(() => {\n    dispatch(clearAnnotations());\n  }, [dispatch]);\n\n  return {\n    annotations,\n    loading,\n    error,\n    selected,\n    creating,\n    createAnnotation,\n    updateAnnotation,\n    deleteAnnotation,\n    selectAnnotation: selectAnnotationById,\n    clearAnnotations: clearAllAnnotations,\n  };\n}\n","import { useState, useCallback } from 'react';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport { setCurrentTool, setAnnotationColor } from '../store/uiSlice';\nimport { setCreatingAnnotation } from '../store/annotationsSlice';\nimport { AnnotationTool, Annotation } from '../types';\n\n/**\n * Hook for managing annotation drawing state\n */\nexport function useAnnotationDraw() {\n  const dispatch = useAppDispatch();\n  const currentTool = useAppSelector((state) => state.ui.currentTool);\n  const color = useAppSelector((state) => state.ui.annotationColor);\n  const creating = useAppSelector((state) => state.annotations.creating);\n  const [isDrawing, setIsDrawing] = useState(false);\n\n  const setTool = useCallback(\n    (tool: AnnotationTool) => {\n      dispatch(setCurrentTool(tool));\n    },\n    [dispatch]\n  );\n\n  const setColor = useCallback(\n    (newColor: string) => {\n      dispatch(setAnnotationColor(newColor));\n    },\n    [dispatch]\n  );\n\n  const startDrawing = useCallback(() => {\n    setIsDrawing(true);\n  }, []);\n\n  const stopDrawing = useCallback(() => {\n    setIsDrawing(false);\n  }, []);\n\n  const setCreating = useCallback(\n    (annotation: Annotation | null) => {\n      dispatch(setCreatingAnnotation(annotation));\n    },\n    [dispatch]\n  );\n\n  return {\n    currentTool,\n    setTool,\n    color,\n    setColor,\n    isDrawing,\n    startDrawing,\n    stopDrawing,\n    creating,\n    setCreating,\n  };\n}\n","import { useAppSelector } from '../store/hooks';\nimport { useAnnotationContext } from '../components/AnnotationProvider/AnnotationContext';\n\n/**\n * Hook for accessing document information\n */\nexport function useDocument() {\n  const { documentId, versionId } = useAnnotationContext();\n  const documentState = useAppSelector((state) => state.document);\n\n  return {\n    documentId,\n    versionId,\n    currentDocument: documentState.currentDocument,\n    loading: documentState.loading,\n    error: documentState.error,\n  };\n}\n","import { useEffect } from 'react';\nimport { useAppDispatch } from '../store/hooks';\nimport { useAnnotationContext } from '../components/AnnotationProvider/AnnotationContext';\nimport {\n  addAnnotationOptimistic,\n  updateAnnotationFromWS,\n  removeAnnotationFromWS,\n} from '../store/annotationsSlice';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('useCollaboration');\n\n/**\n * Hook for managing real-time collaboration\n * Handles WebSocket events and synchronization\n */\nexport function useCollaboration() {\n  const dispatch = useAppDispatch();\n  const { adapters, documentId, versionId } = useAnnotationContext();\n\n  useEffect(() => {\n    const collaboration = adapters.collaboration;\n    if (!collaboration || !collaboration.isConnected()) {\n      return;\n    }\n\n    // Handle annotation created by other users\n    const handleCreated = (data: any) => {\n      if (data.annotation) {\n        dispatch(addAnnotationOptimistic(data.annotation));\n      }\n    };\n\n    // Handle annotation updated by other users\n    const handleUpdated = (data: any) => {\n      if (data.annotation) {\n        dispatch(updateAnnotationFromWS(data.annotation));\n      }\n    };\n\n    // Handle annotation deleted by other users\n    const handleDeleted = (data: any) => {\n      if (data.annotationId) {\n        dispatch(removeAnnotationFromWS(data.annotationId));\n      }\n    };\n\n    // Handle errors\n    const handleError = (data: any) => {\n      logger.error('Error:', data);\n    };\n\n    // Register event listeners\n    collaboration.on('annotationCreated', handleCreated);\n    collaboration.on('annotationUpdated', handleUpdated);\n    collaboration.on('annotationDeleted', handleDeleted);\n    collaboration.on('annotationError', handleError);\n\n    // Join document room\n    if (documentId && versionId) {\n      collaboration.joinDocument(documentId, versionId);\n    }\n\n    // Cleanup\n    return () => {\n      collaboration.off('annotationCreated', handleCreated);\n      collaboration.off('annotationUpdated', handleUpdated);\n      collaboration.off('annotationDeleted', handleDeleted);\n      collaboration.off('annotationError', handleError);\n\n      if (documentId && versionId) {\n        collaboration.leaveDocument(documentId, versionId);\n      }\n    };\n  }, [adapters.collaboration, documentId, versionId, dispatch]);\n\n  return {\n    isConnected: adapters.collaboration?.isConnected() || false,\n  };\n}\n","import { useCallback, useRef, useEffect } from 'react';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport { setViewState } from '../store/uiSlice';\n\n/**\n * Hook for managing viewport state (zoom, page navigation)\n */\nexport function useViewport() {\n  const dispatch = useAppDispatch();\n  const scale = useAppSelector((state) => state.ui.viewState.scale);\n  const currentPage = useAppSelector((state) => state.ui.viewState.currentPage);\n  const totalPages = useAppSelector((state) => state.ui.viewState.totalPages);\n\n  // Use ref to store latest values without triggering re-renders\n  const stateRef = useRef({ scale, currentPage, totalPages });\n\n  useEffect(() => {\n    stateRef.current = { scale, currentPage, totalPages };\n  }, [scale, currentPage, totalPages]);\n\n  const setScale = useCallback(\n    (newScale: number) => {\n      const { currentPage, totalPages } = stateRef.current;\n      dispatch(setViewState({ scale: newScale, currentPage, totalPages }));\n    },\n    [dispatch]\n  );\n\n  const setCurrentPage = useCallback(\n    (page: number) => {\n      const { scale, totalPages } = stateRef.current;\n      dispatch(setViewState({ scale, currentPage: page, totalPages }));\n    },\n    [dispatch]\n  );\n\n  const setTotalPages = useCallback(\n    (total: number) => {\n      const { scale, currentPage } = stateRef.current;\n      dispatch(setViewState({ scale, currentPage, totalPages: total }));\n    },\n    [dispatch]\n  );\n\n  const nextPage = useCallback(() => {\n    const { scale, currentPage, totalPages } = stateRef.current;\n    if (currentPage < totalPages) {\n      dispatch(setViewState({ scale, currentPage: currentPage + 1, totalPages }));\n    }\n  }, [dispatch]);\n\n  const previousPage = useCallback(() => {\n    const { scale, currentPage, totalPages } = stateRef.current;\n    if (currentPage > 1) {\n      dispatch(setViewState({ scale, currentPage: currentPage - 1, totalPages }));\n    }\n  }, [dispatch]);\n\n  const zoomIn = useCallback(() => {\n    const { scale, currentPage, totalPages } = stateRef.current;\n    const newScale = Math.min(scale + 0.1, 3.0);\n    dispatch(setViewState({ scale: newScale, currentPage, totalPages }));\n  }, [dispatch]);\n\n  const zoomOut = useCallback(() => {\n    const { scale, currentPage, totalPages } = stateRef.current;\n    const newScale = Math.max(scale - 0.1, 0.5);\n    dispatch(setViewState({ scale: newScale, currentPage, totalPages }));\n  }, [dispatch]);\n\n  return {\n    scale,\n    currentPage,\n    totalPages,\n    setScale,\n    setCurrentPage,\n    setTotalPages,\n    nextPage,\n    previousPage,\n    zoomIn,\n    zoomOut,\n  };\n}\n","/**\n * Utility functions for parsing and handling @mentions in comments\n */\n\nexport interface MentionMatch {\n  userId: string;\n  userName: string;\n  startIndex: number;\n  endIndex: number;\n}\n\n/**\n * Parse @mentions from text\n * Supports formats:\n * - @username\n * - @[User Name](userId)\n */\nexport function parseMentions(text: string): string[] {\n  const mentions: string[] = [];\n\n  // Match @[Display Name](userId) format\n  const bracketMatches = text.matchAll(/@\\[([^\\]]+)\\]\\(([^)]+)\\)/g);\n  for (const match of bracketMatches) {\n    const userId = match[2];\n    if (userId && !mentions.includes(userId)) {\n      mentions.push(userId);\n    }\n  }\n\n  // Match simple @username format (word characters only)\n  const simpleMatches = text.matchAll(/@([\\w-]+)/g);\n  for (const match of simpleMatches) {\n    const username = match[1];\n    if (username && !mentions.includes(username)) {\n      mentions.push(username);\n    }\n  }\n\n  return mentions;\n}\n\n/**\n * Highlight mentions in text for display\n */\nexport function highlightMentions(\n  text: string,\n  currentUserId?: string\n): { text: string; hasMention: boolean } {\n  let highlightedText = text;\n  let hasMention = false;\n\n  // Replace @[Display Name](userId) with highlighted version\n  highlightedText = highlightedText.replace(\n    /@\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n    (_match, displayName, userId) => {\n      const isCurrentUser = userId === currentUserId;\n      hasMention = hasMention || isCurrentUser;\n      const className = isCurrentUser ? 'mention mention-me' : 'mention';\n      return `<span class=\"${className}\" data-user-id=\"${userId}\">@${displayName}</span>`;\n    }\n  );\n\n  // Replace simple @username with highlighted version\n  highlightedText = highlightedText.replace(/@([\\w-]+)/g, (_match, username) => {\n    const isCurrentUser = username === currentUserId;\n    hasMention = hasMention || isCurrentUser;\n    const className = isCurrentUser ? 'mention mention-me' : 'mention';\n    return `<span class=\"${className}\" data-user-id=\"${username}\">@${username}</span>`;\n  });\n\n  return { text: highlightedText, hasMention };\n}\n\n/**\n * Create a mention string\n */\nexport function createMention(userId: string, userName?: string): string {\n  if (userName) {\n    return `@[${userName}](${userId})`;\n  }\n  return `@${userId}`;\n}\n\n/**\n * Validate mention format\n */\nexport function isValidMention(text: string): boolean {\n  // Check if it matches @[Name](id) or @username\n  const bracketPattern = /@\\[([^\\]]+)\\]\\(([^)]+)\\)/;\n  const simplePattern = /@([\\w-]+)/;\n\n  return bracketPattern.test(text) || simplePattern.test(text);\n}\n\n/**\n * Extract user IDs from mentions\n */\nexport function extractUserIds(text: string): string[] {\n  return parseMentions(text);\n}\n\n/**\n * Replace user IDs with display names in mentions\n */\nexport function replaceMentionIds(text: string, userMap: Map<string, string>): string {\n  let result = text;\n\n  // Replace @userId with @[userName](userId) if userName is available\n  userMap.forEach((userName, userId) => {\n    const regex = new RegExp(`@${userId}(?!\\\\])`, 'g');\n    result = result.replace(regex, createMention(userId, userName));\n  });\n\n  return result;\n}\n","import { useCallback, useMemo } from 'react';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport {\n  createComment,\n  updateComment,\n  deleteComment,\n  resolveComment,\n  updateCommentLocal,\n  removeCommentLocal,\n  resolveCommentLocal,\n} from '../store/commentsSlice';\nimport { recordHistoryEntry } from '../store/historySlice';\nimport { CreateCommentDto, UpdateCommentDto, Comment, CommentThread } from '../types/comment';\nimport { parseMentions } from '../utils/mentionParser';\nimport { useAnnotationContext } from '../components/AnnotationProvider/AnnotationContext';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('useComments');\n\n/**\n * Hook for managing comments on annotations\n */\nexport function useComments(annotationId: string) {\n  const dispatch = useAppDispatch();\n  const { config } = useAnnotationContext();\n\n  const allComments = useAppSelector((state) => state.comments?.comments[annotationId] || []);\n  const loading = useAppSelector((state) => state.comments?.loading || false);\n  const error = useAppSelector((state) => state.comments?.error);\n\n  // Organize comments into threads\n  const threads = useMemo(() => {\n    const threadsMap = new Map<string, CommentThread>();\n\n    // First pass: find all parent comments\n    allComments\n      .filter((c) => !c.parentCommentId && !c.isDeleted)\n      .forEach((comment) => {\n        threadsMap.set(comment.id, {\n          comment,\n          replies: [],\n          replyCount: 0,\n        });\n      });\n\n    // Second pass: add replies to threads\n    allComments\n      .filter((c) => c.parentCommentId && !c.isDeleted)\n      .forEach((reply) => {\n        const thread = threadsMap.get(reply.parentCommentId!);\n        if (thread) {\n          thread.replies.push(reply);\n          thread.replyCount++;\n        }\n      });\n\n    // Sort replies by date\n    threadsMap.forEach((thread) => {\n      thread.replies.sort(\n        (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n      );\n    });\n\n    return Array.from(threadsMap.values()).sort(\n      (a, b) => new Date(b.comment.createdAt).getTime() - new Date(a.comment.createdAt).getTime()\n    );\n  }, [allComments]);\n\n  const commentCount = useMemo(() => allComments.filter((c) => !c.isDeleted).length, [allComments]);\n\n  const addComment = useCallback(\n    async (content: string, parentCommentId?: string) => {\n      if (!config?.userId) {\n        logger.error('Cannot add comment: userId not configured');\n        throw new Error('User ID is required to add comments');\n      }\n\n      const mentions = parseMentions(content);\n\n      const dto: CreateCommentDto = {\n        annotationId,\n        userId: config.userId,\n        userName: config.userName,\n        content,\n        mentions,\n        parentCommentId,\n      };\n\n      try {\n        const result = await dispatch(createComment(dto)).unwrap();\n\n        // Record history\n        dispatch(\n          recordHistoryEntry({\n            entityType: 'comment',\n            entityId: result.id,\n            action: 'created',\n            userId: config.userId,\n            userName: config.userName,\n            metadata: {\n              annotationId,\n              parentCommentId,\n              mentionsCount: mentions.length,\n            },\n          })\n        );\n\n        // Trigger callback\n        config?.callbacks?.onCommentCreate?.(result);\n\n        logger.debug('Comment created', { commentId: result.id });\n        return result;\n      } catch (err) {\n        logger.error('Failed to create comment', { error: err });\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [dispatch, annotationId, config]\n  );\n\n  const editComment = useCallback(\n    async (commentId: string, content: string) => {\n      const mentions = parseMentions(content);\n      const updates: UpdateCommentDto = { content, mentions };\n\n      try {\n        await dispatch(updateComment({ commentId, updates })).unwrap();\n\n        // Record history\n        if (config?.userId) {\n          dispatch(\n            recordHistoryEntry({\n              entityType: 'comment',\n              entityId: commentId,\n              action: 'updated',\n              userId: config.userId,\n              userName: config.userName,\n              changes: [{ field: 'content', oldValue: '', newValue: content, valueType: 'string' }],\n            })\n          );\n        }\n\n        logger.debug('Comment updated', { commentId });\n      } catch (err) {\n        logger.error('Failed to update comment', { error: err });\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [dispatch, config]\n  );\n\n  const removeComment = useCallback(\n    async (commentId: string) => {\n      try {\n        await dispatch(deleteComment({ commentId })).unwrap();\n\n        // Record history\n        if (config?.userId) {\n          dispatch(\n            recordHistoryEntry({\n              entityType: 'comment',\n              entityId: commentId,\n              action: 'deleted',\n              userId: config.userId,\n              userName: config.userName,\n              metadata: { annotationId },\n            })\n          );\n        }\n\n        logger.debug('Comment deleted', { commentId });\n      } catch (err) {\n        logger.error('Failed to delete comment', { error: err });\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [dispatch, annotationId, config]\n  );\n\n  const replyToComment = useCallback(\n    async (parentCommentId: string, content: string) => {\n      return addComment(content, parentCommentId);\n    },\n    [addComment]\n  );\n\n  const toggleResolve = useCallback(\n    async (commentId: string) => {\n      if (!config?.userId) {\n        logger.error('Cannot resolve comment: userId not configured');\n        throw new Error('User ID is required to resolve comments');\n      }\n\n      // Find the comment to get current resolved state\n      const comment = allComments.find((c) => c.id === commentId);\n      if (!comment) {\n        logger.error('Comment not found', { commentId });\n        throw new Error('Comment not found');\n      }\n\n      const newResolvedState = !comment.isResolved;\n\n      try {\n        await dispatch(\n          resolveComment({\n            commentId,\n            userId: config.userId,\n            resolved: newResolvedState,\n          })\n        ).unwrap();\n\n        // Record history\n        dispatch(\n          recordHistoryEntry({\n            entityType: 'comment',\n            entityId: commentId,\n            action: 'updated',\n            userId: config.userId,\n            userName: config.userName,\n            changes: [\n              {\n                field: 'isResolved',\n                oldValue: String(!newResolvedState),\n                newValue: String(newResolvedState),\n                valueType: 'boolean',\n              },\n            ],\n            metadata: {\n              annotationId,\n              resolvedState: newResolvedState,\n            },\n          })\n        );\n\n        // Trigger callback\n        config?.callbacks?.onCommentUpdate?.(comment);\n\n        logger.debug('Comment resolve state toggled', { commentId, resolved: newResolvedState });\n      } catch (err) {\n        logger.error('Failed to toggle comment resolve state', { error: err });\n        config?.callbacks?.onError?.(err as Error);\n        throw err;\n      }\n    },\n    [dispatch, annotationId, config, allComments]\n  );\n\n  return {\n    comments: allComments,\n    threads,\n    commentCount,\n    loading,\n    error,\n    addComment,\n    editComment,\n    removeComment,\n    replyToComment,\n    toggleResolve,\n  };\n}\n\n/**\n * Hook for a single comment\n */\nexport function useComment(commentId: string) {\n  const dispatch = useAppDispatch();\n\n  const comment = useAppSelector((state) => {\n    const allComments = Object.values(state.comments?.comments || {}).flat();\n    return allComments.find((c) => c.id === commentId);\n  });\n\n  const updateLocal = useCallback(\n    (updates: Partial<Comment>) => {\n      dispatch(updateCommentLocal({ commentId, updates }));\n    },\n    [dispatch, commentId]\n  );\n\n  const removeLocal = useCallback(() => {\n    dispatch(removeCommentLocal(commentId));\n  }, [dispatch, commentId]);\n\n  const resolveLocal = useCallback(\n    (resolved: boolean, resolvedBy?: string) => {\n      dispatch(\n        resolveCommentLocal({\n          commentId,\n          resolved,\n          resolvedBy,\n          resolvedAt: resolved ? new Date().toISOString() : undefined,\n        })\n      );\n    },\n    [dispatch, commentId]\n  );\n\n  return {\n    comment,\n    updateLocal,\n    removeLocal,\n    resolveLocal,\n  };\n}\n","/**\n * Utility functions for tracking changes in audit trail\n */\n\nimport { HistoryChange } from '../types/history';\n\n/**\n * Calculate diff between two objects\n */\nexport function calculateDiff(\n  oldValue: Record<string, unknown>,\n  newValue: Record<string, unknown>\n): HistoryChange[] {\n  const changes: HistoryChange[] = [];\n\n  // Check all keys in new value\n  Object.keys(newValue).forEach((key) => {\n    if (shouldTrackField(key) && oldValue[key] !== newValue[key]) {\n      changes.push({\n        field: key,\n        oldValue: oldValue[key],\n        newValue: newValue[key],\n        valueType: getValueType(newValue[key]),\n      });\n    }\n  });\n\n  // Check for deleted keys\n  Object.keys(oldValue).forEach((key) => {\n    if (shouldTrackField(key) && !(key in newValue)) {\n      changes.push({\n        field: key,\n        oldValue: oldValue[key],\n        newValue: undefined,\n        valueType: getValueType(oldValue[key]),\n      });\n    }\n  });\n\n  return changes;\n}\n\n/**\n * Determine if a field should be tracked\n */\nfunction shouldTrackField(field: string): boolean {\n  // Don't track internal fields\n  const ignoredFields = ['id', 'createdAt', 'updatedAt', '__typename'];\n  return !ignoredFields.includes(field);\n}\n\n/**\n * Get the type of a value\n */\nfunction getValueType(value: unknown): HistoryChange['valueType'] {\n  if (Array.isArray(value)) return 'array';\n  if (value === null) return 'object';\n  if (typeof value === 'object') return 'object';\n  if (typeof value === 'string') return 'string';\n  if (typeof value === 'number') return 'number';\n  if (typeof value === 'boolean') return 'boolean';\n  return 'string';\n}\n\n/**\n * Format change for display\n */\nexport function formatChange(change: HistoryChange): string {\n  const { field, oldValue, newValue, valueType } = change;\n\n  if (oldValue === undefined) {\n    return `Added ${field}: ${formatValue(newValue, valueType)}`;\n  }\n\n  if (newValue === undefined) {\n    return `Removed ${field}: ${formatValue(oldValue, valueType)}`;\n  }\n\n  return `Changed ${field} from ${formatValue(oldValue, valueType)} to ${formatValue(newValue, valueType)}`;\n}\n\n/**\n * Format value for display\n */\nfunction formatValue(value: unknown, type: HistoryChange['valueType']): string {\n  if (value === null || value === undefined) {\n    return '(empty)';\n  }\n\n  switch (type) {\n    case 'array':\n      return `[${(value as unknown[]).length} items]`;\n    case 'object':\n      return JSON.stringify(value);\n    case 'string':\n      return `\"${value}\"`;\n    default:\n      return String(value);\n  }\n}\n\n/**\n * Group history entries by date\n */\nexport function groupByDate(entries: Array<{ timestamp: string }>): Map<string, typeof entries> {\n  const grouped = new Map<string, typeof entries>();\n\n  entries.forEach((entry) => {\n    const date = new Date(entry.timestamp).toLocaleDateString();\n    if (!grouped.has(date)) {\n      grouped.set(date, []);\n    }\n    grouped.get(date)!.push(entry);\n  });\n\n  return grouped;\n}\n\n/**\n * Get relative time string\n */\nexport function getRelativeTime(timestamp: string): string {\n  const now = new Date();\n  const date = new Date(timestamp);\n  const diffMs = now.getTime() - date.getTime();\n  const diffSec = Math.floor(diffMs / 1000);\n  const diffMin = Math.floor(diffSec / 60);\n  const diffHour = Math.floor(diffMin / 60);\n  const diffDay = Math.floor(diffHour / 24);\n\n  if (diffSec < 60) return 'just now';\n  if (diffMin < 60) return `${diffMin} minute${diffMin !== 1 ? 's' : ''} ago`;\n  if (diffHour < 24) return `${diffHour} hour${diffHour !== 1 ? 's' : ''} ago`;\n  if (diffDay < 7) return `${diffDay} day${diffDay !== 1 ? 's' : ''} ago`;\n\n  return date.toLocaleDateString();\n}\n\n/**\n * Export history to CSV\n */\nexport function exportHistoryToCSV(\n  entries: Array<{\n    timestamp: string;\n    action: string;\n    entityType: string;\n    entityId: string;\n    userId: string;\n    userName?: string;\n  }>\n): string {\n  const headers = ['Timestamp', 'Action', 'Entity Type', 'Entity ID', 'User', 'User ID'];\n  const rows = entries.map((entry) => [\n    entry.timestamp,\n    entry.action,\n    entry.entityType,\n    entry.entityId,\n    entry.userName || entry.userId,\n    entry.userId,\n  ]);\n\n  return [headers.join(','), ...rows.map((row) => row.map((cell) => `\"${cell}\"`).join(','))].join(\n    '\\n'\n  );\n}\n","import { useCallback, useMemo } from 'react';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport {\n  recordHistoryEntry,\n  setHistoryFilter,\n  clearHistory,\n  selectFilteredHistory,\n  selectHistoryByEntity,\n} from '../store/historySlice';\nimport { HistoryEntry, HistoryFilter, HistoryTimeline } from '../types/history';\nimport { groupByDate } from '../utils/historyTracking';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('useHistory');\n\n/**\n * Hook for managing audit trail/history\n */\nexport function useHistory() {\n  const dispatch = useAppDispatch();\n\n  const allEntries = useAppSelector((state) => state.history?.entries || []);\n  const filteredEntries = useAppSelector(selectFilteredHistory);\n  const currentFilter = useAppSelector((state) => state.history?.filter);\n  const loading = useAppSelector((state) => state.history?.loading || false);\n  const error = useAppSelector((state) => state.history?.error);\n\n  const timeline = useMemo<HistoryTimeline[]>(() => {\n    const grouped = groupByDate(filteredEntries);\n    return Array.from(grouped.entries()).map(([date, entries]) => ({\n      date,\n      entries: entries as HistoryEntry[],\n    }));\n  }, [filteredEntries]);\n\n  const record = useCallback(\n    (entry: Omit<HistoryEntry, 'id' | 'timestamp'>) => {\n      dispatch(recordHistoryEntry(entry));\n      logger.debug('History recorded', { action: entry.action, entityType: entry.entityType });\n    },\n    [dispatch]\n  );\n\n  const setFilter = useCallback(\n    (filter: HistoryFilter | null) => {\n      dispatch(setHistoryFilter(filter));\n    },\n    [dispatch]\n  );\n\n  const clear = useCallback(\n    (options?: { entityId?: string; entityType?: string }) => {\n      dispatch(clearHistory(options || {}));\n    },\n    [dispatch]\n  );\n\n  return {\n    entries: filteredEntries,\n    allEntries,\n    timeline,\n    filter: currentFilter,\n    loading,\n    error,\n    record,\n    setFilter,\n    clear,\n  };\n}\n\n/**\n * Hook for entity-specific history\n */\nexport function useEntityHistory(entityType: 'annotation' | 'comment', entityId: string) {\n  const entries = useAppSelector((state) => selectHistoryByEntity(state, entityType, entityId));\n\n  const timeline = useMemo<HistoryTimeline[]>(() => {\n    const grouped = groupByDate(entries);\n    return Array.from(grouped.entries()).map(([date, entries]) => ({\n      date,\n      entries: entries as HistoryEntry[],\n    }));\n  }, [entries]);\n\n  const latestEntry = useMemo(() => (entries.length > 0 ? entries[0] : null), [entries]);\n\n  const createdEntry = useMemo(\n    () => entries.find((e) => e.action === 'created') || null,\n    [entries]\n  );\n\n  const modificationCount = useMemo(\n    () => entries.filter((e) => e.action === 'updated').length,\n    [entries]\n  );\n\n  return {\n    entries,\n    timeline,\n    latestEntry,\n    createdEntry,\n    modificationCount,\n  };\n}\n","import { useEffect, useCallback } from 'react';\nimport { useAppDispatch } from '../store/hooks';\nimport { setCurrentTool } from '../store/uiSlice';\nimport { AnnotationTool } from '../types';\nimport { createLogger } from '../utils/logger';\n\nconst logger = createLogger('useKeyboardShortcuts');\n\nexport interface KeyboardShortcut {\n  key: string;\n  ctrl?: boolean;\n  shift?: boolean;\n  alt?: boolean;\n  meta?: boolean;\n  action: () => void;\n  description: string;\n}\n\nconst DEFAULT_SHORTCUTS: KeyboardShortcut[] = [\n  {\n    key: 'v',\n    description: 'Select tool',\n    action: () => {},\n  },\n  {\n    key: 'h',\n    description: 'Highlight tool',\n    action: () => {},\n  },\n  {\n    key: 'd',\n    description: 'Draw tool',\n    action: () => {},\n  },\n  {\n    key: 'r',\n    description: 'Rectangle tool',\n    action: () => {},\n  },\n  {\n    key: 'c',\n    description: 'Circle tool',\n    action: () => {},\n  },\n  {\n    key: 'a',\n    description: 'Arrow tool',\n    action: () => {},\n  },\n  {\n    key: 'n',\n    description: 'Note tool',\n    action: () => {},\n  },\n  {\n    key: 'z',\n    ctrl: true,\n    description: 'Undo',\n    action: () => {},\n  },\n  {\n    key: 'z',\n    ctrl: true,\n    shift: true,\n    description: 'Redo',\n    action: () => {},\n  },\n  {\n    key: 'y',\n    ctrl: true,\n    description: 'Redo (alternative)',\n    action: () => {},\n  },\n  {\n    key: 'Delete',\n    description: 'Delete selected annotation',\n    action: () => {},\n  },\n  {\n    key: 'Backspace',\n    description: 'Delete selected annotation',\n    action: () => {},\n  },\n  {\n    key: 'Escape',\n    description: 'Clear selection',\n    action: () => {},\n  },\n];\n\nexport function useKeyboardShortcuts(\n  enabled: boolean = true,\n  customShortcuts: KeyboardShortcut[] = []\n) {\n  const dispatch = useAppDispatch();\n\n  const handleKeyDown = useCallback(\n    (event: KeyboardEvent) => {\n      if (!enabled) return;\n\n      // Don't trigger shortcuts when typing in input fields\n      const target = event.target as HTMLElement;\n      if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n        return;\n      }\n\n      const shortcuts = [...DEFAULT_SHORTCUTS, ...customShortcuts];\n\n      for (const shortcut of shortcuts) {\n        const keyMatch = event.key.toLowerCase() === shortcut.key.toLowerCase();\n        const ctrlMatch = !shortcut.ctrl || event.ctrlKey || event.metaKey;\n        const shiftMatch = !shortcut.shift || event.shiftKey;\n        const altMatch = !shortcut.alt || event.altKey;\n        const metaMatch = !shortcut.meta || event.metaKey;\n\n        if (keyMatch && ctrlMatch && shiftMatch && altMatch && metaMatch) {\n          event.preventDefault();\n          logger.debug('Keyboard shortcut triggered', { key: shortcut.key });\n          shortcut.action();\n          break;\n        }\n      }\n\n      // Tool shortcuts\n      switch (event.key.toLowerCase()) {\n        case 'v':\n          dispatch(setCurrentTool(AnnotationTool.SELECT));\n          break;\n        case 'h':\n          dispatch(setCurrentTool(AnnotationTool.HIGHLIGHT));\n          break;\n        case 'd':\n          dispatch(setCurrentTool(AnnotationTool.DRAW));\n          break;\n        case 'r':\n          dispatch(setCurrentTool(AnnotationTool.RECTANGLE));\n          break;\n        case 'c':\n          dispatch(setCurrentTool(AnnotationTool.CIRCLE));\n          break;\n        case 'a':\n          dispatch(setCurrentTool(AnnotationTool.ARROW));\n          break;\n        case 'n':\n          dispatch(setCurrentTool(AnnotationTool.NOTE));\n          break;\n      }\n    },\n    [dispatch, enabled, customShortcuts]\n  );\n\n  useEffect(() => {\n    if (!enabled) return undefined;\n\n    window.addEventListener('keydown', handleKeyDown);\n\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown);\n    };\n  }, [handleKeyDown, enabled]);\n\n  return {\n    shortcuts: [...DEFAULT_SHORTCUTS, ...customShortcuts],\n  };\n}\n","import { ReactNode, useEffect, useMemo } from 'react';\nimport { Provider } from 'react-redux';\nimport { AnnotationContext } from './AnnotationContext';\nimport { createAnnotationStore } from '../../store/store';\nimport {\n  StorageAdapter,\n  CollaborationAdapter,\n  RendererAdapter,\n  AnnotationConfig,\n  DEFAULT_CONFIG,\n} from '../../types';\nimport { fetchAnnotations } from '../../store/annotationsSlice';\nimport { setCurrentTool, setAnnotationColor } from '../../store/uiSlice';\n\nexport interface AnnotationProviderProps {\n  children: ReactNode;\n\n  // Adapters\n  storage?: StorageAdapter;\n  collaboration?: CollaborationAdapter;\n  renderer?: RendererAdapter;\n\n  // Configuration\n  config?: Partial<AnnotationConfig>;\n\n  // Document context\n  documentId?: string;\n  versionId?: string;\n  userId?: string;\n}\n\nexport const AnnotationProvider = ({\n  children,\n  storage,\n  collaboration,\n  renderer,\n  config: userConfig = {},\n  documentId,\n  versionId,\n  userId,\n}: AnnotationProviderProps) => {\n  // Merge user config with defaults\n  const config: AnnotationConfig = useMemo(\n    () => ({\n      ...DEFAULT_CONFIG,\n      ...userConfig,\n      ui: {\n        ...DEFAULT_CONFIG.ui,\n        ...userConfig.ui,\n      },\n      behavior: {\n        ...DEFAULT_CONFIG.behavior,\n        ...userConfig.behavior,\n      },\n      permissions: {\n        ...DEFAULT_CONFIG.permissions,\n        ...userConfig.permissions,\n      },\n    }),\n    [userConfig]\n  );\n\n  // Create Redux store with adapters\n  const store = useMemo(() => {\n    return createAnnotationStore({\n      adapters: {\n        storage,\n        collaboration,\n      },\n    });\n  }, [storage, collaboration]);\n\n  // Initialize UI state from config\n  useEffect(() => {\n    if (config.defaultTool) {\n      store.dispatch(setCurrentTool(config.defaultTool));\n    }\n    if (config.defaultColor) {\n      store.dispatch(setAnnotationColor(config.defaultColor));\n    }\n  }, [store, config.defaultTool, config.defaultColor]);\n\n  // Fetch annotations when document changes\n  useEffect(() => {\n    if (documentId && storage) {\n      void store.dispatch(fetchAnnotations({ documentId, versionId, adapter: storage }));\n    }\n  }, [store, documentId, versionId, storage]);\n\n  // Collaboration lifecycle\n  useEffect(() => {\n    if (!collaboration || !documentId) return undefined;\n\n    // Connect to collaboration service\n    if (!collaboration.isConnected()) {\n      collaboration.connect();\n    }\n\n    // Join document room\n    collaboration.joinDocument(documentId, versionId);\n\n    // Cleanup on unmount or document change\n    return () => {\n      collaboration.leaveDocument(documentId, versionId);\n      // Note: We don't disconnect here as the adapter might be shared\n      // The adapter itself handles cleanup on disconnect\n    };\n  }, [collaboration, documentId, versionId]);\n\n  // Context value\n  const contextValue = useMemo(\n    () => ({\n      config,\n      adapters: {\n        storage,\n        collaboration,\n        renderer,\n      },\n      documentId,\n      versionId,\n      userId,\n    }),\n    [config, storage, collaboration, renderer, documentId, versionId, userId]\n  );\n\n  return (\n    <Provider store={store}>\n      <AnnotationContext.Provider value={contextValue}>{children}</AnnotationContext.Provider>\n    </Provider>\n  );\n};\n","import { useState, useEffect, memo, useCallback } from 'react';\nimport { Annotation, AnnotationType } from '../../types';\nimport { normalizedToPixels, pixelsToNormalized } from '../../utils/coordinates';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('AnnotationElement');\n\ninterface AnnotationElementProps {\n  annotation: Annotation;\n  pageWidth: number;\n  pageHeight: number;\n  onSelect?: (annotation: Annotation) => void;\n  onUpdate?: (annotation: Annotation) => void;\n}\n\nconst AnnotationElementComponent = ({\n  annotation,\n  pageWidth,\n  pageHeight,\n  onSelect,\n  onUpdate,\n}: AnnotationElementProps) => {\n  const [isDragging, setIsDragging] = useState(false);\n  const [dragStartPos, setDragStartPos] = useState({ x: 0, y: 0 });\n  const [dragPosition, setDragPosition] = useState<{\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n  } | null>(null);\n  const [showCoordinates, setShowCoordinates] = useState(false);\n  const pixels = normalizedToPixels(annotation.positionData, pageWidth, pageHeight);\n\n  // Use dragged position if dragging, otherwise use actual position\n  const displayPixels = dragPosition || pixels;\n\n  const handleClick = (e: React.MouseEvent) => {\n    e.stopPropagation();\n    logger.debug('Clicked annotation:', {\n      id: annotation.id,\n      type: annotation.annotationType,\n      hasOnSelect: !!onSelect,\n    });\n    if (onSelect) {\n      onSelect(annotation);\n      logger.debug('onSelect called for annotation:', annotation.id);\n    }\n  };\n\n  const handleMouseDown = (e: React.MouseEvent) => {\n    // Allow dragging for all annotation types\n    e.stopPropagation();\n    e.preventDefault();\n    setIsDragging(true);\n    setDragStartPos({ x: e.clientX, y: e.clientY });\n    setShowCoordinates(true);\n    logger.debug('Started dragging:', { id: annotation.id, type: annotation.annotationType });\n  };\n\n  const handleGlobalMouseMove = useCallback(\n    (e: MouseEvent) => {\n      setDragStartPos((prevDragStartPos) => {\n        setDragPosition((prevDragPosition) => {\n          const currentPixels = prevDragPosition || pixels;\n          const deltaX = e.clientX - prevDragStartPos.x;\n          const deltaY = e.clientY - prevDragStartPos.y;\n\n          // Update the visual position locally (don't save to backend yet)\n          const newX = currentPixels.x + deltaX;\n          const newY = currentPixels.y + deltaY;\n\n          // Return new drag position for visual feedback (preserve width and height)\n          return { x: newX, y: newY, width: pixels.width, height: pixels.height };\n        });\n\n        // Return new drag start position for smooth dragging\n        return { x: e.clientX, y: e.clientY };\n      });\n    },\n    [pixels]\n  );\n\n  const handleGlobalMouseUp = useCallback(() => {\n    setIsDragging((currentIsDragging) => {\n      if (currentIsDragging) {\n        setShowCoordinates(false);\n        logger.debug('Stopped dragging annotation:', annotation.id);\n\n        // Save final position to backend\n        setDragPosition((currentDragPosition) => {\n          if (currentDragPosition && onUpdate) {\n            // Convert back to normalized coordinates\n            const normalized = pixelsToNormalized(\n              {\n                x: currentDragPosition.x,\n                y: currentDragPosition.y,\n                width: pixels.width,\n                height: pixels.height,\n              },\n              pageWidth,\n              pageHeight\n            );\n\n            logger.debug('Saving dragged position:', { annotationId: annotation.id, normalized });\n\n            // For DRAWING type, preserve the path data\n            let updatedPositionData: typeof annotation.positionData = normalized;\n            if (annotation.annotationType === AnnotationType.DRAWING) {\n              const drawingData = annotation.positionData as any;\n              updatedPositionData = {\n                x: normalized.x,\n                y: normalized.y,\n                width: normalized.width,\n                height: normalized.height,\n                path: drawingData.path,\n                strokeWidth: drawingData.strokeWidth,\n              } as any;\n            } else if (annotation.annotationType === AnnotationType.SHAPE) {\n              const shapeData = annotation.positionData as any;\n              updatedPositionData = {\n                x: normalized.x,\n                y: normalized.y,\n                width: normalized.width,\n                height: normalized.height,\n                type: shapeData.type,\n              } as any;\n            }\n\n            onUpdate({\n              ...annotation,\n              positionData: updatedPositionData,\n            });\n          }\n\n          // Clear drag position\n          return null;\n        });\n      }\n      return false;\n    });\n  }, [annotation, onUpdate, pageWidth, pageHeight, pixels]);\n\n  // Add global event listeners for dragging\n  useEffect(() => {\n    if (isDragging) {\n      window.addEventListener('mousemove', handleGlobalMouseMove);\n      window.addEventListener('mouseup', handleGlobalMouseUp);\n\n      return () => {\n        window.removeEventListener('mousemove', handleGlobalMouseMove);\n        window.removeEventListener('mouseup', handleGlobalMouseUp);\n      };\n    }\n  }, [isDragging, handleGlobalMouseMove, handleGlobalMouseUp]);\n\n  // Render coordinate tooltip\n  const renderCoordinateTooltip = () => {\n    if (!showCoordinates || !dragPosition) return null;\n\n    const tooltipX = displayPixels.x + displayPixels.width + 10;\n    const tooltipY = displayPixels.y - 10;\n    const normalizedCoords = pixelsToNormalized(dragPosition, pageWidth, pageHeight);\n\n    return (\n      <g style={{ pointerEvents: 'none' }}>\n        <rect\n          x={tooltipX}\n          y={tooltipY}\n          width={140}\n          height={50}\n          fill=\"rgba(0, 0, 0, 0.85)\"\n          stroke=\"var(--color-primary-500)\"\n          strokeWidth={1}\n          rx={4}\n        />\n        <text\n          x={tooltipX + 10}\n          y={tooltipY + 20}\n          fill=\"white\"\n          fontSize=\"11\"\n          fontFamily=\"monospace\"\n          fontWeight=\"bold\"\n        >\n          Position\n        </text>\n        <text x={tooltipX + 10} y={tooltipY + 35} fill=\"white\" fontSize=\"10\" fontFamily=\"monospace\">\n          X: {normalizedCoords.x.toFixed(3)}\n        </text>\n        <text x={tooltipX + 10} y={tooltipY + 47} fill=\"white\" fontSize=\"10\" fontFamily=\"monospace\">\n          Y: {normalizedCoords.y.toFixed(3)}\n        </text>\n      </g>\n    );\n  };\n\n  let annotationElement: JSX.Element | null = null;\n\n  switch (annotation.annotationType) {\n    case AnnotationType.HIGHLIGHT:\n      annotationElement = (\n        <g>\n          <rect\n            x={displayPixels.x}\n            y={displayPixels.y}\n            width={displayPixels.width}\n            height={displayPixels.height}\n            fill={annotation.color}\n            opacity={isDragging ? 0.5 : 0.3}\n            className=\"pointer-events-auto hover:opacity-40 transition-opacity\"\n            style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n            onClick={handleClick}\n            onMouseDown={handleMouseDown}\n          />\n          {/* Highlight border during drag */}\n          {isDragging && (\n            <rect\n              x={displayPixels.x}\n              y={displayPixels.y}\n              width={displayPixels.width}\n              height={displayPixels.height}\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth={2}\n              strokeDasharray=\"5,5\"\n              opacity={0.8}\n              style={{ pointerEvents: 'none' }}\n            />\n          )}\n        </g>\n      );\n      break;\n\n    case AnnotationType.SHAPE: {\n      const shapeData = annotation.positionData as any;\n      if (shapeData.type === 'rectangle') {\n        annotationElement = (\n          <g>\n            <rect\n              x={displayPixels.x}\n              y={displayPixels.y}\n              width={displayPixels.width}\n              height={displayPixels.height}\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth={2}\n              className=\"pointer-events-auto hover:opacity-75 transition-opacity\"\n              style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n              onClick={handleClick}\n              onMouseDown={handleMouseDown}\n            />\n            {/* Highlight effect during drag */}\n            {isDragging && (\n              <rect\n                x={displayPixels.x}\n                y={displayPixels.y}\n                width={displayPixels.width}\n                height={displayPixels.height}\n                fill={annotation.color}\n                opacity={0.1}\n                stroke={annotation.color}\n                strokeWidth={3}\n                strokeDasharray=\"5,5\"\n                style={{ pointerEvents: 'none' }}\n              />\n            )}\n          </g>\n        );\n      } else if (shapeData.type === 'circle') {\n        const cx = displayPixels.x + displayPixels.width / 2;\n        const cy = displayPixels.y + displayPixels.height / 2;\n        const r = Math.min(displayPixels.width, displayPixels.height) / 2;\n        annotationElement = (\n          <g>\n            <circle\n              cx={cx}\n              cy={cy}\n              r={r}\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth={2}\n              className=\"pointer-events-auto hover:opacity-75 transition-opacity\"\n              style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n              onClick={handleClick}\n              onMouseDown={handleMouseDown}\n            />\n            {/* Highlight effect during drag */}\n            {isDragging && (\n              <circle\n                cx={cx}\n                cy={cy}\n                r={r}\n                fill={annotation.color}\n                opacity={0.1}\n                stroke={annotation.color}\n                strokeWidth={3}\n                strokeDasharray=\"5,5\"\n                style={{ pointerEvents: 'none' }}\n              />\n            )}\n          </g>\n        );\n      } else if (shapeData.type === 'arrow') {\n        const x1 = displayPixels.x;\n        const y1 = displayPixels.y;\n        const x2 = displayPixels.x + displayPixels.width;\n        const y2 = displayPixels.y + displayPixels.height;\n\n        // Calculate arrow head\n        const angle = Math.atan2(y2 - y1, x2 - x1);\n        const arrowLength = 10;\n\n        const arrowPoint1X = x2 - arrowLength * Math.cos(angle - Math.PI / 6);\n        const arrowPoint1Y = y2 - arrowLength * Math.sin(angle - Math.PI / 6);\n        const arrowPoint2X = x2 - arrowLength * Math.cos(angle + Math.PI / 6);\n        const arrowPoint2Y = y2 - arrowLength * Math.sin(angle + Math.PI / 6);\n\n        annotationElement = (\n          <g\n            className=\"pointer-events-auto hover:opacity-75 transition-opacity\"\n            style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n            onClick={handleClick}\n            onMouseDown={handleMouseDown}\n          >\n            <line x1={x1} y1={y1} x2={x2} y2={y2} stroke={annotation.color} strokeWidth={2} />\n            <polygon\n              points={`${x2},${y2} ${arrowPoint1X},${arrowPoint1Y} ${arrowPoint2X},${arrowPoint2Y}`}\n              fill={annotation.color}\n            />\n            {/* Highlight effect during drag */}\n            {isDragging && (\n              <>\n                <line\n                  x1={x1}\n                  y1={y1}\n                  x2={x2}\n                  y2={y2}\n                  stroke={annotation.color}\n                  strokeWidth={5}\n                  opacity={0.2}\n                  strokeDasharray=\"5,5\"\n                  style={{ pointerEvents: 'none' }}\n                />\n              </>\n            )}\n          </g>\n        );\n      }\n      break;\n    }\n\n    case AnnotationType.DRAWING: {\n      const drawingData = annotation.positionData as any;\n      if (drawingData.path) {\n        // Calculate translation for dragged position\n        const translateX = dragPosition ? dragPosition.x - pixels.x : 0;\n        const translateY = dragPosition ? dragPosition.y - pixels.y : 0;\n        const transform = dragPosition ? `translate(${translateX}, ${translateY})` : undefined;\n\n        annotationElement = (\n          <g>\n            <path\n              d={drawingData.path}\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth={drawingData.strokeWidth || 2}\n              className=\"pointer-events-auto hover:opacity-75 transition-opacity\"\n              style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n              onClick={handleClick}\n              onMouseDown={handleMouseDown}\n              transform={transform}\n            />\n            {/* Highlight effect during drag */}\n            {isDragging && (\n              <path\n                d={drawingData.path}\n                fill=\"none\"\n                stroke={annotation.color}\n                strokeWidth={(drawingData.strokeWidth || 2) + 4}\n                opacity={0.2}\n                style={{ pointerEvents: 'none' }}\n                transform={transform}\n              />\n            )}\n          </g>\n        );\n      }\n      break;\n    }\n\n    case AnnotationType.NOTE:\n      logger.debug('Rendering NOTE:', {\n        annotationId: annotation.id,\n        positionData: annotation.positionData,\n        pixels,\n        pageWidth,\n        pageHeight,\n      });\n      annotationElement = (\n        <g\n          className=\"pointer-events-auto transition-all\"\n          onClick={handleClick}\n          onMouseDown={handleMouseDown}\n          style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n        >\n          {/* Outer circle with border for better visibility */}\n          <circle\n            cx={displayPixels.x}\n            cy={displayPixels.y}\n            r={16}\n            fill={annotation.color}\n            stroke=\"white\"\n            strokeWidth=\"2\"\n            className=\"transition-all\"\n            style={{\n              stroke: isDragging ? 'var(--color-primary-500)' : 'white',\n            }}\n          />\n          {/* Drag highlight ring */}\n          {isDragging && (\n            <circle\n              cx={displayPixels.x}\n              cy={displayPixels.y}\n              r={24}\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth=\"2\"\n              strokeDasharray=\"5,5\"\n              opacity=\"0.5\"\n              style={{ pointerEvents: 'none' }}\n            />\n          )}\n          {/* Hover highlight ring */}\n          <circle\n            cx={displayPixels.x}\n            cy={displayPixels.y}\n            r={20}\n            fill=\"none\"\n            stroke=\"var(--color-primary-500)\"\n            strokeWidth=\"2\"\n            opacity=\"0\"\n            className=\"transition-opacity\"\n            onMouseEnter={(e) => {\n              const target = e.currentTarget as SVGCircleElement;\n              target.setAttribute('opacity', '0.3');\n            }}\n            onMouseLeave={(e) => {\n              const target = e.currentTarget as SVGCircleElement;\n              target.setAttribute('opacity', '0');\n            }}\n          />\n          {/* Modern note icon */}\n          <g\n            transform={`translate(${displayPixels.x - 8}, ${displayPixels.y - 8})`}\n            style={{ pointerEvents: 'none' }}\n          >\n            <path\n              d=\"M3 2h8l4 4v10a1 1 0 01-1 1H3a1 1 0 01-1-1V3a1 1 0 011-1z\"\n              fill=\"white\"\n              stroke=\"white\"\n              strokeWidth=\"0.5\"\n            />\n            <path\n              d=\"M11 2v4h4\"\n              fill=\"none\"\n              stroke={annotation.color}\n              strokeWidth=\"1\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n            />\n            <line\n              x1=\"5\"\n              y1=\"9\"\n              x2=\"11\"\n              y2=\"9\"\n              stroke={annotation.color}\n              strokeWidth=\"1\"\n              strokeLinecap=\"round\"\n            />\n            <line\n              x1=\"5\"\n              y1=\"12\"\n              x2=\"11\"\n              y2=\"12\"\n              stroke={annotation.color}\n              strokeWidth=\"1\"\n              strokeLinecap=\"round\"\n            />\n          </g>\n        </g>\n      );\n      break;\n  }\n\n  // Return annotation element with coordinate tooltip\n  return (\n    <>\n      {annotationElement}\n      {renderCoordinateTooltip()}\n    </>\n  );\n};\n\nexport const AnnotationElement = memo(AnnotationElementComponent);\n","import { memo } from 'react';\nimport { useAppSelector } from '../../store/hooks';\nimport { useAnnotationContext } from '../AnnotationProvider';\nimport { AnnotationElement } from './AnnotationElement';\nimport { selectAnnotation, updateAnnotation } from '../../store/annotationsSlice';\nimport { useAppDispatch } from '../../store/hooks';\nimport { createLogger } from '../../utils/logger';\nimport { Annotation } from '../../types';\n\nconst logger = createLogger('AnnotationLayer');\n\nexport interface AnnotationLayerProps {\n  pageNumber?: number;\n  className?: string;\n}\n\nconst AnnotationLayerComponent = ({ pageNumber, className = '' }: AnnotationLayerProps) => {\n  const dispatch = useAppDispatch();\n  const { list } = useAppSelector((state) => state.annotations);\n  const { viewState } = useAppSelector((state) => state.ui);\n  const { adapters } = useAnnotationContext();\n\n  // Determine current page\n  const currentPage = pageNumber ?? (adapters.renderer?.getCurrentPage() || viewState.currentPage);\n\n  // Filter annotations for current page\n  const pageAnnotations = list.filter((ann) => ann.pageNumber === currentPage && !ann.isDeleted);\n\n  if (pageAnnotations.length === 0) {\n    return null;\n  }\n\n  // Get page dimensions from renderer adapter or viewState\n  let pageWidth = 595 * viewState.scale; // Default A4 width\n  let pageHeight = 842 * viewState.scale; // Default A4 height\n\n  if (adapters.renderer) {\n    const dimensions = adapters.renderer.getPageDimensions(currentPage);\n    pageWidth = dimensions.width;\n    pageHeight = dimensions.height;\n  }\n\n  const handleAnnotationSelect = (annotation: Annotation) => {\n    logger.debug('Selecting annotation:', {\n      id: annotation.id,\n      type: annotation.annotationType,\n    });\n    dispatch(selectAnnotation(annotation));\n  };\n\n  const handleAnnotationUpdate = (annotation: Annotation) => {\n    if (!adapters.storage) {\n      logger.warn('Storage adapter not available');\n      return;\n    }\n\n    logger.debug('Updating annotation:', {\n      id: annotation.id,\n      type: annotation.annotationType,\n      positionData: annotation.positionData,\n    });\n    dispatch(\n      updateAnnotation({\n        annotationId: annotation.id,\n        updates: {\n          positionData: annotation.positionData,\n          content: annotation.content || undefined,\n          color: annotation.color,\n        },\n        adapter: adapters.storage,\n      })\n    );\n  };\n\n  return (\n    <svg\n      className={`absolute top-0 left-0 pointer-events-none ${className}`}\n      width={pageWidth}\n      height={pageHeight}\n      style={{ zIndex: 10 }}\n    >\n      {pageAnnotations.map((annotation) => (\n        <AnnotationElement\n          key={annotation.id}\n          annotation={annotation}\n          pageWidth={pageWidth}\n          pageHeight={pageHeight}\n          onSelect={handleAnnotationSelect}\n          onUpdate={handleAnnotationUpdate}\n        />\n      ))}\n    </svg>\n  );\n};\n\nexport const AnnotationLayer = memo(AnnotationLayerComponent);\n","import { useState, useRef, memo } from 'react';\nimport { useAppDispatch, useAppSelector } from '../../store/hooks';\nimport {\n  addAnnotationOptimistic,\n  createAnnotation,\n  selectAnnotation,\n  updateAnnotation,\n} from '../../store/annotationsSlice';\nimport { createComment } from '../../store/commentsSlice';\nimport { recordHistoryEntry } from '../../store/historySlice';\nimport { useAnnotationContext } from '../AnnotationProvider';\nimport { AnnotationTool, AnnotationType, CreateAnnotationDto, Annotation } from '../../types';\nimport { pixelsToNormalized, normalizedToPixels } from '../../utils/coordinates';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('AnnotationCanvas');\n\n/**\n * Helper function to get human-readable annotation type label\n */\nfunction getAnnotationTypeLabel(type: AnnotationType): string {\n  switch (type) {\n    case AnnotationType.HIGHLIGHT:\n      return 'Highlight';\n    case AnnotationType.DRAWING:\n      return 'Drawing';\n    case AnnotationType.NOTE:\n      return 'Note';\n    case AnnotationType.SHAPE:\n      return 'Shape';\n    default:\n      return 'Annotation';\n  }\n}\n\nexport interface AnnotationCanvasProps {\n  pageNumber?: number;\n  className?: string;\n}\n\nconst AnnotationCanvasComponent = ({ pageNumber, className = '' }: AnnotationCanvasProps) => {\n  const dispatch = useAppDispatch();\n  const { currentTool, annotationColor, viewState } = useAppSelector((state) => state.ui);\n  const { list: annotations } = useAppSelector((state) => state.annotations);\n  const { adapters, documentId, versionId, userId, config } = useAnnotationContext();\n\n  const [isDrawing, setIsDrawing] = useState(false);\n  const [startPos, setStartPos] = useState({ x: 0, y: 0 });\n  const [currentPos, setCurrentPos] = useState({ x: 0, y: 0 });\n  const [drawingPath, setDrawingPath] = useState<string>('');\n  const [isDragging, setIsDragging] = useState(false);\n  const [draggedAnnotation, setDraggedAnnotation] = useState<Annotation | null>(null);\n  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });\n  const [cursorStyle, setCursorStyle] = useState('crosshair');\n  const canvasRef = useRef<SVGSVGElement>(null);\n\n  // Determine current page\n  const currentPage = pageNumber ?? (adapters.renderer?.getCurrentPage() || viewState.currentPage);\n\n  // Get page dimensions from renderer adapter or viewState\n  let pageWidth = 595 * viewState.scale; // Default A4 width\n  let pageHeight = 842 * viewState.scale; // Default A4 height\n\n  if (adapters.renderer) {\n    const dimensions = adapters.renderer.getPageDimensions(currentPage);\n    pageWidth = dimensions.width;\n    pageHeight = dimensions.height;\n  }\n\n  // Check if there's an annotation at the given pixel position\n  const checkAnnotationAtPosition = (clickX: number, clickY: number): Annotation | null => {\n    logger.debug('checkAnnotationAtPosition called', {\n      clickX,\n      clickY,\n      currentPage,\n      totalAnnotations: annotations.length,\n    });\n\n    // Filter annotations for current page\n    const pageAnnotations = annotations.filter(\n      (ann) => ann.pageNumber === currentPage && !ann.isDeleted\n    );\n\n    logger.debug('Page annotations:', {\n      count: pageAnnotations.length,\n      annotations: pageAnnotations.map((a) => ({\n        id: a.id,\n        type: a.annotationType,\n        positionData: a.positionData,\n      })),\n    });\n\n    // Check each annotation to see if click is within its bounds\n    for (const annotation of pageAnnotations) {\n      const pixels = normalizedToPixels(annotation.positionData, pageWidth, pageHeight);\n      logger.debug('Checking annotation:', {\n        id: annotation.id,\n        type: annotation.annotationType,\n        pixels,\n        clickX,\n        clickY,\n      });\n\n      // For notes, check if click is within circle radius (16px)\n      if (annotation.annotationType === AnnotationType.NOTE) {\n        const distance = Math.sqrt(Math.pow(clickX - pixels.x, 2) + Math.pow(clickY - pixels.y, 2));\n        logger.debug('Note distance check:', {\n          noteId: annotation.id,\n          distance,\n          radius: 16,\n          isWithin: distance <= 16,\n        });\n        if (distance <= 16) {\n          logger.debug('Found note at position!');\n          return annotation;\n        }\n      }\n\n      // For rectangles and highlights, check if click is within bounds\n      if (\n        annotation.annotationType === AnnotationType.HIGHLIGHT ||\n        (annotation.annotationType === AnnotationType.SHAPE &&\n          'type' in annotation.positionData &&\n          annotation.positionData.type === 'rectangle')\n      ) {\n        const isWithin =\n          clickX >= pixels.x &&\n          clickX <= pixels.x + pixels.width &&\n          clickY >= pixels.y &&\n          clickY <= pixels.y + pixels.height;\n        logger.debug('Rectangle/Highlight check:', {\n          annotationId: annotation.id,\n          isWithin,\n        });\n        if (isWithin) {\n          return annotation;\n        }\n      }\n\n      // For circles, check if click is within circle radius\n      if (\n        annotation.annotationType === AnnotationType.SHAPE &&\n        'type' in annotation.positionData &&\n        annotation.positionData.type === 'circle'\n      ) {\n        const cx = pixels.x + pixels.width / 2;\n        const cy = pixels.y + pixels.height / 2;\n        const r = Math.min(pixels.width, pixels.height) / 2;\n        const distance = Math.sqrt(Math.pow(clickX - cx, 2) + Math.pow(clickY - cy, 2));\n        if (distance <= r) {\n          return annotation;\n        }\n      }\n    }\n\n    logger.debug('No annotation found at position');\n    return null;\n  };\n\n  // Don't render canvas if in select mode\n  if (currentTool === AnnotationTool.SELECT) {\n    logger.debug('Not rendering - tool is SELECT');\n    return null;\n  }\n\n  logger.debug('Rendering canvas', {\n    currentTool,\n    pageWidth,\n    pageHeight,\n    currentPage,\n    documentId,\n    versionId,\n  });\n\n  const handleMouseDown = (e: React.MouseEvent<SVGSVGElement>) => {\n    logger.debug('Mouse down event triggered', {\n      currentTool,\n      documentId,\n      versionId,\n      userId,\n      pageWidth,\n      pageHeight,\n      clientX: e.clientX,\n      clientY: e.clientY,\n    });\n\n    if (!documentId || !versionId || !userId) {\n      logger.warn('Missing required IDs', { documentId, versionId, userId });\n      return;\n    }\n\n    const rect = canvasRef.current?.getBoundingClientRect();\n    if (!rect) {\n      logger.warn('No canvas rect found');\n      return;\n    }\n\n    const x = e.clientX - rect.left;\n    const y = e.clientY - rect.top;\n\n    logger.debug('Mouse position:', { x, y, pageWidth, pageHeight });\n\n    // Check if clicking on an existing annotation\n    const clickedAnnotation = checkAnnotationAtPosition(x, y);\n\n    // For NOTE tool, check if clicking on an existing annotation\n    if (currentTool === AnnotationTool.NOTE) {\n      logger.debug('NOTE tool - checking for existing annotation at position:', {\n        x,\n        y,\n        clickedAnnotation: clickedAnnotation\n          ? { id: clickedAnnotation.id, type: clickedAnnotation.annotationType }\n          : null,\n      });\n\n      if (clickedAnnotation) {\n        logger.debug('Existing annotation found - starting drag mode', {\n          annotationId: clickedAnnotation.id,\n          annotationType: clickedAnnotation.annotationType,\n        });\n\n        // Select the annotation first\n        logger.debug('Dispatching selectAnnotation for:', clickedAnnotation.id);\n        dispatch(selectAnnotation(clickedAnnotation));\n\n        // Start dragging the annotation\n        const pixels = normalizedToPixels(clickedAnnotation.positionData, pageWidth, pageHeight);\n        logger.debug('Setting up drag:', {\n          pixels,\n          clickPos: { x, y },\n          offset: { x: x - pixels.x, y: y - pixels.y },\n        });\n\n        setIsDragging(true);\n        setDraggedAnnotation(clickedAnnotation);\n        setDragOffset({ x: x - pixels.x, y: y - pixels.y });\n        return;\n      }\n\n      logger.debug('No existing annotation at position - creating new note');\n      createNoteAnnotation(x, y);\n      setIsDrawing(false);\n      return;\n    }\n\n    setIsDrawing(true);\n    setStartPos({ x, y });\n    setCurrentPos({ x, y });\n\n    if (currentTool === AnnotationTool.DRAW) {\n      setDrawingPath(`M ${x} ${y}`);\n    }\n  };\n\n  const handleMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n    const rect = canvasRef.current?.getBoundingClientRect();\n    if (!rect) return;\n\n    const x = e.clientX - rect.left;\n    const y = e.clientY - rect.top;\n\n    // Handle dragging annotation\n    if (isDragging && draggedAnnotation) {\n      const newX = x - dragOffset.x;\n      const newY = y - dragOffset.y;\n\n      logger.debug('Dragging annotation:', {\n        annotationId: draggedAnnotation.id,\n        mouseX: x,\n        mouseY: y,\n        dragOffset,\n        newX,\n        newY,\n      });\n\n      // Update the dragged annotation's position in real-time (visual feedback)\n      setCurrentPos({ x: newX, y: newY });\n      return;\n    }\n\n    // Update cursor based on hover (only when not drawing/dragging)\n    if (!isDrawing && !isDragging) {\n      const hoveredAnnotation = checkAnnotationAtPosition(x, y);\n      if (hoveredAnnotation) {\n        setCursorStyle('move');\n      } else {\n        setCursorStyle('crosshair');\n      }\n    }\n\n    if (!isDrawing) return;\n\n    setCurrentPos({ x, y });\n\n    if (currentTool === AnnotationTool.DRAW) {\n      setDrawingPath((prev) => `${prev} L ${x} ${y}`);\n    }\n  };\n\n  const handleMouseUp = () => {\n    logger.debug('Mouse up event', { isDrawing, isDragging, currentTool });\n\n    // Handle end of dragging\n    if (isDragging && draggedAnnotation && adapters.storage) {\n      logger.debug('Ending drag - saving new position');\n\n      // Calculate new normalized position\n      const newNormalized = pixelsToNormalized(\n        { x: currentPos.x, y: currentPos.y, width: 0, height: 0 },\n        pageWidth,\n        pageHeight\n      );\n\n      logger.debug('New position:', {\n        pixels: currentPos,\n        normalized: newNormalized,\n      });\n\n      // Update annotation position via storage adapter\n      void dispatch(\n        updateAnnotation({\n          annotationId: draggedAnnotation.id,\n          updates: { positionData: newNormalized },\n          adapter: adapters.storage,\n        })\n      );\n\n      setIsDragging(false);\n      setDraggedAnnotation(null);\n      return;\n    }\n\n    if (!isDrawing || !documentId || !versionId || !userId) {\n      logger.warn('Mouse up ignored', { isDrawing, documentId, versionId, userId });\n      return;\n    }\n\n    setIsDrawing(false);\n\n    const width = Math.abs(currentPos.x - startPos.x);\n    const height = Math.abs(currentPos.y - startPos.y);\n\n    logger.debug('Annotation dimensions', { width, height, startPos, currentPos });\n\n    // Ignore tiny clicks\n    if (width < 5 && height < 5 && currentTool !== AnnotationTool.NOTE) {\n      logger.debug('Annotation too small, ignoring');\n      setDrawingPath('');\n      return;\n    }\n\n    // For arrows, preserve the start and end positions\n    if (currentTool === AnnotationTool.ARROW) {\n      createArrowAnnotation();\n      setDrawingPath('');\n      return;\n    }\n\n    const x = Math.min(startPos.x, currentPos.x);\n    const y = Math.min(startPos.y, currentPos.y);\n\n    const normalized = pixelsToNormalized({ x, y, width, height }, pageWidth, pageHeight);\n\n    logger.debug('Creating annotation', { currentTool, normalized });\n\n    switch (currentTool) {\n      case AnnotationTool.HIGHLIGHT:\n        createAnnotationHelper(AnnotationType.HIGHLIGHT, normalized);\n        break;\n      case AnnotationTool.RECTANGLE:\n      case AnnotationTool.CIRCLE:\n        createShapeAnnotation(currentTool, normalized);\n        break;\n      case AnnotationTool.DRAW:\n        createDrawingAnnotation();\n        break;\n    }\n\n    setDrawingPath('');\n  };\n\n  const createAnnotationHelper = async (type: AnnotationType, positionData: any) => {\n    logger.debug('createAnnotationHelper called', {\n      type,\n      positionData,\n      documentId,\n      versionId,\n      userId,\n      hasStorage: !!adapters.storage,\n    });\n\n    if (!documentId || !versionId || !userId || !adapters.storage) {\n      logger.error('Cannot create annotation - missing requirements', {\n        documentId,\n        versionId,\n        userId,\n        hasStorage: !!adapters.storage,\n      });\n      return;\n    }\n\n    const tempId = `temp_${Date.now()}`;\n\n    const annotation: CreateAnnotationDto = {\n      documentVersionId: versionId,\n      userId,\n      annotationType: type,\n      pageNumber: currentPage,\n      positionData,\n      color: annotationColor,\n      tempId,\n    };\n\n    logger.debug('Annotation payload:', annotation);\n\n    // Optimistic update\n    const optimisticAnnotation = {\n      ...annotation,\n      id: tempId,\n      createdAt: new Date().toISOString(),\n      updatedAt: new Date().toISOString(),\n      isDeleted: false,\n    };\n    dispatch(addAnnotationOptimistic(optimisticAnnotation as Annotation));\n    logger.debug('Optimistic annotation added to store');\n\n    // Create via storage adapter\n    logger.debug('Dispatching createAnnotation thunk');\n    const createResult = await dispatch(\n      createAnnotation({ annotation, adapter: adapters.storage })\n    );\n\n    // Auto-create comment if enabled\n    if (config?.behavior?.autoCreateCommentOnAnnotation !== false && config?.userId) {\n      // Use the created annotation ID if available, otherwise use optimistic ID\n      const annotationId = (createResult.payload as Annotation)?.id || optimisticAnnotation.id;\n      const annotationTypeLabel = getAnnotationTypeLabel(type);\n      const commentContent = `${annotationTypeLabel} annotation created on page ${currentPage}`;\n\n      try {\n        logger.debug('Auto-creating comment for annotation', {\n          annotationId,\n          userId: config.userId,\n          userName: config.userName,\n          content: commentContent,\n        });\n\n        const commentResult = await dispatch(\n          createComment({\n            annotationId: annotationId,\n            userId: config.userId,\n            userName: config.userName || `User ${config.userId.slice(-4)}`,\n            content: commentContent,\n            mentions: [],\n          })\n        ).unwrap();\n\n        // Record history for the auto-created comment\n        dispatch(\n          recordHistoryEntry({\n            entityType: 'comment',\n            entityId: commentResult.id,\n            action: 'created',\n            userId: config.userId,\n            userName: config.userName || `User ${config.userId.slice(-4)}`,\n            metadata: {\n              annotationId: annotationId,\n              autoCreated: true,\n            },\n          })\n        );\n\n        logger.debug('Auto-created comment for annotation', {\n          annotationId: annotationId,\n          commentId: commentResult.id,\n          comment: commentResult,\n        });\n      } catch (commentErr) {\n        logger.error('Failed to auto-create comment', {\n          error: commentErr,\n          annotationId,\n          userId: config.userId,\n        });\n        // Don't fail the annotation creation if comment creation fails\n      }\n    }\n\n    // Emit to collaboration adapter\n    if (adapters.collaboration) {\n      logger.debug('Emitting to collaboration adapter');\n      adapters.collaboration.emit({\n        type: 'annotation:created',\n        annotation: annotation,\n      });\n    }\n\n    // Callback\n    config.callbacks?.onAnnotationCreate?.(optimisticAnnotation);\n  };\n\n  const createShapeAnnotation = (tool: AnnotationTool, normalized: any) => {\n    const shapeType = tool === AnnotationTool.RECTANGLE ? 'rectangle' : 'circle';\n\n    const positionData = {\n      ...normalized,\n      type: shapeType,\n    };\n\n    createAnnotationHelper(AnnotationType.SHAPE, positionData);\n  };\n\n  const createArrowAnnotation = () => {\n    if (!documentId || !versionId) return;\n\n    // Store arrow with actual start and end points (not normalized bounding box)\n    const normalized = {\n      x: startPos.x / pageWidth,\n      y: startPos.y / pageHeight,\n      width: (currentPos.x - startPos.x) / pageWidth, // Can be negative!\n      height: (currentPos.y - startPos.y) / pageHeight, // Can be negative!\n      type: 'arrow',\n    };\n\n    logger.debug('Creating arrow with preserved direction', { startPos, currentPos, normalized });\n\n    createAnnotationHelper(AnnotationType.SHAPE, normalized);\n  };\n\n  const createDrawingAnnotation = () => {\n    if (!drawingPath || !documentId || !versionId) return;\n\n    const positionData = {\n      path: drawingPath,\n      strokeWidth: 2,\n      x: 0,\n      y: 0,\n      width: 0,\n      height: 0,\n    };\n\n    createAnnotationHelper(AnnotationType.DRAWING, positionData);\n  };\n\n  const createNoteAnnotation = (x: number, y: number) => {\n    if (!documentId || !versionId) return;\n\n    const normalized = pixelsToNormalized({ x, y, width: 0, height: 0 }, pageWidth, pageHeight);\n\n    logger.debug('Creating note annotation', {\n      pixelCoords: { x, y },\n      normalized,\n      pageWidth,\n      pageHeight,\n    });\n\n    createAnnotationHelper(AnnotationType.NOTE, normalized);\n  };\n\n  // Render preview while drawing\n  const renderPreview = () => {\n    if (!isDrawing) return null;\n\n    const x = Math.min(startPos.x, currentPos.x);\n    const y = Math.min(startPos.y, currentPos.y);\n    const width = Math.abs(currentPos.x - startPos.x);\n    const height = Math.abs(currentPos.y - startPos.y);\n\n    switch (currentTool) {\n      case AnnotationTool.HIGHLIGHT:\n        return (\n          <rect x={x} y={y} width={width} height={height} fill={annotationColor} opacity={0.3} />\n        );\n\n      case AnnotationTool.RECTANGLE:\n        return (\n          <rect\n            x={x}\n            y={y}\n            width={width}\n            height={height}\n            fill=\"none\"\n            stroke={annotationColor}\n            strokeWidth={2}\n          />\n        );\n\n      case AnnotationTool.CIRCLE: {\n        const cx = x + width / 2;\n        const cy = y + height / 2;\n        const r = Math.min(width, height) / 2;\n        return (\n          <circle cx={cx} cy={cy} r={r} fill=\"none\" stroke={annotationColor} strokeWidth={2} />\n        );\n      }\n\n      case AnnotationTool.ARROW: {\n        const angle = Math.atan2(currentPos.y - startPos.y, currentPos.x - startPos.x);\n        const arrowLength = 10;\n\n        const arrowPoint1X = currentPos.x - arrowLength * Math.cos(angle - Math.PI / 6);\n        const arrowPoint1Y = currentPos.y - arrowLength * Math.sin(angle - Math.PI / 6);\n        const arrowPoint2X = currentPos.x - arrowLength * Math.cos(angle + Math.PI / 6);\n        const arrowPoint2Y = currentPos.y - arrowLength * Math.sin(angle + Math.PI / 6);\n\n        return (\n          <g>\n            <line\n              x1={startPos.x}\n              y1={startPos.y}\n              x2={currentPos.x}\n              y2={currentPos.y}\n              stroke={annotationColor}\n              strokeWidth={2}\n            />\n            <polygon\n              points={`${currentPos.x},${currentPos.y} ${arrowPoint1X},${arrowPoint1Y} ${arrowPoint2X},${arrowPoint2Y}`}\n              fill={annotationColor}\n            />\n          </g>\n        );\n      }\n\n      case AnnotationTool.DRAW:\n        return <path d={drawingPath} fill=\"none\" stroke={annotationColor} strokeWidth={2} />;\n\n      default:\n        return null;\n    }\n  };\n\n  return (\n    <svg\n      ref={canvasRef}\n      className={`absolute top-0 left-0 ${className}`}\n      width={pageWidth}\n      height={pageHeight}\n      style={{\n        zIndex: 20,\n        pointerEvents: 'all',\n        cursor: cursorStyle,\n      }}\n      onMouseDown={handleMouseDown}\n      onMouseMove={handleMouseMove}\n      onMouseUp={handleMouseUp}\n      onMouseLeave={() => {\n        if (isDrawing || isDragging) {\n          handleMouseUp();\n        }\n      }}\n    >\n      {renderPreview()}\n      {/* Render dragged annotation preview */}\n      {isDragging && draggedAnnotation && (\n        <g opacity={0.5}>\n          <circle\n            cx={currentPos.x}\n            cy={currentPos.y}\n            r={16}\n            fill={draggedAnnotation.color}\n            stroke=\"white\"\n            strokeWidth={2}\n          />\n          <text\n            x={currentPos.x}\n            y={currentPos.y + 6}\n            textAnchor=\"middle\"\n            fontSize=\"18\"\n            fill=\"white\"\n            fontWeight=\"bold\"\n          >\n            📝\n          </text>\n        </g>\n      )}\n    </svg>\n  );\n};\n\nexport const AnnotationCanvas = memo(AnnotationCanvasComponent);\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n  /^([A-Z])|[\\s-_]+(\\w)/g,\n  (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n  const camelCase = toCamelCase(string);\n  return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n  return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n  for (const prop in props) {\n    if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n      return true;\n    }\n  }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n  xmlns: \"http://www.w3.org/2000/svg\",\n  width: 24,\n  height: 24,\n  viewBox: \"0 0 24 24\",\n  fill: \"none\",\n  stroke: \"currentColor\",\n  strokeWidth: 2,\n  strokeLinecap: \"round\",\n  strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n  ({\n    color = \"currentColor\",\n    size = 24,\n    strokeWidth = 2,\n    absoluteStrokeWidth,\n    className = \"\",\n    children,\n    iconNode,\n    ...rest\n  }, ref) => createElement(\n    \"svg\",\n    {\n      ref,\n      ...defaultAttributes,\n      width: size,\n      height: size,\n      stroke: color,\n      strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n      className: mergeClasses(\"lucide\", className),\n      ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n      ...rest\n    },\n    [\n      ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n      ...Array.isArray(children) ? children : [children]\n    ]\n  )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n  const Component = forwardRef(\n    ({ className, ...props }, ref) => createElement(Icon, {\n      ref,\n      iconNode,\n      className: mergeClasses(\n        `lucide-${toKebabCase(toPascalCase(iconName))}`,\n        `lucide-${iconName}`,\n        className\n      ),\n      ...props\n    })\n  );\n  Component.displayName = toPascalCase(iconName);\n  return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n  [\"path\", { d: \"m12 5 7 7-7 7\", key: \"xquz4c\" }]\n];\nconst ArrowRight = createLucideIcon(\"arrow-right\", __iconNode);\n\nexport { __iconNode, ArrowRight as default };\n//# sourceMappingURL=arrow-right.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]];\nconst Circle = createLucideIcon(\"circle\", __iconNode);\n\nexport { __iconNode, Circle as default };\n//# sourceMappingURL=circle.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n  [\"circle\", { cx: \"12\", cy: \"5\", r: \"1\", key: \"gxeob9\" }],\n  [\"circle\", { cx: \"12\", cy: \"19\", r: \"1\", key: \"lyex9k\" }]\n];\nconst EllipsisVertical = createLucideIcon(\"ellipsis-vertical\", __iconNode);\n\nexport { __iconNode, EllipsisVertical as default };\n//# sourceMappingURL=ellipsis-vertical.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"m9 11-6 6v3h9l3-3\", key: \"1a3l36\" }],\n  [\"path\", { d: \"m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4\", key: \"14a9rk\" }]\n];\nconst Highlighter = createLucideIcon(\"highlighter\", __iconNode);\n\nexport { __iconNode, Highlighter as default };\n//# sourceMappingURL=highlighter.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M12.586 12.586 19 19\", key: \"ea5xo7\" }],\n  [\n    \"path\",\n    {\n      d: \"M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z\",\n      key: \"277e5u\"\n    }\n  ]\n];\nconst MousePointer = createLucideIcon(\"mouse-pointer\", __iconNode);\n\nexport { __iconNode, MousePointer as default };\n//# sourceMappingURL=mouse-pointer.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M13 21h8\", key: \"1jsn5i\" }],\n  [\n    \"path\",\n    {\n      d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n      key: \"1a8usu\"\n    }\n  ]\n];\nconst PenLine = createLucideIcon(\"pen-line\", __iconNode);\n\nexport { __iconNode, PenLine as default };\n//# sourceMappingURL=pen-line.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\n    \"path\",\n    {\n      d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n      key: \"1a8usu\"\n    }\n  ],\n  [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n  [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n];\nconst Square = createLucideIcon(\"square\", __iconNode);\n\nexport { __iconNode, Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M16 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V8Z\", key: \"qazsjp\" }],\n  [\"path\", { d: \"M15 3v4a2 2 0 0 0 2 2h4\", key: \"40519r\" }]\n];\nconst StickyNote = createLucideIcon(\"sticky-note\", __iconNode);\n\nexport { __iconNode, StickyNote as default };\n//# sourceMappingURL=sticky-note.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n  [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n  [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n  [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n  [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n  [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n  [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","import { useState, memo } from 'react';\nimport { useAppDispatch, useAppSelector } from '../../store/hooks';\nimport { setCurrentTool, setAnnotationColor } from '../../store/uiSlice';\nimport { useAnnotationContext } from '../AnnotationProvider';\nimport { AnnotationTool } from '../../types';\nimport { createLogger } from '../../utils/logger';\nimport {\n  MousePointer,\n  Highlighter,\n  Pencil,\n  Square,\n  Circle,\n  ArrowRight,\n  StickyNote,\n  Edit3,\n  X,\n} from 'lucide-react';\n\nconst logger = createLogger('AnnotationToolbar');\n\nexport interface AnnotationToolbarProps {\n  className?: string;\n  position?: 'top' | 'bottom' | 'left' | 'right';\n}\n\nconst AnnotationToolbarComponent = ({ className = '' }: AnnotationToolbarProps) => {\n  const dispatch = useAppDispatch();\n  const { currentTool, annotationColor } = useAppSelector((state) => state.ui);\n  const { config } = useAnnotationContext();\n  const [showColorPicker, setShowColorPicker] = useState(false);\n  const [isToolbarVisible, setIsToolbarVisible] = useState(false);\n\n  const availableTools = config.tools || Object.values(AnnotationTool);\n\n  const handleToolChange = (tool: AnnotationTool) => {\n    logger.debug('Tool changed:', { from: currentTool, to: tool });\n    dispatch(setCurrentTool(tool));\n    config.callbacks?.onToolChange?.(tool);\n  };\n\n  const handleColorChange = (color: string) => {\n    dispatch(setAnnotationColor(color));\n    setShowColorPicker(false);\n    logger.debug('Color changed:', color);\n  };\n\n  const toggleToolbar = () => {\n    setIsToolbarVisible(!isToolbarVisible);\n  };\n\n  return (\n    <>\n      {/* Floating Toolbar - Appears when toggled */}\n      {isToolbarVisible && (\n        <div\n          className={`\n            fixed top-4 right-4 z-[9999]\n            bg-white rounded-xl shadow-2xl border border-gray-200\n            p-2\n            animate-slideIn\n          `}\n          style={{\n            maxWidth: '600px',\n          }}\n        >\n          <style>{`\n            @keyframes slideIn {\n              from {\n                opacity: 0;\n                transform: translateY(-20px);\n              }\n              to {\n                opacity: 1;\n                transform: translateY(0);\n              }\n            }\n            .animate-slideIn {\n              animation: slideIn 0.3s ease-out;\n            }\n          `}</style>\n\n          <div className=\"flex flex-wrap gap-2 items-center\">\n            {/* Annotation Toggle Button - First in toolbar */}\n            <button\n              onClick={toggleToolbar}\n              className=\"\n                w-10 h-10 rounded-lg\n                flex items-center justify-center\n                transition-all duration-200\n                bg-blue-600 text-white\n                hover:bg-blue-700\n                border-2 border-transparent\n              \"\n              title=\"Hide Annotation Tools\"\n            >\n              <X className=\"w-5 h-5\" strokeWidth={2.5} />\n            </button>\n\n            {/* Vertical Divider */}\n            <div className=\"w-px h-8 bg-gray-300 mx-1\" />\n\n            {/* Tool buttons */}\n            {availableTools.map((tool) => {\n              const Icon = TOOL_ICONS[tool];\n              const isActive = currentTool === tool;\n              const colorClass = TOOL_COLORS[tool] || TOOL_COLORS[AnnotationTool.SELECT];\n\n              return (\n                <button\n                  key={tool}\n                  onClick={() => handleToolChange(tool)}\n                  className={`\n                    relative w-10 h-10 rounded-lg\n                    flex items-center justify-center\n                    transition-all duration-200\n                    ${\n                      isActive\n                        ? 'bg-blue-100 border-2 border-blue-500'\n                        : 'hover:bg-gray-100 border-2 border-transparent'\n                    }\n                  `}\n                  title={tool}\n                >\n                  <Icon className={`w-5 h-5 ${colorClass}`} strokeWidth={2} />\n                  {isActive && (\n                    <div className=\"absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-blue-600 rounded-full\" />\n                  )}\n                </button>\n              );\n            })}\n\n            {/* Color picker button - Shows selected color as icon */}\n            <div className=\"relative\">\n              <button\n                onClick={() => setShowColorPicker(!showColorPicker)}\n                className={`\n                  relative w-10 h-10 rounded-lg\n                  flex items-center justify-center\n                  transition-all duration-200\n                  ${\n                    showColorPicker\n                      ? 'bg-blue-100 border-2 border-blue-500'\n                      : 'hover:bg-gray-100 border-2 border-transparent'\n                  }\n                `}\n                title=\"Select color\"\n              >\n                <div\n                  style={{\n                    width: '32px',\n                    height: '32px',\n                    borderRadius: '50%',\n                    backgroundColor: annotationColor || '#FFEB3B',\n                    border: '3px solid white',\n                    boxShadow: '0 0 0 1px rgba(0,0,0,0.2), 0 2px 4px rgba(0,0,0,0.1)',\n                  }}\n                />\n                {showColorPicker && (\n                  <div className=\"absolute bottom-0 left-1/2 -translate-x-1/2 w-6 h-0.5 bg-blue-600 rounded-full\" />\n                )}\n              </button>\n\n              {/* Color picker dropdown */}\n              {showColorPicker && (\n                <>\n                  {/* Backdrop */}\n                  <div\n                    className=\"fixed inset-0 z-[10000]\"\n                    onClick={() => setShowColorPicker(false)}\n                  />\n\n                  {/* Color picker popover */}\n                  <div className=\"absolute top-full right-0 mt-2 bg-white rounded-xl shadow-2xl border border-gray-200 p-2 z-[10001]\">\n                    <div className=\"flex gap-2\">\n                      {ANNOTATION_COLORS.map((color) => (\n                        <button\n                          key={color.value}\n                          onClick={() => handleColorChange(color.value)}\n                          className={`\n                            rounded-lg transition-all duration-200\n                            ${annotationColor === color.value ? 'scale-110' : 'hover:scale-105'}\n                          `}\n                          style={{\n                            width: '40px',\n                            height: '40px',\n                            backgroundColor: color.value,\n                            border:\n                              annotationColor === color.value\n                                ? '2px solid #3B82F6'\n                                : '2px solid #E5E7EB',\n                            boxShadow:\n                              annotationColor === color.value\n                                ? '0 4px 8px rgba(0,0,0,0.15), 0 0 0 3px rgba(59, 130, 246, 0.2)'\n                                : '0 2px 4px rgba(0,0,0,0.1)',\n                          }}\n                          title={color.name}\n                          aria-label={`Select ${color.name} color`}\n                        >\n                          {annotationColor === color.value && (\n                            <svg\n                              className=\"w-5 h-5 text-white drop-shadow-lg mx-auto\"\n                              fill=\"none\"\n                              viewBox=\"0 0 24 24\"\n                              stroke=\"currentColor\"\n                              style={{ filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.3))' }}\n                            >\n                              <path\n                                strokeLinecap=\"round\"\n                                strokeLinejoin=\"round\"\n                                strokeWidth={3}\n                                d=\"M5 13l4 4L19 7\"\n                              />\n                            </svg>\n                          )}\n                        </button>\n                      ))}\n                    </div>\n                  </div>\n                </>\n              )}\n            </div>\n          </div>\n        </div>\n      )}\n\n      {/* Floating Toggle Button - Shows when toolbar is hidden */}\n      {!isToolbarVisible && (\n        <button\n          onClick={toggleToolbar}\n          className={`\n            fixed top-4 right-4 z-[9999]\n            w-12 h-12 rounded-lg\n            flex items-center justify-center\n            shadow-lg hover:shadow-xl\n            transition-all duration-300\n            bg-white text-blue-600 border-2 border-blue-600\n            hover:bg-blue-50\n            ${className}\n          `}\n          title=\"Show Annotation Tools\"\n        >\n          <Edit3 className=\"w-6 h-6\" strokeWidth={2.5} />\n        </button>\n      )}\n    </>\n  );\n};\n\nconst TOOL_ICONS = {\n  [AnnotationTool.SELECT]: MousePointer,\n  [AnnotationTool.HIGHLIGHT]: Highlighter,\n  [AnnotationTool.DRAW]: Pencil,\n  [AnnotationTool.RECTANGLE]: Square,\n  [AnnotationTool.CIRCLE]: Circle,\n  [AnnotationTool.ARROW]: ArrowRight,\n  [AnnotationTool.NOTE]: StickyNote,\n};\n\n// Adobe-style colors - more subtle and professional\nconst TOOL_COLORS = {\n  [AnnotationTool.SELECT]: 'text-gray-700',\n  [AnnotationTool.HIGHLIGHT]: 'text-yellow-600',\n  [AnnotationTool.DRAW]: 'text-red-600',\n  [AnnotationTool.RECTANGLE]: 'text-blue-600',\n  [AnnotationTool.CIRCLE]: 'text-green-600',\n  [AnnotationTool.ARROW]: 'text-orange-600',\n  [AnnotationTool.NOTE]: 'text-purple-600',\n};\n\nconst ANNOTATION_COLORS = [\n  { name: 'Yellow', value: '#FFEB3B' },\n  { name: 'Red', value: '#F44336' },\n  { name: 'Blue', value: '#2196F3' },\n  { name: 'Green', value: '#4CAF50' },\n];\n\nexport const AnnotationToolbar = memo(AnnotationToolbarComponent);\n","import { useState, memo } from 'react';\nimport { Annotation } from '../../types';\nimport { MoreVertical, Edit3 } from 'lucide-react';\n\nexport interface NoteCardProps {\n  note: Annotation;\n  onEdit?: (note: Annotation) => void;\n  onDelete: (note: Annotation) => void;\n  canEdit?: boolean;\n  canDelete?: boolean;\n  isSelected?: boolean;\n}\n\nconst NoteCardComponent = ({\n  note,\n  onEdit,\n  onDelete,\n  canEdit = true,\n  canDelete = true,\n  isSelected = false,\n}: NoteCardProps) => {\n  const [showMenu, setShowMenu] = useState(false);\n\n  const formatTimestamp = (dateString: string) => {\n    const date = new Date(dateString);\n    return date.toLocaleString('en-US', {\n      month: 'short',\n      day: 'numeric',\n      hour: 'numeric',\n      minute: '2-digit',\n      hour12: true,\n    });\n  };\n\n  const handleEdit = () => {\n    if (onEdit) {\n      onEdit(note);\n      setShowMenu(false);\n    }\n  };\n\n  const handleDelete = () => {\n    if (window.confirm('Are you sure you want to delete this note?')) {\n      onDelete(note);\n      setShowMenu(false);\n    }\n  };\n\n  return (\n    <div\n      className={`token-note-card p-4 cursor-pointer hover:bg-gray-50 transition-colors ${\n        isSelected ? 'is-selected' : ''\n      }`}\n      onClick={canEdit ? handleEdit : undefined}\n      onKeyDown={(e) => {\n        if (canEdit && (e.key === 'Enter' || e.key === ' ')) {\n          e.preventDefault();\n          handleEdit();\n        }\n      }}\n      role=\"button\"\n      tabIndex={0}\n    >\n      {/* Header */}\n      <div className=\"flex items-center justify-between mb-3\">\n        <div className=\"flex items-center gap-3\">\n          {/* Color indicator - Avatar size per design system */}\n          <div\n            className=\"w-9 h-9 rounded-full flex-shrink-0\"\n            style={{ backgroundColor: note.color }}\n          />\n          <div className=\"flex flex-col\">\n            <span className=\"font-medium text-sm\" style={{ color: 'var(--color-neutral-800)' }}>\n              Guest\n            </span>\n            <span className=\"text-xs\" style={{ color: 'var(--color-neutral-500)' }}>\n              {formatTimestamp(note.createdAt)}\n            </span>\n          </div>\n        </div>\n\n        {/* Menu */}\n        <div className=\"relative\" onClick={(e) => e.stopPropagation()}>\n          <button onClick={() => setShowMenu(!showMenu)} className=\"p-1 token-secondary-btn\">\n            <MoreVertical className=\"w-4 h-4\" style={{ color: 'var(--color-neutral-500)' }} />\n          </button>\n          {showMenu && (\n            <div\n              className=\"absolute right-0 mt-1 w-32 bg-white border rounded shadow-lg z-10\"\n              style={{ borderColor: 'var(--color-neutral-200)' }}\n            >\n              {canEdit && (\n                <button\n                  onClick={handleEdit}\n                  className=\"w-full px-3 py-2 text-left text-xs token-secondary-btn flex items-center gap-2\"\n                >\n                  <Edit3 className=\"w-3 h-3\" />\n                  Edit\n                </button>\n              )}\n              {canDelete && (\n                <button\n                  onClick={handleDelete}\n                  className=\"w-full px-3 py-2 text-left text-xs\"\n                  style={{ color: 'var(--color-error)' }}\n                >\n                  Delete\n                </button>\n              )}\n            </div>\n          )}\n        </div>\n      </div>\n\n      {/* Content - View Only */}\n      <div className=\"text-sm\" style={{ color: 'var(--color-neutral-800)' }}>\n        {note.content || <span className=\"text-gray-400 italic\">Click to add content...</span>}\n      </div>\n\n      {/* Edit indicator */}\n      {canEdit && (\n        <div className=\"mt-2 flex items-center gap-1 text-xs text-gray-400\">\n          <Edit3 className=\"w-3 h-3\" />\n          <span>Click to edit</span>\n        </div>\n      )}\n    </div>\n  );\n};\n\nexport const NoteCard = memo(NoteCardComponent);\n","import { useState, useEffect, useRef } from 'react';\nimport { Annotation } from '../../types';\nimport { Trash2, X, Check } from 'lucide-react';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('NoteInlineEditor');\n\ninterface NoteInlineEditorProps {\n  note: Annotation;\n  onSave: (note: Annotation, content: string) => void;\n  onDelete: (note: Annotation) => void;\n  onCancel: () => void;\n}\n\nexport const NoteInlineEditor = ({ note, onSave, onDelete, onCancel }: NoteInlineEditorProps) => {\n  const [content, setContent] = useState(note.content || '');\n  const [isDeleting, setIsDeleting] = useState(false);\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n  // Auto-focus the textarea when component mounts\n  useEffect(() => {\n    if (textareaRef.current) {\n      textareaRef.current.focus();\n      // Move cursor to end of text\n      const length = content.length;\n      textareaRef.current.setSelectionRange(length, length);\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  // Auto-resize textarea based on content\n  useEffect(() => {\n    if (textareaRef.current) {\n      textareaRef.current.style.height = 'auto';\n      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n    }\n  }, [content]);\n\n  const handleSave = () => {\n    logger.debug('Saving note content:', { noteId: note.id, content });\n    onSave(note, content);\n  };\n\n  const handleDelete = () => {\n    const confirmDelete = window.confirm('Are you sure you want to delete this note?');\n    if (confirmDelete) {\n      setIsDeleting(true);\n      logger.debug('Deleting note:', note.id);\n      onDelete(note);\n    }\n  };\n\n  const handleCancel = () => {\n    logger.debug('Canceling note edit:', note.id);\n    onCancel();\n  };\n\n  // Handle keyboard shortcuts\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === 'Escape') {\n      handleCancel();\n    } else if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {\n      handleSave();\n    }\n  };\n\n  return (\n    <div className=\"note-inline-editor border-b border-gray-200 bg-white\">\n      {/* Header */}\n      <div className=\"px-4 py-3 border-b border-gray-200 bg-gray-50\">\n        <div className=\"flex items-center justify-between\">\n          <div className=\"flex items-center gap-3\">\n            <div\n              className=\"w-8 h-8 rounded-full flex-shrink-0 border-2 border-white shadow-sm\"\n              style={{ backgroundColor: note.color }}\n            />\n            <div>\n              <h3 className=\"text-sm font-semibold text-gray-900\">Edit Note</h3>\n              <p className=\"text-xs text-gray-500\">\n                Page {note.pageNumber} • {new Date(note.createdAt).toLocaleDateString()}\n              </p>\n            </div>\n          </div>\n          <button\n            onClick={handleCancel}\n            className=\"p-1 rounded hover:bg-gray-200 transition-colors\"\n            title=\"Close editor (Esc)\"\n          >\n            <X className=\"w-5 h-5 text-gray-500\" />\n          </button>\n        </div>\n      </div>\n\n      {/* Editor Body */}\n      <div className=\"p-4\">\n        <textarea\n          ref={textareaRef}\n          value={content}\n          onChange={(e) => setContent(e.target.value)}\n          onKeyDown={handleKeyDown}\n          placeholder=\"Enter your note content here...\"\n          className=\"w-full px-3 py-2 border border-gray-300 rounded-md\n                     focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent\n                     resize-y min-h-[120px] max-h-[400px] text-sm text-gray-900\n                     placeholder-gray-400\"\n          style={{\n            fontFamily: 'inherit',\n            overflow: 'auto'\n          }}\n        />\n        <p className=\"mt-2 text-xs text-gray-500\">\n          Press <kbd className=\"px-1.5 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs\">Esc</kbd> to cancel •\n          <kbd className=\"px-1.5 py-0.5 bg-gray-100 border border-gray-300 rounded text-xs ml-1\">Ctrl+Enter</kbd> to save\n        </p>\n      </div>\n\n      {/* Actions */}\n      <div className=\"px-4 py-3 bg-gray-50 border-t border-gray-200 flex items-center justify-between gap-2\">\n        <button\n          onClick={handleDelete}\n          disabled={isDeleting}\n          className=\"flex items-center gap-2 px-3 py-2 text-sm font-medium text-red-700\n                     hover:bg-red-50 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n          title=\"Delete note\"\n        >\n          <Trash2 className=\"w-4 h-4\" />\n          Delete\n        </button>\n\n        <div className=\"flex items-center gap-2\">\n          <button\n            onClick={handleCancel}\n            className=\"px-4 py-2 text-sm font-medium text-gray-700\n                       hover:bg-gray-200 rounded-md transition-colors\"\n          >\n            Cancel\n          </button>\n          <button\n            onClick={handleSave}\n            className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-white\n                       bg-blue-600 hover:bg-blue-700 rounded-md transition-colors\n                       disabled:opacity-50 disabled:cursor-not-allowed\"\n            disabled={content.trim() === ''}\n          >\n            <Check className=\"w-4 h-4\" />\n            Save Note\n          </button>\n        </div>\n      </div>\n    </div>\n  );\n};\n","import { useState, memo, useEffect } from 'react';\nimport { useAppDispatch, useAppSelector } from '../../store/hooks';\nimport { updateAnnotation, deleteAnnotation } from '../../store/annotationsSlice';\nimport { useAnnotationContext } from '../AnnotationProvider';\nimport { AnnotationType, Annotation } from '../../types';\nimport { NoteCard } from './NoteCard';\nimport { NoteInlineEditor } from './NoteInlineEditor';\nimport { Search } from 'lucide-react';\n\nexport interface NotesPanelProps {\n  pageNumber?: number;\n  className?: string;\n  position?: 'left' | 'right';\n}\n\ntype SortOption = 'position' | 'date' | 'author';\n\nconst NotesPanelComponent = ({ pageNumber, className = '' }: NotesPanelProps) => {\n  const dispatch = useAppDispatch();\n  const { list, selected } = useAppSelector((state) => state.annotations);\n  const { viewState } = useAppSelector((state) => state.ui);\n  const { adapters, config } = useAnnotationContext();\n\n  const [searchQuery, setSearchQuery] = useState('');\n  const [sortBy, setSortBy] = useState<SortOption>('position');\n  const [editingNote, setEditingNote] = useState<Annotation | null>(null);\n\n  // Auto-open editor when a note is clicked/selected\n  useEffect(() => {\n    if (selected && selected.annotationType === AnnotationType.NOTE) {\n      setEditingNote(selected);\n    }\n  }, [selected]);\n\n  const currentPage = pageNumber ?? (adapters.renderer?.getCurrentPage() || viewState.currentPage);\n\n  let pageNotes = list.filter(\n    (ann) =>\n      ann.pageNumber === currentPage && ann.annotationType === AnnotationType.NOTE && !ann.isDeleted\n  );\n\n  if (searchQuery) {\n    pageNotes = pageNotes.filter((note) =>\n      note.content?.toLowerCase().includes(searchQuery.toLowerCase())\n    );\n  }\n\n  pageNotes = [...pageNotes].sort((a, b) => {\n    switch (sortBy) {\n      case 'date':\n        return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n      case 'author':\n        return (a.userId || '').localeCompare(b.userId || '');\n      case 'position':\n      default:\n        const aPos = a.positionData as { y: number };\n        const bPos = b.positionData as { y: number };\n        return aPos.y - bPos.y;\n    }\n  });\n\n  const handleEdit = (note: Annotation) => {\n    setEditingNote(note);\n  };\n\n  const handleSaveNote = (note: Annotation, content: string) => {\n    if (!adapters.storage) return;\n\n    const updates = { content };\n    dispatch(\n      updateAnnotation({\n        annotationId: note.id,\n        updates,\n        adapter: adapters.storage,\n      }) as any\n    );\n\n    if (adapters.collaboration) {\n      adapters.collaboration.emit({\n        type: 'annotation:updated',\n        annotationId: note.id,\n        updates,\n      });\n    }\n\n    config.callbacks?.onAnnotationUpdate?.({ ...note, content });\n    setEditingNote(null);\n  };\n\n  const handleCancelEdit = () => {\n    setEditingNote(null);\n  };\n\n  const handleDelete = (note: Annotation) => {\n    if (!adapters.storage) return;\n\n    if (note.id.startsWith('temp_')) {\n      alert('Please wait for the note to be saved before deleting it.');\n      return;\n    }\n\n    dispatch(\n      deleteAnnotation({\n        annotationId: note.id,\n        adapter: adapters.storage,\n      }) as any\n    );\n\n    if (adapters.collaboration) {\n      adapters.collaboration.emit({\n        type: 'annotation:deleted',\n        annotationId: note.id,\n      });\n    }\n\n    config.callbacks?.onAnnotationDelete?.(note.id);\n    setEditingNote(null);\n  };\n\n  return (\n    <div className={`token-notes-panel flex flex-col ${className}`}>\n      {/* Inline Editor (shows at top when editing) */}\n      {editingNote && (\n        <NoteInlineEditor\n          note={editingNote}\n          onSave={handleSaveNote}\n          onDelete={handleDelete}\n          onCancel={handleCancelEdit}\n        />\n      )}\n\n      {/* Header */}\n      {!editingNote && (\n        <div\n          className=\"px-4 py-5 border-b space-y-4\"\n          style={{ borderColor: 'var(--color-neutral-200)' }}\n        >\n          {/* Search */}\n          <div className=\"relative\">\n            <Search\n              className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4\"\n              style={{ color: 'var(--color-neutral-400)' }}\n            />\n            <input\n              type=\"text\"\n              placeholder=\"Search notes...\"\n              value={searchQuery}\n              onChange={(e) => setSearchQuery(e.target.value)}\n              className=\"w-full pl-9 pr-3 py-2 text-sm token-input\"\n            />\n          </div>\n\n          {/* Title */}\n          <h3 className=\"text-base font-semibold\" style={{ color: 'var(--color-neutral-800)' }}>\n            Comments ({pageNotes.length})\n          </h3>\n\n          {/* Sort */}\n          <div className=\"flex items-center gap-2\">\n            <span className=\"text-xs\" style={{ color: 'var(--color-neutral-600)' }}>\n              Sort:\n            </span>\n            <select\n              value={sortBy}\n              onChange={(e) => setSortBy(e.target.value as SortOption)}\n              className=\"flex-1 px-3 py-1.5 text-xs token-input\"\n            >\n              <option value=\"position\">Position</option>\n              <option value=\"date\">Date</option>\n              <option value=\"author\">Author</option>\n            </select>\n          </div>\n\n          {/* Page */}\n          <p className=\"text-xs\" style={{ color: 'var(--color-neutral-600)' }}>\n            Page {currentPage}\n          </p>\n        </div>\n      )}\n\n      {/* Notes List */}\n      {!editingNote && (\n        <div className=\"flex-1 overflow-y-auto px-4 py-5 space-y-4\">\n          {pageNotes.length === 0 ? (\n            <div className=\"text-center py-8\" style={{ color: 'var(--color-neutral-400)' }}>\n              <p className=\"text-xs\">No comments on this page</p>\n            </div>\n          ) : (\n            pageNotes.map((note) => (\n              <NoteCard\n                key={note.id}\n                note={note}\n                onEdit={handleEdit}\n                onDelete={handleDelete}\n                canEdit={config.permissions?.canEdit}\n                canDelete={config.permissions?.canDelete}\n                isSelected={selected?.id === note.id}\n              />\n            ))\n          )}\n        </div>\n      )}\n    </div>\n  );\n};\n\nexport const NotesPanel = memo(NotesPanelComponent);\n","import { Component, ErrorInfo, ReactNode } from 'react';\nimport { createLogger } from '../../utils/logger';\n\nconst logger = createLogger('ErrorBoundary');\n\nexport interface ErrorBoundaryProps {\n  children: ReactNode;\n  fallback?: ReactNode | ((error: Error, errorInfo: ErrorInfo) => ReactNode);\n  onError?: (error: Error, errorInfo: ErrorInfo) => void;\n  resetKeys?: Array<string | number>;\n}\n\ninterface ErrorBoundaryState {\n  hasError: boolean;\n  error: Error | null;\n  errorInfo: ErrorInfo | null;\n}\n\n/**\n * Error Boundary component to catch and handle errors in the React component tree\n * Prevents the entire application from crashing due to errors in child components\n */\nexport class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n  constructor(props: ErrorBoundaryProps) {\n    super(props);\n    this.state = {\n      hasError: false,\n      error: null,\n      errorInfo: null,\n    };\n  }\n\n  static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n    return {\n      hasError: true,\n      error,\n    };\n  }\n\n  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n    // Log error details\n    logger.error('Component error caught', {\n      error: error.message,\n      stack: error.stack,\n      componentStack: errorInfo.componentStack,\n    });\n\n    // Update state with error info\n    this.setState({\n      errorInfo,\n    });\n\n    // Call custom error handler if provided\n    this.props.onError?.(error, errorInfo);\n  }\n\n  componentDidUpdate(prevProps: ErrorBoundaryProps): void {\n    const { resetKeys } = this.props;\n    const { hasError } = this.state;\n\n    // Reset error boundary if resetKeys change\n    if (\n      hasError &&\n      resetKeys &&\n      prevProps.resetKeys &&\n      resetKeys.some((key, index) => key !== prevProps.resetKeys?.[index])\n    ) {\n      this.reset();\n    }\n  }\n\n  reset = (): void => {\n    this.setState({\n      hasError: false,\n      error: null,\n      errorInfo: null,\n    });\n  };\n\n  render(): ReactNode {\n    const { hasError, error, errorInfo } = this.state;\n    const { children, fallback } = this.props;\n\n    if (hasError && error) {\n      // Render custom fallback if provided\n      if (fallback) {\n        return typeof fallback === 'function' ? fallback(error, errorInfo!) : fallback;\n      }\n\n      // Default fallback UI\n      return (\n        <div\n          role=\"alert\"\n          style={{\n            padding: '20px',\n            margin: '20px',\n            border: '1px solid #dc2626',\n            borderRadius: '8px',\n            backgroundColor: '#fef2f2',\n            color: '#991b1b',\n          }}\n        >\n          <h2 style={{ margin: '0 0 10px 0', fontSize: '18px', fontWeight: 600 }}>\n            Something went wrong\n          </h2>\n          <details style={{ whiteSpace: 'pre-wrap', fontSize: '14px' }}>\n            <summary style={{ cursor: 'pointer', marginBottom: '10px' }}>\n              View error details\n            </summary>\n            <div style={{ marginTop: '10px' }}>\n              <strong>Error:</strong> {error.message}\n            </div>\n            {error.stack && (\n              <div style={{ marginTop: '10px' }}>\n                <strong>Stack Trace:</strong>\n                <pre\n                  style={{\n                    marginTop: '5px',\n                    padding: '10px',\n                    backgroundColor: '#fee2e2',\n                    borderRadius: '4px',\n                    fontSize: '12px',\n                    overflow: 'auto',\n                  }}\n                >\n                  {error.stack}\n                </pre>\n              </div>\n            )}\n            {errorInfo?.componentStack && (\n              <div style={{ marginTop: '10px' }}>\n                <strong>Component Stack:</strong>\n                <pre\n                  style={{\n                    marginTop: '5px',\n                    padding: '10px',\n                    backgroundColor: '#fee2e2',\n                    borderRadius: '4px',\n                    fontSize: '12px',\n                    overflow: 'auto',\n                  }}\n                >\n                  {errorInfo.componentStack}\n                </pre>\n              </div>\n            )}\n          </details>\n          <button\n            onClick={this.reset}\n            style={{\n              marginTop: '15px',\n              padding: '8px 16px',\n              backgroundColor: '#dc2626',\n              color: 'white',\n              border: 'none',\n              borderRadius: '4px',\n              cursor: 'pointer',\n              fontSize: '14px',\n            }}\n            onMouseOver={(e) => {\n              e.currentTarget.style.backgroundColor = '#b91c1c';\n            }}\n            onMouseOut={(e) => {\n              e.currentTarget.style.backgroundColor = '#dc2626';\n            }}\n          >\n            Try Again\n          </button>\n        </div>\n      );\n    }\n\n    return children;\n  }\n}\n","import React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { Comment, CommentThread as CommentThreadType } from '../../types/comment';\nimport { highlightMentions } from '../../utils/mentionParser';\nimport { getRelativeTime } from '../../utils/historyTracking';\n\nexport interface CommentThreadProps {\n  thread: CommentThreadType;\n  currentUserId?: string;\n  onReply?: (commentId: string, content: string) => void;\n  onEdit?: (commentId: string, content: string) => void;\n  onDelete?: (commentId: string) => void;\n  onResolve?: (commentId: string) => void;\n}\n\nexport function CommentThread({\n  thread,\n  currentUserId,\n  onReply,\n  onEdit,\n  onDelete,\n  onResolve,\n}: CommentThreadProps) {\n  const [showReplyInput, setShowReplyInput] = useState(false);\n  const [replyContent, setReplyContent] = useState('');\n  const [editingId, setEditingId] = useState<string | null>(null);\n  const [editContent, setEditContent] = useState('');\n\n  const handleReply = useCallback(() => {\n    if (replyContent.trim() && onReply) {\n      onReply(thread.comment.id, replyContent);\n      setReplyContent('');\n      setShowReplyInput(false);\n    }\n  }, [replyContent, onReply, thread.comment.id]);\n\n  const handleEdit = useCallback(\n    (commentId: string) => {\n      if (editContent.trim() && onEdit) {\n        onEdit(commentId, editContent);\n        setEditingId(null);\n        setEditContent('');\n      }\n    },\n    [editContent, onEdit]\n  );\n\n  const startEdit = useCallback((commentId: string, content: string) => {\n    setEditingId(commentId);\n    setEditContent(content);\n  }, []);\n\n  const cancelEdit = useCallback(() => {\n    setEditingId(null);\n    setEditContent('');\n  }, []);\n\n  return (\n    <div className=\"comment-thread\" role=\"article\" aria-label=\"Comment thread\">\n      {/* Main Comment */}\n      <CommentItem\n        comment={thread.comment}\n        currentUserId={currentUserId}\n        isEditing={editingId === thread.comment.id}\n        editContent={editContent}\n        onEditChange={setEditContent}\n        onEditSave={() => handleEdit(thread.comment.id)}\n        onEditCancel={cancelEdit}\n        onEditStart={() => startEdit(thread.comment.id, thread.comment.content)}\n        onDelete={() => onDelete?.(thread.comment.id)}\n        onReplyClick={() => setShowReplyInput(true)}\n        onResolve={() => onResolve?.(thread.comment.id)}\n      />\n\n      {/* Replies */}\n      {thread.replies.length > 0 && (\n        <div className=\"comment-replies\" role=\"list\" aria-label=\"Replies\">\n          {thread.replies.map((reply) => (\n            <CommentItem\n              key={reply.id}\n              comment={reply}\n              currentUserId={currentUserId}\n              isReply\n              isEditing={editingId === reply.id}\n              editContent={editContent}\n              onEditChange={setEditContent}\n              onEditSave={() => handleEdit(reply.id)}\n              onEditCancel={cancelEdit}\n              onEditStart={() => startEdit(reply.id, reply.content)}\n              onDelete={() => onDelete?.(reply.id)}\n            />\n          ))}\n        </div>\n      )}\n\n      {/* Reply Input */}\n      {showReplyInput && (\n        <div className=\"comment-reply-input\" role=\"form\">\n          <textarea\n            value={replyContent}\n            onChange={(e) => setReplyContent(e.target.value)}\n            placeholder=\"Write a reply... (use @username to mention)\"\n            className=\"comment-textarea\"\n            rows={3}\n            aria-label=\"Reply to comment\"\n          />\n          <div className=\"comment-actions\">\n            <button\n              onClick={handleReply}\n              className=\"btn btn-primary btn-sm\"\n              disabled={!replyContent.trim()}\n              aria-label=\"Submit reply\"\n            >\n              Reply\n            </button>\n            <button\n              onClick={() => {\n                setShowReplyInput(false);\n                setReplyContent('');\n              }}\n              className=\"btn btn-secondary btn-sm\"\n              aria-label=\"Cancel reply\"\n            >\n              Cancel\n            </button>\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\ninterface CommentItemProps {\n  comment: Comment;\n  currentUserId?: string;\n  isReply?: boolean;\n  isEditing?: boolean;\n  editContent?: string;\n  onEditChange?: (value: string) => void;\n  onEditSave?: () => void;\n  onEditCancel?: () => void;\n  onEditStart?: () => void;\n  onDelete?: () => void;\n  onReplyClick?: () => void;\n  onResolve?: () => void;\n}\n\nfunction CommentItem({\n  comment,\n  currentUserId,\n  isReply = false,\n  isEditing = false,\n  editContent = '',\n  onEditChange,\n  onEditSave,\n  onEditCancel,\n  onEditStart,\n  onDelete,\n  onReplyClick,\n  onResolve,\n}: CommentItemProps) {\n  const isOwnComment = comment.userId === currentUserId;\n  const firstChar = (comment.userName || comment.userId).charAt(0).toUpperCase();\n  const { text: highlightedContent, hasMention } = highlightMentions(\n    comment.content,\n    currentUserId\n  );\n\n  return (\n    <div\n      className={`comment-item ${isReply ? 'comment-item-reply' : ''} ${\n        hasMention ? 'comment-mentioned' : ''\n      }`}\n      role={isReply ? 'listitem' : 'article'}\n      aria-label={`Comment by ${comment.userName || comment.userId}`}\n    >\n      {/* Avatar */}\n      <div className=\"comment-avatar\" aria-hidden=\"true\">\n        {comment.userAvatar ? (\n          <img src={comment.userAvatar} alt=\"\" />\n        ) : (\n          <div className=\"comment-avatar-placeholder\">{firstChar}</div>\n        )}\n      </div>\n\n      {/* Content */}\n      <div className=\"comment-content\">\n        {/* Header */}\n        <div className=\"comment-header\">\n          <span className=\"comment-author\" aria-label=\"Comment author\">\n            {comment.userName || comment.userId}\n          </span>\n          <span className=\"comment-timestamp\" aria-label=\"Comment time\">\n            <time dateTime={comment.createdAt}>{getRelativeTime(comment.createdAt)}</time>\n            {comment.isEdited && (\n              <span className=\"comment-edited\" aria-label=\"Edited\">\n                {' '}\n                (edited)\n              </span>\n            )}\n          </span>\n          {comment.isResolved && (\n            <span className=\"comment-resolved-badge\" aria-label=\"Resolved comment\">\n              ✓ Resolved\n            </span>\n          )}\n        </div>\n\n        {/* Body */}\n        {isEditing ? (\n          <div className=\"comment-edit-form\" role=\"form\">\n            <textarea\n              value={editContent}\n              onChange={(e) => onEditChange?.(e.target.value)}\n              className=\"comment-textarea\"\n              rows={3}\n              aria-label=\"Edit comment\"\n              autoFocus\n            />\n            <div className=\"comment-actions\">\n              <button\n                onClick={onEditSave}\n                className=\"btn btn-primary btn-sm\"\n                disabled={!editContent.trim()}\n                aria-label=\"Save changes\"\n              >\n                Save\n              </button>\n              <button\n                onClick={onEditCancel}\n                className=\"btn btn-secondary btn-sm\"\n                aria-label=\"Cancel editing\"\n              >\n                Cancel\n              </button>\n            </div>\n          </div>\n        ) : (\n          <div\n            className=\"comment-body\"\n            dangerouslySetInnerHTML={{ __html: highlightedContent }}\n            aria-label=\"Comment content\"\n          />\n        )}\n\n        {/* Actions */}\n        {!isEditing && (\n          <div className=\"comment-footer\" role=\"group\" aria-label=\"Comment actions\">\n            {!isReply && onReplyClick && (\n              <button\n                onClick={onReplyClick}\n                className=\"comment-action\"\n                aria-label=\"Reply to comment\"\n              >\n                Reply\n              </button>\n            )}\n            {!isReply && onResolve && (\n              <button\n                onClick={onResolve}\n                className={`comment-action ${comment.isResolved ? 'comment-action-resolved' : ''}`}\n                aria-label={comment.isResolved ? 'Mark as unresolved' : 'Mark as resolved'}\n                title={comment.isResolved ? 'Mark as unresolved' : 'Mark as resolved'}\n              >\n                {comment.isResolved ? '↻ Unresolve' : '✓ Resolve'}\n              </button>\n            )}\n            {isOwnComment && onEditStart && (\n              <button onClick={onEditStart} className=\"comment-action\" aria-label=\"Edit comment\">\n                Edit\n              </button>\n            )}\n            {isOwnComment && onDelete && (\n              <button\n                onClick={onDelete}\n                className=\"comment-action comment-action-danger\"\n                aria-label=\"Delete comment\"\n              >\n                Delete\n              </button>\n            )}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n\nexport interface CommentInputProps {\n  onSubmit: (content: string) => void;\n  placeholder?: string;\n  autoFocus?: boolean;\n}\n\nexport function CommentInput({\n  onSubmit,\n  placeholder = 'Write a comment... (use @username to mention)',\n  autoFocus = false,\n}: CommentInputProps) {\n  const [content, setContent] = useState('');\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n  useEffect(() => {\n    if (autoFocus && textareaRef.current) {\n      textareaRef.current.focus();\n    }\n  }, [autoFocus]);\n\n  const handleSubmit = useCallback(() => {\n    if (content.trim()) {\n      onSubmit(content);\n      setContent('');\n    }\n  }, [content, onSubmit]);\n\n  const handleKeyDown = useCallback(\n    (e: React.KeyboardEvent) => {\n      if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault();\n        handleSubmit();\n      }\n    },\n    [handleSubmit]\n  );\n\n  return (\n    <div className=\"comment-input\" role=\"form\" aria-label=\"Add comment\">\n      <textarea\n        ref={textareaRef}\n        value={content}\n        onChange={(e) => setContent(e.target.value)}\n        onKeyDown={handleKeyDown}\n        placeholder={placeholder}\n        className=\"comment-textarea\"\n        rows={3}\n        aria-label=\"Comment text\"\n      />\n      <div className=\"comment-input-footer\">\n        <span className=\"comment-input-hint\" aria-label=\"Keyboard shortcut\">\n          Tip: Press Cmd/Ctrl + Enter to submit\n        </span>\n        <button\n          onClick={handleSubmit}\n          className=\"btn btn-primary\"\n          disabled={!content.trim()}\n          aria-label=\"Submit comment\"\n        >\n          Comment\n        </button>\n      </div>\n    </div>\n  );\n}\n","import { useMemo, useState } from 'react';\nimport { HistoryEntry, HistoryTimeline } from '../../types/history';\nimport { formatChange, getRelativeTime } from '../../utils/historyTracking';\n\nexport interface HistoryPanelProps {\n  entries: HistoryEntry[];\n  timeline?: HistoryTimeline[];\n  showFilters?: boolean;\n  maxHeight?: string;\n  onEntryClick?: (entry: HistoryEntry) => void;\n}\n\nexport function HistoryPanel({\n  entries,\n  timeline,\n  showFilters = false,\n  maxHeight = '600px',\n  onEntryClick,\n}: HistoryPanelProps) {\n  const [filter, setFilter] = useState<'all' | 'annotation' | 'comment'>('all');\n  const [actionFilter, setActionFilter] = useState<'all' | 'created' | 'updated' | 'deleted'>(\n    'all'\n  );\n\n  const filteredEntries = useMemo(() => {\n    return entries.filter((entry) => {\n      if (filter !== 'all' && entry.entityType !== filter) return false;\n      if (actionFilter !== 'all' && entry.action !== actionFilter) return false;\n      return true;\n    });\n  }, [entries, filter, actionFilter]);\n\n  const displayTimeline = useMemo(() => {\n    if (timeline) return timeline;\n\n    // Group by date if timeline not provided\n    const grouped = new Map<string, HistoryEntry[]>();\n    filteredEntries.forEach((entry) => {\n      const date = new Date(entry.timestamp).toLocaleDateString();\n      if (!grouped.has(date)) {\n        grouped.set(date, []);\n      }\n      grouped.get(date)!.push(entry);\n    });\n\n    return Array.from(grouped.entries()).map(([date, entries]) => ({\n      date,\n      entries,\n    }));\n  }, [filteredEntries, timeline]);\n\n  return (\n    <div className=\"history-panel\" role=\"region\" aria-label=\"Activity history\">\n      {/* Header */}\n      <div className=\"history-header\">\n        <h3 className=\"history-title\">Activity History</h3>\n        {entries.length > 0 && (\n          <span className=\"history-count\" aria-label={`${entries.length} entries`}>\n            {entries.length} {entries.length === 1 ? 'entry' : 'entries'}\n          </span>\n        )}\n      </div>\n\n      {/* Filters */}\n      {showFilters && (\n        <div className=\"history-filters\" role=\"group\" aria-label=\"Filter history\">\n          <div className=\"filter-group\">\n            <label htmlFor=\"entity-filter\">Type:</label>\n            <select\n              id=\"entity-filter\"\n              value={filter}\n              onChange={(e) => setFilter(e.target.value as typeof filter)}\n              className=\"filter-select\"\n              aria-label=\"Filter by entity type\"\n            >\n              <option value=\"all\">All</option>\n              <option value=\"annotation\">Annotations</option>\n              <option value=\"comment\">Comments</option>\n            </select>\n          </div>\n\n          <div className=\"filter-group\">\n            <label htmlFor=\"action-filter\">Action:</label>\n            <select\n              id=\"action-filter\"\n              value={actionFilter}\n              onChange={(e) => setActionFilter(e.target.value as typeof actionFilter)}\n              className=\"filter-select\"\n              aria-label=\"Filter by action type\"\n            >\n              <option value=\"all\">All</option>\n              <option value=\"created\">Created</option>\n              <option value=\"updated\">Updated</option>\n              <option value=\"deleted\">Deleted</option>\n            </select>\n          </div>\n        </div>\n      )}\n\n      {/* Timeline */}\n      <div\n        className=\"history-timeline\"\n        style={{ maxHeight, overflowY: 'auto' }}\n        role=\"list\"\n        aria-label=\"History timeline\"\n      >\n        {displayTimeline.length === 0 ? (\n          <div className=\"history-empty\" role=\"status\">\n            <p>No history entries found</p>\n          </div>\n        ) : (\n          displayTimeline.map(({ date, entries }) => (\n            <div key={date} className=\"history-date-group\" role=\"listitem\">\n              <h4 className=\"history-date\">{date}</h4>\n              <div className=\"history-entries\">\n                {entries.map((entry) => (\n                  <HistoryEntryItem\n                    key={entry.id}\n                    entry={entry}\n                    onClick={() => onEntryClick?.(entry)}\n                  />\n                ))}\n              </div>\n            </div>\n          ))\n        )}\n      </div>\n    </div>\n  );\n}\n\ninterface HistoryEntryItemProps {\n  entry: HistoryEntry;\n  onClick?: () => void;\n}\n\nfunction HistoryEntryItem({ entry, onClick }: HistoryEntryItemProps) {\n  const actionIcon = getActionIcon(entry.action);\n  const actionColor = getActionColor(entry.action);\n\n  return (\n    <div\n      className={`history-entry ${onClick ? 'history-entry-clickable' : ''}`}\n      onClick={onClick}\n      role=\"article\"\n      aria-label={`History entry: ${entry.action} ${entry.entityType}`}\n      tabIndex={onClick ? 0 : undefined}\n      onKeyDown={\n        onClick\n          ? (e) => {\n              if (e.key === 'Enter' || e.key === ' ') {\n                e.preventDefault();\n                onClick();\n              }\n            }\n          : undefined\n      }\n    >\n      {/* Icon */}\n      <div className={`history-icon ${actionColor}`} aria-hidden=\"true\">\n        {actionIcon}\n      </div>\n\n      {/* Content */}\n      <div className=\"history-content\">\n        <div className=\"history-message\">\n          <strong>{entry.userName || entry.userId}</strong>{' '}\n          <span className=\"history-action\">{entry.action}</span>{' '}\n          <span className=\"history-entity\">{entry.entityType}</span>\n        </div>\n\n        {/* Changes */}\n        {entry.changes && entry.changes.length > 0 && (\n          <ul className=\"history-changes\" role=\"list\" aria-label=\"Changes made\">\n            {entry.changes.slice(0, 3).map((change, index) => (\n              <li key={index} className=\"history-change\">\n                {formatChange(change)}\n              </li>\n            ))}\n            {entry.changes.length > 3 && (\n              <li className=\"history-change-more\">+{entry.changes.length - 3} more changes</li>\n            )}\n          </ul>\n        )}\n\n        {/* Metadata */}\n        {entry.metadata && Object.keys(entry.metadata).length > 0 && (\n          <div className=\"history-metadata\" aria-label=\"Additional information\">\n            {Object.entries(entry.metadata)\n              .slice(0, 2)\n              .map(([key, value]) => (\n                <span key={key} className=\"history-metadata-item\">\n                  {key}: {String(value)}\n                </span>\n              ))}\n          </div>\n        )}\n\n        {/* Timestamp */}\n        <div className=\"history-timestamp\">\n          <time dateTime={entry.timestamp}>{getRelativeTime(entry.timestamp)}</time>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nfunction getActionIcon(action: HistoryEntry['action']): string {\n  switch (action) {\n    case 'created':\n      return '+';\n    case 'updated':\n      return '✎';\n    case 'deleted':\n      return '×';\n    case 'restored':\n      return '↺';\n    default:\n      return '•';\n  }\n}\n\nfunction getActionColor(action: HistoryEntry['action']): string {\n  switch (action) {\n    case 'created':\n      return 'history-icon-success';\n    case 'updated':\n      return 'history-icon-info';\n    case 'deleted':\n      return 'history-icon-danger';\n    case 'restored':\n      return 'history-icon-warning';\n    default:\n      return 'history-icon-default';\n  }\n}\n\nexport interface HistoryDrawerProps {\n  entityType: 'annotation' | 'comment';\n  entityId: string;\n  entries: HistoryEntry[];\n  isOpen: boolean;\n  onClose: () => void;\n}\n\nexport function HistoryDrawer({ entityType, entries, isOpen, onClose }: HistoryDrawerProps) {\n  if (!isOpen) return null;\n\n  return (\n    <div\n      className=\"history-drawer-overlay\"\n      onClick={onClose}\n      role=\"dialog\"\n      aria-label=\"History drawer\"\n      aria-modal=\"true\"\n    >\n      <div className=\"history-drawer\" onClick={(e) => e.stopPropagation()}>\n        <div className=\"history-drawer-header\">\n          <h3>History: {entityType}</h3>\n          <button\n            onClick={onClose}\n            className=\"history-drawer-close\"\n            aria-label=\"Close history drawer\"\n          >\n            ×\n          </button>\n        </div>\n\n        <div className=\"history-drawer-content\">\n          <HistoryPanel entries={entries} maxHeight=\"calc(100vh - 120px)\" />\n        </div>\n      </div>\n    </div>\n  );\n}\n","import React, { useState, useMemo, useEffect } from 'react';\nimport { Annotation, AnnotationType } from '../types';\nimport { useAppDispatch, useAppSelector } from '../store/hooks';\nimport {\n  selectAnnotation,\n  deleteAnnotation,\n  toggleResolveAnnotation,\n} from '../store/annotationsSlice';\nimport { fetchComments, createComment, deleteComment } from '../store/commentsSlice';\nimport type { StorageAdapter } from '../types';\nimport type { Comment } from '../types/comment';\nimport { CommentThread, CommentInput } from './CommentThread';\n\ninterface AnnotationsListPanelProps {\n  storageAdapter: StorageAdapter;\n  currentUserId: string;\n  onAnnotationClick?: (annotation: Annotation) => void;\n}\n\ntype FilterType = 'all' | 'shapes' | 'notes' | 'resolved';\ntype ViewMode = 'list' | 'detail';\n\nexport function AnnotationsListPanel({\n  storageAdapter,\n  currentUserId,\n  onAnnotationClick,\n}: AnnotationsListPanelProps) {\n  const dispatch = useAppDispatch();\n  const annotations = useAppSelector((state) => state.annotations.list);\n  const selectedAnnotation = useAppSelector((state) => state.annotations.selected);\n  const allComments = useAppSelector((state) => state.comments.comments);\n\n  const [searchQuery, setSearchQuery] = useState('');\n  const [filterType, setFilterType] = useState<FilterType>('all');\n  const [deleteConfirm, setDeleteConfirm] = useState<string | null>(null);\n  const [viewMode, setViewMode] = useState<ViewMode>('list');\n  const [detailAnnotation, setDetailAnnotation] = useState<Annotation | null>(null);\n\n  // Get comments for the detail annotation\n  const detailComments = useMemo(() => {\n    if (!detailAnnotation) return [];\n    return allComments[detailAnnotation.id] || [];\n  }, [detailAnnotation, allComments]);\n\n  // Build comment threads (Reddit-style, one level deep)\n  const commentThreads = useMemo(() => {\n    const threads: Array<{ comment: Comment; replies: Comment[] }> = [];\n    const topLevelComments = detailComments.filter((c) => !c.parentCommentId);\n\n    topLevelComments.forEach((comment) => {\n      const replies = detailComments.filter((c) => c.parentCommentId === comment.id);\n      threads.push({ comment, replies });\n    });\n\n    return threads;\n  }, [detailComments]);\n\n  // Load comments when opening detail view\n  useEffect(() => {\n    if (viewMode === 'detail' && detailAnnotation) {\n      dispatch(\n        fetchComments({\n          annotationId: detailAnnotation.id,\n        })\n      );\n    }\n  }, [viewMode, detailAnnotation, dispatch]);\n\n  // Filter and search logic\n  const filteredAnnotations = useMemo(() => {\n    let filtered = annotations;\n\n    // Apply type filter\n    if (filterType === 'shapes') {\n      filtered = filtered.filter(\n        (a) =>\n          a.annotationType === AnnotationType.SHAPE ||\n          a.annotationType === AnnotationType.DRAWING ||\n          a.annotationType === AnnotationType.HIGHLIGHT\n      );\n    } else if (filterType === 'notes') {\n      filtered = filtered.filter((a) => a.annotationType === AnnotationType.NOTE);\n    } else if (filterType === 'resolved') {\n      filtered = filtered.filter((a) => a.isResolved === true);\n    }\n\n    // Apply search\n    if (searchQuery.trim()) {\n      const query = searchQuery.toLowerCase();\n      filtered = filtered.filter(\n        (a) =>\n          a.userId.toLowerCase().includes(query) ||\n          (a.content && a.content.toLowerCase().includes(query))\n      );\n    }\n\n    // Sort by creation time (newest first) - create a copy to avoid mutating Redux state\n    return [...filtered].sort(\n      (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n    );\n  }, [annotations, filterType, searchQuery]);\n\n  const handleAnnotationClick = (annotation: Annotation) => {\n    dispatch(selectAnnotation(annotation));\n    if (onAnnotationClick) {\n      onAnnotationClick(annotation);\n    }\n\n    // If it's a note, switch to detail view\n    if (annotation.annotationType === AnnotationType.NOTE) {\n      setDetailAnnotation(annotation);\n      setViewMode('detail');\n    }\n  };\n\n  const handleBackToList = () => {\n    setViewMode('list');\n    setDetailAnnotation(null);\n  };\n\n  const handleDeleteClick = (e: React.MouseEvent, annotationId: string) => {\n    e.stopPropagation();\n    setDeleteConfirm(annotationId);\n  };\n\n  const confirmDelete = async (e: React.MouseEvent, annotationId: string) => {\n    e.stopPropagation();\n    await dispatch(deleteAnnotation({ annotationId, adapter: storageAdapter }));\n    setDeleteConfirm(null);\n    if (detailAnnotation?.id === annotationId) {\n      handleBackToList();\n    }\n  };\n\n  const cancelDelete = (e: React.MouseEvent) => {\n    e.stopPropagation();\n    setDeleteConfirm(null);\n  };\n\n  const handleAddComment = async (content: string) => {\n    if (!detailAnnotation) return;\n    await dispatch(\n      createComment({\n        annotationId: detailAnnotation.id,\n        userId: currentUserId,\n        userName: `User ${currentUserId.slice(-4)}`,\n        content,\n      })\n    );\n  };\n\n  const handleReplyToComment = async (commentId: string, content: string) => {\n    if (!detailAnnotation) return;\n    await dispatch(\n      createComment({\n        annotationId: detailAnnotation.id,\n        userId: currentUserId,\n        userName: `User ${currentUserId.slice(-4)}`,\n        content,\n        parentCommentId: commentId,\n      })\n    );\n  };\n\n  const handleDeleteComment = async (commentId: string) => {\n    await dispatch(deleteComment({ commentId }));\n  };\n\n  const handleToggleResolve = async () => {\n    if (!detailAnnotation) return;\n    await dispatch(\n      toggleResolveAnnotation({\n        annotationId: detailAnnotation.id,\n        adapter: storageAdapter,\n      })\n    );\n    // Update the local state\n    if (detailAnnotation) {\n      setDetailAnnotation({\n        ...detailAnnotation,\n        isResolved: !detailAnnotation.isResolved,\n      });\n    }\n  };\n\n  const formatTimestamp = (timestamp: string) => {\n    const date = new Date(timestamp);\n    const now = new Date();\n    const diff = now.getTime() - date.getTime();\n    const minutes = Math.floor(diff / 60000);\n    const hours = Math.floor(diff / 3600000);\n    const days = Math.floor(diff / 86400000);\n\n    if (minutes < 1) return 'just now';\n    if (minutes < 60) return `${minutes}m ago`;\n    if (hours < 24) return `${hours}h ago`;\n    if (days < 7) return `${days}d ago`;\n    return date.toLocaleDateString();\n  };\n\n  const getAnnotationTypeLabel = (annotation: Annotation) => {\n    switch (annotation.annotationType) {\n      case AnnotationType.SHAPE:\n        return 'Shape';\n      case AnnotationType.DRAWING:\n        return 'Drawing';\n      case AnnotationType.HIGHLIGHT:\n        return 'Highlight';\n      case AnnotationType.NOTE:\n        return 'Note';\n      default:\n        return 'Annotation';\n    }\n  };\n\n  // Detail View for NOTE annotations\n  if (viewMode === 'detail' && detailAnnotation) {\n    return (\n      <div className=\"w-96 bg-white border-l border-gray-200 flex flex-col h-full\">\n        {/* Detail Header */}\n        <div className=\"p-4 border-b bg-gray-50 flex items-center gap-3\">\n          <button\n            onClick={handleBackToList}\n            className=\"text-gray-600 hover:text-gray-900\"\n            title=\"Back to list\"\n          >\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"h-5 w-5\"\n              viewBox=\"0 0 20 20\"\n              fill=\"currentColor\"\n            >\n              <path\n                fillRule=\"evenodd\"\n                d=\"M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z\"\n                clipRule=\"evenodd\"\n              />\n            </svg>\n          </button>\n          <div className=\"flex-1\">\n            <h2 className=\"text-lg font-semibold text-gray-900\">Note Details</h2>\n            <p className=\"text-xs text-gray-500\">\n              {detailComments.length} comment{detailComments.length !== 1 ? 's' : ''}\n            </p>\n          </div>\n          <button\n            onClick={handleToggleResolve}\n            className={`px-3 py-1 text-xs rounded ${\n              detailAnnotation.isResolved\n                ? 'bg-gray-200 text-gray-700 hover:bg-gray-300'\n                : 'bg-green-500 text-white hover:bg-green-600'\n            }`}\n            title={detailAnnotation.isResolved ? 'Reopen' : 'Mark as resolved'}\n          >\n            {detailAnnotation.isResolved ? 'Reopen' : 'Resolve'}\n          </button>\n        </div>\n\n        {/* Note Content */}\n        <div className=\"p-4 border-b\">\n          <div className=\"flex items-start justify-between mb-2\">\n            <div className=\"flex items-center gap-2\">\n              <span\n                className=\"w-3 h-3 rounded-full flex-shrink-0\"\n                style={{ backgroundColor: detailAnnotation.color }}\n              />\n              <span className=\"text-xs font-medium text-gray-700\">\n                {getAnnotationTypeLabel(detailAnnotation)}\n              </span>\n              {detailAnnotation.isResolved && (\n                <span className=\"text-xs px-2 py-0.5 bg-green-100 text-green-700 rounded\">\n                  Resolved\n                </span>\n              )}\n            </div>\n          </div>\n\n          <div className=\"flex items-center gap-2 text-xs text-gray-600 mb-2\">\n            <span className=\"font-medium\">{detailAnnotation.userId}</span>\n            <span>•</span>\n            <span>{formatTimestamp(detailAnnotation.createdAt)}</span>\n            <span>•</span>\n            <span>Page {detailAnnotation.pageNumber}</span>\n          </div>\n\n          {detailAnnotation.content && (\n            <p className=\"text-sm text-gray-700 whitespace-pre-wrap\">{detailAnnotation.content}</p>\n          )}\n        </div>\n\n        {/* Comments Section */}\n        <div className=\"flex-1 overflow-y-auto p-4\">\n          <h3 className=\"text-sm font-semibold text-gray-900 mb-3\">Comments</h3>\n\n          {/* Comment Input */}\n          <div className=\"mb-4\">\n            <CommentInput\n              onSubmit={handleAddComment}\n              placeholder=\"Add a comment... (Use @username to mention)\"\n            />\n          </div>\n\n          {/* Comment Threads */}\n          {commentThreads.length > 0 ? (\n            <div className=\"space-y-4\">\n              {commentThreads.map((thread) => (\n                <CommentThread\n                  key={thread.comment.id}\n                  thread={{\n                    comment: thread.comment,\n                    replies: thread.replies,\n                    replyCount: thread.replies.length,\n                  }}\n                  currentUserId={currentUserId}\n                  onReply={handleReplyToComment}\n                  onEdit={() => {}}\n                  onDelete={handleDeleteComment}\n                  onResolve={() => {}}\n                />\n              ))}\n            </div>\n          ) : (\n            <p className=\"text-sm text-gray-500 text-center py-8\">\n              No comments yet. Be the first to comment!\n            </p>\n          )}\n        </div>\n      </div>\n    );\n  }\n\n  // List View (default)\n  return (\n    <div className=\"w-96 bg-white border-l border-gray-200 flex flex-col h-full\">\n      {/* Header */}\n      <div className=\"p-4 border-b bg-gray-50\">\n        <h2 className=\"text-lg font-semibold text-gray-900 mb-3\">\n          Annotations ({filteredAnnotations.length})\n        </h2>\n\n        {/* Search Bar */}\n        <input\n          type=\"text\"\n          placeholder=\"Search by user or content...\"\n          value={searchQuery}\n          onChange={(e) => setSearchQuery(e.target.value)}\n          className=\"w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 mb-3\"\n        />\n\n        {/* Filter Buttons */}\n        <div className=\"flex gap-2 flex-wrap\">\n          <button\n            onClick={() => setFilterType('all')}\n            className={`px-3 py-1 text-xs rounded-full ${\n              filterType === 'all'\n                ? 'bg-blue-500 text-white'\n                : 'bg-gray-200 text-gray-700 hover:bg-gray-300'\n            }`}\n          >\n            All\n          </button>\n          <button\n            onClick={() => setFilterType('shapes')}\n            className={`px-3 py-1 text-xs rounded-full ${\n              filterType === 'shapes'\n                ? 'bg-blue-500 text-white'\n                : 'bg-gray-200 text-gray-700 hover:bg-gray-300'\n            }`}\n          >\n            Shapes\n          </button>\n          <button\n            onClick={() => setFilterType('notes')}\n            className={`px-3 py-1 text-xs rounded-full ${\n              filterType === 'notes'\n                ? 'bg-blue-500 text-white'\n                : 'bg-gray-200 text-gray-700 hover:bg-gray-300'\n            }`}\n          >\n            Notes\n          </button>\n          <button\n            onClick={() => setFilterType('resolved')}\n            className={`px-3 py-1 text-xs rounded-full ${\n              filterType === 'resolved'\n                ? 'bg-blue-500 text-white'\n                : 'bg-gray-200 text-gray-700 hover:bg-gray-300'\n            }`}\n          >\n            Resolved\n          </button>\n        </div>\n      </div>\n\n      {/* Annotations List */}\n      <div className=\"flex-1 overflow-y-auto\">\n        {filteredAnnotations.length === 0 ? (\n          <div className=\"p-8 text-center text-gray-500\">\n            <p className=\"text-sm\">\n              {searchQuery || filterType !== 'all'\n                ? 'No annotations match your filters'\n                : 'No annotations yet'}\n            </p>\n          </div>\n        ) : (\n          <div className=\"divide-y divide-gray-200\">\n            {filteredAnnotations.map((annotation) => (\n              <div\n                key={annotation.id}\n                onClick={() => handleAnnotationClick(annotation)}\n                className={`p-4 cursor-pointer transition-colors ${\n                  selectedAnnotation?.id === annotation.id\n                    ? 'bg-blue-50 border-l-4 border-blue-500'\n                    : 'hover:bg-gray-50'\n                } ${annotation.isResolved ? 'opacity-60' : ''}`}\n              >\n                {/* Annotation Header */}\n                <div className=\"flex items-start justify-between mb-2\">\n                  <div className=\"flex items-center gap-2\">\n                    <span\n                      className=\"w-3 h-3 rounded-full flex-shrink-0\"\n                      style={{ backgroundColor: annotation.color }}\n                    />\n                    <span className=\"text-xs font-medium text-gray-700\">\n                      {getAnnotationTypeLabel(annotation)}\n                    </span>\n                    {annotation.isResolved && (\n                      <span className=\"text-xs px-2 py-0.5 bg-green-100 text-green-700 rounded\">\n                        Resolved\n                      </span>\n                    )}\n                  </div>\n\n                  {/* Delete Button */}\n                  {deleteConfirm === annotation.id ? (\n                    <div className=\"flex gap-1\" onClick={(e) => e.stopPropagation()}>\n                      <button\n                        onClick={(e) => confirmDelete(e, annotation.id)}\n                        className=\"text-xs px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600\"\n                      >\n                        Delete\n                      </button>\n                      <button\n                        onClick={cancelDelete}\n                        className=\"text-xs px-2 py-1 bg-gray-300 text-gray-700 rounded hover:bg-gray-400\"\n                      >\n                        Cancel\n                      </button>\n                    </div>\n                  ) : (\n                    <button\n                      onClick={(e) => handleDeleteClick(e, annotation.id)}\n                      className=\"text-gray-400 hover:text-red-500 transition-colors\"\n                      title=\"Delete annotation\"\n                    >\n                      <svg\n                        xmlns=\"http://www.w3.org/2000/svg\"\n                        className=\"h-4 w-4\"\n                        fill=\"none\"\n                        viewBox=\"0 0 24 24\"\n                        stroke=\"currentColor\"\n                      >\n                        <path\n                          strokeLinecap=\"round\"\n                          strokeLinejoin=\"round\"\n                          strokeWidth={2}\n                          d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n                        />\n                      </svg>\n                    </button>\n                  )}\n                </div>\n\n                {/* User and Timestamp */}\n                <div className=\"flex items-center gap-2 text-xs text-gray-600 mb-2\">\n                  <span className=\"font-medium\">{annotation.userId}</span>\n                  <span>•</span>\n                  <span>{formatTimestamp(annotation.createdAt)}</span>\n                  <span>•</span>\n                  <span>Page {annotation.pageNumber}</span>\n                </div>\n\n                {/* Content Preview (for notes) */}\n                {annotation.content && annotation.annotationType === AnnotationType.NOTE && (\n                  <p className=\"text-sm text-gray-700 line-clamp-2\">{annotation.content}</p>\n                )}\n\n                {/* Comment count for notes */}\n                {annotation.annotationType === AnnotationType.NOTE && (\n                  <div className=\"mt-2 text-xs text-gray-500\">\n                    {(allComments[annotation.id] || []).length} comment\n                    {(allComments[annotation.id] || []).length !== 1 ? 's' : ''}\n                  </div>\n                )}\n              </div>\n            ))}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n","import React, { useState, useRef, useEffect } from 'react';\n\nexport interface InlineCommentInputProps {\n  position: { x: number; y: number };\n  onSubmit: (content: string) => void;\n  onCancel: () => void;\n  currentUserId: string;\n}\n\nexport function InlineCommentInput({\n  position,\n  onSubmit,\n  onCancel,\n  currentUserId: _currentUserId,\n}: InlineCommentInputProps) {\n  const [content, setContent] = useState('');\n  const inputRef = useRef<HTMLTextAreaElement>(null);\n\n  useEffect(() => {\n    // Focus the input when component mounts\n    inputRef.current?.focus();\n  }, []);\n\n  const handleSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n    if (content.trim()) {\n      onSubmit(content.trim());\n      setContent('');\n    }\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === 'Enter' && !e.shiftKey) {\n      e.preventDefault();\n      handleSubmit(e);\n    } else if (e.key === 'Escape') {\n      onCancel();\n    }\n  };\n\n  return (\n    <div\n      className=\"absolute z-50 bg-white rounded-lg shadow-xl border border-gray-300 p-3\"\n      style={{\n        left: `${position.x}px`,\n        top: `${position.y}px`,\n        width: '300px',\n      }}\n    >\n      <div className=\"text-xs font-semibold text-gray-700 mb-2\">Add a comment to your note</div>\n      <form onSubmit={handleSubmit}>\n        <textarea\n          ref={inputRef}\n          value={content}\n          onChange={(e) => setContent(e.target.value)}\n          onKeyDown={handleKeyDown}\n          placeholder=\"Type your comment... (Enter to submit, Shift+Enter for new line, Esc to skip)\"\n          className=\"w-full px-2 py-1.5 text-sm border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none\"\n          rows={3}\n        />\n        <div className=\"flex justify-end gap-2 mt-2\">\n          <button\n            type=\"button\"\n            onClick={onCancel}\n            className=\"px-3 py-1 text-xs text-gray-600 hover:text-gray-800 hover:bg-gray-100 rounded\"\n          >\n            Skip\n          </button>\n          <button\n            type=\"submit\"\n            disabled={!content.trim()}\n            className=\"px-3 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed\"\n          >\n            Add Comment\n          </button>\n        </div>\n      </form>\n    </div>\n  );\n}\n"],"names":["AnnotationType","AnnotationTool","DEFAULT_CONFIG","LogLevel","Logger","config","isProduction","message","data","level","fullMessage","logger","createLogger","namespace","normalizedToPixels","normalized","pageWidth","pageHeight","result","pixelsToNormalized","pixels","getSelectionBounds","selection","container","rects","containerRect","rect","clamp","value","min","max","normalizeBounds","bounds","USER_COLORS","ANNOTATION_COLORS","hashCode","str","hash","i","char","getUserColor","userId","color","isColorLight","hex","r","g","b","getContrastColor","backgroundColor","rgbToHex","x","hexToRgb","withOpacity","opacity","rgb","pointsToPath","points","first","rest","path","point","pointsToSmoothPath","second","curr","next","midX","midY","last","createArrowMarker","id","createArrowPath","startX","startY","endX","endY","isValidNormalizedPosition","position","isValidHexColor","isValidAnnotationType","type","isValidPageNumber","page","totalPages","sanitizeString","input","maxLength","debounce","func","wait","timeout","args","later","throttle","limit","inThrottle","lastResult","rafThrottle","rafId","memoize","keyGenerator","cache","key","batchCalls","callback","delay","items","item","TaskQueue","concurrency","task","resolve","reject","error","Queue","ApiStorage","axios","response","documentId","versionId","docId","verId","annotation","created","annotationId","updates","updated","annotations","results","update","createApiStorage","LocalStorageAdapter","stored","newAnnotation","index","a","existing","filtered","newAnnotations","dto","json","createLocalStorage","io","socketio","SocketIOAdapter","options","event","handler","handlers","createSocketIOCollaboration","NoOpAdapter","_documentId","_versionId","_event","_handler","createNoOpCollaboration","ReactPDFAdapter","_pageNumber","canvas","dims","pageDiv","pageNumber","scale","createReactPDFAdapter","GenericAdapter","createGenericAdapter","initialState","fetchAnnotations","createAsyncThunk","adapter","createAnnotation","updateAnnotation","deleteAnnotation","toggleResolveAnnotation","annotationsSlice","createSlice","state","action","builder","tempIndex","addAnnotationOptimistic","updateAnnotationFromWS","removeAnnotationFromWS","setCreatingAnnotation","selectAnnotation","clearAnnotations","clearError","annotationsReducer","uiSlice","setCurrentTool","setAnnotationColor","setScale","setCurrentPage","setTotalPages","setViewState","toggleSidebar","setSidebarOpen","toggleNotesPanel","setNotesPanelOpen","resetUI","uiReducer","documentSlice","setCurrentDocument","setDocumentIds","setLoading","setError","clearDocument","documentReducer","fetchComments","createComment","updateComment","commentId","deleteComment","resolveComment","resolved","commentsSlice","comments","comment","c","resolvedBy","resolvedAt","commentsArray","addCommentOptimistic","updateCommentLocal","removeCommentLocal","resolveCommentLocal","clearComments","clearAllComments","commentsReducer","historySlice","entry","recordHistoryEntry","setHistoryFilter","clearHistory","historyReducer","selectFilteredHistory","entries","filter","entryDate","start","end","selectHistoryByEntity","entityType","entityId","createAnnotationStore","adapters","extraMiddleware","preloadedState","store","configureStore","getDefaultMiddleware","getAdapters","useAppDispatch","useDispatch","useAppSelector","useSelector","useUI","useSelectedAnnotation","useCurrentTool","useAnnotationColor","useViewState","useCreatingAnnotation","AnnotationContext","createContext","useAnnotationContext","context","useContext","getAnnotationTypeLabel","useAnnotations","dispatch","loading","selected","creating","useCallback","tempAnnotation","commentContent","commentResult","commentErr","err","selectAnnotationById","clearAllAnnotations","useAnnotationDraw","currentTool","isDrawing","setIsDrawing","useState","setTool","tool","setColor","newColor","startDrawing","stopDrawing","setCreating","useDocument","documentState","useCollaboration","useEffect","collaboration","handleCreated","handleUpdated","handleDeleted","handleError","useViewport","currentPage","stateRef","useRef","newScale","total","nextPage","previousPage","zoomIn","zoomOut","parseMentions","text","mentions","bracketMatches","match","simpleMatches","username","highlightMentions","currentUserId","highlightedText","hasMention","_match","displayName","isCurrentUser","useComments","allComments","threads","useMemo","threadsMap","reply","thread","commentCount","addComment","content","parentCommentId","editComment","removeComment","replyToComment","toggleResolve","newResolvedState","useComment","updateLocal","removeLocal","resolveLocal","formatChange","change","field","oldValue","newValue","valueType","formatValue","groupByDate","grouped","date","getRelativeTime","timestamp","now","diffMs","diffSec","diffMin","diffHour","diffDay","useHistory","allEntries","filteredEntries","currentFilter","timeline","record","setFilter","clear","useEntityHistory","latestEntry","createdEntry","e","modificationCount","AnnotationProvider","children","storage","renderer","userConfig","contextValue","jsx","Provider","AnnotationElementComponent","onSelect","onUpdate","isDragging","setIsDragging","dragStartPos","setDragStartPos","dragPosition","setDragPosition","showCoordinates","setShowCoordinates","displayPixels","handleClick","handleMouseDown","handleGlobalMouseMove","prevDragStartPos","prevDragPosition","currentPixels","deltaX","deltaY","newX","newY","handleGlobalMouseUp","currentIsDragging","currentDragPosition","updatedPositionData","drawingData","shapeData","renderCoordinateTooltip","tooltipX","tooltipY","normalizedCoords","jsxs","annotationElement","cx","cy","x1","y1","x2","y2","angle","arrowLength","arrowPoint1X","arrowPoint1Y","arrowPoint2X","arrowPoint2Y","Fragment","translateX","translateY","transform","AnnotationElement","memo","AnnotationLayerComponent","className","list","viewState","pageAnnotations","ann","dimensions","handleAnnotationSelect","handleAnnotationUpdate","AnnotationLayer","AnnotationCanvasComponent","annotationColor","startPos","setStartPos","currentPos","setCurrentPos","drawingPath","setDrawingPath","draggedAnnotation","setDraggedAnnotation","dragOffset","setDragOffset","cursorStyle","setCursorStyle","canvasRef","checkAnnotationAtPosition","clickX","clickY","distance","isWithin","y","clickedAnnotation","createNoteAnnotation","handleMouseMove","hoveredAnnotation","prev","handleMouseUp","newNormalized","width","height","createArrowAnnotation","createAnnotationHelper","createShapeAnnotation","createDrawingAnnotation","positionData","tempId","optimisticAnnotation","createResult","shapeType","renderPreview","AnnotationCanvas","toKebabCase","string","toCamelCase","p1","p2","toPascalCase","camelCase","mergeClasses","classes","array","hasA11yProp","props","prop","defaultAttributes","Icon","forwardRef","size","strokeWidth","absoluteStrokeWidth","iconNode","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","__iconNode","ArrowRight","Check","Circle","EllipsisVertical","Highlighter","MousePointer","PenLine","Pencil","Search","Square","StickyNote","Trash2","X","AnnotationToolbarComponent","showColorPicker","setShowColorPicker","isToolbarVisible","setIsToolbarVisible","availableTools","handleToolChange","handleColorChange","toggleToolbar","TOOL_ICONS","isActive","colorClass","TOOL_COLORS","Edit3","AnnotationToolbar","NoteCardComponent","note","onEdit","onDelete","canEdit","canDelete","isSelected","showMenu","setShowMenu","formatTimestamp","dateString","handleEdit","handleDelete","MoreVertical","NoteCard","NoteInlineEditor","onSave","onCancel","setContent","isDeleting","setIsDeleting","textareaRef","length","handleSave","handleCancel","handleKeyDown","NotesPanelComponent","searchQuery","setSearchQuery","sortBy","setSortBy","editingNote","setEditingNote","pageNotes","aPos","bPos","handleSaveNote","handleCancelEdit","NotesPanel","ErrorBoundary","errorInfo","prevProps","resetKeys","hasError","fallback","CommentThread","onReply","onResolve","showReplyInput","setShowReplyInput","replyContent","setReplyContent","editingId","setEditingId","editContent","setEditContent","handleReply","startEdit","cancelEdit","CommentItem","isReply","isEditing","onEditChange","onEditSave","onEditCancel","onEditStart","onReplyClick","isOwnComment","firstChar","highlightedContent","CommentInput","onSubmit","placeholder","autoFocus","handleSubmit","HistoryPanel","showFilters","maxHeight","onEntryClick","actionFilter","setActionFilter","displayTimeline","HistoryEntryItem","onClick","actionIcon","getActionIcon","actionColor","getActionColor","HistoryDrawer","isOpen","onClose","AnnotationsListPanel","storageAdapter","onAnnotationClick","selectedAnnotation","filterType","setFilterType","deleteConfirm","setDeleteConfirm","viewMode","setViewMode","detailAnnotation","setDetailAnnotation","detailComments","commentThreads","replies","filteredAnnotations","query","handleAnnotationClick","handleBackToList","handleDeleteClick","confirmDelete","cancelDelete","handleAddComment","handleReplyToComment","handleDeleteComment","handleToggleResolve","diff","minutes","hours","days","InlineCommentInput","_currentUserId","inputRef"],"mappings":"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","x_google_ignoreList":[36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52]}