@semiont/api-client 0.2.28-build.38 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/branded-types.ts","../../src/utils/annotations.ts","../../src/utils/events.ts","../../src/utils/fuzzy-anchor.ts","../../src/utils/locales.ts","../../src/utils/resources.ts","../../src/utils/svg-utils.ts","../../src/utils/text-encoding.ts","../../src/utils/validation.ts"],"names":["resourceUri","pos"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from '../types';\nimport type { ResourceUri } from '../branded-types';\nimport { resourceUri } from '../branded-types';\n\ntype Annotation = components['schemas']['Annotation'];\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype Selector = TextPositionSelector | TextQuoteSelector | SvgSelector;\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): ResourceUri | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return resourceUri(itemSource);\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return resourceUri(bodySource);\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): ResourceUri {\n if (typeof target === 'string') {\n return resourceUri(target);\n }\n return resourceUri(target.source);\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Extract entity types from annotation bodies\n * Entity types are stored as TextualBody with purpose: \"tagging\"\n * Accepts any object with a body property matching Annotation['body']\n */\nexport function getEntityTypes(annotation: { body: Annotation['body'] }): string[] {\n // Extract from TextualBody bodies with purpose: \"tagging\"\n if (Array.isArray(annotation.body)) {\n const entityTags: string[] = [];\n\n for (const item of annotation.body) {\n // Runtime check for TextualBody with tagging purpose\n // TypeScript incorrectly narrows the union type here, so we use runtime checks only\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'value' in item &&\n 'purpose' in item\n ) {\n // Access properties as unknown first to avoid TypeScript narrowing issues\n const itemType = (item as { type: unknown }).type;\n const itemValue = (item as { value: unknown }).value;\n const itemPurpose = (item as { purpose: unknown }).purpose;\n\n if (itemType === 'TextualBody' && itemPurpose === 'tagging' && typeof itemValue === 'string' && itemValue.length > 0) {\n entityTags.push(itemValue);\n }\n }\n }\n\n return entityTags;\n }\n\n return [];\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Extract tag category from a tag annotation's body\n * Tags use dual-body structure: first body has purpose: \"tagging\" with category value\n * @param annotation - The annotation to extract category from\n * @returns The tag category (e.g., \"Issue\", \"Rule\"), or undefined if not a tag or no category found\n */\nexport function getTagCategory(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const taggingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'tagging');\n if (taggingBody && 'value' in taggingBody) {\n return taggingBody.value;\n }\n return undefined;\n}\n\n/**\n * Extract tag schema ID from a tag annotation's body\n * Tags use dual-body structure: second body has purpose: \"classifying\" with schema ID\n * @param annotation - The annotation to extract schema ID from\n * @returns The schema ID (e.g., \"legal-irac\"), or undefined if not a tag or no schema found\n */\nexport function getTagSchemaId(annotation: Annotation): string | undefined {\n if (!isTag(annotation)) return undefined;\n const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];\n const classifyingBody = bodies.find(b => b && 'purpose' in b && b.purpose === 'classifying');\n if (classifyingBody && 'value' in classifyingBody) {\n return classifyingBody.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n *\n * Returns the first TextPositionSelector found, or null if none exists.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null; // No selector means entire resource\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n *\n * Returns the first SvgSelector found, or null if none exists.\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * Checks that:\n * - SVG contains xmlns attribute\n * - SVG is well-formed XML\n * - SVG contains at least one shape element\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n // Check for xmlns attribute (required by W3C spec)\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n // Check for basic SVG tag structure\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n // Check for at least one shape element\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null; // Valid\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * Event Utilities\n *\n * Pure TypeScript utilities for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { paths, components } from '../types';\nimport { AnnotationUri } from '../branded-types';\nimport { getExactText, getTargetSelector } from './annotations';\n\n// Extract StoredEvent type from events endpoint response\ntype EventsResponse = paths['/resources/{id}/events']['get']['responses'][200]['content']['application/json'];\nexport type StoredEvent = EventsResponse['events'][number];\nexport type ResourceEvent = StoredEvent['event'];\nexport type EventMetadata = StoredEvent['metadata'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Event types\nexport type ResourceEventType =\n | 'resource.created'\n | 'resource.cloned'\n | 'resource.archived'\n | 'resource.unarchived'\n | 'annotation.added'\n | 'annotation.removed'\n | 'annotation.body.updated'\n | 'entitytag.added'\n | 'entitytag.removed'\n | 'entitytype.added' // Global entity type collection\n | 'job.started'\n | 'job.progress'\n | 'job.completed'\n | 'job.failed';\n\ntype TranslateFn = (key: string, params?: Record<string, string | number>) => string;\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For annotation.added: extracts full URI from payload.annotation.id\n * For annotation.removed/body.updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEvent): AnnotationUri | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (!payload) {\n return null;\n }\n\n switch (eventData.type) {\n case 'annotation.added':\n // annotation.added has the full annotation object with id as full URI\n return payload.annotation?.id || null;\n\n case 'annotation.removed':\n case 'annotation.body.updated':\n // These events have annotationId (UUID only), need to construct full URI\n // Extract base URL from resourceId (format: http://host/resources/id)\n if (payload.annotationId && eventData.resourceId) {\n try {\n const resourceUri = eventData.resourceId;\n // Extract base URL by removing the /resources/{id} part\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEvent, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if event is a resource event\n */\nexport function isResourceEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.event === 'object' &&\n typeof event.event.id === 'string' &&\n typeof event.event.timestamp === 'string' &&\n typeof event.event.resourceId === 'string' &&\n typeof event.event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n// =============================================================================\n// EVENT FORMATTING AND DISPLAY\n// =============================================================================\n\n/**\n * Format event type for display with i18n support\n */\nexport function formatEventType(type: ResourceEventType, t: TranslateFn, payload?: any): string {\n switch (type) {\n case 'resource.created':\n return t('resourceCreated');\n case 'resource.cloned':\n return t('resourceCloned');\n case 'resource.archived':\n return t('resourceArchived');\n case 'resource.unarchived':\n return t('resourceUnarchived');\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return t('highlightAdded');\n if (motivation === 'linking') return t('referenceCreated');\n if (motivation === 'assessing') return t('assessmentAdded');\n return t('annotationAdded');\n }\n case 'annotation.removed': {\n return t('annotationRemoved');\n }\n case 'annotation.body.updated': {\n return t('annotationBodyUpdated');\n }\n\n case 'entitytag.added':\n return t('entitytagAdded');\n case 'entitytag.removed':\n return t('entitytagRemoved');\n case 'entitytype.added':\n return t('entitytypeAdded');\n\n case 'job.completed':\n case 'job.started':\n case 'job.progress':\n case 'job.failed':\n return t('jobEvent');\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Get emoji for event type\n * For unified annotation events, pass the payload to determine motivation\n */\nexport function getEventEmoji(type: ResourceEventType, payload?: any): string {\n switch (type) {\n case 'resource.created':\n case 'resource.cloned':\n case 'resource.archived':\n case 'resource.unarchived':\n return '📄';\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return '🟡';\n if (motivation === 'linking') return '🔵';\n if (motivation === 'assessing') return '🔴';\n return '📝';\n }\n case 'annotation.removed': {\n return '🗑️';\n }\n case 'annotation.body.updated': {\n return '✏️';\n }\n\n case 'entitytag.added':\n case 'entitytag.removed':\n return '🏷️';\n case 'entitytype.added':\n return '🏷️'; // Same emoji as entitytag (global entity type collection)\n\n case 'job.completed':\n return '🔗'; // Link emoji for linked document creation\n case 'job.started':\n case 'job.progress':\n return '⚙️'; // Gear for job processing\n case 'job.failed':\n return '❌'; // X mark for failed jobs\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Format timestamp as relative time with i18n support\n */\nexport function formatRelativeTime(timestamp: string, t: TranslateFn): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return t('justNow');\n if (diffMins < 60) return t('minutesAgo', { count: diffMins });\n if (diffHours < 24) return t('hoursAgo', { count: diffHours });\n if (diffDays < 7) return t('daysAgo', { count: diffDays });\n\n return date.toLocaleDateString();\n}\n\n/**\n * Helper to truncate text for display\n */\nfunction truncateText(text: string, maxLength = 50): string {\n const trimmed = text.trim();\n return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + '...' : trimmed;\n}\n\n/**\n * Get display content from event payload - complete implementation\n */\nexport function getEventDisplayContent(\n event: StoredEvent,\n annotations: Annotation[], // Unified annotations array (all types)\n allEvents: StoredEvent[]\n): { exact: string; isQuoted: boolean; isTag: boolean } | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n // Use type discriminators instead of runtime typeof checks\n switch (eventData.type) {\n case 'resource.created':\n case 'resource.cloned': {\n return { exact: payload.name, isQuoted: false, isTag: false };\n }\n\n // Unified annotation events\n case 'annotation.body.updated': {\n // Find current annotation to get its text\n // payload.annotationId is just the UUID, but annotation.id is the full URI\n const annotation = annotations.find(a =>\n a.id.endsWith(`/annotations/${payload.annotationId}`)\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n return null;\n }\n\n case 'annotation.removed': {\n // Find the original annotation.added event to get the text\n // payload.annotationId is just the UUID, but annotation.id in the added event is the full URI\n const addedEvent = allEvents.find(e =>\n e.event.type === 'annotation.added' &&\n (e.event.payload as any).annotation?.id?.endsWith(`/annotations/${payload.annotationId}`)\n );\n if (addedEvent) {\n const addedPayload = addedEvent.event.payload as any;\n try {\n const exact = getExactText(addedPayload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n }\n return null;\n }\n\n case 'annotation.added': {\n // New unified event structure - annotation is in payload\n try {\n const exact = getExactText(payload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n return null;\n }\n\n case 'entitytag.added':\n case 'entitytag.removed': {\n return { exact: payload.entityType, isQuoted: false, isTag: true };\n }\n\n case 'job.completed': {\n // Find the annotation that was used to generate the resource\n if (payload.annotationUri) {\n const annotation = annotations.find(a =>\n a.id === payload.annotationUri\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Get entity types from event payload\n */\nexport function getEventEntityTypes(event: StoredEvent): string[] {\n const eventData = event.event;\n\n if (eventData.type === 'annotation.added') {\n const payload = eventData.payload as any;\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'linking') {\n return payload.annotation?.body?.entityTypes ?? [];\n }\n }\n\n return [];\n}\n\n/**\n * Resource creation details\n */\nexport interface ResourceCreationDetails {\n type: 'created' | 'cloned';\n method: string;\n userId?: string;\n sourceDocId?: string; // For cloned resources\n parentResourceId?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Get resource creation details from event\n */\nexport function getResourceCreationDetails(event: StoredEvent): ResourceCreationDetails | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (eventData.type === 'resource.created') {\n return {\n type: 'created',\n method: payload.creationMethod || 'unknown',\n userId: eventData.userId,\n metadata: payload.metadata,\n };\n }\n\n if (eventData.type === 'resource.cloned') {\n return {\n type: 'cloned',\n method: payload.creationMethod || 'clone',\n userId: eventData.userId,\n sourceDocId: payload.parentResourceId,\n parentResourceId: payload.parentResourceId,\n metadata: payload.metadata,\n };\n }\n\n return null;\n}\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\n/**\n * Find text using exact match with optional prefix/suffix context\n *\n * When the exact text appears multiple times in the content, prefix and suffix\n * are used to disambiguate and find the correct occurrence.\n *\n * @param content - Full text content to search within\n * @param exact - The exact text to find\n * @param prefix - Optional text that should appear immediately before the match\n * @param suffix - Optional text that should appear immediately after the match\n * @returns Position of the matched text, or null if not found\n *\n * @example\n * ```typescript\n * const content = \"The cat sat. The cat ran.\";\n * // Find second \"The cat\" occurrence\n * const pos = findTextWithContext(content, \"The cat\", \"sat. \", \" ran\");\n * // Returns { start: 13, end: 20 }\n * ```\n */\nexport function findTextWithContext(\n content: string,\n exact: string,\n prefix?: string,\n suffix?: string\n): TextPosition | null {\n if (!exact) return null;\n\n // Find all occurrences of exact text\n const occurrences: number[] = [];\n let index = content.indexOf(exact);\n while (index !== -1) {\n occurrences.push(index);\n index = content.indexOf(exact, index + 1);\n }\n\n // No matches found\n if (occurrences.length === 0) {\n console.warn(`[FuzzyAnchor] Text not found: \"${exact.substring(0, 50)}...\"`);\n return null;\n }\n\n // Only one match - no need for prefix/suffix disambiguation\n if (occurrences.length === 1) {\n const pos = occurrences[0]!; // Safe: length === 1 means first element exists\n return { start: pos, end: pos + exact.length };\n }\n\n // Multiple matches - use prefix/suffix to disambiguate\n if (prefix || suffix) {\n for (const pos of occurrences) {\n // Extract actual prefix from content\n const actualPrefixStart = Math.max(0, pos - (prefix?.length || 0));\n const actualPrefix = content.substring(actualPrefixStart, pos);\n\n // Extract actual suffix from content\n const actualSuffixEnd = Math.min(content.length, pos + exact.length + (suffix?.length || 0));\n const actualSuffix = content.substring(pos + exact.length, actualSuffixEnd);\n\n // Check if prefix matches\n const prefixMatch = !prefix || actualPrefix.endsWith(prefix);\n\n // Check if suffix matches\n const suffixMatch = !suffix || actualSuffix.startsWith(suffix);\n\n if (prefixMatch && suffixMatch) {\n return { start: pos, end: pos + exact.length };\n }\n }\n\n // No match with exact prefix/suffix - try fuzzy matching\n console.warn(\n `[FuzzyAnchor] Multiple matches found but none match prefix/suffix exactly. ` +\n `Exact: \"${exact.substring(0, 30)}...\", ` +\n `Prefix: \"${prefix?.substring(0, 20) || 'none'}\", ` +\n `Suffix: \"${suffix?.substring(0, 20) || 'none'}\"`\n );\n\n // Fallback: try partial prefix/suffix match\n for (const pos of occurrences) {\n const actualPrefix = content.substring(Math.max(0, pos - (prefix?.length || 0)), pos);\n const actualSuffix = content.substring(pos + exact.length, pos + exact.length + (suffix?.length || 0));\n\n // Fuzzy match: check if prefix/suffix are substrings (handles whitespace variations)\n const fuzzyPrefixMatch = !prefix || actualPrefix.includes(prefix.trim());\n const fuzzySuffixMatch = !suffix || actualSuffix.includes(suffix.trim());\n\n if (fuzzyPrefixMatch && fuzzySuffixMatch) {\n console.warn(`[FuzzyAnchor] Using fuzzy match at position ${pos}`);\n return { start: pos, end: pos + exact.length };\n }\n }\n }\n\n // Fallback: return first occurrence if no prefix/suffix or no match\n console.warn(\n `[FuzzyAnchor] Multiple matches but no context match. Using first occurrence. ` +\n `Exact: \"${exact.substring(0, 30)}...\"`\n );\n const pos = occurrences[0]!; // Safe: we checked length > 0 earlier\n return { start: pos, end: pos + exact.length };\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from '../types';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * For internal resources: extracts UUID from \"http://localhost:4000/resources/{uuid}\"\n * For external resources: returns undefined\n *\n * This is used for routing - the frontend URL should contain only the resource ID,\n * not the full HTTP URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n\n const fullId = resource['@id'];\n\n // For internal resources, extract the last path segment\n // http://localhost:4000/resources/{uuid} -> {uuid}\n if (fullId.includes('/resources/')) {\n const parts = fullId.split('/resources/');\n const lastPart = parts[parts.length - 1];\n return lastPart || undefined;\n }\n\n // For external resources, cannot extract ID\n return undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/api-client\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n"]}
1
+ {"version":3,"sources":["../../src/branded-types.ts","../../src/utils/annotations.ts","../../src/utils/events.ts","../../src/utils/fuzzy-anchor.ts","../../src/utils/locales.ts","../../src/utils/resources.ts","../../src/utils/svg-utils.ts","../../src/utils/text-context.ts","../../src/utils/text-encoding.ts","../../src/utils/validation.ts"],"names":["resourceUri","pos","context"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from '../types';\nimport type { ResourceUri } from '../branded-types';\nimport { resourceUri } from '../branded-types';\n\ntype Annotation = components['schemas']['Annotation'];\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype Selector = TextPositionSelector | TextQuoteSelector | SvgSelector;\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): ResourceUri | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return resourceUri(itemSource);\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return resourceUri(bodySource);\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): ResourceUri {\n if (typeof target === 'string') {\n return resourceUri(target);\n }\n return resourceUri(target.source);\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n *\n * Returns the first TextPositionSelector found, or null if none exists.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null; // No selector means entire resource\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n *\n * Returns the first SvgSelector found, or null if none exists.\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * Checks that:\n * - SVG contains xmlns attribute\n * - SVG is well-formed XML\n * - SVG contains at least one shape element\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n // Check for xmlns attribute (required by W3C spec)\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n // Check for basic SVG tag structure\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n // Check for at least one shape element\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null; // Valid\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * Event Utilities\n *\n * Pure TypeScript utilities for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { paths, components } from '../types';\nimport { AnnotationUri } from '../branded-types';\nimport { getExactText, getTargetSelector } from './annotations';\n\n// Extract StoredEvent type from events endpoint response\ntype EventsResponse = paths['/resources/{id}/events']['get']['responses'][200]['content']['application/json'];\nexport type StoredEvent = EventsResponse['events'][number];\nexport type ResourceEvent = StoredEvent['event'];\nexport type EventMetadata = StoredEvent['metadata'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Event types\nexport type ResourceEventType =\n | 'resource.created'\n | 'resource.cloned'\n | 'resource.archived'\n | 'resource.unarchived'\n | 'annotation.added'\n | 'annotation.removed'\n | 'annotation.body.updated'\n | 'entitytag.added'\n | 'entitytag.removed'\n | 'entitytype.added' // Global entity type collection\n | 'job.started'\n | 'job.progress'\n | 'job.completed'\n | 'job.failed';\n\ntype TranslateFn = (key: string, params?: Record<string, string | number>) => string;\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For annotation.added: extracts full URI from payload.annotation.id\n * For annotation.removed/body.updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEvent): AnnotationUri | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (!payload) {\n return null;\n }\n\n switch (eventData.type) {\n case 'annotation.added':\n // annotation.added has the full annotation object with id as full URI\n return payload.annotation?.id || null;\n\n case 'annotation.removed':\n case 'annotation.body.updated':\n // These events have annotationId (UUID only), need to construct full URI\n // Extract base URL from resourceId (format: http://host/resources/id)\n if (payload.annotationId && eventData.resourceId) {\n try {\n const resourceUri = eventData.resourceId;\n // Extract base URL by removing the /resources/{id} part\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEvent, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if event is a resource event\n */\nexport function isResourceEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.event === 'object' &&\n typeof event.event.id === 'string' &&\n typeof event.event.timestamp === 'string' &&\n typeof event.event.resourceId === 'string' &&\n typeof event.event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n// =============================================================================\n// EVENT FORMATTING AND DISPLAY\n// =============================================================================\n\n/**\n * Format event type for display with i18n support\n */\nexport function formatEventType(type: ResourceEventType, t: TranslateFn, payload?: any): string {\n switch (type) {\n case 'resource.created':\n return t('resourceCreated');\n case 'resource.cloned':\n return t('resourceCloned');\n case 'resource.archived':\n return t('resourceArchived');\n case 'resource.unarchived':\n return t('resourceUnarchived');\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return t('highlightAdded');\n if (motivation === 'linking') return t('referenceCreated');\n if (motivation === 'assessing') return t('assessmentAdded');\n return t('annotationAdded');\n }\n case 'annotation.removed': {\n return t('annotationRemoved');\n }\n case 'annotation.body.updated': {\n return t('annotationBodyUpdated');\n }\n\n case 'entitytag.added':\n return t('entitytagAdded');\n case 'entitytag.removed':\n return t('entitytagRemoved');\n case 'entitytype.added':\n return t('entitytypeAdded');\n\n case 'job.completed':\n case 'job.started':\n case 'job.progress':\n case 'job.failed':\n return t('jobEvent');\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Get emoji for event type\n * For unified annotation events, pass the payload to determine motivation\n */\nexport function getEventEmoji(type: ResourceEventType, payload?: any): string {\n switch (type) {\n case 'resource.created':\n case 'resource.cloned':\n case 'resource.archived':\n case 'resource.unarchived':\n return '📄';\n\n case 'annotation.added': {\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'highlighting') return '🟡';\n if (motivation === 'linking') return '🔵';\n if (motivation === 'assessing') return '🔴';\n return '📝';\n }\n case 'annotation.removed': {\n return '🗑️';\n }\n case 'annotation.body.updated': {\n return '✏️';\n }\n\n case 'entitytag.added':\n case 'entitytag.removed':\n return '🏷️';\n case 'entitytype.added':\n return '🏷️'; // Same emoji as entitytag (global entity type collection)\n\n case 'job.completed':\n return '🔗'; // Link emoji for linked document creation\n case 'job.started':\n case 'job.progress':\n return '⚙️'; // Gear for job processing\n case 'job.failed':\n return '❌'; // X mark for failed jobs\n\n default:\n const _exhaustiveCheck: never = type;\n return _exhaustiveCheck;\n }\n}\n\n/**\n * Format timestamp as relative time with i18n support\n */\nexport function formatRelativeTime(timestamp: string, t: TranslateFn): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return t('justNow');\n if (diffMins < 60) return t('minutesAgo', { count: diffMins });\n if (diffHours < 24) return t('hoursAgo', { count: diffHours });\n if (diffDays < 7) return t('daysAgo', { count: diffDays });\n\n return date.toLocaleDateString();\n}\n\n/**\n * Helper to truncate text for display\n */\nfunction truncateText(text: string, maxLength = 50): string {\n const trimmed = text.trim();\n return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + '...' : trimmed;\n}\n\n/**\n * Get display content from event payload - complete implementation\n */\nexport function getEventDisplayContent(\n event: StoredEvent,\n annotations: Annotation[], // Unified annotations array (all types)\n allEvents: StoredEvent[]\n): { exact: string; isQuoted: boolean; isTag: boolean } | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n // Use type discriminators instead of runtime typeof checks\n switch (eventData.type) {\n case 'resource.created':\n case 'resource.cloned': {\n return { exact: payload.name, isQuoted: false, isTag: false };\n }\n\n // Unified annotation events\n case 'annotation.body.updated': {\n // Find current annotation to get its text\n // payload.annotationId is just the UUID, but annotation.id is the full URI\n const annotation = annotations.find(a =>\n a.id.endsWith(`/annotations/${payload.annotationId}`)\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n return null;\n }\n\n case 'annotation.removed': {\n // Find the original annotation.added event to get the text\n // payload.annotationId is just the UUID, but annotation.id in the added event is the full URI\n const addedEvent = allEvents.find(e =>\n e.event.type === 'annotation.added' &&\n (e.event.payload as any).annotation?.id?.endsWith(`/annotations/${payload.annotationId}`)\n );\n if (addedEvent) {\n const addedPayload = addedEvent.event.payload as any;\n try {\n const exact = getExactText(addedPayload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n }\n return null;\n }\n\n case 'annotation.added': {\n // New unified event structure - annotation is in payload\n try {\n const exact = getExactText(payload.annotation.target.selector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, return null\n }\n return null;\n }\n\n case 'entitytag.added':\n case 'entitytag.removed': {\n return { exact: payload.entityType, isQuoted: false, isTag: true };\n }\n\n case 'job.completed': {\n // Find the annotation that was used to generate the resource\n if (payload.annotationUri) {\n const annotation = annotations.find(a =>\n a.id === payload.annotationUri\n );\n\n if (annotation?.target) {\n try {\n const targetSelector = getTargetSelector(annotation.target);\n const exact = getExactText(targetSelector);\n if (exact) {\n return { exact: truncateText(exact), isQuoted: true, isTag: false };\n }\n } catch {\n // If selector parsing fails, continue to return null\n }\n }\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Get entity types from event payload\n */\nexport function getEventEntityTypes(event: StoredEvent): string[] {\n const eventData = event.event;\n\n if (eventData.type === 'annotation.added') {\n const payload = eventData.payload as any;\n const motivation = payload?.annotation?.motivation;\n if (motivation === 'linking') {\n return payload.annotation?.body?.entityTypes ?? [];\n }\n }\n\n return [];\n}\n\n/**\n * Resource creation details\n */\nexport interface ResourceCreationDetails {\n type: 'created' | 'cloned';\n method: string;\n userId?: string;\n sourceDocId?: string; // For cloned resources\n parentResourceId?: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Get resource creation details from event\n */\nexport function getResourceCreationDetails(event: StoredEvent): ResourceCreationDetails | null {\n const eventData = event.event;\n const payload = eventData.payload as any;\n\n if (eventData.type === 'resource.created') {\n return {\n type: 'created',\n method: payload.creationMethod || 'unknown',\n userId: eventData.userId,\n metadata: payload.metadata,\n };\n }\n\n if (eventData.type === 'resource.cloned') {\n return {\n type: 'cloned',\n method: payload.creationMethod || 'clone',\n userId: eventData.userId,\n sourceDocId: payload.parentResourceId,\n parentResourceId: payload.parentResourceId,\n metadata: payload.metadata,\n };\n }\n\n return null;\n}\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\n/**\n * Find text using exact match with optional prefix/suffix context\n *\n * When the exact text appears multiple times in the content, prefix and suffix\n * are used to disambiguate and find the correct occurrence.\n *\n * @param content - Full text content to search within\n * @param exact - The exact text to find\n * @param prefix - Optional text that should appear immediately before the match\n * @param suffix - Optional text that should appear immediately after the match\n * @returns Position of the matched text, or null if not found\n *\n * @example\n * ```typescript\n * const content = \"The cat sat. The cat ran.\";\n * // Find second \"The cat\" occurrence\n * const pos = findTextWithContext(content, \"The cat\", \"sat. \", \" ran\");\n * // Returns { start: 13, end: 20 }\n * ```\n */\nexport function findTextWithContext(\n content: string,\n exact: string,\n prefix?: string,\n suffix?: string\n): TextPosition | null {\n if (!exact) return null;\n\n // Find all occurrences of exact text\n const occurrences: number[] = [];\n let index = content.indexOf(exact);\n while (index !== -1) {\n occurrences.push(index);\n index = content.indexOf(exact, index + 1);\n }\n\n // No matches found\n if (occurrences.length === 0) {\n console.warn(`[FuzzyAnchor] Text not found: \"${exact.substring(0, 50)}...\"`);\n return null;\n }\n\n // Only one match - no need for prefix/suffix disambiguation\n if (occurrences.length === 1) {\n const pos = occurrences[0]!; // Safe: length === 1 means first element exists\n return { start: pos, end: pos + exact.length };\n }\n\n // Multiple matches - use prefix/suffix to disambiguate\n if (prefix || suffix) {\n for (const pos of occurrences) {\n // Extract actual prefix from content\n const actualPrefixStart = Math.max(0, pos - (prefix?.length || 0));\n const actualPrefix = content.substring(actualPrefixStart, pos);\n\n // Extract actual suffix from content\n const actualSuffixEnd = Math.min(content.length, pos + exact.length + (suffix?.length || 0));\n const actualSuffix = content.substring(pos + exact.length, actualSuffixEnd);\n\n // Check if prefix matches\n const prefixMatch = !prefix || actualPrefix.endsWith(prefix);\n\n // Check if suffix matches\n const suffixMatch = !suffix || actualSuffix.startsWith(suffix);\n\n if (prefixMatch && suffixMatch) {\n return { start: pos, end: pos + exact.length };\n }\n }\n\n // No match with exact prefix/suffix - try fuzzy matching\n console.warn(\n `[FuzzyAnchor] Multiple matches found but none match prefix/suffix exactly. ` +\n `Exact: \"${exact.substring(0, 30)}...\", ` +\n `Prefix: \"${prefix?.substring(0, 20) || 'none'}\", ` +\n `Suffix: \"${suffix?.substring(0, 20) || 'none'}\"`\n );\n\n // Fallback: try partial prefix/suffix match\n for (const pos of occurrences) {\n const actualPrefix = content.substring(Math.max(0, pos - (prefix?.length || 0)), pos);\n const actualSuffix = content.substring(pos + exact.length, pos + exact.length + (suffix?.length || 0));\n\n // Fuzzy match: check if prefix/suffix are substrings (handles whitespace variations)\n const fuzzyPrefixMatch = !prefix || actualPrefix.includes(prefix.trim());\n const fuzzySuffixMatch = !suffix || actualSuffix.includes(suffix.trim());\n\n if (fuzzyPrefixMatch && fuzzySuffixMatch) {\n console.warn(`[FuzzyAnchor] Using fuzzy match at position ${pos}`);\n return { start: pos, end: pos + exact.length };\n }\n }\n }\n\n // Fallback: return first occurrence if no prefix/suffix or no match\n console.warn(\n `[FuzzyAnchor] Multiple matches but no context match. Using first occurrence. ` +\n `Exact: \"${exact.substring(0, 30)}...\"`\n );\n const pos = occurrences[0]!; // Safe: we checked length > 0 earlier\n return { start: pos, end: pos + exact.length };\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from '../types';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * For internal resources: extracts UUID from \"http://localhost:4000/resources/{uuid}\"\n * For external resources: returns undefined\n *\n * This is used for routing - the frontend URL should contain only the resource ID,\n * not the full HTTP URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n\n const fullId = resource['@id'];\n\n // For internal resources, extract the last path segment\n // http://localhost:4000/resources/{uuid} -> {uuid}\n if (fullId.includes('/resources/')) {\n const parts = fullId.split('/resources/');\n const lastPart = parts[parts.length - 1];\n return lastPart || undefined;\n }\n\n // For external resources, cannot extract ID\n return undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n\n/**\n * Get storage URI from primary representation\n *\n * @param resource - ResourceDescriptor\n * @returns Storage URI or undefined\n */\nexport function getStorageUri(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.storageUri;\n}\n\n/**\n * Get creator agent from wasAttributedTo\n * Handles both single agent and array of agents\n *\n * @param resource - ResourceDescriptor\n * @returns First agent or undefined\n */\nexport function getCreator(resource: ResourceDescriptor | undefined): components['schemas']['Agent'] | undefined {\n if (!resource?.wasAttributedTo) return undefined;\n\n return Array.isArray(resource.wasAttributedTo)\n ? resource.wasAttributedTo[0]\n : resource.wasAttributedTo;\n}\n\n/**\n * Get derived-from URI\n * Handles both single URI and array of URIs\n *\n * @param resource - ResourceDescriptor\n * @returns First derivation URI or undefined\n */\nexport function getDerivedFrom(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource?.wasDerivedFrom) return undefined;\n\n return Array.isArray(resource.wasDerivedFrom)\n ? resource.wasDerivedFrom[0]\n : resource.wasDerivedFrom;\n}\n\n/**\n * Check if resource is archived (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if archived, false otherwise\n */\nexport function isArchived(resource: ResourceDescriptor | undefined): boolean {\n return resource?.archived === true;\n}\n\n/**\n * Get entity types from resource (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns Array of entity types, empty if not set\n */\nexport function getResourceEntityTypes(resource: ResourceDescriptor | undefined): string[] {\n return resource?.entityTypes || [];\n}\n\n/**\n * Check if resource is a draft (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if draft, false otherwise\n */\nexport function isDraft(resource: ResourceDescriptor | undefined): boolean {\n return resource?.isDraft === true;\n}\n\n/**\n * Map charset names to Node.js Buffer encoding names\n * Node.js Buffer.toString() supports: 'utf8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2'\n *\n * @param charset - Charset name (e.g., \"UTF-8\", \"ISO-8859-1\", \"Windows-1252\")\n * @returns Node.js BufferEncoding\n */\nexport function getNodeEncoding(charset: string): BufferEncoding {\n const normalized = charset.toLowerCase().replace(/[-_]/g, '');\n\n // Map common charset names to Node.js encodings\n const charsetMap: Record<string, BufferEncoding> = {\n 'utf8': 'utf8',\n 'iso88591': 'latin1',\n 'latin1': 'latin1',\n 'ascii': 'ascii',\n 'usascii': 'ascii',\n 'utf16le': 'utf16le',\n 'ucs2': 'ucs2',\n 'binary': 'binary',\n 'windows1252': 'latin1', // Windows-1252 is a superset of Latin-1\n 'cp1252': 'latin1',\n };\n\n return charsetMap[normalized] || 'utf8';\n}\n\n/**\n * Decode a representation buffer to string using the correct charset\n * Extracts charset from media type and uses appropriate encoding\n *\n * @param buffer - The raw representation data\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=iso-8859-1\")\n * @returns Decoded string\n *\n * @example\n * ```typescript\n * const content = decodeRepresentation(buffer, \"text/plain; charset=utf-8\");\n * const legacy = decodeRepresentation(buffer, \"text/plain; charset=windows-1252\");\n * ```\n */\nexport function decodeRepresentation(buffer: Buffer, mediaType: string): string {\n // Extract charset from mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n const charset = (charsetMatch?.[1] || 'utf-8').toLowerCase();\n\n // Map to Node.js encoding\n const encoding = getNodeEncoding(charset);\n\n return buffer.toString(encoding);\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Text context extraction utilities for W3C Web Annotation TextQuoteSelector\n *\n * Provides robust prefix/suffix context extraction with word boundary detection\n * to ensure fuzzy anchoring works correctly when the same text appears multiple times.\n *\n * Also provides AI offset validation and correction for handling AI-generated annotations\n * where the model may return slightly incorrect character offsets.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\n/**\n * Extract prefix and suffix context for TextQuoteSelector\n *\n * Extracts up to 64 characters before and after the selected text,\n * extending to word boundaries to avoid cutting words in half.\n * This ensures prefix/suffix are meaningful context for fuzzy anchoring.\n *\n * @param content - Full text content\n * @param start - Start offset of selection\n * @param end - End offset of selection\n * @returns Object with prefix and suffix (undefined if at boundaries)\n *\n * @example\n * ```typescript\n * const content = \"The United States Congress...\";\n * const context = extractContext(content, 4, 17); // \"United States\"\n * // Returns: { prefix: \"The \", suffix: \" Congress...\" }\n * // NOT: { prefix: \"nited \", suffix: \"gress...\" }\n * ```\n */\nexport function extractContext(\n content: string,\n start: number,\n end: number\n): { prefix?: string; suffix?: string } {\n const CONTEXT_LENGTH = 64;\n const MAX_EXTENSION = 32; // Maximum additional chars to extend for word boundary\n\n // Extract prefix (up to CONTEXT_LENGTH chars before start, extended to word boundary)\n let prefix: string | undefined;\n if (start > 0) {\n let prefixStart = Math.max(0, start - CONTEXT_LENGTH);\n\n // Extend backward to word boundary (whitespace or punctuation)\n // Stop if we hit start of content or exceed MAX_EXTENSION\n let extensionCount = 0;\n while (prefixStart > 0 && extensionCount < MAX_EXTENSION) {\n const char = content[prefixStart - 1];\n // Break on whitespace, punctuation, or common delimiters\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) {\n break;\n }\n prefixStart--;\n extensionCount++;\n }\n\n prefix = content.substring(prefixStart, start);\n }\n\n // Extract suffix (up to CONTEXT_LENGTH chars after end, extended to word boundary)\n let suffix: string | undefined;\n if (end < content.length) {\n let suffixEnd = Math.min(content.length, end + CONTEXT_LENGTH);\n\n // Extend forward to word boundary (whitespace or punctuation)\n // Stop if we hit end of content or exceed MAX_EXTENSION\n let extensionCount = 0;\n while (suffixEnd < content.length && extensionCount < MAX_EXTENSION) {\n const char = content[suffixEnd];\n // Break on whitespace, punctuation, or common delimiters\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) {\n break;\n }\n suffixEnd++;\n extensionCount++;\n }\n\n suffix = content.substring(end, suffixEnd);\n }\n\n return { prefix, suffix };\n}\n\n/**\n * Result of validating and correcting AI-provided annotation offsets\n */\nexport interface ValidatedAnnotation {\n start: number;\n end: number;\n exact: string;\n prefix?: string;\n suffix?: string;\n corrected: boolean; // True if offsets were adjusted from AI's original values\n fuzzyMatched?: boolean; // True if we had to use fuzzy matching (minor text differences)\n matchQuality?: 'exact' | 'case-insensitive' | 'fuzzy'; // How we found the match\n}\n\n/**\n * Calculate Levenshtein distance between two strings\n * Used for fuzzy matching when exact text doesn't match\n */\nfunction levenshteinDistance(str1: string, str2: string): number {\n const len1 = str1.length;\n const len2 = str2.length;\n const matrix: number[][] = [];\n\n // Initialize matrix\n for (let i = 0; i <= len1; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= len2; j++) {\n matrix[0]![j] = j;\n }\n\n // Fill matrix\n for (let i = 1; i <= len1; i++) {\n for (let j = 1; j <= len2; j++) {\n const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n const deletion = matrix[i - 1]![j]! + 1;\n const insertion = matrix[i]![j - 1]! + 1;\n const substitution = matrix[i - 1]![j - 1]! + cost;\n matrix[i]![j] = Math.min(deletion, insertion, substitution);\n }\n }\n\n return matrix[len1]![len2]!;\n}\n\n/**\n * Find best match for text in content using various strategies\n * Returns { start, end, matchQuality } or null if no acceptable match found\n */\nfunction findBestMatch(\n content: string,\n searchText: string,\n aiStart: number,\n aiEnd: number\n): { start: number; end: number; matchQuality: 'exact' | 'case-insensitive' | 'fuzzy' } | null {\n const maxFuzzyDistance = Math.max(5, Math.floor(searchText.length * 0.05)); // 5% tolerance or minimum 5 chars\n\n // Strategy 1: Exact match (case-sensitive)\n const exactIndex = content.indexOf(searchText);\n if (exactIndex !== -1) {\n return {\n start: exactIndex,\n end: exactIndex + searchText.length,\n matchQuality: 'exact'\n };\n }\n\n console.log('[findBestMatch] Exact match failed, trying case-insensitive...');\n\n // Strategy 2: Case-insensitive match\n const lowerContent = content.toLowerCase();\n const lowerSearch = searchText.toLowerCase();\n const caseInsensitiveIndex = lowerContent.indexOf(lowerSearch);\n if (caseInsensitiveIndex !== -1) {\n console.log('[findBestMatch] Found case-insensitive match');\n return {\n start: caseInsensitiveIndex,\n end: caseInsensitiveIndex + searchText.length,\n matchQuality: 'case-insensitive'\n };\n }\n\n console.log('[findBestMatch] Case-insensitive failed, trying fuzzy match...');\n\n // Strategy 3: Fuzzy match using sliding window\n // Search near AI's suggested position first, then expand outward\n const windowSize = searchText.length;\n const searchRadius = Math.min(500, content.length); // Search within 500 chars of AI position\n const searchStart = Math.max(0, aiStart - searchRadius);\n const searchEnd = Math.min(content.length, aiEnd + searchRadius);\n\n let bestMatch: { start: number; distance: number } | null = null;\n\n // Scan through content with sliding window\n for (let i = searchStart; i <= searchEnd - windowSize; i++) {\n const candidate = content.substring(i, i + windowSize);\n const distance = levenshteinDistance(searchText, candidate);\n\n if (distance <= maxFuzzyDistance) {\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { start: i, distance };\n console.log(`[findBestMatch] Found fuzzy match at ${i} with distance ${distance}`);\n }\n }\n }\n\n if (bestMatch) {\n return {\n start: bestMatch.start,\n end: bestMatch.start + windowSize,\n matchQuality: 'fuzzy'\n };\n }\n\n console.log('[findBestMatch] No acceptable match found');\n return null;\n}\n\n/**\n * Validate and correct AI-provided annotation offsets with fuzzy matching tolerance\n *\n * AI models sometimes return offsets that don't match the actual text position,\n * or provide text with minor variations (case differences, whitespace, typos).\n *\n * This function uses a multi-strategy approach:\n * 1. Check if AI's offsets are exactly correct\n * 2. Try exact case-sensitive search\n * 3. Try case-insensitive search\n * 4. Try fuzzy matching with Levenshtein distance (5% tolerance)\n *\n * This ensures we're maximally tolerant of AI errors while still maintaining\n * annotation quality and logging what corrections were made.\n *\n * @param content - Full text content\n * @param aiStart - Start offset from AI\n * @param aiEnd - End offset from AI\n * @param exact - The exact text that should be at this position (from AI)\n * @returns Validated annotation with corrected offsets and context\n * @throws Error if no acceptable match can be found\n *\n * @example\n * ```typescript\n * // AI said start=1143, but actual text is at 1161\n * const result = validateAndCorrectOffsets(\n * content,\n * 1143,\n * 1289,\n * \"the question \\\"whether...\"\n * );\n * // Returns: { start: 1161, end: 1303, exact: \"...\", corrected: true, matchQuality: 'exact', ... }\n * ```\n */\nexport function validateAndCorrectOffsets(\n content: string,\n aiStart: number,\n aiEnd: number,\n exact: string\n): ValidatedAnnotation {\n const exactPreview = exact.length > 50 ? exact.substring(0, 50) + '...' : exact;\n\n // First, check if AI's offsets are correct\n const textAtOffset = content.substring(aiStart, aiEnd);\n\n if (textAtOffset === exact) {\n // AI got it right! Just add proper context\n console.log(`[validateAndCorrectOffsets] ✓ Offsets correct for: \"${exactPreview}\"`);\n const context = extractContext(content, aiStart, aiEnd);\n return {\n start: aiStart,\n end: aiEnd,\n exact,\n prefix: context.prefix,\n suffix: context.suffix,\n corrected: false,\n matchQuality: 'exact'\n };\n }\n\n // AI's offsets are wrong - try to find the text using multiple strategies\n const foundPreview = textAtOffset.length > 50 ? textAtOffset.substring(0, 50) + '...' : textAtOffset;\n\n console.warn(\n '[validateAndCorrectOffsets] ⚠ AI offset mismatch:\\n' +\n ` Expected text: \"${exactPreview}\"\\n` +\n ` Found at AI offset (${aiStart}-${aiEnd}): \"${foundPreview}\"\\n` +\n ` Attempting multi-strategy search...`\n );\n\n const match = findBestMatch(content, exact, aiStart, aiEnd);\n\n if (!match) {\n const exactLong = exact.length > 100 ? exact.substring(0, 100) + '...' : exact;\n console.error(\n '[validateAndCorrectOffsets] ✗ No acceptable match found:\\n' +\n ` AI offsets: start=${aiStart}, end=${aiEnd}\\n` +\n ` AI text: \"${exactLong}\"\\n` +\n ` Text at AI offset: \"${foundPreview}\"\\n` +\n ' All search strategies (exact, case-insensitive, fuzzy) failed.\\n' +\n ' This suggests the AI hallucinated text that doesn\\'t exist in the document.'\n );\n throw new Error(\n 'Cannot find acceptable match for text in content. ' +\n 'All search strategies failed. Text may be hallucinated.'\n );\n }\n\n // Found a match! Extract the actual text from content\n const actualText = content.substring(match.start, match.end);\n const actualPreview = actualText.length > 50 ? actualText.substring(0, 50) + '...' : actualText;\n\n const offsetDelta = match.start - aiStart;\n const matchSymbol = match.matchQuality === 'exact' ? '✓' : match.matchQuality === 'case-insensitive' ? '≈' : '~';\n\n console.warn(\n `[validateAndCorrectOffsets] ${matchSymbol} Found ${match.matchQuality} match:\\n` +\n ` AI offsets: start=${aiStart}, end=${aiEnd}\\n` +\n ` Corrected: start=${match.start}, end=${match.end}\\n` +\n ` Offset delta: ${offsetDelta} characters\\n` +\n ` Actual text: \"${actualPreview}\"`\n );\n\n // If fuzzy match, log the difference for debugging\n if (match.matchQuality === 'fuzzy') {\n console.warn(\n '[validateAndCorrectOffsets] Fuzzy match details:\\n' +\n ` AI provided: \"${exactPreview}\"\\n` +\n ` Found in doc: \"${actualPreview}\"\\n` +\n ' Minor text differences detected - using document version'\n );\n }\n\n // Extract context using corrected offsets\n const context = extractContext(content, match.start, match.end);\n\n return {\n start: match.start,\n end: match.end,\n exact: actualText, // Use actual text from document, not AI's version\n prefix: context.prefix,\n suffix: context.suffix,\n corrected: true,\n fuzzyMatched: match.matchQuality !== 'exact',\n matchQuality: match.matchQuality\n };\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/api-client\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/api-client",
3
- "version": "0.2.28-build.38",
3
+ "version": "0.2.28",
4
4
  "description": "Semiont API SDK - types, client, and utilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",