@semiont/graph 0.2.28-build.40
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.
- package/README.md +231 -0
- package/dist/index.d.ts +355 -0
- package/dist/index.js +2708 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/implementations/neptune.ts","../src/implementations/neo4j.ts","../src/implementations/janusgraph.ts","../src/implementations/memorygraph.ts","../src/factory.ts"],"sourcesContent":["// AWS Neptune implementation of GraphDatabase interface\n// Uses Gremlin for graph traversal\n\nimport { GraphDatabase } from '../interface';\nimport { getBodySource } from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport type { components } from '@semiont/api-client';\nimport type {\n AnnotationCategory,\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n ResourceFilter,\n UpdateResourceInput,\n CreateAnnotationInternal,\n ResourceId,\n AnnotationId,\n} from '@semiont/core';\nimport type { ResourceUri, AnnotationUri } from '@semiont/api-client';\nimport { getExactText } from '@semiont/api-client';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getTargetSource, getTargetSelector } from '@semiont/api-client';\nimport { getPrimaryRepresentation, getResourceId } from '@semiont/api-client';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Dynamic imports for AWS SDK and Gremlin\nlet NeptuneClient: any;\nlet DescribeDBClustersCommand: any;\nlet gremlin: any;\nlet process: any;\nlet TextP: any;\nlet order: any;\nlet cardinality: any;\nlet __: any;\n\nasync function loadDependencies() {\n if (!NeptuneClient) {\n const neptuneModule = await import('@aws-sdk/client-neptune');\n NeptuneClient = neptuneModule.NeptuneClient;\n DescribeDBClustersCommand = neptuneModule.DescribeDBClustersCommand;\n }\n if (!gremlin) {\n // @ts-ignore - gremlin module has no types\n gremlin = await import('gremlin');\n process = gremlin.process;\n TextP = process.TextP;\n order = process.order;\n cardinality = process.cardinality;\n __ = process.statics;\n }\n}\n\n// Helper function to convert Neptune vertex to ResourceDescriptor\nfunction vertexToResource(vertex: any): ResourceDescriptor {\n const props = vertex.properties || vertex;\n\n // Handle different property formats from Neptune\n const getValue = (key: string, required: boolean = false) => {\n const prop = props[key];\n if (!prop) {\n if (required) {\n throw new Error(`Resource ${vertex.id || 'unknown'} missing required field: ${key}`);\n }\n return undefined;\n }\n if (Array.isArray(prop) && prop.length > 0) {\n return prop[0].value !== undefined ? prop[0].value : prop[0];\n }\n return prop.value !== undefined ? prop.value : prop;\n };\n\n // Get all required fields and validate\n const id = getValue('id', true);\n const name = getValue('name', true);\n const entityTypesRaw = getValue('entityTypes', true);\n const mediaType = getValue('mediaType', true);\n const archived = getValue('archived', true);\n const dateCreated = getValue('dateCreated', true);\n const checksum = getValue('checksum', true);\n const creatorRaw = getValue('creator', true);\n\n const resource: ResourceDescriptor = {\n '@context': 'https://schema.org/',\n '@id': id,\n name,\n entityTypes: JSON.parse(entityTypesRaw),\n representations: [{\n mediaType,\n checksum,\n rel: 'original',\n }],\n archived: archived === 'true' || archived === true,\n dateCreated,\n wasAttributedTo: typeof creatorRaw === 'string' ? JSON.parse(creatorRaw) : creatorRaw,\n creationMethod: getValue('creationMethod', true),\n };\n\n const sourceResourceId = getValue('sourceResourceId');\n if (sourceResourceId) resource.sourceResourceId = sourceResourceId;\n\n return resource;\n}\n\n// Helper function to convert Neptune vertex to Annotation\nfunction vertexToAnnotation(vertex: any, entityTypes: string[] = []): Annotation {\n const props = vertex.properties || vertex;\n\n // Handle different property formats from Neptune\n const getValue = (key: string, required: boolean = false) => {\n const prop = props[key];\n if (!prop) {\n if (required) {\n throw new Error(`Annotation ${vertex.id || 'unknown'} missing required field: ${key}`);\n }\n return undefined;\n }\n if (Array.isArray(prop) && prop.length > 0) {\n return prop[0].value !== undefined ? prop[0].value : prop[0];\n }\n if (typeof prop === 'object' && 'value' in prop) return prop.value;\n return prop;\n };\n\n // Get required fields\n const id = getValue('id', true);\n const resourceId = getValue('resourceId', true);\n const selectorRaw = getValue('selector', true);\n const creatorRaw = getValue('creator', true);\n const createdRaw = getValue('created', true);\n\n // Derive motivation from type if not present (backward compatibility)\n const motivation = getValue('motivation') || 'linking';\n\n // Parse creator - always stored as JSON string in DB\n const creator = JSON.parse(creatorRaw);\n\n // Reconstruct body array from entity tags and linking body\n const bodyArray: Array<{type: 'TextualBody'; value: string; purpose: 'tagging'} | {type: 'SpecificResource'; source: string; purpose: 'linking'}> = [];\n\n // Add entity tag bodies (TextualBody with purpose: \"tagging\")\n for (const entityType of entityTypes) {\n if (entityType) {\n bodyArray.push({\n type: 'TextualBody' as const,\n value: entityType,\n purpose: 'tagging' as const,\n });\n }\n }\n\n // Add linking body (SpecificResource) if annotation is resolved\n const bodySource = getValue('source');\n if (bodySource) {\n bodyArray.push({\n type: 'SpecificResource' as const,\n source: bodySource,\n purpose: 'linking' as const,\n });\n }\n\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id,\n motivation,\n target: {\n source: resourceId,\n selector: JSON.parse(selectorRaw),\n },\n body: bodyArray,\n creator,\n created: createdRaw, // ISO string from DB\n };\n\n // W3C Web Annotation modification tracking\n const modified = getValue('modified');\n if (modified) annotation.modified = modified;\n\n const generatorJson = getValue('generator');\n if (generatorJson) {\n try {\n annotation.generator = JSON.parse(generatorJson);\n } catch (e) {\n // Ignore parse errors\n }\n }\n\n return annotation;\n}\n\n\nexport class NeptuneGraphDatabase implements GraphDatabase {\n private connected: boolean = false;\n private neptuneEndpoint?: string;\n private neptunePort: number = 8182;\n private region?: string;\n private g: any; // Gremlin graph traversal source\n private connection: any; // Gremlin connection\n\n // Helper method to fetch annotations with their entity types\n private async fetchAnnotationsWithEntityTypes(annotationVertices: any[]): Promise<Annotation[]> {\n const annotations: Annotation[] = [];\n\n for (const vertex of annotationVertices) {\n const id = vertex.properties?.id?.[0]?.value || vertex.id;\n\n // Fetch entity types for this annotation\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n annotations.push(vertexToAnnotation(vertex, entityTypes));\n }\n\n return annotations;\n }\n \n constructor(config: {\n endpoint?: string;\n port?: number;\n region?: string;\n } = {}) {\n if (config.endpoint) this.neptuneEndpoint = config.endpoint;\n this.neptunePort = config.port || 8182;\n if (config.region) this.region = config.region;\n }\n \n private async discoverNeptuneEndpoint(): Promise<void> {\n // If endpoint is already provided, use it\n if (this.neptuneEndpoint) {\n return;\n }\n \n // In AWS environment, discover Neptune cluster endpoint\n if (!this.region) {\n throw new Error('AWS region must be configured in environment JSON file (aws.region) for Neptune endpoint discovery');\n }\n\n try {\n // Load AWS SDK dynamically\n await loadDependencies();\n \n // Create Neptune client\n const client = new NeptuneClient({ region: this.region });\n \n // List all Neptune clusters\n const command = new DescribeDBClustersCommand({});\n const response = await client.send(command);\n \n if (!response.DBClusters || response.DBClusters.length === 0) {\n throw new Error('No Neptune clusters found in region ' + this.region);\n }\n \n // Find the Semiont cluster by tags\n let cluster = null;\n for (const dbCluster of response.DBClusters) {\n // Check if this cluster has our application tag\n const tagsCommand = new DescribeDBClustersCommand({\n DBClusterIdentifier: dbCluster.DBClusterIdentifier\n });\n const clusterDetails = await client.send(tagsCommand);\n \n if (clusterDetails.DBClusters && clusterDetails.DBClusters[0]) {\n const clusterInfo = clusterDetails.DBClusters[0];\n // Check for Semiont tag or name pattern\n if (clusterInfo.DBClusterIdentifier?.includes('Semiont') || \n clusterInfo.DBClusterIdentifier?.includes('semiont')) {\n cluster = clusterInfo;\n break;\n }\n }\n }\n \n if (!cluster) {\n throw new Error('No Semiont Neptune cluster found in region ' + this.region);\n }\n \n // Set the endpoint and port\n this.neptuneEndpoint = cluster.Endpoint;\n this.neptunePort = cluster.Port || 8182;\n \n console.log(`Discovered Neptune endpoint: ${this.neptuneEndpoint}:${this.neptunePort}`);\n } catch (error: any) {\n console.error('Failed to discover Neptune endpoint:', error);\n throw error;\n }\n }\n \n async connect(): Promise<void> {\n // Discover Neptune endpoint if needed\n await this.discoverNeptuneEndpoint();\n \n try {\n // Load Gremlin dynamically\n await loadDependencies();\n \n // Create Gremlin connection\n const traversal = gremlin.process.AnonymousTraversalSource.traversal;\n const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;\n \n // Neptune requires WebSocket Secure (wss) protocol\n const connectionUrl = `wss://${this.neptuneEndpoint}:${this.neptunePort}/gremlin`;\n console.log(`Connecting to Neptune at ${connectionUrl}`);\n \n // Create the connection\n this.connection = new DriverRemoteConnection(connectionUrl, {\n authenticator: null, // Neptune uses IAM authentication via task role\n rejectUnauthorized: true,\n traversalSource: 'g'\n });\n \n // Create the graph traversal source\n this.g = traversal().withRemote(this.connection);\n \n // Test the connection\n const count = await this.g.V().limit(1).count().next();\n console.log(`Connected to Neptune. Vertex count test: ${count.value}`);\n \n this.connected = true;\n } catch (error: any) {\n console.error('Failed to connect to Neptune:', error);\n throw error;\n }\n }\n \n async disconnect(): Promise<void> {\n // Close Gremlin connection if it exists\n if (this.connection) {\n try {\n await this.connection.close();\n } catch (error) {\n console.error('Error closing Neptune connection:', error);\n }\n }\n \n this.connected = false;\n console.log('Disconnected from Neptune');\n }\n \n isConnected(): boolean {\n return this.connected;\n }\n\n async createResource(resource: ResourceDescriptor): Promise<ResourceDescriptor> {\n const id = getResourceId(resource);\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) {\n throw new Error('Resource must have at least one representation');\n }\n\n // Create vertex in Neptune\n try {\n const vertex = this.g.addV('Resource')\n .property('id', id)\n .property('name', resource.name)\n .property('mediaType', primaryRep.mediaType)\n .property('archived', resource.archived || false)\n .property('dateCreated', resource.dateCreated)\n .property('creator', JSON.stringify(resource.wasAttributedTo))\n .property('creationMethod', resource.creationMethod)\n .property('checksum', primaryRep.checksum)\n .property('entityTypes', JSON.stringify(resource.entityTypes));\n\n if (resource.sourceResourceId) {\n vertex.property('sourceResourceId', resource.sourceResourceId);\n }\n\n await vertex.next();\n\n console.log(`Created resource vertex in Neptune: ${id}`);\n return resource;\n } catch (error) {\n console.error('Failed to create resource in Neptune:', error);\n throw error;\n }\n }\n \n async getResource(id: ResourceUri): Promise<ResourceDescriptor | null> {\n try {\n const result = await this.g.V()\n .hasLabel('Resource')\n .has('id', id)\n .elementMap()\n .next();\n \n if (!result.value) {\n return null;\n }\n \n return vertexToResource(result.value);\n } catch (error) {\n console.error('Failed to get resource from Neptune:', error);\n throw error;\n }\n }\n \n async updateResource(id: ResourceUri, input: UpdateResourceInput): Promise<ResourceDescriptor> {\n // Resources are immutable - only archiving is allowed\n if (Object.keys(input).length !== 1 || input.archived === undefined) {\n throw new Error('Resources are immutable. Only archiving is allowed.');\n }\n\n try {\n const result = await this.g.V()\n .hasLabel('Resource')\n .has('id', id)\n .property('archived', input.archived)\n .elementMap()\n .next();\n\n if (!result.value) {\n throw new Error('Resource not found');\n }\n\n return vertexToResource(result.value);\n } catch (error) {\n console.error('Failed to update resource in Neptune:', error);\n throw error;\n }\n }\n \n async deleteResource(id: ResourceUri): Promise<void> {\n try {\n // Delete the resource vertex and all connected edges\n await this.g.V()\n .hasLabel('Resource')\n .has('id', id)\n .drop()\n .iterate();\n \n console.log(`Deleted resource from Neptune: ${id}`);\n } catch (error) {\n console.error('Failed to delete resource from Neptune:', error);\n throw error;\n }\n }\n \n async listResources(filter: ResourceFilter): Promise<{ resources: ResourceDescriptor[]; total: number }> {\n try {\n let traversal = this.g.V().hasLabel('Resource');\n \n // Apply filters\n if (filter.entityTypes && filter.entityTypes.length > 0) {\n // Filter by entity types (stored as JSON string)\n traversal = traversal.filter(\n process.statics.or(\n ...filter.entityTypes.map((type: string) =>\n process.statics.has('entityTypes', TextP.containing(`\"${type}\"`))\n )\n )\n );\n }\n \n if (filter.search) {\n // Case-insensitive search in resource name\n traversal = traversal.has('name', TextP.containing(filter.search));\n }\n \n // Count total before pagination\n const totalResult = await traversal.clone().count().next();\n const total = totalResult.value || 0;\n \n // Apply pagination\n const offset = filter.offset || 0;\n const limit = filter.limit || 20;\n \n const results = await traversal\n .order().by('created', order.desc)\n .range(offset, offset + limit)\n .elementMap()\n .toList();\n \n const resources = results.map(vertexToResource);\n \n return { resources, total };\n } catch (error) {\n console.error('Failed to list resources from Neptune:', error);\n throw error;\n }\n }\n \n async searchResources(query: string, limit: number = 20): Promise<ResourceDescriptor[]> {\n try {\n // Use Neptune's text search capabilities\n const results = await this.g.V()\n .hasLabel('Resource')\n .has('name', TextP.containing(query))\n .order().by('created', order.desc)\n .limit(limit)\n .elementMap()\n .toList();\n \n return results.map(vertexToResource);\n } catch (error) {\n console.error('Failed to search resources in Neptune:', error);\n throw error;\n }\n }\n \n async createAnnotation(input: CreateAnnotationInternal): Promise<Annotation> {\n const id = this.generateId();\n\n // Only linking motivation with SpecificResource or empty array (stub)\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id,\n motivation: input.motivation,\n target: input.target,\n body: input.body,\n creator: input.creator,\n created: new Date().toISOString(),\n };\n\n // Extract values for Gremlin query\n const targetSource = getTargetSource(input.target);\n const targetSelector = getTargetSelector(input.target);\n const bodySource = getBodySource(input.body);\n const entityTypes = getEntityTypes(input);\n\n try {\n // Create Annotation vertex\n const vertex = this.g.addV('Annotation')\n .property('id', annotation.id)\n .property('resourceId', targetSource) // Store full URI\n .property('text', targetSelector ? getExactText(targetSelector) : '')\n .property('selector', JSON.stringify(targetSelector || {}))\n .property('type', 'SpecificResource')\n .property('motivation', annotation.motivation)\n .property('creator', JSON.stringify(annotation.creator))\n .property('created', annotation.created);\n\n // Add optional source property for resolved references\n if (bodySource) {\n vertex.property('source', bodySource);\n }\n\n const newVertex = await vertex.next();\n\n // Create edge from Annotation to Resource (BELONGS_TO)\n await this.g.V(newVertex.value)\n .addE('BELONGS_TO')\n .to(this.g.V().hasLabel('Resource').has('id', targetSource)) // Use full URI\n .next();\n\n // If it's a resolved reference, create edge to target resource (REFERENCES)\n if (bodySource) {\n await this.g.V(newVertex.value)\n .addE('REFERENCES')\n .to(this.g.V().hasLabel('Resource').has('id', bodySource)) // Use full URI\n .next();\n }\n\n // Create TAGGED_AS relationships for entity types\n for (const entityType of entityTypes) {\n // Get or create EntityType vertex\n const etVertex = await this.g.V()\n .hasLabel('EntityType')\n .has('name', entityType)\n .fold()\n .coalesce(\n __.unfold(),\n this.g.addV('EntityType').property('name', entityType)\n )\n .next();\n\n // Create TAGGED_AS edge from Annotation to EntityType\n await this.g.V(newVertex.value)\n .addE('TAGGED_AS')\n .to(this.g.V(etVertex.value))\n .next();\n }\n\n console.log(`Created annotation vertex in Neptune: ${annotation.id}`);\n return annotation;\n } catch (error) {\n console.error('Failed to create annotation in Neptune:', error);\n throw error;\n }\n }\n \n async getAnnotation(id: AnnotationUri): Promise<Annotation | null> {\n try {\n const result = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .elementMap()\n .next();\n\n if (!result.value) {\n return null;\n }\n\n // Fetch entity types from TAGGED_AS relationships\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n\n return vertexToAnnotation(result.value, entityTypes);\n } catch (error) {\n console.error('Failed to get annotation from Neptune:', error);\n throw error;\n }\n }\n \n async updateAnnotation(id: AnnotationUri, updates: Partial<Annotation>): Promise<Annotation> {\n try {\n let traversal = this.g.V()\n .hasLabel('Annotation')\n .has('id', id);\n\n // Update target properties\n if (updates.target !== undefined && typeof updates.target !== 'string') {\n if (updates.target.selector !== undefined) {\n traversal = traversal.property('text', getExactText(updates.target.selector));\n }\n }\n\n // Update body properties and entity types\n if (updates.body !== undefined) {\n const bodySource = getBodySource(updates.body);\n const entityTypes = getEntityTypes({ body: updates.body });\n\n if (bodySource) {\n traversal = traversal.property('source', bodySource);\n }\n\n // Update entity type relationships - remove old ones and create new ones\n if (entityTypes.length >= 0) {\n // Remove existing TAGGED_AS edges\n await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .outE('TAGGED_AS')\n .drop()\n .iterate();\n\n // Create new TAGGED_AS edges\n for (const entityType of entityTypes) {\n const etVertex = await this.g.V()\n .hasLabel('EntityType')\n .has('name', entityType)\n .fold()\n .coalesce(\n __.unfold(),\n this.g.addV('EntityType').property('name', entityType)\n )\n .next();\n\n await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .addE('TAGGED_AS')\n .to(this.g.V(etVertex.value))\n .next();\n }\n }\n }\n\n if (updates.modified !== undefined) {\n traversal = traversal.property('modified', updates.modified);\n }\n if (updates.generator !== undefined) {\n traversal = traversal.property('generator', JSON.stringify(updates.generator));\n }\n\n const result = await traversal.elementMap().next();\n\n if (!result.value) {\n throw new Error('Annotation not found');\n }\n\n // Fetch entity types from TAGGED_AS relationships\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n\n return vertexToAnnotation(result.value, entityTypes);\n } catch (error) {\n console.error('Failed to update annotation in Neptune:', error);\n throw error;\n }\n }\n \n async deleteAnnotation(id: AnnotationUri): Promise<void> {\n try {\n await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .drop()\n .iterate();\n \n console.log(`Deleted annotation from Neptune: ${id}`);\n } catch (error) {\n console.error('Failed to delete annotation from Neptune:', error);\n throw error;\n }\n }\n \n async listAnnotations(filter: { resourceId?: ResourceId; type?: AnnotationCategory }): Promise<{ annotations: Annotation[]; total: number }> {\n try {\n let traversal = this.g.V().hasLabel('Annotation');\n\n // Apply filters\n if (filter.resourceId) {\n traversal = traversal.has('resourceId', filter.resourceId);\n }\n\n if (filter.type) {\n const w3cType = filter.type === 'highlight' ? 'TextualBody' : 'SpecificResource';\n traversal = traversal.has('type', w3cType);\n }\n\n const results = await traversal.elementMap().toList();\n const annotations = await this.fetchAnnotationsWithEntityTypes(results);\n\n return { annotations, total: annotations.length };\n } catch (error) {\n console.error('Failed to list annotations from Neptune:', error);\n throw error;\n }\n }\n \n \n async getHighlights(resourceId: ResourceId): Promise<Annotation[]> {\n try {\n const results = await this.g.V()\n .hasLabel('Annotation')\n .has('resourceId', resourceId)\n .hasNot('resolvedResourceId')\n .elementMap()\n .toList();\n\n return await this.fetchAnnotationsWithEntityTypes(results);\n } catch (error) {\n console.error('Failed to get highlights from Neptune:', error);\n throw error;\n }\n }\n \n async resolveReference(annotationId: AnnotationId, source: ResourceId): Promise<Annotation> {\n try {\n // Get target resource name\n const targetDocResult = await this.g.V()\n .hasLabel('Resource')\n .has('id', source)\n .elementMap()\n .next();\n const targetDoc = targetDocResult.value ? vertexToResource(targetDocResult.value) : null;\n\n // Update the existing Annotation vertex\n const traversal = this.g.V()\n .hasLabel('Annotation')\n .has('id', annotationId)\n .property('source', source)\n .property('resolvedResourceName', targetDoc?.name)\n .property('resolvedAt', new Date().toISOString());\n\n const result = await traversal.elementMap().next();\n\n if (!result.value) {\n throw new Error('Annotation not found');\n }\n\n // Create REFERENCES edge to the resolved resource\n const annVertex = await this.g.V()\n .hasLabel('Annotation')\n .has('id', annotationId)\n .next();\n\n await this.g.V(annVertex.value)\n .addE('REFERENCES')\n .to(this.g.V().hasLabel('Resource').has('id', source))\n .next();\n\n // Fetch entity types from TAGGED_AS relationships\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', annotationId)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n\n return vertexToAnnotation(result.value, entityTypes);\n } catch (error) {\n console.error('Failed to resolve reference in Neptune:', error);\n throw error;\n }\n }\n \n async getReferences(resourceId: ResourceId): Promise<Annotation[]> {\n try {\n const results = await this.g.V()\n .hasLabel('Annotation')\n .has('resourceId', resourceId)\n .has('resolvedResourceId')\n .elementMap()\n .toList();\n\n return await this.fetchAnnotationsWithEntityTypes(results);\n } catch (error) {\n console.error('Failed to get references from Neptune:', error);\n throw error;\n }\n }\n \n async getEntityReferences(resourceId: ResourceId, entityTypes?: string[]): Promise<Annotation[]> {\n try {\n let traversal = this.g.V()\n .hasLabel('Annotation')\n .has('resourceId', resourceId)\n .has('resolvedResourceId')\n .has('entityTypes');\n \n if (entityTypes && entityTypes.length > 0) {\n traversal = traversal.filter(\n process.statics.or(\n ...entityTypes.map((type: string) =>\n process.statics.has('entityTypes', TextP.containing(`\"${type}\"`))\n )\n )\n );\n }\n \n const results = await traversal.elementMap().toList();\n\n return await this.fetchAnnotationsWithEntityTypes(results);\n } catch (error) {\n console.error('Failed to get entity references from Neptune:', error);\n throw error;\n }\n }\n \n async getResourceAnnotations(resourceId: ResourceId): Promise<Annotation[]> {\n try {\n const results = await this.g.V()\n .hasLabel('Annotation')\n .has('resourceId', resourceId)\n .elementMap()\n .toList();\n\n return await this.fetchAnnotationsWithEntityTypes(results);\n } catch (error) {\n console.error('Failed to get resource annotations from Neptune:', error);\n throw error;\n }\n }\n \n async getResourceReferencedBy(resourceUri: ResourceUri, _motivation?: string): Promise<Annotation[]> {\n try {\n const results = await this.g.V()\n .hasLabel('Annotation')\n .has('resolvedResourceId', resourceUri)\n .elementMap()\n .toList();\n\n return await this.fetchAnnotationsWithEntityTypes(results);\n } catch (error) {\n console.error('Failed to get resource referenced by from Neptune:', error);\n throw error;\n }\n }\n \n async getResourceConnections(resourceId: ResourceId): Promise<GraphConnection[]> {\n try {\n // Get all annotations from this resource that reference other resources\n const outgoingAnnotations = await this.g.V()\n .hasLabel('Annotation')\n .has('resourceId', resourceId)\n .has('source')\n .elementMap()\n .toList();\n\n // Get all annotations that reference this resource\n const incomingAnnotations = await this.g.V()\n .hasLabel('Annotation')\n .has('source', resourceId)\n .elementMap()\n .toList();\n\n // Build connections map\n const connectionsMap = new Map<string, GraphConnection>();\n\n // Process outgoing references\n for (const annVertex of outgoingAnnotations) {\n const id = annVertex.properties?.id?.[0]?.value || annVertex.id;\n\n // Fetch entity types for this annotation\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n const annotation = vertexToAnnotation(annVertex, entityTypes);\n const targetDocId = getBodySource(annotation.body);\n if (!targetDocId) continue; // Skip stubs\n\n // Get the target resource\n const targetDocResult = await this.g.V()\n .hasLabel('Resource')\n .has('id', targetDocId)\n .elementMap()\n .next();\n\n if (targetDocResult.value) {\n const targetDoc = vertexToResource(targetDocResult.value);\n const targetDocId = getResourceId(targetDoc);\n if (!targetDocId) continue;\n const existing = connectionsMap.get(targetDocId);\n if (existing) {\n existing.annotations.push(annotation);\n } else {\n connectionsMap.set(targetDocId, {\n targetResource: targetDoc,\n annotations: [annotation],\n bidirectional: false,\n });\n }\n }\n }\n\n // Check for bidirectional connections\n for (const annVertex of incomingAnnotations) {\n const id = annVertex.properties?.id?.[0]?.value || annVertex.id;\n\n // Fetch entity types for this annotation\n const entityTypesResult = await this.g.V()\n .hasLabel('Annotation')\n .has('id', id)\n .out('TAGGED_AS')\n .hasLabel('EntityType')\n .values('name')\n .toList();\n\n const entityTypes = entityTypesResult || [];\n const annotation = vertexToAnnotation(annVertex, entityTypes);\n const sourceDocId = getTargetSource(annotation.target);\n const existing = connectionsMap.get(sourceDocId);\n if (existing) {\n existing.bidirectional = true;\n }\n }\n\n return Array.from(connectionsMap.values());\n } catch (error) {\n console.error('Failed to get resource connections from Neptune:', error);\n throw error;\n }\n }\n \n async findPath(fromResourceId: string, toResourceId: string, maxDepth: number = 5): Promise<GraphPath[]> {\n try {\n // Use Neptune's optimized path queries\n const results = await this.g.V()\n .hasLabel('Resource')\n .has('id', fromResourceId)\n .repeat(\n process.statics.both('REFERENCES')\n .simplePath()\n )\n .times(maxDepth)\n .emit()\n .has('id', toResourceId)\n .path()\n .by(process.statics.elementMap())\n .limit(10)\n .toList();\n \n const paths: GraphPath[] = [];\n \n for (const pathResult of results) {\n const resources: ResourceDescriptor[] = [];\n\n // Process path elements (alternating vertices and edges)\n for (let i = 0; i < pathResult.objects.length; i++) {\n const element = pathResult.objects[i];\n\n if (i % 2 === 0) {\n // Vertex (Resource)\n resources.push(vertexToResource(element));\n } else {\n // Edge - skip for now as we're using vertex-based annotations\n // We'd need to query for annotations between resources\n }\n }\n\n paths.push({ resources, annotations: [] });\n }\n \n return paths;\n } catch (error) {\n console.error('Failed to find paths in Neptune:', error);\n throw error;\n }\n }\n \n async getEntityTypeStats(): Promise<EntityTypeStats[]> {\n try {\n // Use Neptune's analytics capabilities\n const results = await this.g.V()\n .hasLabel('Resource')\n .values('entityTypes')\n .map((entityTypesJson: string) => {\n const types = JSON.parse(entityTypesJson);\n return types;\n })\n .unfold()\n .groupCount()\n .next();\n \n const stats: EntityTypeStats[] = [];\n \n if (results.value) {\n for (const [type, count] of Object.entries(results.value)) {\n stats.push({\n type,\n count: count as number,\n });\n }\n }\n \n return stats;\n } catch (error) {\n console.error('Failed to get entity type stats from Neptune:', error);\n throw error;\n }\n }\n \n async getStats(): Promise<{\n resourceCount: number;\n annotationCount: number;\n highlightCount: number;\n referenceCount: number;\n entityReferenceCount: number;\n entityTypes: Record<string, number>;\n contentTypes: Record<string, number>;\n }> {\n try {\n // Get resource count\n const docCountResult = await this.g.V()\n .hasLabel('Resource')\n .count()\n .next();\n const resourceCount = docCountResult.value || 0;\n \n // Get annotation count\n const selCountResult = await this.g.V()\n .hasLabel('Annotation')\n .count()\n .next();\n const annotationCount = selCountResult.value || 0;\n\n // Get highlight count (annotations without resolved resource)\n const highlightCountResult = await this.g.V()\n .hasLabel('Annotation')\n .hasNot('resolvedResourceId')\n .count()\n .next();\n const highlightCount = highlightCountResult.value || 0;\n\n // Get reference count (annotations with resolved resource)\n const referenceCountResult = await this.g.V()\n .hasLabel('Annotation')\n .has('resolvedResourceId')\n .count()\n .next();\n const referenceCount = referenceCountResult.value || 0;\n\n // Get entity reference count\n const entityRefCountResult = await this.g.V()\n .hasLabel('Annotation')\n .has('resolvedResourceId')\n .has('entityTypes')\n .count()\n .next();\n const entityReferenceCount = entityRefCountResult.value || 0;\n \n // Get entity type stats\n const entityTypeStats = await this.getEntityTypeStats();\n const entityTypes: Record<string, number> = {};\n for (const stat of entityTypeStats) {\n entityTypes[stat.type] = stat.count;\n }\n \n // Get content type stats\n const contentTypeResult = await this.g.V()\n .hasLabel('Resource')\n .groupCount()\n .by('contentType')\n .next();\n const contentTypes = contentTypeResult.value || {};\n \n return {\n resourceCount,\n annotationCount,\n highlightCount,\n referenceCount,\n entityReferenceCount,\n entityTypes,\n contentTypes,\n };\n } catch (error) {\n console.error('Failed to get stats from Neptune:', error);\n throw error;\n }\n }\n \n async createAnnotations(inputs: CreateAnnotationInternal[]): Promise<Annotation[]> {\n const results: Annotation[] = [];\n\n try {\n for (const input of inputs) {\n const annotation = await this.createAnnotation(input);\n results.push(annotation);\n }\n\n return results;\n } catch (error) {\n console.error('Failed to create annotations in Neptune:', error);\n throw error;\n }\n }\n\n\n async resolveReferences(inputs: { annotationId: AnnotationId; source: ResourceId }[]): Promise<Annotation[]> {\n const results: Annotation[] = [];\n\n try {\n for (const input of inputs) {\n const annotation = await this.resolveReference(input.annotationId, input.source);\n results.push(annotation);\n }\n\n return results;\n } catch (error) {\n console.error('Failed to resolve references in Neptune:', error);\n throw error;\n }\n }\n \n async detectAnnotations(_resourceId: ResourceId): Promise<Annotation[]> {\n // This would use AI/ML to detect annotations in a resource\n // For now, return empty array as a placeholder\n return [];\n }\n \n // Tag Collections - stored as special vertices in the graph\n private entityTypesCollection: Set<string> | null = null;\n \n async getEntityTypes(): Promise<string[]> {\n // Initialize if not already loaded\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n return Array.from(this.entityTypesCollection!).sort();\n }\n \n async addEntityType(tag: string): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n this.entityTypesCollection!.add(tag);\n // Persist to Neptune\n try {\n await this.g.V()\n .has('tagCollection', 'type', 'entity-types')\n .fold()\n .coalesce(\n __.unfold(),\n __.addV('TagCollection').property('type', 'entity-types')\n )\n .property(cardinality.set, 'tags', tag)\n .iterate();\n } catch (error) {\n console.error('Failed to add entity type:', error);\n }\n }\n \n async addEntityTypes(tags: string[]): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n tags.forEach(tag => this.entityTypesCollection!.add(tag));\n // Persist to Neptune\n try {\n const vertex = await this.g.V()\n .has('tagCollection', 'type', 'entity-types')\n .fold()\n .coalesce(\n __.unfold(),\n __.addV('TagCollection').property('type', 'entity-types')\n );\n \n for (const tag of tags) {\n await vertex.property(cardinality.set, 'tags', tag).iterate();\n }\n } catch (error) {\n console.error('Failed to add entity types:', error);\n }\n }\n \n private async initializeTagCollections(): Promise<void> {\n try {\n // Check Neptune for existing collections\n const collections = await this.g.V()\n .hasLabel('TagCollection')\n .project('type', 'tags')\n .by('type')\n .by(__.values('tags').fold())\n .toList();\n\n // Process existing collections\n for (const col of collections) {\n if (col.type === 'entity-types') {\n this.entityTypesCollection = new Set(col.tags as string[]);\n }\n }\n } catch (error) {\n console.log('No existing tag collections found, will initialize with defaults');\n }\n\n // Initialize with defaults if not present\n if (this.entityTypesCollection === null) {\n const { DEFAULT_ENTITY_TYPES } = await import('@semiont/ontology');\n this.entityTypesCollection = new Set(DEFAULT_ENTITY_TYPES);\n // Persist defaults to Neptune\n try {\n const vertex = await this.g.addV('TagCollection')\n .property('type', 'entity-types')\n .next();\n for (const tag of DEFAULT_ENTITY_TYPES) {\n await this.g.V(vertex.value.id)\n .property(cardinality.set, 'tags', tag)\n .iterate();\n }\n } catch (error) {\n console.error('Failed to initialize entity types:', error);\n }\n }\n }\n \n generateId(): string {\n return uuidv4().replace(/-/g, '').substring(0, 12);\n }\n \n async clearDatabase(): Promise<void> {\n try {\n // CAREFUL! This clears the entire graph\n await this.g.V().drop().iterate();\n console.log('Cleared all data from Neptune');\n // Reset tag collections\n this.entityTypesCollection = null;\n } catch (error) {\n console.error('Failed to clear Neptune database:', error);\n throw error;\n }\n }\n}","// Neo4j implementation of GraphDatabase interface\n// Uses Cypher query language\n\nimport neo4j, { Driver, Session } from 'neo4j-driver';\nimport { GraphDatabase } from '../interface';\nimport type { components } from '@semiont/api-client';\nimport type {\n AnnotationCategory,\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n ResourceFilter,\n UpdateResourceInput,\n CreateAnnotationInternal,\n ResourceId,\n AnnotationId,\n} from '@semiont/core';\nimport type { ResourceUri, AnnotationUri } from '@semiont/api-client';\nimport { getExactText } from '@semiont/api-client';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getBodySource, getTargetSource, getTargetSelector } from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport { getPrimaryRepresentation } from '@semiont/api-client';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Annotation = components['schemas']['Annotation'];\n\n/**\n * Convert motivation to a valid Neo4j label name\n *\n * Annotations get both a property (`motivation: \"linking\"`) and a label (`:Linking`)\n * for the same motivation value. This enables:\n * - Fast filtering: `MATCH (a:Annotation:Linking)` vs `MATCH (a:Annotation) WHERE a.motivation = 'linking'`\n * - Automatic indexing: Neo4j indexes labels by default\n * - Visual exploration: Graph visualization tools prominently display labels\n *\n * Example: \"linking\" -> \"Linking\", \"commenting\" -> \"Commenting\"\n *\n * W3C Motivation values:\n * assessing, bookmarking, classifying, commenting, describing, editing,\n * highlighting, identifying, linking, moderating, questioning, replying, tagging\n */\nfunction motivationToLabel(motivation: string): string {\n return motivation.charAt(0).toUpperCase() + motivation.slice(1);\n}\n\nexport class Neo4jGraphDatabase implements GraphDatabase {\n private driver: Driver | null = null;\n private connected: boolean = false;\n private config: {\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n };\n\n // Tag Collections - cached in memory for performance\n private entityTypesCollection: Set<string> | null = null;\n\n constructor(config: {\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n } = {}) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n try {\n const uri = this.config.uri;\n const username = this.config.username;\n const password = this.config.password;\n const database = this.config.database;\n\n if (!uri) {\n throw new Error('Neo4j URI not configured! Pass uri in config.');\n }\n if (!username) {\n throw new Error('Neo4j username not configured! Pass username in config.');\n }\n if (!password) {\n throw new Error('Neo4j password not configured! Pass password in config.');\n }\n if (!database) {\n throw new Error('Neo4j database not configured! Pass database in config.');\n }\n\n console.log(`Connecting to Neo4j at ${uri}...`);\n\n this.driver = neo4j.driver(\n uri,\n neo4j.auth.basic(username, password),\n {\n maxConnectionPoolSize: 50,\n connectionAcquisitionTimeout: 60000,\n }\n );\n\n // Test connection\n const session = this.driver.session({ database });\n\n await session.run('RETURN 1 as test');\n await session.close();\n\n // Create constraints and indexes if they don't exist\n await this.ensureSchemaExists();\n\n console.log('Successfully connected to Neo4j');\n this.connected = true;\n } catch (error) {\n console.error('Failed to connect to Neo4j:', error);\n throw new Error(`Neo4j connection failed: ${error}`);\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.driver) {\n await this.driver.close();\n this.driver = null;\n }\n this.connected = false;\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n private getSession(): Session {\n if (!this.driver) {\n throw new Error('Neo4j driver not initialized');\n }\n if (!this.config.database) {\n throw new Error('Neo4j database not configured! Pass database in config.');\n }\n return this.driver.session({\n database: this.config.database\n });\n }\n\n private async ensureSchemaExists(): Promise<void> {\n const session = this.getSession();\n try {\n // Create constraints for unique IDs\n const constraints = [\n 'CREATE CONSTRAINT doc_id IF NOT EXISTS FOR (d:Resource) REQUIRE d.id IS UNIQUE',\n 'CREATE CONSTRAINT sel_id IF NOT EXISTS FOR (s:Annotation) REQUIRE s.id IS UNIQUE',\n 'CREATE CONSTRAINT tag_id IF NOT EXISTS FOR (t:TagCollection) REQUIRE t.type IS UNIQUE'\n ];\n\n for (const constraint of constraints) {\n try {\n await session.run(constraint);\n } catch (error: any) {\n // Ignore if constraint already exists\n if (!error.message?.includes('already exists')) {\n console.warn(`Schema creation warning: ${error.message}`);\n }\n }\n }\n\n // Create indexes for common queries\n const indexes = [\n 'CREATE INDEX doc_name IF NOT EXISTS FOR (d:Resource) ON (d.name)',\n 'CREATE INDEX doc_entity_types IF NOT EXISTS FOR (d:Resource) ON (d.entityTypes)',\n 'CREATE INDEX sel_doc_id IF NOT EXISTS FOR (s:Annotation) ON (s.resourceId)',\n 'CREATE INDEX sel_resolved_id IF NOT EXISTS FOR (s:Annotation) ON (s.resolvedResourceId)'\n ];\n\n for (const index of indexes) {\n try {\n await session.run(index);\n } catch (error: any) {\n // Ignore if index already exists\n if (!error.message?.includes('already exists')) {\n console.warn(`Index creation warning: ${error.message}`);\n }\n }\n }\n } finally {\n await session.close();\n }\n }\n\n async createResource(resource: ResourceDescriptor): Promise<ResourceDescriptor> {\n const session = this.getSession();\n try {\n const id = resource['@id']; // Use full URI for consistency\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) {\n throw new Error('Resource must have at least one representation');\n }\n\n const result = await session.run(\n `CREATE (d:Resource {\n id: $id,\n name: $name,\n entityTypes: $entityTypes,\n format: $format,\n archived: $archived,\n created: datetime($created),\n creator: $creator,\n creationMethod: $creationMethod,\n contentChecksum: $contentChecksum,\n sourceAnnotationId: $sourceAnnotationId,\n sourceResourceId: $sourceResourceId\n }) RETURN d`,\n {\n id,\n name: resource.name,\n entityTypes: resource.entityTypes,\n format: primaryRep.mediaType,\n archived: resource.archived || false,\n created: resource.dateCreated,\n creator: JSON.stringify(resource.wasAttributedTo),\n creationMethod: resource.creationMethod,\n contentChecksum: primaryRep.checksum,\n sourceAnnotationId: resource.sourceAnnotationId ?? null,\n sourceResourceId: resource.sourceResourceId ?? null,\n }\n );\n\n return this.parseResourceNode(result.records[0]!.get('d'));\n } finally {\n await session.close();\n }\n }\n\n async getResource(id: ResourceUri): Promise<ResourceDescriptor | null> {\n const session = this.getSession();\n try {\n const result = await session.run(\n 'MATCH (d:Resource {id: $id}) RETURN d',\n { id }\n );\n\n if (result.records.length === 0) return null;\n return this.parseResourceNode(result.records[0]!.get('d'));\n } finally {\n await session.close();\n }\n }\n\n async updateResource(id: ResourceUri, input: UpdateResourceInput): Promise<ResourceDescriptor> {\n // Resources are immutable - only archiving is allowed\n if (Object.keys(input).length !== 1 || input.archived === undefined) {\n throw new Error('Resources are immutable. Only archiving is allowed.');\n }\n\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (d:Resource {id: $id})\n SET d.archived = $archived\n RETURN d`,\n { id, archived: input.archived }\n );\n\n if (result.records.length === 0) {\n throw new Error('Resource not found');\n }\n\n return this.parseResourceNode(result.records[0]!.get('d'));\n } finally {\n await session.close();\n }\n }\n\n async deleteResource(id: ResourceUri): Promise<void> {\n const session = this.getSession();\n try {\n // Delete resource and all its annotations\n await session.run(\n `MATCH (d:Resource {id: $id})\n OPTIONAL MATCH (a:Annotation)-[:BELONGS_TO|:REFERENCES]->(d)\n DETACH DELETE d, a`,\n { id }\n );\n } finally {\n await session.close();\n }\n }\n\n async listResources(filter: ResourceFilter): Promise<{ resources: ResourceDescriptor[]; total: number }> {\n const session = this.getSession();\n try {\n let whereClause = '';\n const params: any = {};\n const conditions: string[] = [];\n\n if (filter.entityTypes && filter.entityTypes.length > 0) {\n conditions.push('ANY(type IN $entityTypes WHERE type IN d.entityTypes)');\n params.entityTypes = filter.entityTypes;\n }\n\n if (filter.search) {\n conditions.push('toLower(d.name) CONTAINS toLower($search)');\n params.search = filter.search;\n }\n\n if (conditions.length > 0) {\n whereClause = 'WHERE ' + conditions.join(' AND ');\n }\n\n // Get total count\n const countResult = await session.run(\n `MATCH (d:Resource) ${whereClause} RETURN count(d) as total`,\n params\n );\n const total = countResult.records[0]!.get('total').toNumber();\n\n // Get paginated results - ensure integers for Neo4j\n params.skip = neo4j.int(filter.offset || 0);\n params.limit = neo4j.int(filter.limit || 20);\n\n const result = await session.run(\n `MATCH (d:Resource) ${whereClause}\n RETURN d\n ORDER BY d.updatedAt DESC\n SKIP $skip LIMIT $limit`,\n params\n );\n\n const resources = result.records.map(record => this.parseResourceNode(record.get('d')));\n\n return { resources, total };\n } finally {\n await session.close();\n }\n }\n\n async searchResources(query: string, limit: number = 20): Promise<ResourceDescriptor[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (d:Resource)\n WHERE toLower(d.name) CONTAINS toLower($query)\n RETURN d\n ORDER BY d.updatedAt DESC\n LIMIT $limit`,\n { query, limit: neo4j.int(limit) }\n );\n\n return result.records.map(record => this.parseResourceNode(record.get('d')));\n } finally {\n await session.close();\n }\n }\n\n async createAnnotation(input: CreateAnnotationInternal): Promise<Annotation> {\n const session = this.getSession();\n try {\n const id = input.id;\n\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id,\n motivation: input.motivation,\n target: input.target,\n body: input.body,\n creator: input.creator,\n created: new Date().toISOString(),\n };\n\n // Extract values for Cypher query\n const targetSource = getTargetSource(input.target);\n const targetSelector = getTargetSelector(input.target);\n const bodySource = getBodySource(input.body);\n\n // Extract entity types from TextualBody bodies with purpose: \"tagging\"\n const entityTypes = getEntityTypes(input);\n\n // Convert motivation to label (e.g., \"linking\" -> \"Linking\")\n const motivationLabel = motivationToLabel(annotation.motivation);\n\n // Create the annotation node and relationships\n let cypher: string;\n if (bodySource) {\n // Resolved reference with target resource\n // Add motivation as both a property and a label for efficient querying\n cypher = `MATCH (from:Resource {id: $fromId})\n MATCH (to:Resource {id: $toId})\n CREATE (a:Annotation:${motivationLabel} {\n id: $id,\n resourceId: $resourceId,\n exact: $exact,\n selector: $selector,\n type: $type,\n motivation: $motivation,\n creator: $creator,\n created: datetime($created),\n source: $source\n })\n CREATE (a)-[:BELONGS_TO]->(from)\n CREATE (a)-[:REFERENCES]->(to)\n FOREACH (entityType IN $entityTypes |\n MERGE (et:EntityType {name: entityType})\n CREATE (a)-[:TAGGED_AS]->(et)\n )\n RETURN a`;\n } else {\n // Stub reference (unresolved)\n // Add motivation as both a property and a label for efficient querying\n cypher = `MATCH (d:Resource {id: $resourceId})\n CREATE (a:Annotation:${motivationLabel} {\n id: $id,\n resourceId: $resourceId,\n exact: $exact,\n selector: $selector,\n type: $type,\n motivation: $motivation,\n creator: $creator,\n created: datetime($created)\n })\n CREATE (a)-[:BELONGS_TO]->(d)\n FOREACH (entityType IN $entityTypes |\n MERGE (et:EntityType {name: entityType})\n CREATE (a)-[:TAGGED_AS]->(et)\n )\n RETURN a`;\n }\n\n const params: any = {\n id,\n resourceId: targetSource, // Store full URI\n fromId: targetSource, // Store full URI\n toId: bodySource || null, // Store full URI\n exact: targetSelector ? getExactText(targetSelector) : '',\n selector: JSON.stringify(targetSelector || {}),\n type: 'SpecificResource',\n motivation: annotation.motivation,\n creator: JSON.stringify(annotation.creator),\n created: annotation.created,\n entityTypes,\n source: bodySource || null,\n };\n\n const result = await session.run(cypher, params);\n\n if (result.records.length === 0) {\n throw new Error(`Failed to create annotation: Resource ${targetSource} not found in graph database`);\n }\n\n return this.parseAnnotationNode(result.records[0]!.get('a'), entityTypes);\n } finally {\n await session.close();\n }\n }\n\n async getAnnotation(id: AnnotationUri): Promise<Annotation | null> {\n console.log(`[Neo4j] getAnnotation called for: ${id}`);\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (a:Annotation {id: $id})\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n { id }\n );\n\n if (result.records.length === 0) {\n console.log(`[Neo4j] getAnnotation: Annotation ${id} NOT FOUND`);\n return null;\n }\n console.log(`[Neo4j] getAnnotation: Annotation ${id} FOUND`);\n return this.parseAnnotationNode(\n result.records[0]!.get('a'),\n result.records[0]!.get('entityTypes')\n );\n } finally {\n await session.close();\n }\n }\n\n async updateAnnotation(id: AnnotationUri, updates: Partial<Annotation>): Promise<Annotation> {\n const session = this.getSession();\n try {\n const setClauses: string[] = ['a.updatedAt = datetime()'];\n const params: any = { id };\n\n // Build SET clauses dynamically\n Object.entries(updates).forEach(([key, value]) => {\n if (key !== 'id' && key !== 'updatedAt') {\n setClauses.push(`a.${key} = $${key}`);\n if (key === 'selector' || key === 'metadata' || key === 'body') {\n params[key] = JSON.stringify(value);\n } else if (key === 'created' || key === 'resolvedAt') {\n params[key] = value ? new Date(value as any).toISOString() : null;\n } else {\n params[key] = value;\n }\n }\n });\n\n // Update annotation properties\n const result = await session.run(\n `MATCH (a:Annotation {id: $id})\n SET ${setClauses.join(', ')}\n WITH a\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n params\n );\n\n if (result.records.length === 0) {\n throw new Error('Annotation not found');\n }\n\n // If motivation was updated, update the label\n if (updates.motivation) {\n const newLabel = motivationToLabel(updates.motivation);\n console.log(`[Neo4j] Updating motivation label to: ${newLabel}`);\n\n // Remove all possible motivation labels and add the new one\n const allMotivations = ['Assessing', 'Bookmarking', 'Classifying', 'Commenting',\n 'Describing', 'Editing', 'Highlighting', 'Identifying',\n 'Linking', 'Moderating', 'Questioning', 'Replying', 'Tagging'];\n const removeLabels = allMotivations.filter(m => m !== newLabel).map(m => `a:${m}`).join(', ');\n\n await session.run(\n `MATCH (a:Annotation {id: $id})\n REMOVE ${removeLabels}\n SET a:${newLabel}`,\n { id }\n );\n console.log(`[Neo4j] ✅ Motivation label updated to: ${newLabel}`);\n }\n\n // If body was updated and contains a SpecificResource, create REFERENCES relationship\n if (updates.body) {\n console.log(`[Neo4j] ====== BODY UPDATE for Annotation ${id} ======`);\n console.log(`[Neo4j] updates.body:`, JSON.stringify(updates.body));\n const bodyArray = Array.isArray(updates.body) ? updates.body : [updates.body];\n console.log(`[Neo4j] bodyArray length: ${bodyArray.length}`);\n\n bodyArray.forEach((item, idx) => {\n console.log(`[Neo4j] Body item ${idx}:`, JSON.stringify(item));\n });\n\n const specificResource = bodyArray.find((item: any) => item.type === 'SpecificResource' && item.purpose === 'linking');\n console.log(`[Neo4j] Found SpecificResource:`, specificResource ? JSON.stringify(specificResource) : 'null');\n\n if (specificResource && 'source' in specificResource && specificResource.source) {\n console.log(`[Neo4j] ✅ Creating REFERENCES edge: ${id} -> ${specificResource.source}`);\n // Create REFERENCES relationship to the target resource\n const refResult = await session.run(\n `MATCH (a:Annotation {id: $annotationId})\n MATCH (target:Resource {id: $targetResourceId})\n MERGE (a)-[:REFERENCES]->(target)\n RETURN a, target`,\n {\n annotationId: id,\n targetResourceId: specificResource.source\n }\n );\n console.log(`[Neo4j] ✅ REFERENCES edge created! Matched ${refResult.records.length} nodes`);\n if (refResult.records.length > 0) {\n console.log(`[Neo4j] Annotation: ${refResult.records[0]!.get('a').properties.id}`);\n console.log(`[Neo4j] Target Resource: ${refResult.records[0]!.get('target').properties.id}`);\n }\n } else {\n console.log(`[Neo4j] No SpecificResource in body - this is a stub reference (not yet resolved)`);\n }\n } else {\n console.log(`[Neo4j] No body update for annotation ${id}`);\n }\n\n return this.parseAnnotationNode(\n result.records[0]!.get('a'),\n result.records[0]!.get('entityTypes')\n );\n } finally {\n await session.close();\n }\n }\n\n async deleteAnnotation(id: AnnotationUri): Promise<void> {\n const session = this.getSession();\n try {\n await session.run(\n 'MATCH (a:Annotation {id: $id}) DETACH DELETE a',\n { id }\n );\n } finally {\n await session.close();\n }\n }\n\n async listAnnotations(filter: { resourceId?: ResourceId; type?: AnnotationCategory }): Promise<{ annotations: Annotation[]; total: number }> {\n const session = this.getSession();\n try {\n const conditions: string[] = [];\n const params: any = {};\n\n if (filter.resourceId) {\n conditions.push('a.resourceId = $resourceId');\n params.resourceId = filter.resourceId;\n }\n\n if (filter.type) {\n const w3cType = filter.type === 'highlight' ? 'TextualBody' : 'SpecificResource';\n conditions.push('a.type = $type');\n params.type = w3cType;\n }\n\n const whereClause = conditions.length > 0 ? 'WHERE ' + conditions.join(' AND ') : '';\n\n // Get all results (no pagination in new simplified interface)\n const result = await session.run(\n `MATCH (a:Annotation) ${whereClause}\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n params\n );\n\n const annotations = result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n\n return { annotations, total: annotations.length };\n } finally {\n await session.close();\n }\n }\n\n async getHighlights(resourceId: ResourceId): Promise<Annotation[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (a:Annotation {resourceId: $resourceId})\n WHERE a.annotationCategory = 'highlight'\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes\n ORDER BY a.created DESC`,\n { resourceId }\n );\n\n return result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n } finally {\n await session.close();\n }\n }\n\n async resolveReference(annotationId: AnnotationId, source: ResourceId): Promise<Annotation> {\n const session = this.getSession();\n try {\n // Get the target resource's name\n const docResult = await session.run(\n 'MATCH (d:Resource {id: $id}) RETURN d.name as name',\n { id: source }\n );\n const resourceName = docResult.records[0]?.get('name');\n\n // Update annotation and create REFERENCES relationship\n const result = await session.run(\n `MATCH (a:Annotation {id: $annotationId})\n MATCH (to:Resource {id: $source})\n SET a.source = $source,\n a.resolvedResourceName = $resourceName,\n a.resolvedAt = datetime()\n MERGE (a)-[:REFERENCES]->(to)\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n { annotationId, source, resourceName }\n );\n\n if (result.records.length === 0) {\n throw new Error('Annotation not found');\n }\n\n return this.parseAnnotationNode(\n result.records[0]!.get('a'),\n result.records[0]!.get('entityTypes')\n );\n } finally {\n await session.close();\n }\n }\n\n async getReferences(resourceId: ResourceId): Promise<Annotation[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (a:Annotation {resourceId: $resourceId})\n WHERE a.annotationCategory IN ['stub_reference', 'resolved_reference']\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes\n ORDER BY a.created DESC`,\n { resourceId }\n );\n\n return result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n } finally {\n await session.close();\n }\n }\n\n async getEntityReferences(resourceId: ResourceId, entityTypes?: string[]): Promise<Annotation[]> {\n const session = this.getSession();\n try {\n let cypher = `MATCH (a:Annotation {resourceId: $resourceId})\n WHERE a.source IS NOT NULL`;\n\n const params: any = { resourceId };\n\n if (entityTypes && entityTypes.length > 0) {\n cypher += `\n MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n WHERE et.name IN $entityTypes`;\n params.entityTypes = entityTypes;\n }\n\n cypher += `\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et2:EntityType)\n RETURN a, collect(et2.name) as entityTypes\n ORDER BY a.created DESC`;\n\n const result = await session.run(cypher, params);\n\n return result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n } finally {\n await session.close();\n }\n }\n\n async getResourceAnnotations(resourceId: ResourceId): Promise<Annotation[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (a:Annotation {resourceId: $resourceId})\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes\n ORDER BY a.created DESC`,\n { resourceId }\n );\n\n return result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n } finally {\n await session.close();\n }\n }\n\n async getResourceReferencedBy(resourceUri: ResourceUri, motivation?: string): Promise<Annotation[]> {\n const session = this.getSession();\n try {\n const filterDesc = motivation ? ` with motivation=${motivation}` : '';\n console.log(`[Neo4j] getResourceReferencedBy: Searching for annotations${filterDesc} referencing ${resourceUri}`);\n\n // Build query with optional motivation label filter\n // If motivation is specified, use the label for efficient filtering\n const motivationLabel = motivation ? `:${motivationToLabel(motivation)}` : '';\n const cypher = `MATCH (a:Annotation${motivationLabel})-[:REFERENCES]->(d:Resource {id: $resourceUri})\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes\n ORDER BY a.created DESC`;\n\n const result = await session.run(cypher, { resourceUri });\n\n console.log(`[Neo4j] getResourceReferencedBy: Found ${result.records.length} annotations`);\n\n return result.records.map(record =>\n this.parseAnnotationNode(record.get('a'), record.get('entityTypes'))\n );\n } finally {\n await session.close();\n }\n }\n\n async getResourceConnections(resourceId: ResourceId): Promise<GraphConnection[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (d:Resource {id: $resourceId})\n OPTIONAL MATCH (d)<-[:BELONGS_TO]-(a1:Annotation)-[:REFERENCES]->(other:Resource)\n OPTIONAL MATCH (other)<-[:BELONGS_TO]-(a2:Annotation)-[:REFERENCES]->(d)\n WITH other, COLLECT(DISTINCT a1) as outgoing, COLLECT(DISTINCT a2) as incoming\n WHERE other IS NOT NULL\n RETURN other, outgoing, incoming`,\n { resourceId }\n );\n\n const connections: GraphConnection[] = [];\n\n for (const record of result.records) {\n const targetResource = this.parseResourceNode(record.get('other'));\n\n // Fetch entity types for outgoing annotations\n const outgoingNodes = record.get('outgoing');\n const outgoing: Annotation[] = [];\n for (const annNode of outgoingNodes) {\n const annId = annNode.properties.id;\n const annResult = await session.run(\n `MATCH (a:Annotation {id: $id})\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n { id: annId }\n );\n if (annResult.records.length > 0) {\n outgoing.push(this.parseAnnotationNode(\n annResult.records[0]!.get('a'),\n annResult.records[0]!.get('entityTypes')\n ));\n }\n }\n\n // Fetch entity types for incoming annotations\n const incomingNodes = record.get('incoming');\n const incoming: Annotation[] = [];\n for (const annNode of incomingNodes) {\n const annId = annNode.properties.id;\n const annResult = await session.run(\n `MATCH (a:Annotation {id: $id})\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n { id: annId }\n );\n if (annResult.records.length > 0) {\n incoming.push(this.parseAnnotationNode(\n annResult.records[0]!.get('a'),\n annResult.records[0]!.get('entityTypes')\n ));\n }\n }\n\n connections.push({\n targetResource,\n annotations: outgoing,\n bidirectional: incoming.length > 0\n });\n }\n\n return connections;\n } finally {\n await session.close();\n }\n }\n\n async findPath(fromResourceId: string, toResourceId: string, maxDepth: number = 5): Promise<GraphPath[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH path = shortestPath((from:Resource {id: $fromId})-[:REFERENCES*..${maxDepth}]-(to:Resource {id: $toId}))\n WITH path, nodes(path) as docs, relationships(path) as rels\n RETURN docs, rels\n LIMIT 10`,\n { fromId: fromResourceId, toId: toResourceId }\n );\n\n const paths: GraphPath[] = [];\n\n for (const record of result.records) {\n const docs = record.get('docs').map((node: any) => this.parseResourceNode(node));\n const rels = record.get('rels');\n\n // Get annotation details for the relationships\n const annotationIds = rels.map((rel: any) => rel.properties.id).filter((id: any) => id);\n const annotations: Annotation[] = [];\n\n if (annotationIds.length > 0) {\n const selResult = await session.run(\n `MATCH (a:Annotation) WHERE a.id IN $ids\n OPTIONAL MATCH (a)-[:TAGGED_AS]->(et:EntityType)\n RETURN a, collect(et.name) as entityTypes`,\n { ids: annotationIds }\n );\n selResult.records.forEach(rec => {\n annotations.push(this.parseAnnotationNode(\n rec.get('a'),\n rec.get('entityTypes')\n ));\n });\n }\n\n paths.push({\n resources: docs,\n annotations: annotations\n });\n }\n\n return paths;\n } finally {\n await session.close();\n }\n }\n\n async getEntityTypeStats(): Promise<EntityTypeStats[]> {\n const session = this.getSession();\n try {\n const result = await session.run(\n `MATCH (d:Resource)\n UNWIND d.entityTypes AS type\n RETURN type, count(*) AS count\n ORDER BY count DESC`\n );\n\n return result.records.map(record => ({\n type: record.get('type'),\n count: record.get('count').toNumber()\n }));\n } finally {\n await session.close();\n }\n }\n\n async getStats(): Promise<{\n resourceCount: number;\n annotationCount: number;\n highlightCount: number;\n referenceCount: number;\n entityReferenceCount: number;\n entityTypes: Record<string, number>;\n contentTypes: Record<string, number>;\n }> {\n const session = this.getSession();\n try {\n // Get resource count\n const docCountResult = await session.run('MATCH (d:Resource) RETURN count(d) as count');\n const resourceCount = docCountResult.records[0]!.get('count').toNumber();\n\n // Get annotation counts\n const selCountResult = await session.run('MATCH (a:Annotation) RETURN count(a) as count');\n const annotationCount = selCountResult.records[0]!.get('count').toNumber();\n\n const highlightCountResult = await session.run(\n 'MATCH (a:Annotation) WHERE a.resolvedResourceId IS NULL RETURN count(a) as count'\n );\n const highlightCount = highlightCountResult.records[0]!.get('count').toNumber();\n\n const referenceCountResult = await session.run(\n 'MATCH (a:Annotation) WHERE a.resolvedResourceId IS NOT NULL RETURN count(a) as count'\n );\n const referenceCount = referenceCountResult.records[0]!.get('count').toNumber();\n\n const entityRefCountResult = await session.run(\n 'MATCH (a:Annotation) WHERE a.resolvedResourceId IS NOT NULL AND size(a.entityTypes) > 0 RETURN count(a) as count'\n );\n const entityReferenceCount = entityRefCountResult.records[0]!.get('count').toNumber();\n\n // Get entity type stats\n const entityTypeResult = await session.run(\n `MATCH (d:Resource)\n UNWIND d.entityTypes AS type\n RETURN type, count(*) AS count`\n );\n\n const entityTypes: Record<string, number> = {};\n entityTypeResult.records.forEach(record => {\n entityTypes[record.get('type')] = record.get('count').toNumber();\n });\n\n // Get content type stats\n const contentTypeResult = await session.run(\n `MATCH (d:Resource)\n RETURN d.format as type, count(*) AS count`\n );\n\n const contentTypes: Record<string, number> = {};\n contentTypeResult.records.forEach(record => {\n contentTypes[record.get('type')] = record.get('count').toNumber();\n });\n\n return {\n resourceCount,\n annotationCount,\n highlightCount,\n referenceCount,\n entityReferenceCount,\n entityTypes,\n contentTypes\n };\n } finally {\n await session.close();\n }\n }\n\n async createAnnotations(inputs: CreateAnnotationInternal[]): Promise<Annotation[]> {\n const results: Annotation[] = [];\n for (const input of inputs) {\n results.push(await this.createAnnotation(input));\n }\n return results;\n }\n\n async resolveReferences(inputs: { annotationId: AnnotationId; source: ResourceId }[]): Promise<Annotation[]> {\n const results: Annotation[] = [];\n for (const input of inputs) {\n results.push(await this.resolveReference(input.annotationId, input.source));\n }\n return results;\n }\n\n async detectAnnotations(_resourceId: ResourceId): Promise<Annotation[]> {\n // This would use AI/ML to detect annotations in a resource\n // For now, return empty array as a placeholder\n return [];\n }\n\n // Tag Collections\n async getEntityTypes(): Promise<string[]> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n return Array.from(this.entityTypesCollection!).sort();\n }\n\n async addEntityType(tag: string): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n this.entityTypesCollection!.add(tag);\n await this.persistTagCollection('entity-types', this.entityTypesCollection!);\n }\n\n async addEntityTypes(tags: string[]): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n tags.forEach(tag => this.entityTypesCollection!.add(tag));\n await this.persistTagCollection('entity-types', this.entityTypesCollection!);\n }\n\n private async initializeTagCollections(): Promise<void> {\n const session = this.getSession();\n try {\n // Load existing collections from Neo4j\n const result = await session.run(\n 'MATCH (t:TagCollection {type: \"entity-types\"}) RETURN t.tags as tags'\n );\n\n let entityTypesFromDb: string[] = [];\n\n if (result.records.length > 0) {\n const record = result.records[0];\n if (record) {\n const tags = record.get('tags');\n entityTypesFromDb = tags || [];\n }\n }\n\n // Load defaults\n const { DEFAULT_ENTITY_TYPES } = await import('@semiont/ontology');\n\n // Merge with defaults\n this.entityTypesCollection = new Set([...DEFAULT_ENTITY_TYPES, ...entityTypesFromDb]);\n\n // Persist merged collection back to Neo4j\n await this.persistTagCollection('entity-types', this.entityTypesCollection);\n } finally {\n await session.close();\n }\n }\n\n private async persistTagCollection(type: string, collection: Set<string>): Promise<void> {\n const session = this.getSession();\n try {\n await session.run(\n 'MERGE (t:TagCollection {type: $type}) SET t.tags = $tags',\n { type, tags: Array.from(collection) }\n );\n } finally {\n await session.close();\n }\n }\n\n generateId(): string {\n return uuidv4().replace(/-/g, '').substring(0, 12);\n }\n\n async clearDatabase(): Promise<void> {\n const session = this.getSession();\n try {\n // CAREFUL! This clears the entire database\n await session.run('MATCH (n) DETACH DELETE n');\n this.entityTypesCollection = null;\n } finally {\n await session.close();\n }\n }\n\n // Helper methods to parse Neo4j nodes\n private parseResourceNode(node: any): ResourceDescriptor {\n const props = node.properties;\n\n // Validate all required fields\n if (!props.id) throw new Error('Resource missing required field: id');\n if (!props.name) throw new Error(`Resource ${props.id} missing required field: name`);\n if (!props.entityTypes) throw new Error(`Resource ${props.id} missing required field: entityTypes`);\n if (!props.format) throw new Error(`Resource ${props.id} missing required field: contentType`);\n if (props.archived === undefined || props.archived === null) throw new Error(`Resource ${props.id} missing required field: archived`);\n if (!props.created) throw new Error(`Resource ${props.id} missing required field: created`);\n if (!props.creator) throw new Error(`Resource ${props.id} missing required field: creator`);\n if (!props.creationMethod) throw new Error(`Resource ${props.id} missing required field: creationMethod`);\n if (!props.contentChecksum) throw new Error(`Resource ${props.id} missing required field: contentChecksum`);\n\n const resource: ResourceDescriptor = {\n '@context': 'https://schema.org/',\n '@id': props.id,\n name: props.name,\n entityTypes: props.entityTypes,\n representations: [{\n mediaType: props.format,\n checksum: props.contentChecksum,\n rel: 'original',\n }],\n archived: props.archived,\n dateCreated: props.created.toString(),\n wasAttributedTo: typeof props.creator === 'string' ? JSON.parse(props.creator) : props.creator,\n creationMethod: props.creationMethod,\n };\n\n if (props.sourceResourceId) resource.sourceResourceId = props.sourceResourceId;\n\n return resource;\n }\n\n private parseAnnotationNode(node: any, entityTypes: string[] = []): Annotation {\n const props = node.properties;\n\n // Validate required fields\n if (!props.id) throw new Error('Annotation missing required field: id');\n if (!props.resourceId) throw new Error(`Annotation ${props.id} missing required field: resourceId`);\n // props.exact is optional - not all annotation types have selected text (e.g., image annotations)\n if (!props.type) throw new Error(`Annotation ${props.id} missing required field: type`);\n if (!props.selector) throw new Error(`Annotation ${props.id} missing required field: selector`);\n if (!props.creator) throw new Error(`Annotation ${props.id} missing required field: creator`);\n\n if (!props.motivation) throw new Error(`Annotation ${props.id} missing required field: motivation`);\n\n // Parse creator - always stored as JSON string in DB\n const creator = JSON.parse(props.creator);\n\n // Reconstruct body array from entity tags and linking body\n const bodyArray: Array<{type: 'TextualBody'; value: string; purpose: 'tagging'} | {type: 'SpecificResource'; source: string; purpose: 'linking'}> = [];\n\n // Add entity tag bodies (TextualBody with purpose: \"tagging\")\n for (const entityType of entityTypes) {\n if (entityType) { // Filter out nulls\n bodyArray.push({\n type: 'TextualBody' as const,\n value: entityType,\n purpose: 'tagging' as const,\n });\n }\n }\n\n // Add linking body (SpecificResource) if annotation is resolved\n if (props.source) {\n bodyArray.push({\n type: 'SpecificResource' as const,\n source: props.source,\n purpose: 'linking' as const,\n });\n }\n\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: props.id,\n motivation: props.motivation,\n target: {\n source: props.resourceId,\n selector: JSON.parse(props.selector),\n },\n body: bodyArray as Annotation['body'],\n creator,\n created: props.created, // ISO string from DB\n };\n\n // W3C Web Annotation modification tracking\n if (props.modified) annotation.modified = props.modified.toString();\n if (props.generator) {\n try {\n annotation.generator = JSON.parse(props.generator);\n } catch (e) {\n // Ignore parse errors\n }\n }\n\n return annotation;\n }\n}","// JanusGraph implementation with real Gremlin connection\n// This replaces the mock in-memory implementation\n\nimport gremlin from 'gremlin';\nimport { GraphDatabase } from '../interface';\nimport {\n getBodySource,\n getPrimaryRepresentation,\n getResourceId,\n getExactText,\n type components,\n type ResourceUri,\n type AnnotationUri,\n resourceUri,\n} from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport { annotationIdToURI } from '@semiont/core';\nimport type {\n AnnotationCategory,\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n ResourceFilter,\n UpdateResourceInput,\n CreateAnnotationInternal,\n ResourceId,\n AnnotationId,\n EnvironmentConfig,\n} from '@semiont/core';\nimport { v4 as uuidv4 } from 'uuid';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Annotation = components['schemas']['Annotation'];\n\nconst traversal = gremlin.process.AnonymousTraversalSource.traversal;\nconst DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;\n\nexport class JanusGraphDatabase implements GraphDatabase {\n private connected: boolean = false;\n private connection: gremlin.driver.DriverRemoteConnection | null = null;\n private g: gremlin.process.GraphTraversalSource | null = null;\n\n // Tag Collections - cached in memory for performance\n private entityTypesCollection: Set<string> | null = null;\n\n\n constructor(\n private graphConfig: {\n host?: string;\n port?: number;\n storageBackend?: 'cassandra' | 'hbase' | 'berkeleydb';\n indexBackend?: 'elasticsearch' | 'solr' | 'lucene';\n },\n private envConfig: EnvironmentConfig\n ) {}\n \n async connect(): Promise<void> {\n // Configuration must be provided via constructor\n const host = this.graphConfig.host;\n if (!host) {\n throw new Error('JanusGraph host is required: provide in config');\n }\n\n const port = this.graphConfig.port;\n if (!port) {\n throw new Error('JanusGraph port is required: provide in config');\n }\n\n console.log(`Attempting to connect to JanusGraph at ws://${host}:${port}/gremlin`);\n\n this.connection = new DriverRemoteConnection(\n `ws://${host}:${port}/gremlin`,\n {}\n );\n\n this.g = traversal().withRemote(this.connection);\n\n // Test the connection with a simple query\n await this.g.V().limit(1).toList();\n\n this.connected = true;\n console.log('Successfully connected to JanusGraph');\n\n // Initialize schema if needed\n await this.initializeSchema();\n }\n \n async disconnect(): Promise<void> {\n if (this.connection) {\n await this.connection.close();\n }\n this.connected = false;\n }\n \n isConnected(): boolean {\n return this.connected;\n }\n \n private async initializeSchema(): Promise<void> {\n // Note: Schema management in JanusGraph typically requires direct access\n // to the management API, which isn't available through Gremlin.\n // In production, you'd run schema initialization scripts separately.\n console.log('Schema initialization would happen here in production');\n }\n \n // Helper function to convert vertex to Resource\n private vertexToResource(vertex: any): ResourceDescriptor {\n const props = vertex.properties || {};\n const id = this.getPropertyValue(props, 'id');\n\n // Validate required fields\n const creatorRaw = this.getPropertyValue(props, 'creator');\n const creationMethod = this.getPropertyValue(props, 'creationMethod');\n const contentChecksum = this.getPropertyValue(props, 'contentChecksum');\n const mediaType = this.getPropertyValue(props, 'contentType');\n\n if (!creatorRaw) throw new Error(`Resource ${id} missing required field: creator`);\n if (!creationMethod) throw new Error(`Resource ${id} missing required field: creationMethod`);\n if (!contentChecksum) throw new Error(`Resource ${id} missing required field: contentChecksum`);\n if (!mediaType) throw new Error(`Resource ${id} missing required field: contentType`);\n\n const creator = typeof creatorRaw === 'string' ? JSON.parse(creatorRaw) : creatorRaw;\n\n const resource: ResourceDescriptor = {\n '@context': 'https://schema.org/',\n '@id': id,\n name: this.getPropertyValue(props, 'name'),\n entityTypes: JSON.parse(this.getPropertyValue(props, 'entityTypes') || '[]'),\n representations: [{\n mediaType,\n checksum: contentChecksum,\n rel: 'original',\n }],\n archived: this.getPropertyValue(props, 'archived') === 'true',\n dateCreated: this.getPropertyValue(props, 'created'),\n wasAttributedTo: creator,\n creationMethod,\n };\n\n const sourceAnnotationId = this.getPropertyValue(props, 'sourceAnnotationId');\n const sourceResourceId = this.getPropertyValue(props, 'sourceResourceId');\n\n if (sourceAnnotationId) resource.sourceAnnotationId = sourceAnnotationId;\n if (sourceResourceId) resource.sourceResourceId = sourceResourceId;\n\n return resource;\n }\n \n // Helper to get property value from Gremlin vertex properties\n private getPropertyValue(props: any, key: string): any {\n if (!props[key]) return undefined;\n const prop = Array.isArray(props[key]) ? props[key][0] : props[key];\n return prop?.value || prop;\n }\n\n // Helper method to fetch annotations with their entity types\n private async fetchAnnotationsWithEntityTypes(annotationVertices: any[]): Promise<Annotation[]> {\n const annotations: Annotation[] = [];\n\n for (const vertex of annotationVertices) {\n const id = this.getPropertyValue(vertex.properties || {}, 'id');\n\n // Fetch entity types for this annotation\n const entityTypeVertices = await this.g!\n .V()\n .has('Annotation', 'id', id)\n .out('TAGGED_AS')\n .has('EntityType')\n .toList();\n\n const entityTypes = entityTypeVertices.map((v: any) =>\n this.getPropertyValue(v.properties || {}, 'name')\n ).filter(Boolean);\n\n annotations.push(this.vertexToAnnotation(vertex, entityTypes));\n }\n\n return annotations;\n }\n\n // Helper function to convert vertex to Annotation\n private vertexToAnnotation(vertex: any, entityTypes: string[] = []): Annotation {\n const props = vertex.properties || {};\n\n // Derive motivation from type if not present (backward compatibility)\n const motivation = this.getPropertyValue(props, 'motivation') || 'linking';\n\n // Parse creator - always stored as JSON string in DB\n const creatorJson = this.getPropertyValue(props, 'creator');\n const creator = JSON.parse(creatorJson);\n\n // Reconstruct body array from entity tags and linking body\n const bodyArray: Array<{type: 'TextualBody'; value: string; purpose: 'tagging'} | {type: 'SpecificResource'; source: string; purpose: 'linking'}> = [];\n\n // Add entity tag bodies (TextualBody with purpose: \"tagging\")\n for (const entityType of entityTypes) {\n if (entityType) {\n bodyArray.push({\n type: 'TextualBody' as const,\n value: entityType,\n purpose: 'tagging' as const,\n });\n }\n }\n\n // Add linking body (SpecificResource) if annotation is resolved\n const bodySource = this.getPropertyValue(props, 'source');\n if (bodySource) {\n bodyArray.push({\n type: 'SpecificResource' as const,\n source: bodySource,\n purpose: 'linking' as const,\n });\n }\n\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: this.getPropertyValue(props, 'id'),\n motivation,\n target: {\n source: this.getPropertyValue(props, 'resourceId'),\n selector: JSON.parse(this.getPropertyValue(props, 'selector') || '{}'),\n },\n body: bodyArray,\n creator,\n created: this.getPropertyValue(props, 'created'), // ISO string from DB\n };\n\n // W3C Web Annotation modification tracking\n const modified = this.getPropertyValue(props, 'modified');\n if (modified) {\n annotation.modified = modified;\n }\n\n const generatorJson = this.getPropertyValue(props, 'generator');\n if (generatorJson) {\n try {\n annotation.generator = JSON.parse(generatorJson);\n } catch (e) {\n // Ignore parse errors\n }\n }\n\n return annotation;\n }\n\n async createResource(resource: ResourceDescriptor): Promise<ResourceDescriptor> {\n const id = getResourceId(resource);\n const primaryRep = getPrimaryRepresentation(resource);\n if (!primaryRep) {\n throw new Error('Resource must have at least one representation');\n }\n\n // Create vertex in JanusGraph using fields from ResourceDescriptor\n const vertex = this.g!\n .addV('Resource')\n .property('id', id)\n .property('name', resource.name)\n .property('entityTypes', JSON.stringify(resource.entityTypes))\n .property('contentType', primaryRep.mediaType)\n .property('archived', resource.archived || false)\n .property('created', resource.dateCreated)\n .property('creator', JSON.stringify(resource.wasAttributedTo))\n .property('creationMethod', resource.creationMethod)\n .property('contentChecksum', primaryRep.checksum);\n\n if (resource.sourceAnnotationId) {\n vertex.property('sourceAnnotationId', resource.sourceAnnotationId);\n }\n if (resource.sourceResourceId) {\n vertex.property('sourceResourceId', resource.sourceResourceId);\n }\n\n await vertex.next();\n\n console.log('Created resource vertex in JanusGraph:', id);\n return resource;\n }\n \n async getResource(id: ResourceUri): Promise<ResourceDescriptor | null> {\n const vertices = await this.g!\n .V()\n .has('Resource', 'id', id)\n .toList();\n\n if (vertices.length === 0) {\n return null;\n }\n\n return this.vertexToResource(vertices[0] as any);\n }\n \n async updateResource(id: ResourceUri, input: UpdateResourceInput): Promise<ResourceDescriptor> {\n // Resources are immutable - only archiving is allowed\n if (Object.keys(input).length !== 1 || input.archived === undefined) {\n throw new Error('Resources are immutable. Only archiving is allowed.');\n }\n\n await this.g!\n .V()\n .has('Resource', 'id', id)\n .property('archived', input.archived)\n .next();\n\n const updatedResource = await this.getResource(id);\n if (!updatedResource) {\n throw new Error('Resource not found');\n }\n\n return updatedResource;\n }\n \n async deleteResource(id: ResourceUri): Promise<void> {\n // Delete the vertex and all its edges\n await this.g!\n .V()\n .has('Resource', 'id', id)\n .drop()\n .next();\n\n console.log('Deleted resource from JanusGraph:', id);\n }\n \n async listResources(filter: ResourceFilter): Promise<{ resources: ResourceDescriptor[]; total: number }> {\n let traversalQuery = this.g!.V().hasLabel('Resource');\n\n // Apply filters\n if (filter.search) {\n // Note: This is a simple text search. In production, you'd use\n // JanusGraph's full-text search capabilities with Elasticsearch\n traversalQuery = traversalQuery.has('name', gremlin.process.TextP.containing(filter.search));\n }\n\n const docs = await traversalQuery.toList();\n let resources = docs.map((v: any) => this.vertexToResource(v));\n\n // Apply entity type filtering after retrieval since JanusGraph stores as JSON\n if (filter.entityTypes && filter.entityTypes.length > 0) {\n resources = resources.filter(doc =>\n filter.entityTypes!.some((type: string) => doc.entityTypes?.includes(type))\n );\n }\n\n const total = resources.length;\n const offset = filter.offset || 0;\n const limit = filter.limit || 50;\n\n return {\n resources: resources.slice(offset, offset + limit),\n total\n };\n }\n \n async searchResources(query: string, limit?: number): Promise<ResourceDescriptor[]> {\n const result = await this.listResources({ search: query, limit: limit || 10 });\n return result.resources;\n }\n \n async createAnnotation(input: CreateAnnotationInternal): Promise<Annotation> {\n const id = this.generateId();\n\n // Only linking motivation with SpecificResource or empty array (stub)\n const motivation = input.motivation;\n\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id,\n motivation,\n target: input.target,\n body: input.body,\n creator: input.creator,\n created: new Date().toISOString(),\n };\n\n // Extract source from body using helper\n const bodySource = getBodySource(input.body);\n const entityTypes = getEntityTypes(input);\n const bodyType = Array.isArray(input.body) ? 'SpecificResource' : input.body.type;\n\n // Extract target source and selector\n const targetSource = typeof input.target === 'string' ? input.target : input.target.source;\n const targetSelector = typeof input.target === 'string' ? undefined : input.target.selector;\n\n // Create annotation vertex\n const vertex = this.g!\n .addV('Annotation')\n .property('id', id)\n .property('resourceId', targetSource) // Store full URI\n .property('text', targetSelector ? getExactText(targetSelector) : '')\n .property('selector', JSON.stringify(targetSelector || {}))\n .property('type', bodyType)\n .property('motivation', motivation)\n .property('creator', JSON.stringify(input.creator))\n .property('created', annotation.created);\n\n if (bodySource) {\n vertex.property('source', bodySource);\n }\n\n const annVertex = await vertex.next();\n\n // Create edge from annotation to resource (BELONGS_TO)\n await this.g!\n .V(annVertex.value)\n .addE('BELONGS_TO')\n .to(this.g!.V().has('Resource', 'id', targetSource))\n .next();\n\n // If it's a resolved reference, create edge to target resource\n if (bodySource) {\n await this.g!\n .V(annVertex.value)\n .addE('REFERENCES')\n .to(this.g!.V().has('Resource', 'id', bodySource))\n .next();\n }\n\n // Create TAGGED_AS relationships for entity types\n for (const entityType of entityTypes) {\n // Get or create EntityType vertex\n const etResults = await this.g!\n .V()\n .has('EntityType', 'name', entityType)\n .toList();\n\n let etVertex;\n if (etResults.length === 0) {\n // Create new EntityType vertex\n etVertex = await this.g!\n .addV('EntityType')\n .property('name', entityType)\n .next();\n } else {\n etVertex = { value: etResults[0] };\n }\n\n // Create TAGGED_AS edge from Annotation to EntityType\n await this.g!\n .V(annVertex.value)\n .addE('TAGGED_AS')\n .to(this.g!.V(etVertex.value))\n .next();\n }\n\n console.log('Created annotation in JanusGraph:', id);\n return annotation;\n }\n \n async getAnnotation(id: AnnotationUri): Promise<Annotation | null> {\n const vertices = await this.g!\n .V()\n .has('Annotation', 'id', id)\n .toList();\n\n if (vertices.length === 0) {\n return null;\n }\n\n // Fetch entity types from TAGGED_AS relationships\n const entityTypeVertices = await this.g!\n .V()\n .has('Annotation', 'id', id)\n .out('TAGGED_AS')\n .has('EntityType')\n .toList();\n\n const entityTypes = entityTypeVertices.map((v: any) =>\n this.getPropertyValue(v.properties || {}, 'name')\n ).filter(Boolean);\n\n return this.vertexToAnnotation(vertices[0] as any, entityTypes);\n }\n \n async updateAnnotation(id: AnnotationUri, updates: Partial<Annotation>): Promise<Annotation> {\n const traversalQuery = this.g!\n .V()\n .has('Annotation', 'id', id);\n\n // Update target properties\n if (updates.target !== undefined && typeof updates.target !== 'string') {\n if (updates.target.selector !== undefined) {\n await traversalQuery.property('text', getExactText(updates.target.selector)).next();\n await traversalQuery.property('selector', JSON.stringify(updates.target.selector)).next();\n }\n }\n\n // Update body properties and entity types\n if (updates.body !== undefined) {\n const bodySource = getBodySource(updates.body);\n const entityTypes = getEntityTypes({ body: updates.body });\n\n if (bodySource) {\n await traversalQuery.property('source', bodySource).next();\n }\n\n // Update entity type relationships - remove old ones and create new ones\n if (entityTypes.length >= 0) {\n // Remove existing TAGGED_AS edges\n await this.g!\n .V()\n .has('Annotation', 'id', id)\n .outE('TAGGED_AS')\n .drop()\n .iterate();\n\n // Create new TAGGED_AS edges\n for (const entityType of entityTypes) {\n // Get or create EntityType vertex\n const etResults = await this.g!\n .V()\n .has('EntityType', 'name', entityType)\n .toList();\n\n let etVertex;\n if (etResults.length === 0) {\n // Create new EntityType vertex\n etVertex = await this.g!\n .addV('EntityType')\n .property('name', entityType)\n .next();\n } else {\n etVertex = { value: etResults[0] };\n }\n\n // Create TAGGED_AS edge from Annotation to EntityType\n const annVertices = await this.g!\n .V()\n .has('Annotation', 'id', id)\n .toList();\n\n if (annVertices.length > 0) {\n await this.g!\n .V(annVertices[0])\n .addE('TAGGED_AS')\n .to(this.g!.V(etVertex.value))\n .next();\n }\n }\n }\n }\n\n if (updates.modified !== undefined) {\n await traversalQuery.property('modified', updates.modified).next();\n }\n if (updates.generator !== undefined) {\n await traversalQuery.property('generator', JSON.stringify(updates.generator)).next();\n }\n\n const updatedAnnotation = await this.getAnnotation(id);\n if (!updatedAnnotation) {\n throw new Error('Annotation not found');\n }\n\n return updatedAnnotation;\n }\n \n async deleteAnnotation(id: AnnotationUri): Promise<void> {\n await this.g!\n .V()\n .has('Annotation', 'id', id)\n .drop()\n .next();\n\n console.log('Deleted annotation from JanusGraph:', id);\n }\n \n async listAnnotations(filter: { resourceId?: ResourceId; type?: AnnotationCategory }): Promise<{ annotations: Annotation[]; total: number }> {\n let traversalQuery = this.g!.V().hasLabel('Annotation');\n\n // Apply filters\n if (filter.resourceId) {\n traversalQuery = traversalQuery.has('resourceId', filter.resourceId);\n }\n\n if (filter.type) {\n const w3cType = filter.type === 'highlight' ? 'TextualBody' : 'SpecificResource';\n traversalQuery = traversalQuery.has('type', w3cType);\n }\n\n const vertices = await traversalQuery.toList();\n const annotations = await this.fetchAnnotationsWithEntityTypes(vertices);\n\n return {\n annotations,\n total: annotations.length\n };\n }\n\n async getHighlights(resourceId: ResourceId): Promise<Annotation[]> {\n const { annotations } = await this.listAnnotations({\n resourceId,\n type: 'highlight'\n });\n return annotations;\n }\n\n async resolveReference(annotationId: AnnotationId, source: ResourceId): Promise<Annotation> {\n const publicURL = this.envConfig.services.backend!.publicURL;\n const annotation = await this.getAnnotation(annotationIdToURI(annotationId, publicURL));\n if (!annotation) throw new Error('Annotation not found');\n\n // TODO Preserve existing TextualBody entities, add SpecificResource\n // For now, just update with SpecificResource (losing entity tags)\n await this.updateAnnotation(annotationIdToURI(annotationId, publicURL), {\n body: [\n {\n type: 'SpecificResource',\n source,\n purpose: 'linking' as const,\n },\n ],\n });\n\n // Create edge from annotation to target resource\n await this.g!\n .V()\n .has('Annotation', 'id', annotationId)\n .addE('REFERENCES')\n .to(this.g!.V().has('Resource', 'id', source))\n .next();\n\n const updatedAnnotation = await this.getAnnotation(annotationIdToURI(annotationId, publicURL));\n if (!updatedAnnotation) {\n throw new Error('Annotation not found after update');\n }\n\n return updatedAnnotation;\n }\n\n async getReferences(resourceId: ResourceId): Promise<Annotation[]> {\n const { annotations } = await this.listAnnotations({\n resourceId,\n type: 'reference'\n });\n return annotations;\n }\n\n async getEntityReferences(resourceId: ResourceId, entityTypes?: string[]): Promise<Annotation[]> {\n const { annotations } = await this.listAnnotations({\n resourceId,\n type: 'reference'\n });\n\n // TODO Extract entity types from body using helper\n if (entityTypes && entityTypes.length > 0) {\n return annotations.filter(ann => {\n const annEntityTypes = getEntityTypes(ann);\n return annEntityTypes.some((type: string) => entityTypes.includes(type));\n });\n }\n\n return annotations.filter(ann => getEntityTypes(ann).length > 0);\n }\n\n async getResourceAnnotations(resourceId: ResourceId): Promise<Annotation[]> {\n const { annotations } = await this.listAnnotations({ resourceId });\n return annotations;\n }\n\n async getResourceReferencedBy(resourceUri: ResourceUri, _motivation?: string): Promise<Annotation[]> {\n // Find annotations that reference this resource\n const vertices = await this.g!\n .V()\n .hasLabel('Annotation')\n .has('source', resourceUri)\n .toList();\n\n return await this.fetchAnnotationsWithEntityTypes(vertices);\n }\n \n async getResourceConnections(resourceId: ResourceId): Promise<GraphConnection[]> {\n // Use Gremlin to find connected resources\n const paths = await this.g!\n .V()\n .has('Resource', 'id', resourceId)\n .inE('BELONGS_TO')\n .outV()\n .outE('REFERENCES')\n .inV()\n .path()\n .toList();\n\n // Convert paths to connections\n // This is simplified - real implementation would process paths properly\n console.log('Found paths:', paths.length);\n\n // For now, also build connections from references\n const connections: GraphConnection[] = [];\n const refs = await this.getReferences(resourceId);\n\n for (const ref of refs) {\n // Extract source from body using helper\n const bodySource = getBodySource(ref.body);\n if (bodySource) {\n const targetDoc = await this.getResource(resourceUri(bodySource));\n if (targetDoc) {\n const existing = connections.find(c => c.targetResource.id === targetDoc.id);\n if (existing) {\n existing.annotations.push(ref);\n } else {\n connections.push({\n targetResource: targetDoc,\n annotations: [ref],\n relationshipType: undefined,\n bidirectional: false,\n });\n }\n }\n }\n }\n\n return connections;\n }\n \n async findPath(_fromResourceId: string, _toResourceId: string, _maxDepth?: number): Promise<GraphPath[]> {\n // TODO: Implement real graph traversal with JanusGraph\n // For now, return empty array\n return [];\n }\n \n async getEntityTypeStats(): Promise<EntityTypeStats[]> {\n const docs = await this.g!.V().hasLabel('Resource').toList();\n const resources = docs.map((v: any) => this.vertexToResource(v));\n\n const stats = new Map<string, number>();\n\n for (const doc of resources) {\n for (const type of doc.entityTypes || []) {\n stats.set(type, (stats.get(type) || 0) + 1);\n }\n }\n\n return Array.from(stats.entries()).map(([type, count]) => ({ type, count }));\n }\n \n async getStats(): Promise<any> {\n const entityTypes: Record<string, number> = {};\n const contentTypes: Record<string, number> = {};\n\n // Get all resources\n const docs = await this.g!.V().hasLabel('Resource').toList();\n const resources = docs.map((v: any) => this.vertexToResource(v));\n\n for (const doc of resources) {\n for (const type of doc.entityTypes || []) {\n entityTypes[type] = (entityTypes[type] || 0) + 1;\n }\n const primaryRep = getPrimaryRepresentation(doc);\n if (primaryRep?.mediaType) {\n contentTypes[primaryRep.mediaType] = (contentTypes[primaryRep.mediaType] || 0) + 1;\n }\n }\n\n // Get all annotations\n const anns = await this.g!.V().hasLabel('Annotation').toList();\n const annotations = await this.fetchAnnotationsWithEntityTypes(anns);\n\n const highlights = annotations.filter(a => a.motivation === 'highlighting');\n const references = annotations.filter(a => a.motivation === 'linking');\n const entityReferences = references.filter(a => getEntityTypes(a).length > 0);\n\n return {\n resourceCount: resources.length,\n annotationCount: annotations.length,\n highlightCount: highlights.length,\n referenceCount: references.length,\n entityReferenceCount: entityReferences.length,\n entityTypes,\n contentTypes,\n };\n }\n\n async createAnnotations(inputs: CreateAnnotationInternal[]): Promise<Annotation[]> {\n const results = [];\n for (const input of inputs) {\n results.push(await this.createAnnotation(input));\n }\n return results;\n }\n\n async resolveReferences(inputs: Array<{ annotationId: AnnotationId; source: ResourceId }>): Promise<Annotation[]> {\n const results = [];\n for (const input of inputs) {\n results.push(await this.resolveReference(input.annotationId, input.source));\n }\n return results;\n }\n\n async detectAnnotations(_resourceId: ResourceId): Promise<Annotation[]> {\n // Auto-detection would analyze resource content\n return [];\n }\n \n async getEntityTypes(): Promise<string[]> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n return Array.from(this.entityTypesCollection!).sort();\n }\n \n async addEntityType(tag: string): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n this.entityTypesCollection!.add(tag);\n\n // Persist to JanusGraph\n try {\n // Find or create the TagCollection vertex\n const existing = await this.g!.V()\n .hasLabel('TagCollection')\n .has('type', 'entity-types')\n .toList();\n\n if (existing.length > 0) {\n // Update existing collection\n await this.g!.V(existing[0])\n .property('tags', JSON.stringify(Array.from(this.entityTypesCollection!)))\n .next();\n } else {\n // Create new collection\n await this.g!.addV('TagCollection')\n .property('type', 'entity-types')\n .property('tags', JSON.stringify(Array.from(this.entityTypesCollection!)))\n .next();\n }\n } catch (error) {\n console.error('Failed to add entity type:', error);\n }\n }\n\n async addEntityTypes(tags: string[]): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n tags.forEach(tag => this.entityTypesCollection!.add(tag));\n\n // Persist all at once\n try {\n const existing = await this.g!.V()\n .hasLabel('TagCollection')\n .has('type', 'entity-types')\n .toList();\n\n if (existing.length > 0) {\n await this.g!.V(existing[0])\n .property('tags', JSON.stringify(Array.from(this.entityTypesCollection!)))\n .next();\n } else {\n await this.g!.addV('TagCollection')\n .property('type', 'entity-types')\n .property('tags', JSON.stringify(Array.from(this.entityTypesCollection!)))\n .next();\n }\n } catch (error) {\n console.error('Failed to add entity types:', error);\n }\n }\n\n private async initializeTagCollections(): Promise<void> {\n // Load existing collections from JanusGraph\n const collections = await this.g!.V()\n .hasLabel('TagCollection')\n .toList();\n\n let entityTypesFromDb: string[] = [];\n\n for (const vertex of collections) {\n const props = (vertex as any).properties || {};\n const type = this.getPropertyValue(props, 'type');\n const tagsJson = this.getPropertyValue(props, 'tags');\n const tags = tagsJson ? JSON.parse(tagsJson) : [];\n\n if (type === 'entity-types') {\n entityTypesFromDb = tags;\n }\n }\n\n // Load defaults\n const { DEFAULT_ENTITY_TYPES } = await import('@semiont/ontology');\n\n // Merge with defaults\n this.entityTypesCollection = new Set([...DEFAULT_ENTITY_TYPES, ...entityTypesFromDb]);\n\n // Persist merged collection back to JanusGraph if it doesn't exist\n if (entityTypesFromDb.length === 0) {\n await this.addEntityTypes([]);\n }\n }\n\n generateId(): string {\n return uuidv4().replace(/-/g, '').substring(0, 12);\n }\n \n async clearDatabase(): Promise<void> {\n // Drop all vertices in JanusGraph\n await this.g!.V().drop().next();\n // Reset cached collections\n this.entityTypesCollection = null;\n console.log('Cleared JanusGraph database');\n }\n}","// In-memory implementation of GraphDatabase interface\n// Used for development and testing without requiring a real graph database\n\nimport { GraphDatabase } from '../interface';\nimport { getResourceEntityTypes } from '@semiont/api-client';\nimport { getEntityTypes } from '@semiont/ontology';\nimport type { components } from '@semiont/api-client';\nimport type {\n AnnotationCategory,\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n ResourceFilter,\n UpdateResourceInput,\n CreateAnnotationInternal,\n ResourceId,\n AnnotationId,\n} from '@semiont/core';\nimport { resourceId as makeResourceId } from '@semiont/core';\nimport type { ResourceUri, AnnotationUri } from '@semiont/api-client';\nimport { resourceUri } from '@semiont/api-client';\nimport { v4 as uuidv4 } from 'uuid';\nimport { getBodySource, getTargetSource } from '@semiont/api-client';\nimport { getResourceId, getPrimaryRepresentation } from '@semiont/api-client';\n\ntype ResourceDescriptor = components['schemas']['ResourceDescriptor'];\ntype Annotation = components['schemas']['Annotation'];\n\n// Simple in-memory storage using Maps\n// Useful for development and testing\n\nexport class MemoryGraphDatabase implements GraphDatabase {\n private connected: boolean = false;\n \n // In-memory storage using Maps\n private resources: Map<string, ResourceDescriptor> = new Map();\n private annotations: Map<string, Annotation> = new Map();\n \n constructor(config: any = {}) {\n // Config is ignored for in-memory implementation\n void config;\n }\n \n async connect(): Promise<void> {\n // No actual connection needed for in-memory storage\n console.log('Using in-memory graph database...');\n this.connected = true;\n }\n \n async disconnect(): Promise<void> {\n // Nothing to close for in-memory storage\n this.connected = false;\n }\n \n isConnected(): boolean {\n return this.connected;\n }\n\n async createResource(resource: ResourceDescriptor): Promise<ResourceDescriptor> {\n const id = getResourceId(resource);\n if (!id) {\n throw new Error('Resource must have an id');\n }\n\n // Simply add to in-memory map\n // await this.client.submit(`\n // graph.tx().rollback()\n // g.addV('Resource')\n // .property('id', id)\n // .property('name', name)\n // .property('entityTypes', entityTypes)\n // .property('contentType', contentType)\n // .property('created', created)\n // .property('updatedAt', updatedAt)\n // graph.tx().commit()\n // `, { id, name, entityTypes, ... });\n\n this.resources.set(id, resource);\n return resource;\n }\n \n async getResource(id: ResourceUri): Promise<ResourceDescriptor | null> {\n // Simply retrieve from map\n // const result = await this.client.submit(`\n // g.V().hasLabel('Resource').has('id', id).valueMap(true)\n // `, { id });\n\n return this.resources.get(id) || null;\n }\n\n async updateResource(id: ResourceUri, input: UpdateResourceInput): Promise<ResourceDescriptor> {\n // Resources are immutable - only archiving is allowed\n if (Object.keys(input).length !== 1 || input.archived === undefined) {\n throw new Error('Resources are immutable. Only archiving is allowed.');\n }\n\n const doc = this.resources.get(id);\n if (!doc) throw new Error('Resource not found');\n\n doc.archived = input.archived;\n return doc;\n }\n \n async deleteResource(id: ResourceUri): Promise<void> {\n // Simply delete from map\n // await this.client.submit(`\n // graph.tx().rollback()\n // g.V().has('id', id).drop()\n // graph.tx().commit()\n // `, { id });\n \n this.resources.delete(id);\n \n // Delete annotations\n for (const [selId, sel] of this.annotations) {\n if (getTargetSource(sel.target) === id || getBodySource(sel.body) === id) {\n this.annotations.delete(selId);\n }\n }\n }\n \n async listResources(filter: ResourceFilter): Promise<{ resources: ResourceDescriptor[]; total: number }> {\n let docs = Array.from(this.resources.values());\n\n if (filter.entityTypes && filter.entityTypes.length > 0) {\n docs = docs.filter(doc =>\n doc.entityTypes && doc.entityTypes.some((type: string) => filter.entityTypes!.includes(type))\n );\n }\n\n if (filter.search) {\n const searchLower = filter.search.toLowerCase();\n docs = docs.filter(doc =>\n doc.name.toLowerCase().includes(searchLower)\n );\n }\n\n const total = docs.length;\n const offset = filter.offset || 0;\n const limit = filter.limit || 20;\n docs = docs.slice(offset, offset + limit);\n\n return { resources: docs, total };\n }\n\n async searchResources(query: string, limit: number = 20): Promise<ResourceDescriptor[]> {\n // Simple text search in memory\n // const results = await this.client.submit(`\n // g.V().has('Resource', 'name', textContains(query)).limit(limit).valueMap(true)\n // `, { query, limit });\n\n const searchLower = query.toLowerCase();\n const results = Array.from(this.resources.values())\n .filter(doc => doc.name.toLowerCase().includes(searchLower))\n .slice(0, limit);\n \n return results;\n }\n \n async createAnnotation(input: CreateAnnotationInternal): Promise<Annotation> {\n const id = this.generateId();\n\n // Only linking motivation with SpecificResource or empty array (stub)\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id,\n motivation: input.motivation,\n target: input.target,\n body: input.body,\n creator: input.creator,\n created: new Date().toISOString(),\n };\n\n this.annotations.set(id, annotation);\n console.log('Memory: Created annotation:', {\n id,\n motivation: annotation.motivation,\n hasSource: !!getBodySource(annotation.body),\n targetSource: getTargetSource(annotation.target)\n });\n return annotation;\n }\n \n async getAnnotation(id: AnnotationUri): Promise<Annotation | null> {\n return this.annotations.get(id) || null;\n }\n \n async updateAnnotation(id: AnnotationUri, updates: Partial<Annotation>): Promise<Annotation> {\n const annotation = this.annotations.get(id);\n if (!annotation) throw new Error('Annotation not found');\n\n const updated: Annotation = {\n ...annotation,\n ...updates,\n };\n\n // Motivation should come from updates if provided\n // No need to derive from body type\n\n this.annotations.set(id, updated);\n return updated;\n }\n \n async deleteAnnotation(id: AnnotationUri): Promise<void> {\n this.annotations.delete(id);\n }\n \n async listAnnotations(filter: { resourceId?: ResourceId; type?: AnnotationCategory }): Promise<{ annotations: Annotation[]; total: number }> {\n let results = Array.from(this.annotations.values());\n\n if (filter.resourceId) {\n const resourceIdStr = String(filter.resourceId);\n results = results.filter(a => {\n const targetSource = getTargetSource(a.target);\n return targetSource === resourceIdStr || targetSource === resourceUri(resourceIdStr);\n });\n }\n\n // Only SpecificResource supported, use motivation to distinguish\n if (filter.type) {\n const motivation = filter.type === 'highlight' ? 'highlighting' : 'linking';\n results = results.filter(a => a.motivation === motivation);\n }\n\n return { annotations: results, total: results.length };\n }\n \n \n async getHighlights(resourceId: ResourceId): Promise<Annotation[]> {\n const resourceIdStr = String(resourceId);\n const highlights = Array.from(this.annotations.values())\n .filter(sel => {\n const targetSource = getTargetSource(sel.target);\n return (targetSource === resourceIdStr || targetSource === resourceUri(resourceIdStr)) && sel.motivation === 'highlighting';\n });\n console.log(`Memory: getHighlights for ${resourceId} found ${highlights.length} highlights`);\n return highlights;\n }\n\n async resolveReference(annotationId: AnnotationId, source: ResourceId): Promise<Annotation> {\n const annotation = this.annotations.get(annotationId);\n if (!annotation) throw new Error('Annotation not found');\n\n // Convert stub (empty array) to resolved SpecificResource\n const updated: Annotation = {\n ...annotation,\n body: {\n type: 'SpecificResource',\n source,\n purpose: 'linking',\n },\n };\n\n this.annotations.set(annotationId, updated);\n return updated;\n }\n\n async getReferences(resourceId: ResourceId): Promise<Annotation[]> {\n const resourceIdStr = String(resourceId);\n const references = Array.from(this.annotations.values())\n .filter(sel => {\n const targetSource = getTargetSource(sel.target);\n return (targetSource === resourceIdStr || targetSource === resourceUri(resourceIdStr)) && sel.motivation === 'linking';\n });\n console.log(`Memory: getReferences for ${resourceId} found ${references.length} references`);\n references.forEach(ref => {\n console.log(' Reference:', {\n id: ref.id,\n source: getBodySource(ref.body),\n entityTypes: getEntityTypes(ref) // from body\n });\n });\n return references;\n }\n\n async getEntityReferences(resourceId: ResourceId, entityTypes?: string[]): Promise<Annotation[]> {\n // TODO Extract entity types from body\n const resourceIdStr = String(resourceId);\n let refs = Array.from(this.annotations.values())\n .filter(sel => {\n const selEntityTypes = getEntityTypes(sel);\n const targetSource = getTargetSource(sel.target);\n return (targetSource === resourceIdStr || targetSource === resourceUri(resourceIdStr)) && selEntityTypes.length > 0;\n });\n\n if (entityTypes && entityTypes.length > 0) {\n refs = refs.filter(sel => {\n const selEntityTypes = getEntityTypes(sel);\n return selEntityTypes.some((type: string) => entityTypes.includes(type));\n });\n }\n\n return refs;\n }\n\n async getResourceAnnotations(resourceId: ResourceId): Promise<Annotation[]> {\n const resourceIdStr = String(resourceId);\n return Array.from(this.annotations.values())\n .filter(sel => {\n const targetSource = getTargetSource(sel.target);\n return targetSource === resourceIdStr || targetSource === resourceUri(resourceIdStr);\n });\n }\n\n async getResourceReferencedBy(resourceUri: ResourceUri, _motivation?: string): Promise<Annotation[]> {\n return Array.from(this.annotations.values())\n .filter(sel => getBodySource(sel.body) === resourceUri);\n }\n \n async getResourceConnections(resourceId: ResourceId): Promise<GraphConnection[]> {\n // Simple in-memory traversal\n // const results = await this.client.submit(`\n // g.V().has('id', resourceId)\n // .bothE('REFERENCES').as('e')\n // .otherV().as('v')\n // .select('e', 'v')\n // `, { resourceId });\n \n const connections: GraphConnection[] = [];\n const refs = await this.getReferences(resourceId);\n \n for (const ref of refs) {\n const bodySource = getBodySource(ref.body);\n if (bodySource) {\n const targetDoc = await this.getResource(resourceUri(bodySource));\n if (targetDoc) {\n const reverseRefs = await this.getReferences(makeResourceId(bodySource));\n const resourceIdStr = String(resourceId);\n const bidirectional = reverseRefs.some(r => {\n const reverseBodySource = getBodySource(r.body);\n return reverseBodySource === resourceIdStr || reverseBodySource === resourceUri(resourceIdStr);\n });\n\n connections.push({\n targetResource: targetDoc,\n annotations: [ref],\n bidirectional,\n });\n }\n }\n }\n \n return connections;\n }\n \n async findPath(fromResourceId: string, toResourceId: string, maxDepth: number = 5): Promise<GraphPath[]> {\n // Path finding not implemented in memory version\n // const results = await this.client.submit(`\n // g.V().has('id', fromResourceId)\n // .repeat(both().simplePath()).times(maxDepth).emit()\n // .has('id', toResourceId)\n // .path()\n // .by(valueMap(true))\n // .limit(10)\n // `, { fromResourceId, toResourceId, maxDepth });\n\n // Using BFS implementation for stub\n const visited = new Set<string>();\n const queue: { docId: string; path: ResourceDescriptor[]; sels: Annotation[] }[] = [];\n const fromDoc = await this.getResource(resourceUri(fromResourceId));\n\n if (!fromDoc) return [];\n\n queue.push({ docId: fromResourceId, path: [fromDoc], sels: [] });\n visited.add(fromResourceId);\n\n const paths: GraphPath[] = [];\n\n while (queue.length > 0 && paths.length < 10) {\n const { docId, path, sels } = queue.shift()!;\n\n if (path.length > maxDepth) continue;\n\n if (docId === toResourceId) {\n paths.push({ resources: path, annotations: sels });\n continue;\n }\n\n const connections = await this.getResourceConnections(makeResourceId(docId));\n\n for (const conn of connections) {\n const targetId = getResourceId(conn.targetResource);\n if (targetId && !visited.has(targetId)) {\n visited.add(targetId);\n queue.push({\n docId: targetId,\n path: [...path, conn.targetResource],\n sels: [...sels, ...conn.annotations],\n });\n }\n }\n }\n\n return paths;\n }\n \n async getEntityTypeStats(): Promise<EntityTypeStats[]> {\n // Simple in-memory statistics\n // const results = await this.client.submit(`\n // g.V().hasLabel('Resource')\n // .values('entityTypes').unfold()\n // .groupCount()\n // `);\n\n const typeCounts = new Map<string, number>();\n\n for (const doc of this.resources.values()) {\n const types = getResourceEntityTypes(doc);\n for (const type of types) {\n typeCounts.set(type, (typeCounts.get(type) || 0) + 1);\n }\n }\n \n return Array.from(typeCounts.entries()).map(([type, count]) => ({\n type,\n count,\n }));\n }\n \n async getStats(): Promise<{\n resourceCount: number;\n annotationCount: number;\n highlightCount: number;\n referenceCount: number;\n entityReferenceCount: number;\n entityTypes: Record<string, number>;\n contentTypes: Record<string, number>;\n }> {\n const entityTypes: Record<string, number> = {};\n const contentTypes: Record<string, number> = {};\n\n for (const doc of this.resources.values()) {\n for (const type of doc.entityTypes || []) {\n entityTypes[type] = (entityTypes[type] || 0) + 1;\n }\n const primaryRep = getPrimaryRepresentation(doc);\n if (primaryRep?.mediaType) {\n contentTypes[primaryRep.mediaType] = (contentTypes[primaryRep.mediaType] || 0) + 1;\n }\n }\n \n const annotations = Array.from(this.annotations.values());\n // Use motivation to distinguish types\n const highlightCount = annotations.filter(a => a.motivation === 'highlighting').length;\n const referenceCount = annotations.filter(a => a.motivation === 'linking').length;\n // TODO Extract entity types from body\n const entityReferenceCount = annotations.filter(a => a.motivation === 'linking' && getEntityTypes(a).length > 0).length;\n \n return {\n resourceCount: this.resources.size,\n annotationCount: this.annotations.size,\n highlightCount,\n referenceCount,\n entityReferenceCount,\n entityTypes,\n contentTypes,\n };\n }\n \n async createAnnotations(inputs: CreateAnnotationInternal[]): Promise<Annotation[]> {\n // In production: Use batch operations for better performance\n // const tx = graph.tx()\n // tx.rollback()\n // ... batch operations ...\n // tx.commit()\n \n const results: Annotation[] = [];\n for (const input of inputs) {\n results.push(await this.createAnnotation(input));\n }\n return results;\n }\n \n \n async resolveReferences(inputs: { annotationId: AnnotationId; source: ResourceId }[]): Promise<Annotation[]> {\n const results: Annotation[] = [];\n for (const input of inputs) {\n results.push(await this.resolveReference(input.annotationId, input.source));\n }\n return results;\n }\n \n async detectAnnotations(_resourceId: ResourceId): Promise<Annotation[]> {\n // This would use AI/ML to detect annotations in a resource\n // For now, return empty array as a placeholder\n return [];\n }\n \n // Tag Collections - stored as special vertices in the graph\n private entityTypesCollection: Set<string> | null = null;\n \n async getEntityTypes(): Promise<string[]> {\n // Initialize if not already loaded\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n return Array.from(this.entityTypesCollection!).sort();\n }\n\n async addEntityType(tag: string): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n this.entityTypesCollection!.add(tag);\n // Simply add to set\n // await this.client.submit(`g.V().has('tagCollection', 'type', 'entity-types')\n // .property(set, 'tags', '${tag}')`, {});\n }\n\n async addEntityTypes(tags: string[]): Promise<void> {\n if (this.entityTypesCollection === null) {\n await this.initializeTagCollections();\n }\n tags.forEach(tag => this.entityTypesCollection!.add(tag));\n // Simply add to set\n }\n \n private async initializeTagCollections(): Promise<void> {\n // Initialize in-memory collections\n // const result = await this.client.submit(\n // `g.V().has('tagCollection', 'type', 'entity-types')\n // .project('type', 'tags').by('type').by('tags')`, {}\n // );\n\n // For now, initialize with defaults if not present\n if (this.entityTypesCollection === null) {\n const { DEFAULT_ENTITY_TYPES } = await import('@semiont/ontology');\n this.entityTypesCollection = new Set(DEFAULT_ENTITY_TYPES);\n }\n }\n \n generateId(): string {\n return uuidv4().replace(/-/g, '').substring(0, 12);\n }\n \n async clearDatabase(): Promise<void> {\n // In production: CAREFUL! This would clear the entire graph\n // await this.client.submit(`g.V().drop()`);\n this.resources.clear();\n this.annotations.clear();\n this.entityTypesCollection = null;\n }\n}","// Factory for creating graph database instances based on configuration\n\nimport { GraphDatabase } from './interface';\nimport { NeptuneGraphDatabase } from './implementations/neptune';\nimport { Neo4jGraphDatabase } from './implementations/neo4j';\nimport { JanusGraphDatabase } from './implementations/janusgraph';\nimport { MemoryGraphDatabase } from './implementations/memorygraph';\nimport type { EnvironmentConfig } from '@semiont/core';\n\nexport type GraphDatabaseType = 'neptune' | 'neo4j' | 'janusgraph' | 'memory';\n\nexport interface GraphDatabaseConfig {\n type: GraphDatabaseType;\n \n // Neptune config\n neptuneEndpoint?: string;\n neptunePort?: number;\n neptuneRegion?: string;\n \n // Neo4j config\n neo4jUri?: string;\n neo4jUsername?: string;\n neo4jPassword?: string;\n neo4jDatabase?: string;\n \n // JanusGraph config\n janusHost?: string;\n janusPort?: number;\n janusStorageBackend?: 'cassandra' | 'hbase' | 'berkeleydb';\n janusIndexBackend?: 'elasticsearch' | 'solr' | 'lucene';\n}\n\n// Singleton instance\nlet graphDatabaseInstance: GraphDatabase | null = null;\n\nexport function createGraphDatabase(config: GraphDatabaseConfig, envConfig: EnvironmentConfig): GraphDatabase {\n switch (config.type) {\n case 'neptune': {\n const neptuneConfig: any = {};\n if (config.neptuneEndpoint !== undefined) neptuneConfig.endpoint = config.neptuneEndpoint;\n if (config.neptunePort !== undefined) neptuneConfig.port = config.neptunePort;\n if (config.neptuneRegion !== undefined) neptuneConfig.region = config.neptuneRegion;\n return new NeptuneGraphDatabase(neptuneConfig);\n }\n\n case 'neo4j': {\n const neo4jConfig: any = {};\n if (config.neo4jUri !== undefined) neo4jConfig.uri = config.neo4jUri;\n if (config.neo4jUsername !== undefined) neo4jConfig.username = config.neo4jUsername;\n if (config.neo4jPassword !== undefined) neo4jConfig.password = config.neo4jPassword;\n if (config.neo4jDatabase !== undefined) neo4jConfig.database = config.neo4jDatabase;\n return new Neo4jGraphDatabase(neo4jConfig);\n }\n\n case 'janusgraph': {\n const janusConfig: any = {};\n if (config.janusHost !== undefined) janusConfig.host = config.janusHost;\n if (config.janusPort !== undefined) janusConfig.port = config.janusPort;\n if (config.janusStorageBackend !== undefined) janusConfig.storageBackend = config.janusStorageBackend;\n if (config.janusIndexBackend !== undefined) janusConfig.indexBackend = config.janusIndexBackend;\n return new JanusGraphDatabase(janusConfig, envConfig);\n }\n\n case 'memory':\n return new MemoryGraphDatabase({});\n\n default:\n throw new Error(`Unsupported graph database type: ${config.type}`);\n }\n}\n\n// Helper function to evaluate environment variable placeholders\nfunction evaluateEnvVar(value: string | undefined): string | undefined {\n if (!value) return undefined;\n\n // Replace ${VAR_NAME} with actual environment variable value\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName];\n if (!envValue) {\n throw new Error(`Environment variable ${varName} is not set. Referenced in configuration as ${match}`);\n }\n return envValue;\n });\n}\n\nexport async function getGraphDatabase(envConfig: EnvironmentConfig): Promise<GraphDatabase> {\n if (!graphDatabaseInstance) {\n const graphConfig = envConfig.services.graph!;\n\n const config: GraphDatabaseConfig = {\n type: graphConfig.type,\n };\n\n // Apply configuration based on type\n if (graphConfig.type === 'janusgraph') {\n if (graphConfig.host) {\n config.janusHost = graphConfig.host;\n }\n if (graphConfig.port) {\n config.janusPort = graphConfig.port;\n }\n if (graphConfig.storage) {\n config.janusStorageBackend = graphConfig.storage as any;\n }\n if (graphConfig.index && graphConfig.index !== 'none') {\n config.janusIndexBackend = graphConfig.index as any;\n }\n } else if (graphConfig.type === 'neptune') {\n if (graphConfig.endpoint) {\n config.neptuneEndpoint = graphConfig.endpoint;\n }\n if (graphConfig.port) {\n config.neptunePort = graphConfig.port;\n }\n if (graphConfig.region) {\n config.neptuneRegion = graphConfig.region;\n }\n } else if (graphConfig.type === 'neo4j') {\n if (graphConfig.uri) {\n config.neo4jUri = evaluateEnvVar(graphConfig.uri);\n }\n if (graphConfig.username) {\n config.neo4jUsername = evaluateEnvVar(graphConfig.username);\n }\n if (graphConfig.password) {\n config.neo4jPassword = evaluateEnvVar(graphConfig.password);\n }\n if (graphConfig.database) {\n config.neo4jDatabase = evaluateEnvVar(graphConfig.database);\n }\n }\n\n graphDatabaseInstance = createGraphDatabase(config, envConfig);\n await graphDatabaseInstance.connect();\n }\n\n if (!graphDatabaseInstance.isConnected()) {\n await graphDatabaseInstance.connect();\n }\n\n return graphDatabaseInstance;\n}\n\nexport async function closeGraphDatabase(): Promise<void> {\n if (graphDatabaseInstance) {\n await graphDatabaseInstance.disconnect();\n graphDatabaseInstance = null;\n }\n}"],"mappings":";AAIA,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAc/B,SAAS,oBAAoB;AAC7B,SAAS,MAAM,cAAc;AAC7B,SAAS,iBAAiB,yBAAyB;AACnD,SAAS,0BAA0B,qBAAqB;AAMxD,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAIA;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEJ,eAAe,mBAAmB;AAChC,MAAI,CAAC,eAAe;AAClB,UAAM,gBAAgB,MAAM,OAAO,yBAAyB;AAC5D,oBAAgB,cAAc;AAC9B,gCAA4B,cAAc;AAAA,EAC5C;AACA,MAAI,CAAC,SAAS;AAEZ,cAAU,MAAM,OAAO,SAAS;AAChC,IAAAA,WAAU,QAAQ;AAClB,YAAQA,SAAQ;AAChB,YAAQA,SAAQ;AAChB,kBAAcA,SAAQ;AACtB,SAAKA,SAAQ;AAAA,EACf;AACF;AAGA,SAAS,iBAAiB,QAAiC;AACzD,QAAM,QAAQ,OAAO,cAAc;AAGnC,QAAM,WAAW,CAAC,KAAa,WAAoB,UAAU;AAC3D,UAAM,OAAO,MAAM,GAAG;AACtB,QAAI,CAAC,MAAM;AACT,UAAI,UAAU;AACZ,cAAM,IAAI,MAAM,YAAY,OAAO,MAAM,SAAS,4BAA4B,GAAG,EAAE;AAAA,MACrF;AACA,aAAO;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,GAAG;AAC1C,aAAO,KAAK,CAAC,EAAE,UAAU,SAAY,KAAK,CAAC,EAAE,QAAQ,KAAK,CAAC;AAAA,IAC7D;AACA,WAAO,KAAK,UAAU,SAAY,KAAK,QAAQ;AAAA,EACjD;AAGA,QAAM,KAAK,SAAS,MAAM,IAAI;AAC9B,QAAM,OAAO,SAAS,QAAQ,IAAI;AAClC,QAAM,iBAAiB,SAAS,eAAe,IAAI;AACnD,QAAM,YAAY,SAAS,aAAa,IAAI;AAC5C,QAAM,WAAW,SAAS,YAAY,IAAI;AAC1C,QAAM,cAAc,SAAS,eAAe,IAAI;AAChD,QAAM,WAAW,SAAS,YAAY,IAAI;AAC1C,QAAM,aAAa,SAAS,WAAW,IAAI;AAE3C,QAAM,WAA+B;AAAA,IACnC,YAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,aAAa,KAAK,MAAM,cAAc;AAAA,IACtC,iBAAiB,CAAC;AAAA,MAChB;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP,CAAC;AAAA,IACD,UAAU,aAAa,UAAU,aAAa;AAAA,IAC9C;AAAA,IACA,iBAAiB,OAAO,eAAe,WAAW,KAAK,MAAM,UAAU,IAAI;AAAA,IAC3E,gBAAgB,SAAS,kBAAkB,IAAI;AAAA,EACjD;AAEA,QAAM,mBAAmB,SAAS,kBAAkB;AACpD,MAAI,iBAAkB,UAAS,mBAAmB;AAElD,SAAO;AACT;AAGA,SAAS,mBAAmB,QAAa,cAAwB,CAAC,GAAe;AAC/E,QAAM,QAAQ,OAAO,cAAc;AAGnC,QAAM,WAAW,CAAC,KAAa,WAAoB,UAAU;AAC3D,UAAM,OAAO,MAAM,GAAG;AACtB,QAAI,CAAC,MAAM;AACT,UAAI,UAAU;AACZ,cAAM,IAAI,MAAM,cAAc,OAAO,MAAM,SAAS,4BAA4B,GAAG,EAAE;AAAA,MACvF;AACA,aAAO;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,GAAG;AAC1C,aAAO,KAAK,CAAC,EAAE,UAAU,SAAY,KAAK,CAAC,EAAE,QAAQ,KAAK,CAAC;AAAA,IAC7D;AACA,QAAI,OAAO,SAAS,YAAY,WAAW,KAAM,QAAO,KAAK;AAC7D,WAAO;AAAA,EACT;AAGA,QAAM,KAAK,SAAS,MAAM,IAAI;AAC9B,QAAM,aAAa,SAAS,cAAc,IAAI;AAC9C,QAAM,cAAc,SAAS,YAAY,IAAI;AAC7C,QAAM,aAAa,SAAS,WAAW,IAAI;AAC3C,QAAM,aAAa,SAAS,WAAW,IAAI;AAG3C,QAAM,aAAa,SAAS,YAAY,KAAK;AAG7C,QAAM,UAAU,KAAK,MAAM,UAAU;AAGrC,QAAM,YAA8I,CAAC;AAGrJ,aAAW,cAAc,aAAa;AACpC,QAAI,YAAY;AACd,gBAAU,KAAK;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,aAAa,SAAS,QAAQ;AACpC,MAAI,YAAY;AACd,cAAU,KAAK;AAAA,MACb,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,QAAM,aAAyB;AAAA,IAC7B,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,UAAU,KAAK,MAAM,WAAW;AAAA,IAClC;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,SAAS;AAAA;AAAA,EACX;AAGA,QAAM,WAAW,SAAS,UAAU;AACpC,MAAI,SAAU,YAAW,WAAW;AAEpC,QAAM,gBAAgB,SAAS,WAAW;AAC1C,MAAI,eAAe;AACjB,QAAI;AACF,iBAAW,YAAY,KAAK,MAAM,aAAa;AAAA,IACjD,SAAS,GAAG;AAAA,IAEZ;AAAA,EACF;AAEA,SAAO;AACT;AAGO,IAAM,uBAAN,MAAoD;AAAA,EACjD,YAAqB;AAAA,EACrB;AAAA,EACA,cAAsB;AAAA,EACtB;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA;AAAA,EAGR,MAAc,gCAAgC,oBAAkD;AAC9F,UAAM,cAA4B,CAAC;AAEnC,eAAW,UAAU,oBAAoB;AACvC,YAAM,KAAK,OAAO,YAAY,KAAK,CAAC,GAAG,SAAS,OAAO;AAGvD,YAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,YAAM,cAAc,qBAAqB,CAAC;AAC1C,kBAAY,KAAK,mBAAmB,QAAQ,WAAW,CAAC;AAAA,IAC1D;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,SAIR,CAAC,GAAG;AACN,QAAI,OAAO,SAAU,MAAK,kBAAkB,OAAO;AACnD,SAAK,cAAc,OAAO,QAAQ;AAClC,QAAI,OAAO,OAAQ,MAAK,SAAS,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAc,0BAAyC;AAErD,QAAI,KAAK,iBAAiB;AACxB;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI,MAAM,oGAAoG;AAAA,IACtH;AAEA,QAAI;AAEF,YAAM,iBAAiB;AAGvB,YAAM,SAAS,IAAI,cAAc,EAAE,QAAQ,KAAK,OAAO,CAAC;AAGxD,YAAM,UAAU,IAAI,0BAA0B,CAAC,CAAC;AAChD,YAAM,WAAW,MAAM,OAAO,KAAK,OAAO;AAE1C,UAAI,CAAC,SAAS,cAAc,SAAS,WAAW,WAAW,GAAG;AAC5D,cAAM,IAAI,MAAM,yCAAyC,KAAK,MAAM;AAAA,MACtE;AAGA,UAAI,UAAU;AACd,iBAAW,aAAa,SAAS,YAAY;AAE3C,cAAM,cAAc,IAAI,0BAA0B;AAAA,UAChD,qBAAqB,UAAU;AAAA,QACjC,CAAC;AACD,cAAM,iBAAiB,MAAM,OAAO,KAAK,WAAW;AAEpD,YAAI,eAAe,cAAc,eAAe,WAAW,CAAC,GAAG;AAC7D,gBAAM,cAAc,eAAe,WAAW,CAAC;AAE/C,cAAI,YAAY,qBAAqB,SAAS,SAAS,KACnD,YAAY,qBAAqB,SAAS,SAAS,GAAG;AACxD,sBAAU;AACV;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,gDAAgD,KAAK,MAAM;AAAA,MAC7E;AAGA,WAAK,kBAAkB,QAAQ;AAC/B,WAAK,cAAc,QAAQ,QAAQ;AAEnC,cAAQ,IAAI,gCAAgC,KAAK,eAAe,IAAI,KAAK,WAAW,EAAE;AAAA,IACxF,SAAS,OAAY;AACnB,cAAQ,MAAM,wCAAwC,KAAK;AAC3D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,UAAyB;AAE7B,UAAM,KAAK,wBAAwB;AAEnC,QAAI;AAEF,YAAM,iBAAiB;AAGvB,YAAMC,aAAY,QAAQ,QAAQ,yBAAyB;AAC3D,YAAMC,0BAAyB,QAAQ,OAAO;AAG9C,YAAM,gBAAgB,SAAS,KAAK,eAAe,IAAI,KAAK,WAAW;AACvE,cAAQ,IAAI,4BAA4B,aAAa,EAAE;AAGvD,WAAK,aAAa,IAAIA,wBAAuB,eAAe;AAAA,QAC1D,eAAe;AAAA;AAAA,QACf,oBAAoB;AAAA,QACpB,iBAAiB;AAAA,MACnB,CAAC;AAGD,WAAK,IAAID,WAAU,EAAE,WAAW,KAAK,UAAU;AAG/C,YAAM,QAAQ,MAAM,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK;AACrD,cAAQ,IAAI,4CAA4C,MAAM,KAAK,EAAE;AAErE,WAAK,YAAY;AAAA,IACnB,SAAS,OAAY;AACnB,cAAQ,MAAM,iCAAiC,KAAK;AACpD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAEhC,QAAI,KAAK,YAAY;AACnB,UAAI;AACF,cAAM,KAAK,WAAW,MAAM;AAAA,MAC9B,SAAS,OAAO;AACd,gBAAQ,MAAM,qCAAqC,KAAK;AAAA,MAC1D;AAAA,IACF;AAEA,SAAK,YAAY;AACjB,YAAQ,IAAI,2BAA2B;AAAA,EACzC;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,eAAe,UAA2D;AAC9E,UAAM,KAAK,cAAc,QAAQ;AACjC,UAAM,aAAa,yBAAyB,QAAQ;AACpD,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAGA,QAAI;AACF,YAAM,SAAS,KAAK,EAAE,KAAK,UAAU,EAClC,SAAS,MAAM,EAAE,EACjB,SAAS,QAAQ,SAAS,IAAI,EAC9B,SAAS,aAAa,WAAW,SAAS,EAC1C,SAAS,YAAY,SAAS,YAAY,KAAK,EAC/C,SAAS,eAAe,SAAS,WAAW,EAC5C,SAAS,WAAW,KAAK,UAAU,SAAS,eAAe,CAAC,EAC5D,SAAS,kBAAkB,SAAS,cAAc,EAClD,SAAS,YAAY,WAAW,QAAQ,EACxC,SAAS,eAAe,KAAK,UAAU,SAAS,WAAW,CAAC;AAE/D,UAAI,SAAS,kBAAkB;AAC7B,eAAO,SAAS,oBAAoB,SAAS,gBAAgB;AAAA,MAC/D;AAEA,YAAM,OAAO,KAAK;AAElB,cAAQ,IAAI,uCAAuC,EAAE,EAAE;AACvD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,yCAAyC,KAAK;AAC5D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,IAAqD;AACrE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,EAAE,EAAE,EAC3B,SAAS,UAAU,EACnB,IAAI,MAAM,EAAE,EACZ,WAAW,EACX,KAAK;AAER,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAEA,aAAO,iBAAiB,OAAO,KAAK;AAAA,IACtC,SAAS,OAAO;AACd,cAAQ,MAAM,wCAAwC,KAAK;AAC3D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,IAAiB,OAAyD;AAE7F,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,MAAM,aAAa,QAAW;AACnE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,EAAE,EAAE,EAC3B,SAAS,UAAU,EACnB,IAAI,MAAM,EAAE,EACZ,SAAS,YAAY,MAAM,QAAQ,EACnC,WAAW,EACX,KAAK;AAER,UAAI,CAAC,OAAO,OAAO;AACjB,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC;AAEA,aAAO,iBAAiB,OAAO,KAAK;AAAA,IACtC,SAAS,OAAO;AACd,cAAQ,MAAM,yCAAyC,KAAK;AAC5D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,IAAgC;AACnD,QAAI;AAEF,YAAM,KAAK,EAAE,EAAE,EACZ,SAAS,UAAU,EACnB,IAAI,MAAM,EAAE,EACZ,KAAK,EACL,QAAQ;AAEX,cAAQ,IAAI,kCAAkC,EAAE,EAAE;AAAA,IACpD,SAAS,OAAO;AACd,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAqF;AACvG,QAAI;AACF,UAAIA,aAAY,KAAK,EAAE,EAAE,EAAE,SAAS,UAAU;AAG9C,UAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AAEvD,QAAAA,aAAYA,WAAU;AAAA,UACpBD,SAAQ,QAAQ;AAAA,YACd,GAAG,OAAO,YAAY;AAAA,cAAI,CAAC,SACzBA,SAAQ,QAAQ,IAAI,eAAe,MAAM,WAAW,IAAI,IAAI,GAAG,CAAC;AAAA,YAClE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ;AAEjB,QAAAC,aAAYA,WAAU,IAAI,QAAQ,MAAM,WAAW,OAAO,MAAM,CAAC;AAAA,MACnE;AAGA,YAAM,cAAc,MAAMA,WAAU,MAAM,EAAE,MAAM,EAAE,KAAK;AACzD,YAAM,QAAQ,YAAY,SAAS;AAGnC,YAAM,SAAS,OAAO,UAAU;AAChC,YAAM,QAAQ,OAAO,SAAS;AAE9B,YAAM,UAAU,MAAMA,WACnB,MAAM,EAAE,GAAG,WAAW,MAAM,IAAI,EAChC,MAAM,QAAQ,SAAS,KAAK,EAC5B,WAAW,EACX,OAAO;AAEV,YAAM,YAAY,QAAQ,IAAI,gBAAgB;AAE9C,aAAO,EAAE,WAAW,MAAM;AAAA,IAC5B,SAAS,OAAO;AACd,cAAQ,MAAM,0CAA0C,KAAK;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,OAAe,QAAgB,IAAmC;AACtF,QAAI;AAEF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,UAAU,EACnB,IAAI,QAAQ,MAAM,WAAW,KAAK,CAAC,EACnC,MAAM,EAAE,GAAG,WAAW,MAAM,IAAI,EAChC,MAAM,KAAK,EACX,WAAW,EACX,OAAO;AAEV,aAAO,QAAQ,IAAI,gBAAgB;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,MAAM,0CAA0C,KAAK;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAsD;AAC3E,UAAM,KAAK,KAAK,WAAW;AAG3B,UAAM,aAAyB;AAAA,MAC7B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAGA,UAAM,eAAe,gBAAgB,MAAM,MAAM;AACjD,UAAM,iBAAiB,kBAAkB,MAAM,MAAM;AACrD,UAAM,aAAa,cAAc,MAAM,IAAI;AAC3C,UAAM,cAAc,eAAe,KAAK;AAExC,QAAI;AAEF,YAAM,SAAS,KAAK,EAAE,KAAK,YAAY,EACpC,SAAS,MAAM,WAAW,EAAE,EAC5B,SAAS,cAAc,YAAY,EACnC,SAAS,QAAQ,iBAAiB,aAAa,cAAc,IAAI,EAAE,EACnE,SAAS,YAAY,KAAK,UAAU,kBAAkB,CAAC,CAAC,CAAC,EACzD,SAAS,QAAQ,kBAAkB,EACnC,SAAS,cAAc,WAAW,UAAU,EAC5C,SAAS,WAAW,KAAK,UAAU,WAAW,OAAO,CAAC,EACtD,SAAS,WAAW,WAAW,OAAO;AAGzC,UAAI,YAAY;AACd,eAAO,SAAS,UAAU,UAAU;AAAA,MACtC;AAEA,YAAM,YAAY,MAAM,OAAO,KAAK;AAGpC,YAAM,KAAK,EAAE,EAAE,UAAU,KAAK,EAC3B,KAAK,YAAY,EACjB,GAAG,KAAK,EAAE,EAAE,EAAE,SAAS,UAAU,EAAE,IAAI,MAAM,YAAY,CAAC,EAC1D,KAAK;AAGR,UAAI,YAAY;AACd,cAAM,KAAK,EAAE,EAAE,UAAU,KAAK,EAC3B,KAAK,YAAY,EACjB,GAAG,KAAK,EAAE,EAAE,EAAE,SAAS,UAAU,EAAE,IAAI,MAAM,UAAU,CAAC,EACxD,KAAK;AAAA,MACV;AAGA,iBAAW,cAAc,aAAa;AAEpC,cAAM,WAAW,MAAM,KAAK,EAAE,EAAE,EAC7B,SAAS,YAAY,EACrB,IAAI,QAAQ,UAAU,EACtB,KAAK,EACL;AAAA,UACC,GAAG,OAAO;AAAA,UACV,KAAK,EAAE,KAAK,YAAY,EAAE,SAAS,QAAQ,UAAU;AAAA,QACvD,EACC,KAAK;AAGR,cAAM,KAAK,EAAE,EAAE,UAAU,KAAK,EAC3B,KAAK,WAAW,EAChB,GAAG,KAAK,EAAE,EAAE,SAAS,KAAK,CAAC,EAC3B,KAAK;AAAA,MACV;AAEA,cAAQ,IAAI,yCAAyC,WAAW,EAAE,EAAE;AACpE,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,IAA+C;AACjE,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,EAAE,EAAE,EAC3B,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,WAAW,EACX,KAAK;AAER,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAGA,YAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,YAAM,cAAc,qBAAqB,CAAC;AAE1C,aAAO,mBAAmB,OAAO,OAAO,WAAW;AAAA,IACrD,SAAS,OAAO;AACd,cAAQ,MAAM,0CAA0C,KAAK;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,IAAmB,SAAmD;AAC3F,QAAI;AACF,UAAIA,aAAY,KAAK,EAAE,EAAE,EACtB,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE;AAGf,UAAI,QAAQ,WAAW,UAAa,OAAO,QAAQ,WAAW,UAAU;AACtE,YAAI,QAAQ,OAAO,aAAa,QAAW;AACzC,UAAAA,aAAYA,WAAU,SAAS,QAAQ,aAAa,QAAQ,OAAO,QAAQ,CAAC;AAAA,QAC9E;AAAA,MACF;AAGA,UAAI,QAAQ,SAAS,QAAW;AAC9B,cAAM,aAAa,cAAc,QAAQ,IAAI;AAC7C,cAAME,eAAc,eAAe,EAAE,MAAM,QAAQ,KAAK,CAAC;AAEzD,YAAI,YAAY;AACd,UAAAF,aAAYA,WAAU,SAAS,UAAU,UAAU;AAAA,QACrD;AAGA,YAAIE,aAAY,UAAU,GAAG;AAE3B,gBAAM,KAAK,EAAE,EAAE,EACZ,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,KAAK,WAAW,EAChB,KAAK,EACL,QAAQ;AAGX,qBAAW,cAAcA,cAAa;AACpC,kBAAM,WAAW,MAAM,KAAK,EAAE,EAAE,EAC7B,SAAS,YAAY,EACrB,IAAI,QAAQ,UAAU,EACtB,KAAK,EACL;AAAA,cACC,GAAG,OAAO;AAAA,cACV,KAAK,EAAE,KAAK,YAAY,EAAE,SAAS,QAAQ,UAAU;AAAA,YACvD,EACC,KAAK;AAER,kBAAM,KAAK,EAAE,EAAE,EACZ,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,KAAK,WAAW,EAChB,GAAG,KAAK,EAAE,EAAE,SAAS,KAAK,CAAC,EAC3B,KAAK;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAEA,UAAI,QAAQ,aAAa,QAAW;AAClC,QAAAF,aAAYA,WAAU,SAAS,YAAY,QAAQ,QAAQ;AAAA,MAC7D;AACA,UAAI,QAAQ,cAAc,QAAW;AACnC,QAAAA,aAAYA,WAAU,SAAS,aAAa,KAAK,UAAU,QAAQ,SAAS,CAAC;AAAA,MAC/E;AAEA,YAAM,SAAS,MAAMA,WAAU,WAAW,EAAE,KAAK;AAEjD,UAAI,CAAC,OAAO,OAAO;AACjB,cAAM,IAAI,MAAM,sBAAsB;AAAA,MACxC;AAGA,YAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,YAAM,cAAc,qBAAqB,CAAC;AAE1C,aAAO,mBAAmB,OAAO,OAAO,WAAW;AAAA,IACrD,SAAS,OAAO;AACd,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,IAAkC;AACvD,QAAI;AACF,YAAM,KAAK,EAAE,EAAE,EACZ,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,KAAK,EACL,QAAQ;AAEX,cAAQ,IAAI,oCAAoC,EAAE,EAAE;AAAA,IACtD,SAAS,OAAO;AACd,cAAQ,MAAM,6CAA6C,KAAK;AAChE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,QAAuH;AAC3I,QAAI;AACF,UAAIA,aAAY,KAAK,EAAE,EAAE,EAAE,SAAS,YAAY;AAGhD,UAAI,OAAO,YAAY;AACrB,QAAAA,aAAYA,WAAU,IAAI,cAAc,OAAO,UAAU;AAAA,MAC3D;AAEA,UAAI,OAAO,MAAM;AACf,cAAM,UAAU,OAAO,SAAS,cAAc,gBAAgB;AAC9D,QAAAA,aAAYA,WAAU,IAAI,QAAQ,OAAO;AAAA,MAC3C;AAEA,YAAM,UAAU,MAAMA,WAAU,WAAW,EAAE,OAAO;AACpD,YAAM,cAAc,MAAM,KAAK,gCAAgC,OAAO;AAEtE,aAAO,EAAE,aAAa,OAAO,YAAY,OAAO;AAAA,IAClD,SAAS,OAAO;AACd,cAAQ,MAAM,4CAA4C,KAAK;AAC/D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAGA,MAAM,cAAc,YAA+C;AACjE,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,YAAY,EACrB,IAAI,cAAc,UAAU,EAC5B,OAAO,oBAAoB,EAC3B,WAAW,EACX,OAAO;AAEV,aAAO,MAAM,KAAK,gCAAgC,OAAO;AAAA,IAC3D,SAAS,OAAO;AACd,cAAQ,MAAM,0CAA0C,KAAK;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,cAA4B,QAAyC;AAC1F,QAAI;AAEF,YAAM,kBAAkB,MAAM,KAAK,EAAE,EAAE,EACpC,SAAS,UAAU,EACnB,IAAI,MAAM,MAAM,EAChB,WAAW,EACX,KAAK;AACR,YAAM,YAAY,gBAAgB,QAAQ,iBAAiB,gBAAgB,KAAK,IAAI;AAGpF,YAAMA,aAAY,KAAK,EAAE,EAAE,EACxB,SAAS,YAAY,EACrB,IAAI,MAAM,YAAY,EACtB,SAAS,UAAU,MAAM,EACzB,SAAS,wBAAwB,WAAW,IAAI,EAChD,SAAS,eAAc,oBAAI,KAAK,GAAE,YAAY,CAAC;AAElD,YAAM,SAAS,MAAMA,WAAU,WAAW,EAAE,KAAK;AAEjD,UAAI,CAAC,OAAO,OAAO;AACjB,cAAM,IAAI,MAAM,sBAAsB;AAAA,MACxC;AAGA,YAAM,YAAY,MAAM,KAAK,EAAE,EAAE,EAC9B,SAAS,YAAY,EACrB,IAAI,MAAM,YAAY,EACtB,KAAK;AAER,YAAM,KAAK,EAAE,EAAE,UAAU,KAAK,EAC3B,KAAK,YAAY,EACjB,GAAG,KAAK,EAAE,EAAE,EAAE,SAAS,UAAU,EAAE,IAAI,MAAM,MAAM,CAAC,EACpD,KAAK;AAGR,YAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,YAAY,EACtB,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,YAAM,cAAc,qBAAqB,CAAC;AAE1C,aAAO,mBAAmB,OAAO,OAAO,WAAW;AAAA,IACrD,SAAS,OAAO;AACd,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,YAAY,EACrB,IAAI,cAAc,UAAU,EAC5B,IAAI,oBAAoB,EACxB,WAAW,EACX,OAAO;AAEV,aAAO,MAAM,KAAK,gCAAgC,OAAO;AAAA,IAC3D,SAAS,OAAO;AACd,cAAQ,MAAM,0CAA0C,KAAK;AAC7D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,YAAwB,aAA+C;AAC/F,QAAI;AACF,UAAIA,aAAY,KAAK,EAAE,EAAE,EACtB,SAAS,YAAY,EACrB,IAAI,cAAc,UAAU,EAC5B,IAAI,oBAAoB,EACxB,IAAI,aAAa;AAEpB,UAAI,eAAe,YAAY,SAAS,GAAG;AACzC,QAAAA,aAAYA,WAAU;AAAA,UACpBD,SAAQ,QAAQ;AAAA,YACd,GAAG,YAAY;AAAA,cAAI,CAAC,SAClBA,SAAQ,QAAQ,IAAI,eAAe,MAAM,WAAW,IAAI,IAAI,GAAG,CAAC;AAAA,YAClE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAMC,WAAU,WAAW,EAAE,OAAO;AAEpD,aAAO,MAAM,KAAK,gCAAgC,OAAO;AAAA,IAC3D,SAAS,OAAO;AACd,cAAQ,MAAM,iDAAiD,KAAK;AACpE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,YAA+C;AAC1E,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,YAAY,EACrB,IAAI,cAAc,UAAU,EAC5B,WAAW,EACX,OAAO;AAEV,aAAO,MAAM,KAAK,gCAAgC,OAAO;AAAA,IAC3D,SAAS,OAAO;AACd,cAAQ,MAAM,oDAAoD,KAAK;AACvE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,wBAAwBG,cAA0B,aAA6C;AACnG,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,YAAY,EACrB,IAAI,sBAAsBA,YAAW,EACrC,WAAW,EACX,OAAO;AAEV,aAAO,MAAM,KAAK,gCAAgC,OAAO;AAAA,IAC3D,SAAS,OAAO;AACd,cAAQ,MAAM,sDAAsD,KAAK;AACzE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,YAAoD;AAC/E,QAAI;AAEF,YAAM,sBAAsB,MAAM,KAAK,EAAE,EAAE,EACxC,SAAS,YAAY,EACrB,IAAI,cAAc,UAAU,EAC5B,IAAI,QAAQ,EACZ,WAAW,EACX,OAAO;AAGV,YAAM,sBAAsB,MAAM,KAAK,EAAE,EAAE,EACxC,SAAS,YAAY,EACrB,IAAI,UAAU,UAAU,EACxB,WAAW,EACX,OAAO;AAGV,YAAM,iBAAiB,oBAAI,IAA6B;AAGxD,iBAAW,aAAa,qBAAqB;AAC3C,cAAM,KAAK,UAAU,YAAY,KAAK,CAAC,GAAG,SAAS,UAAU;AAG7D,cAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,cAAM,cAAc,qBAAqB,CAAC;AAC1C,cAAM,aAAa,mBAAmB,WAAW,WAAW;AAC5D,cAAM,cAAc,cAAc,WAAW,IAAI;AACjD,YAAI,CAAC,YAAa;AAGlB,cAAM,kBAAkB,MAAM,KAAK,EAAE,EAAE,EACpC,SAAS,UAAU,EACnB,IAAI,MAAM,WAAW,EACrB,WAAW,EACX,KAAK;AAER,YAAI,gBAAgB,OAAO;AACzB,gBAAM,YAAY,iBAAiB,gBAAgB,KAAK;AACxD,gBAAMC,eAAc,cAAc,SAAS;AAC3C,cAAI,CAACA,aAAa;AAClB,gBAAM,WAAW,eAAe,IAAIA,YAAW;AAC/C,cAAI,UAAU;AACZ,qBAAS,YAAY,KAAK,UAAU;AAAA,UACtC,OAAO;AACL,2BAAe,IAAIA,cAAa;AAAA,cAC9B,gBAAgB;AAAA,cAChB,aAAa,CAAC,UAAU;AAAA,cACxB,eAAe;AAAA,YACjB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAGA,iBAAW,aAAa,qBAAqB;AAC3C,cAAM,KAAK,UAAU,YAAY,KAAK,CAAC,GAAG,SAAS,UAAU;AAG7D,cAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,YAAY,EACrB,IAAI,MAAM,EAAE,EACZ,IAAI,WAAW,EACf,SAAS,YAAY,EACrB,OAAO,MAAM,EACb,OAAO;AAEV,cAAM,cAAc,qBAAqB,CAAC;AAC1C,cAAM,aAAa,mBAAmB,WAAW,WAAW;AAC5D,cAAM,cAAc,gBAAgB,WAAW,MAAM;AACrD,cAAM,WAAW,eAAe,IAAI,WAAW;AAC/C,YAAI,UAAU;AACZ,mBAAS,gBAAgB;AAAA,QAC3B;AAAA,MACF;AAEA,aAAO,MAAM,KAAK,eAAe,OAAO,CAAC;AAAA,IAC3C,SAAS,OAAO;AACd,cAAQ,MAAM,oDAAoD,KAAK;AACvE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,gBAAwB,cAAsB,WAAmB,GAAyB;AACvG,QAAI;AAEF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,UAAU,EACnB,IAAI,MAAM,cAAc,EACxB;AAAA,QACCL,SAAQ,QAAQ,KAAK,YAAY,EAC9B,WAAW;AAAA,MAChB,EACC,MAAM,QAAQ,EACd,KAAK,EACL,IAAI,MAAM,YAAY,EACtB,KAAK,EACL,GAAGA,SAAQ,QAAQ,WAAW,CAAC,EAC/B,MAAM,EAAE,EACR,OAAO;AAEV,YAAM,QAAqB,CAAC;AAE5B,iBAAW,cAAc,SAAS;AAChC,cAAM,YAAkC,CAAC;AAGzC,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,QAAQ,KAAK;AAClD,gBAAM,UAAU,WAAW,QAAQ,CAAC;AAEpC,cAAI,IAAI,MAAM,GAAG;AAEf,sBAAU,KAAK,iBAAiB,OAAO,CAAC;AAAA,UAC1C,OAAO;AAAA,UAGP;AAAA,QACF;AAEA,cAAM,KAAK,EAAE,WAAW,aAAa,CAAC,EAAE,CAAC;AAAA,MAC3C;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,oCAAoC,KAAK;AACvD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,qBAAiD;AACrD,QAAI;AAEF,YAAM,UAAU,MAAM,KAAK,EAAE,EAAE,EAC5B,SAAS,UAAU,EACnB,OAAO,aAAa,EACpB,IAAI,CAAC,oBAA4B;AAChC,cAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,eAAO;AAAA,MACT,CAAC,EACA,OAAO,EACP,WAAW,EACX,KAAK;AAER,YAAM,QAA2B,CAAC;AAElC,UAAI,QAAQ,OAAO;AACjB,mBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAK,GAAG;AACzD,gBAAM,KAAK;AAAA,YACT;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,iDAAiD,KAAK;AACpE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,WAQH;AACD,QAAI;AAEF,YAAM,iBAAiB,MAAM,KAAK,EAAE,EAAE,EACnC,SAAS,UAAU,EACnB,MAAM,EACN,KAAK;AACR,YAAM,gBAAgB,eAAe,SAAS;AAG9C,YAAM,iBAAiB,MAAM,KAAK,EAAE,EAAE,EACnC,SAAS,YAAY,EACrB,MAAM,EACN,KAAK;AACR,YAAM,kBAAkB,eAAe,SAAS;AAGhD,YAAM,uBAAuB,MAAM,KAAK,EAAE,EAAE,EACzC,SAAS,YAAY,EACrB,OAAO,oBAAoB,EAC3B,MAAM,EACN,KAAK;AACR,YAAM,iBAAiB,qBAAqB,SAAS;AAGrD,YAAM,uBAAuB,MAAM,KAAK,EAAE,EAAE,EACzC,SAAS,YAAY,EACrB,IAAI,oBAAoB,EACxB,MAAM,EACN,KAAK;AACR,YAAM,iBAAiB,qBAAqB,SAAS;AAGrD,YAAM,uBAAuB,MAAM,KAAK,EAAE,EAAE,EACzC,SAAS,YAAY,EACrB,IAAI,oBAAoB,EACxB,IAAI,aAAa,EACjB,MAAM,EACN,KAAK;AACR,YAAM,uBAAuB,qBAAqB,SAAS;AAG3D,YAAM,kBAAkB,MAAM,KAAK,mBAAmB;AACtD,YAAM,cAAsC,CAAC;AAC7C,iBAAW,QAAQ,iBAAiB;AAClC,oBAAY,KAAK,IAAI,IAAI,KAAK;AAAA,MAChC;AAGA,YAAM,oBAAoB,MAAM,KAAK,EAAE,EAAE,EACtC,SAAS,UAAU,EACnB,WAAW,EACX,GAAG,aAAa,EAChB,KAAK;AACR,YAAM,eAAe,kBAAkB,SAAS,CAAC;AAEjD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,qCAAqC,KAAK;AACxD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAA2D;AACjF,UAAM,UAAwB,CAAC;AAE/B,QAAI;AACF,iBAAW,SAAS,QAAQ;AAC1B,cAAM,aAAa,MAAM,KAAK,iBAAiB,KAAK;AACpD,gBAAQ,KAAK,UAAU;AAAA,MACzB;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,4CAA4C,KAAK;AAC/D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAGA,MAAM,kBAAkB,QAAqF;AAC3G,UAAM,UAAwB,CAAC;AAE/B,QAAI;AACF,iBAAW,SAAS,QAAQ;AAC1B,cAAM,aAAa,MAAM,KAAK,iBAAiB,MAAM,cAAc,MAAM,MAAM;AAC/E,gBAAQ,KAAK,UAAU;AAAA,MACzB;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,4CAA4C,KAAK;AAC/D,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,aAAgD;AAGtE,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGQ,wBAA4C;AAAA,EAEpD,MAAM,iBAAoC;AAExC,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,WAAO,MAAM,KAAK,KAAK,qBAAsB,EAAE,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,cAAc,KAA4B;AAC9C,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,sBAAuB,IAAI,GAAG;AAEnC,QAAI;AACF,YAAM,KAAK,EAAE,EAAE,EACZ,IAAI,iBAAiB,QAAQ,cAAc,EAC3C,KAAK,EACL;AAAA,QACC,GAAG,OAAO;AAAA,QACV,GAAG,KAAK,eAAe,EAAE,SAAS,QAAQ,cAAc;AAAA,MAC1D,EACC,SAAS,YAAY,KAAK,QAAQ,GAAG,EACrC,QAAQ;AAAA,IACb,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,MAA+B;AAClD,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,QAAQ,SAAO,KAAK,sBAAuB,IAAI,GAAG,CAAC;AAExD,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,EAAE,EAAE,EAC3B,IAAI,iBAAiB,QAAQ,cAAc,EAC3C,KAAK,EACL;AAAA,QACC,GAAG,OAAO;AAAA,QACV,GAAG,KAAK,eAAe,EAAE,SAAS,QAAQ,cAAc;AAAA,MAC1D;AAEF,iBAAW,OAAO,MAAM;AACtB,cAAM,OAAO,SAAS,YAAY,KAAK,QAAQ,GAAG,EAAE,QAAQ;AAAA,MAC9D;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA+B,KAAK;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAc,2BAA0C;AACtD,QAAI;AAEF,YAAM,cAAc,MAAM,KAAK,EAAE,EAAE,EAChC,SAAS,eAAe,EACxB,QAAQ,QAAQ,MAAM,EACtB,GAAG,MAAM,EACT,GAAG,GAAG,OAAO,MAAM,EAAE,KAAK,CAAC,EAC3B,OAAO;AAGV,iBAAW,OAAO,aAAa;AAC7B,YAAI,IAAI,SAAS,gBAAgB;AAC/B,eAAK,wBAAwB,IAAI,IAAI,IAAI,IAAgB;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,IAAI,kEAAkE;AAAA,IAChF;AAGA,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,mBAAmB;AACjE,WAAK,wBAAwB,IAAI,IAAI,oBAAoB;AAEzD,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,EAAE,KAAK,eAAe,EAC7C,SAAS,QAAQ,cAAc,EAC/B,KAAK;AACR,mBAAW,OAAO,sBAAsB;AACtC,gBAAM,KAAK,EAAE,EAAE,OAAO,MAAM,EAAE,EAC3B,SAAS,YAAY,KAAK,QAAQ,GAAG,EACrC,QAAQ;AAAA,QACb;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,sCAAsC,KAAK;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,aAAqB;AACnB,WAAO,OAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,UAAU,GAAG,EAAE;AAAA,EACnD;AAAA,EAEA,MAAM,gBAA+B;AACnC,QAAI;AAEF,YAAM,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ;AAChC,cAAQ,IAAI,+BAA+B;AAE3C,WAAK,wBAAwB;AAAA,IAC/B,SAAS,OAAO;AACd,cAAQ,MAAM,qCAAqC,KAAK;AACxD,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AChwCA,OAAO,WAAgC;AAevC,SAAS,gBAAAM,qBAAoB;AAC7B,SAAS,MAAMC,eAAc;AAC7B,SAAS,iBAAAC,gBAAe,mBAAAC,kBAAiB,qBAAAC,0BAAyB;AAClE,SAAS,kBAAAC,uBAAsB;AAC/B,SAAS,4BAAAC,iCAAgC;AAoBzC,SAAS,kBAAkB,YAA4B;AACrD,SAAO,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,WAAW,MAAM,CAAC;AAChE;AAEO,IAAM,qBAAN,MAAkD;AAAA,EAC/C,SAAwB;AAAA,EACxB,YAAqB;AAAA,EACrB;AAAA;AAAA,EAQA,wBAA4C;AAAA,EAEpD,YAAY,SAKR,CAAC,GAAG;AACN,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI;AACF,YAAM,MAAM,KAAK,OAAO;AACxB,YAAM,WAAW,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,OAAO;AAC7B,YAAM,WAAW,KAAK,OAAO;AAE7B,UAAI,CAAC,KAAK;AACR,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AACA,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AACA,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AACA,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AAEA,cAAQ,IAAI,0BAA0B,GAAG,KAAK;AAE9C,WAAK,SAAS,MAAM;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,MAAM,UAAU,QAAQ;AAAA,QACnC;AAAA,UACE,uBAAuB;AAAA,UACvB,8BAA8B;AAAA,QAChC;AAAA,MACF;AAGA,YAAM,UAAU,KAAK,OAAO,QAAQ,EAAE,SAAS,CAAC;AAEhD,YAAM,QAAQ,IAAI,kBAAkB;AACpC,YAAM,QAAQ,MAAM;AAGpB,YAAM,KAAK,mBAAmB;AAE9B,cAAQ,IAAI,iCAAiC;AAC7C,WAAK,YAAY;AAAA,IACnB,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA+B,KAAK;AAClD,YAAM,IAAI,MAAM,4BAA4B,KAAK,EAAE;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAChC,QAAI,KAAK,QAAQ;AACf,YAAM,KAAK,OAAO,MAAM;AACxB,WAAK,SAAS;AAAA,IAChB;AACA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,aAAsB;AAC5B,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,QAAI,CAAC,KAAK,OAAO,UAAU;AACzB,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AACA,WAAO,KAAK,OAAO,QAAQ;AAAA,MACzB,UAAU,KAAK,OAAO;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,qBAAoC;AAChD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,iBAAW,cAAc,aAAa;AACpC,YAAI;AACF,gBAAM,QAAQ,IAAI,UAAU;AAAA,QAC9B,SAAS,OAAY;AAEnB,cAAI,CAAC,MAAM,SAAS,SAAS,gBAAgB,GAAG;AAC9C,oBAAQ,KAAK,4BAA4B,MAAM,OAAO,EAAE;AAAA,UAC1D;AAAA,QACF;AAAA,MACF;AAGA,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,iBAAW,SAAS,SAAS;AAC3B,YAAI;AACF,gBAAM,QAAQ,IAAI,KAAK;AAAA,QACzB,SAAS,OAAY;AAEnB,cAAI,CAAC,MAAM,SAAS,SAAS,gBAAgB,GAAG;AAC9C,oBAAQ,KAAK,2BAA2B,MAAM,OAAO,EAAE;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,UAA2D;AAC9E,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,KAAK,SAAS,KAAK;AACzB,YAAM,aAAaA,0BAAyB,QAAQ;AACpD,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AAEA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAaA;AAAA,UACE;AAAA,UACA,MAAM,SAAS;AAAA,UACf,aAAa,SAAS;AAAA,UACtB,QAAQ,WAAW;AAAA,UACnB,UAAU,SAAS,YAAY;AAAA,UAC/B,SAAS,SAAS;AAAA,UAClB,SAAS,KAAK,UAAU,SAAS,eAAe;AAAA,UAChD,gBAAgB,SAAS;AAAA,UACzB,iBAAiB,WAAW;AAAA,UAC5B,oBAAoB,SAAS,sBAAsB;AAAA,UACnD,kBAAkB,SAAS,oBAAoB;AAAA,QACjD;AAAA,MACF;AAEA,aAAO,KAAK,kBAAkB,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG,CAAC;AAAA,IAC3D,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,IAAqD;AACrE,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA,QACA,EAAE,GAAG;AAAA,MACP;AAEA,UAAI,OAAO,QAAQ,WAAW,EAAG,QAAO;AACxC,aAAO,KAAK,kBAAkB,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG,CAAC;AAAA,IAC3D,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,IAAiB,OAAyD;AAE7F,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,MAAM,aAAa,QAAW;AACnE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA,QAGA,EAAE,IAAI,UAAU,MAAM,SAAS;AAAA,MACjC;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC;AAEA,aAAO,KAAK,kBAAkB,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG,CAAC;AAAA,IAC3D,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,IAAgC;AACnD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,QAAQ;AAAA,QACZ;AAAA;AAAA;AAAA,QAGA,EAAE,GAAG;AAAA,MACP;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAqF;AACvG,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,UAAI,cAAc;AAClB,YAAM,SAAc,CAAC;AACrB,YAAM,aAAuB,CAAC;AAE9B,UAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AACvD,mBAAW,KAAK,uDAAuD;AACvE,eAAO,cAAc,OAAO;AAAA,MAC9B;AAEA,UAAI,OAAO,QAAQ;AACjB,mBAAW,KAAK,2CAA2C;AAC3D,eAAO,SAAS,OAAO;AAAA,MACzB;AAEA,UAAI,WAAW,SAAS,GAAG;AACzB,sBAAc,WAAW,WAAW,KAAK,OAAO;AAAA,MAClD;AAGA,YAAM,cAAc,MAAM,QAAQ;AAAA,QAChC,sBAAsB,WAAW;AAAA,QACjC;AAAA,MACF;AACA,YAAM,QAAQ,YAAY,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAG5D,aAAO,OAAO,MAAM,IAAI,OAAO,UAAU,CAAC;AAC1C,aAAO,QAAQ,MAAM,IAAI,OAAO,SAAS,EAAE;AAE3C,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,sBAAsB,WAAW;AAAA;AAAA;AAAA;AAAA,QAIjC;AAAA,MACF;AAEA,YAAM,YAAY,OAAO,QAAQ,IAAI,YAAU,KAAK,kBAAkB,OAAO,IAAI,GAAG,CAAC,CAAC;AAEtF,aAAO,EAAE,WAAW,MAAM;AAAA,IAC5B,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,OAAe,QAAgB,IAAmC;AACtF,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,EAAE,OAAO,OAAO,MAAM,IAAI,KAAK,EAAE;AAAA,MACnC;AAEA,aAAO,OAAO,QAAQ,IAAI,YAAU,KAAK,kBAAkB,OAAO,IAAI,GAAG,CAAC,CAAC;AAAA,IAC7E,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAsD;AAC3E,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,KAAK,MAAM;AAEjB,YAAM,aAAyB;AAAA,QAC7B,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR;AAAA,QACA,YAAY,MAAM;AAAA,QAClB,QAAQ,MAAM;AAAA,QACd,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAGA,YAAM,eAAeH,iBAAgB,MAAM,MAAM;AACjD,YAAM,iBAAiBC,mBAAkB,MAAM,MAAM;AACrD,YAAM,aAAaF,eAAc,MAAM,IAAI;AAG3C,YAAM,cAAcG,gBAAe,KAAK;AAGxC,YAAM,kBAAkB,kBAAkB,WAAW,UAAU;AAG/D,UAAI;AACJ,UAAI,YAAY;AAGd,iBAAS;AAAA;AAAA,kCAEiB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkB3C,OAAO;AAGL,iBAAS;AAAA,kCACiB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgB3C;AAEA,YAAM,SAAc;AAAA,QAClB;AAAA,QACA,YAAY;AAAA;AAAA,QACZ,QAAQ;AAAA;AAAA,QACR,MAAM,cAAc;AAAA;AAAA,QACpB,OAAO,iBAAiBL,cAAa,cAAc,IAAI;AAAA,QACvD,UAAU,KAAK,UAAU,kBAAkB,CAAC,CAAC;AAAA,QAC7C,MAAM;AAAA,QACN,YAAY,WAAW;AAAA,QACvB,SAAS,KAAK,UAAU,WAAW,OAAO;AAAA,QAC1C,SAAS,WAAW;AAAA,QACpB;AAAA,QACA,QAAQ,cAAc;AAAA,MACxB;AAEA,YAAM,SAAS,MAAM,QAAQ,IAAI,QAAQ,MAAM;AAE/C,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,cAAM,IAAI,MAAM,yCAAyC,YAAY,8BAA8B;AAAA,MACrG;AAEA,aAAO,KAAK,oBAAoB,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG,GAAG,WAAW;AAAA,IAC1E,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,IAA+C;AACjE,YAAQ,IAAI,qCAAqC,EAAE,EAAE;AACrD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA,QAGA,EAAE,GAAG;AAAA,MACP;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,gBAAQ,IAAI,qCAAqC,EAAE,YAAY;AAC/D,eAAO;AAAA,MACT;AACA,cAAQ,IAAI,qCAAqC,EAAE,QAAQ;AAC3D,aAAO,KAAK;AAAA,QACV,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG;AAAA,QAC1B,OAAO,QAAQ,CAAC,EAAG,IAAI,aAAa;AAAA,MACtC;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,IAAmB,SAAmD;AAC3F,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,aAAuB,CAAC,0BAA0B;AACxD,YAAM,SAAc,EAAE,GAAG;AAGzB,aAAO,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAChD,YAAI,QAAQ,QAAQ,QAAQ,aAAa;AACvC,qBAAW,KAAK,KAAK,GAAG,OAAO,GAAG,EAAE;AACpC,cAAI,QAAQ,cAAc,QAAQ,cAAc,QAAQ,QAAQ;AAC9D,mBAAO,GAAG,IAAI,KAAK,UAAU,KAAK;AAAA,UACpC,WAAW,QAAQ,aAAa,QAAQ,cAAc;AACpD,mBAAO,GAAG,IAAI,QAAQ,IAAI,KAAK,KAAY,EAAE,YAAY,IAAI;AAAA,UAC/D,OAAO;AACL,mBAAO,GAAG,IAAI;AAAA,UAChB;AAAA,QACF;AAAA,MACF,CAAC;AAGD,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA,eACO,WAAW,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,QAI5B;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,cAAM,IAAI,MAAM,sBAAsB;AAAA,MACxC;AAGA,UAAI,QAAQ,YAAY;AACtB,cAAM,WAAW,kBAAkB,QAAQ,UAAU;AACrD,gBAAQ,IAAI,yCAAyC,QAAQ,EAAE;AAG/D,cAAM,iBAAiB;AAAA,UAAC;AAAA,UAAa;AAAA,UAAe;AAAA,UAAe;AAAA,UAC3C;AAAA,UAAc;AAAA,UAAW;AAAA,UAAgB;AAAA,UACzC;AAAA,UAAW;AAAA,UAAc;AAAA,UAAe;AAAA,UAAY;AAAA,QAAS;AACrF,cAAM,eAAe,eAAe,OAAO,OAAK,MAAM,QAAQ,EAAE,IAAI,OAAK,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAE5F,cAAM,QAAQ;AAAA,UACZ;AAAA,oBACU,YAAY;AAAA,mBACb,QAAQ;AAAA,UACjB,EAAE,GAAG;AAAA,QACP;AACA,gBAAQ,IAAI,+CAA0C,QAAQ,EAAE;AAAA,MAClE;AAGA,UAAI,QAAQ,MAAM;AAChB,gBAAQ,IAAI,6CAA6C,EAAE,SAAS;AACpE,gBAAQ,IAAI,yBAAyB,KAAK,UAAU,QAAQ,IAAI,CAAC;AACjE,cAAM,YAAY,MAAM,QAAQ,QAAQ,IAAI,IAAI,QAAQ,OAAO,CAAC,QAAQ,IAAI;AAC5E,gBAAQ,IAAI,6BAA6B,UAAU,MAAM,EAAE;AAE3D,kBAAU,QAAQ,CAAC,MAAM,QAAQ;AAC/B,kBAAQ,IAAI,uBAAuB,GAAG,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,QACjE,CAAC;AAED,cAAM,mBAAmB,UAAU,KAAK,CAAC,SAAc,KAAK,SAAS,sBAAsB,KAAK,YAAY,SAAS;AACrH,gBAAQ,IAAI,mCAAmC,mBAAmB,KAAK,UAAU,gBAAgB,IAAI,MAAM;AAE3G,YAAI,oBAAoB,YAAY,oBAAoB,iBAAiB,QAAQ;AAC/E,kBAAQ,IAAI,4CAAuC,EAAE,OAAO,iBAAiB,MAAM,EAAE;AAErF,gBAAM,YAAY,MAAM,QAAQ;AAAA,YAC9B;AAAA;AAAA;AAAA;AAAA,YAIA;AAAA,cACE,cAAc;AAAA,cACd,kBAAkB,iBAAiB;AAAA,YACrC;AAAA,UACF;AACA,kBAAQ,IAAI,mDAA8C,UAAU,QAAQ,MAAM,QAAQ;AAC1F,cAAI,UAAU,QAAQ,SAAS,GAAG;AAChC,oBAAQ,IAAI,yBAAyB,UAAU,QAAQ,CAAC,EAAG,IAAI,GAAG,EAAE,WAAW,EAAE,EAAE;AACnF,oBAAQ,IAAI,8BAA8B,UAAU,QAAQ,CAAC,EAAG,IAAI,QAAQ,EAAE,WAAW,EAAE,EAAE;AAAA,UAC/F;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,mFAAmF;AAAA,QACjG;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,yCAAyC,EAAE,EAAE;AAAA,MAC3D;AAEA,aAAO,KAAK;AAAA,QACV,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG;AAAA,QAC1B,OAAO,QAAQ,CAAC,EAAG,IAAI,aAAa;AAAA,MACtC;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,IAAkC;AACvD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,GAAG;AAAA,MACP;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,QAAuH;AAC3I,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,aAAuB,CAAC;AAC9B,YAAM,SAAc,CAAC;AAErB,UAAI,OAAO,YAAY;AACrB,mBAAW,KAAK,4BAA4B;AAC5C,eAAO,aAAa,OAAO;AAAA,MAC7B;AAEA,UAAI,OAAO,MAAM;AACf,cAAM,UAAU,OAAO,SAAS,cAAc,gBAAgB;AAC9D,mBAAW,KAAK,gBAAgB;AAChC,eAAO,OAAO;AAAA,MAChB;AAEA,YAAM,cAAc,WAAW,SAAS,IAAI,WAAW,WAAW,KAAK,OAAO,IAAI;AAGlF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,wBAAwB,WAAW;AAAA;AAAA;AAAA,QAGnC;AAAA,MACF;AAEA,YAAM,cAAc,OAAO,QAAQ;AAAA,QAAI,YACrC,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAEA,aAAO,EAAE,aAAa,OAAO,YAAY,OAAO;AAAA,IAClD,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,EAAE,WAAW;AAAA,MACf;AAEA,aAAO,OAAO,QAAQ;AAAA,QAAI,YACxB,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,cAA4B,QAAyC;AAC1F,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B;AAAA,QACA,EAAE,IAAI,OAAO;AAAA,MACf;AACA,YAAM,eAAe,UAAU,QAAQ,CAAC,GAAG,IAAI,MAAM;AAGrD,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQA,EAAE,cAAc,QAAQ,aAAa;AAAA,MACvC;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,cAAM,IAAI,MAAM,sBAAsB;AAAA,MACxC;AAEA,aAAO,KAAK;AAAA,QACV,OAAO,QAAQ,CAAC,EAAG,IAAI,GAAG;AAAA,QAC1B,OAAO,QAAQ,CAAC,EAAG,IAAI,aAAa;AAAA,MACtC;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,EAAE,WAAW;AAAA,MACf;AAEA,aAAO,OAAO,QAAQ;AAAA,QAAI,YACxB,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,YAAwB,aAA+C;AAC/F,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,UAAI,SAAS;AAAA;AAGb,YAAM,SAAc,EAAE,WAAW;AAEjC,UAAI,eAAe,YAAY,SAAS,GAAG;AACzC,kBAAU;AAAA;AAAA;AAGV,eAAO,cAAc;AAAA,MACvB;AAEA,gBAAU;AAAA;AAAA;AAAA;AAKV,YAAM,SAAS,MAAM,QAAQ,IAAI,QAAQ,MAAM;AAE/C,aAAO,OAAO,QAAQ;AAAA,QAAI,YACxB,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,YAA+C;AAC1E,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA,QAIA,EAAE,WAAW;AAAA,MACf;AAEA,aAAO,OAAO,QAAQ;AAAA,QAAI,YACxB,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,wBAAwBO,cAA0B,YAA4C;AAClG,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,aAAa,aAAa,oBAAoB,UAAU,KAAK;AACnE,cAAQ,IAAI,6DAA6D,UAAU,gBAAgBA,YAAW,EAAE;AAIhH,YAAM,kBAAkB,aAAa,IAAI,kBAAkB,UAAU,CAAC,KAAK;AAC3E,YAAM,SAAS,sBAAsB,eAAe;AAAA;AAAA;AAAA;AAKpD,YAAM,SAAS,MAAM,QAAQ,IAAI,QAAQ,EAAE,aAAAA,aAAY,CAAC;AAExD,cAAQ,IAAI,0CAA0C,OAAO,QAAQ,MAAM,cAAc;AAEzF,aAAO,OAAO,QAAQ;AAAA,QAAI,YACxB,KAAK,oBAAoB,OAAO,IAAI,GAAG,GAAG,OAAO,IAAI,aAAa,CAAC;AAAA,MACrE;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,YAAoD;AAC/E,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMA,EAAE,WAAW;AAAA,MACf;AAEA,YAAM,cAAiC,CAAC;AAExC,iBAAW,UAAU,OAAO,SAAS;AACnC,cAAM,iBAAiB,KAAK,kBAAkB,OAAO,IAAI,OAAO,CAAC;AAGjE,cAAM,gBAAgB,OAAO,IAAI,UAAU;AAC3C,cAAM,WAAyB,CAAC;AAChC,mBAAW,WAAW,eAAe;AACnC,gBAAM,QAAQ,QAAQ,WAAW;AACjC,gBAAM,YAAY,MAAM,QAAQ;AAAA,YAC9B;AAAA;AAAA;AAAA,YAGA,EAAE,IAAI,MAAM;AAAA,UACd;AACA,cAAI,UAAU,QAAQ,SAAS,GAAG;AAChC,qBAAS,KAAK,KAAK;AAAA,cACjB,UAAU,QAAQ,CAAC,EAAG,IAAI,GAAG;AAAA,cAC7B,UAAU,QAAQ,CAAC,EAAG,IAAI,aAAa;AAAA,YACzC,CAAC;AAAA,UACH;AAAA,QACF;AAGA,cAAM,gBAAgB,OAAO,IAAI,UAAU;AAC3C,cAAM,WAAyB,CAAC;AAChC,mBAAW,WAAW,eAAe;AACnC,gBAAM,QAAQ,QAAQ,WAAW;AACjC,gBAAM,YAAY,MAAM,QAAQ;AAAA,YAC9B;AAAA;AAAA;AAAA,YAGA,EAAE,IAAI,MAAM;AAAA,UACd;AACA,cAAI,UAAU,QAAQ,SAAS,GAAG;AAChC,qBAAS,KAAK,KAAK;AAAA,cACjB,UAAU,QAAQ,CAAC,EAAG,IAAI,GAAG;AAAA,cAC7B,UAAU,QAAQ,CAAC,EAAG,IAAI,aAAa;AAAA,YACzC,CAAC;AAAA,UACH;AAAA,QACF;AAEA,oBAAY,KAAK;AAAA,UACf;AAAA,UACA,aAAa;AAAA,UACb,eAAe,SAAS,SAAS;AAAA,QACnC,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,gBAAwB,cAAsB,WAAmB,GAAyB;AACvG,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,0EAA0E,QAAQ;AAAA;AAAA;AAAA;AAAA,QAIlF,EAAE,QAAQ,gBAAgB,MAAM,aAAa;AAAA,MAC/C;AAEA,YAAM,QAAqB,CAAC;AAE5B,iBAAW,UAAU,OAAO,SAAS;AACnC,cAAM,OAAO,OAAO,IAAI,MAAM,EAAE,IAAI,CAAC,SAAc,KAAK,kBAAkB,IAAI,CAAC;AAC/E,cAAM,OAAO,OAAO,IAAI,MAAM;AAG9B,cAAM,gBAAgB,KAAK,IAAI,CAAC,QAAa,IAAI,WAAW,EAAE,EAAE,OAAO,CAAC,OAAY,EAAE;AACtF,cAAM,cAA4B,CAAC;AAEnC,YAAI,cAAc,SAAS,GAAG;AAC5B,gBAAM,YAAY,MAAM,QAAQ;AAAA,YAC9B;AAAA;AAAA;AAAA,YAGA,EAAE,KAAK,cAAc;AAAA,UACvB;AACA,oBAAU,QAAQ,QAAQ,SAAO;AAC/B,wBAAY,KAAK,KAAK;AAAA,cACpB,IAAI,IAAI,GAAG;AAAA,cACX,IAAI,IAAI,aAAa;AAAA,YACvB,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAEA,cAAM,KAAK;AAAA,UACT,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,qBAAiD;AACrD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA;AAAA;AAAA;AAAA,MAIF;AAEA,aAAO,OAAO,QAAQ,IAAI,aAAW;AAAA,QACnC,MAAM,OAAO,IAAI,MAAM;AAAA,QACvB,OAAO,OAAO,IAAI,OAAO,EAAE,SAAS;AAAA,MACtC,EAAE;AAAA,IACJ,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,WAQH;AACD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,iBAAiB,MAAM,QAAQ,IAAI,6CAA6C;AACtF,YAAM,gBAAgB,eAAe,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAGvE,YAAM,iBAAiB,MAAM,QAAQ,IAAI,+CAA+C;AACxF,YAAM,kBAAkB,eAAe,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAEzE,YAAM,uBAAuB,MAAM,QAAQ;AAAA,QACzC;AAAA,MACF;AACA,YAAM,iBAAiB,qBAAqB,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAE9E,YAAM,uBAAuB,MAAM,QAAQ;AAAA,QACzC;AAAA,MACF;AACA,YAAM,iBAAiB,qBAAqB,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAE9E,YAAM,uBAAuB,MAAM,QAAQ;AAAA,QACzC;AAAA,MACF;AACA,YAAM,uBAAuB,qBAAqB,QAAQ,CAAC,EAAG,IAAI,OAAO,EAAE,SAAS;AAGpF,YAAM,mBAAmB,MAAM,QAAQ;AAAA,QACrC;AAAA;AAAA;AAAA,MAGF;AAEA,YAAM,cAAsC,CAAC;AAC7C,uBAAiB,QAAQ,QAAQ,YAAU;AACzC,oBAAY,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,IAAI,OAAO,EAAE,SAAS;AAAA,MACjE,CAAC;AAGD,YAAM,oBAAoB,MAAM,QAAQ;AAAA,QACtC;AAAA;AAAA,MAEF;AAEA,YAAM,eAAuC,CAAC;AAC9C,wBAAkB,QAAQ,QAAQ,YAAU;AAC1C,qBAAa,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,IAAI,OAAO,EAAE,SAAS;AAAA,MAClE,CAAC;AAED,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAA2D;AACjF,UAAM,UAAwB,CAAC;AAC/B,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,KAAK,CAAC;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,QAAqF;AAC3G,UAAM,UAAwB,CAAC;AAC/B,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,MAAM,cAAc,MAAM,MAAM,CAAC;AAAA,IAC5E;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,aAAgD;AAGtE,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGA,MAAM,iBAAoC;AACxC,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,WAAO,MAAM,KAAK,KAAK,qBAAsB,EAAE,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,cAAc,KAA4B;AAC9C,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,sBAAuB,IAAI,GAAG;AACnC,UAAM,KAAK,qBAAqB,gBAAgB,KAAK,qBAAsB;AAAA,EAC7E;AAAA,EAEA,MAAM,eAAe,MAA+B;AAClD,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,QAAQ,SAAO,KAAK,sBAAuB,IAAI,GAAG,CAAC;AACxD,UAAM,KAAK,qBAAqB,gBAAgB,KAAK,qBAAsB;AAAA,EAC7E;AAAA,EAEA,MAAc,2BAA0C;AACtD,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B;AAAA,MACF;AAEA,UAAI,oBAA8B,CAAC;AAEnC,UAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,cAAM,SAAS,OAAO,QAAQ,CAAC;AAC/B,YAAI,QAAQ;AACV,gBAAM,OAAO,OAAO,IAAI,MAAM;AAC9B,8BAAoB,QAAQ,CAAC;AAAA,QAC/B;AAAA,MACF;AAGA,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,mBAAmB;AAGjE,WAAK,wBAAwB,oBAAI,IAAI,CAAC,GAAG,sBAAsB,GAAG,iBAAiB,CAAC;AAGpF,YAAM,KAAK,qBAAqB,gBAAgB,KAAK,qBAAqB;AAAA,IAC5E,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAc,qBAAqB,MAAc,YAAwC;AACvF,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AACF,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,EAAE,MAAM,MAAM,MAAM,KAAK,UAAU,EAAE;AAAA,MACvC;AAAA,IACF,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,aAAqB;AACnB,WAAON,QAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,UAAU,GAAG,EAAE;AAAA,EACnD;AAAA,EAEA,MAAM,gBAA+B;AACnC,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI;AAEF,YAAM,QAAQ,IAAI,2BAA2B;AAC7C,WAAK,wBAAwB;AAAA,IAC/B,UAAE;AACA,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGQ,kBAAkB,MAA+B;AACvD,UAAM,QAAQ,KAAK;AAGnB,QAAI,CAAC,MAAM,GAAI,OAAM,IAAI,MAAM,qCAAqC;AACpE,QAAI,CAAC,MAAM,KAAM,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,+BAA+B;AACpF,QAAI,CAAC,MAAM,YAAa,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,sCAAsC;AAClG,QAAI,CAAC,MAAM,OAAQ,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,sCAAsC;AAC7F,QAAI,MAAM,aAAa,UAAa,MAAM,aAAa,KAAM,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,mCAAmC;AACpI,QAAI,CAAC,MAAM,QAAS,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,kCAAkC;AAC1F,QAAI,CAAC,MAAM,QAAS,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,kCAAkC;AAC1F,QAAI,CAAC,MAAM,eAAgB,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,yCAAyC;AACxG,QAAI,CAAC,MAAM,gBAAiB,OAAM,IAAI,MAAM,YAAY,MAAM,EAAE,0CAA0C;AAE1G,UAAM,WAA+B;AAAA,MACnC,YAAY;AAAA,MACZ,OAAO,MAAM;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,iBAAiB,CAAC;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,QAChB,KAAK;AAAA,MACP,CAAC;AAAA,MACD,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM,QAAQ,SAAS;AAAA,MACpC,iBAAiB,OAAO,MAAM,YAAY,WAAW,KAAK,MAAM,MAAM,OAAO,IAAI,MAAM;AAAA,MACvF,gBAAgB,MAAM;AAAA,IACxB;AAEA,QAAI,MAAM,iBAAkB,UAAS,mBAAmB,MAAM;AAE9D,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,MAAW,cAAwB,CAAC,GAAe;AAC7E,UAAM,QAAQ,KAAK;AAGnB,QAAI,CAAC,MAAM,GAAI,OAAM,IAAI,MAAM,uCAAuC;AACtE,QAAI,CAAC,MAAM,WAAY,OAAM,IAAI,MAAM,cAAc,MAAM,EAAE,qCAAqC;AAElG,QAAI,CAAC,MAAM,KAAM,OAAM,IAAI,MAAM,cAAc,MAAM,EAAE,+BAA+B;AACtF,QAAI,CAAC,MAAM,SAAU,OAAM,IAAI,MAAM,cAAc,MAAM,EAAE,mCAAmC;AAC9F,QAAI,CAAC,MAAM,QAAS,OAAM,IAAI,MAAM,cAAc,MAAM,EAAE,kCAAkC;AAE5F,QAAI,CAAC,MAAM,WAAY,OAAM,IAAI,MAAM,cAAc,MAAM,EAAE,qCAAqC;AAGlG,UAAM,UAAU,KAAK,MAAM,MAAM,OAAO;AAGxC,UAAM,YAA8I,CAAC;AAGrJ,eAAW,cAAc,aAAa;AACpC,UAAI,YAAY;AACd,kBAAU,KAAK;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,MAAM,QAAQ;AAChB,gBAAU,KAAK;AAAA,QACb,MAAM;AAAA,QACN,QAAQ,MAAM;AAAA,QACd,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,aAAyB;AAAA,MAC7B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,IAAI,MAAM;AAAA,MACV,YAAY,MAAM;AAAA,MAClB,QAAQ;AAAA,QACN,QAAQ,MAAM;AAAA,QACd,UAAU,KAAK,MAAM,MAAM,QAAQ;AAAA,MACrC;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,SAAS,MAAM;AAAA;AAAA,IACjB;AAGA,QAAI,MAAM,SAAU,YAAW,WAAW,MAAM,SAAS,SAAS;AAClE,QAAI,MAAM,WAAW;AACnB,UAAI;AACF,mBAAW,YAAY,KAAK,MAAM,MAAM,SAAS;AAAA,MACnD,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;;;AClqCA,OAAOO,cAAa;AAEpB;AAAA,EACE,iBAAAC;AAAA,EACA,4BAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,gBAAAC;AAAA,EAIA;AAAA,OACK;AACP,SAAS,kBAAAC,uBAAsB;AAC/B,SAAS,yBAAyB;AAalC,SAAS,MAAMC,eAAc;AAK7B,IAAM,YAAYN,SAAQ,QAAQ,yBAAyB;AAC3D,IAAM,yBAAyBA,SAAQ,OAAO;AAEvC,IAAM,qBAAN,MAAkD;AAAA,EASvD,YACU,aAMA,WACR;AAPQ;AAMA;AAAA,EACP;AAAA,EAhBK,YAAqB;AAAA,EACrB,aAA2D;AAAA,EAC3D,IAAiD;AAAA;AAAA,EAGjD,wBAA4C;AAAA,EAapD,MAAM,UAAyB;AAE7B,UAAM,OAAO,KAAK,YAAY;AAC9B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,UAAM,OAAO,KAAK,YAAY;AAC9B,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,YAAQ,IAAI,+CAA+C,IAAI,IAAI,IAAI,UAAU;AAEjF,SAAK,aAAa,IAAI;AAAA,MACpB,QAAQ,IAAI,IAAI,IAAI;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,SAAK,IAAI,UAAU,EAAE,WAAW,KAAK,UAAU;AAG/C,UAAM,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO;AAEjC,SAAK,YAAY;AACjB,YAAQ,IAAI,sCAAsC;AAGlD,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AAAA,EAEA,MAAM,aAA4B;AAChC,QAAI,KAAK,YAAY;AACnB,YAAM,KAAK,WAAW,MAAM;AAAA,IAC9B;AACA,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,mBAAkC;AAI9C,YAAQ,IAAI,uDAAuD;AAAA,EACrE;AAAA;AAAA,EAGQ,iBAAiB,QAAiC;AACxD,UAAM,QAAQ,OAAO,cAAc,CAAC;AACpC,UAAM,KAAK,KAAK,iBAAiB,OAAO,IAAI;AAG5C,UAAM,aAAa,KAAK,iBAAiB,OAAO,SAAS;AACzD,UAAM,iBAAiB,KAAK,iBAAiB,OAAO,gBAAgB;AACpE,UAAM,kBAAkB,KAAK,iBAAiB,OAAO,iBAAiB;AACtE,UAAM,YAAY,KAAK,iBAAiB,OAAO,aAAa;AAE5D,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,YAAY,EAAE,kCAAkC;AACjF,QAAI,CAAC,eAAgB,OAAM,IAAI,MAAM,YAAY,EAAE,yCAAyC;AAC5F,QAAI,CAAC,gBAAiB,OAAM,IAAI,MAAM,YAAY,EAAE,0CAA0C;AAC9F,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY,EAAE,sCAAsC;AAEpF,UAAM,UAAU,OAAO,eAAe,WAAW,KAAK,MAAM,UAAU,IAAI;AAE1E,UAAM,WAA+B;AAAA,MACnC,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,MAAM,KAAK,iBAAiB,OAAO,MAAM;AAAA,MACzC,aAAa,KAAK,MAAM,KAAK,iBAAiB,OAAO,aAAa,KAAK,IAAI;AAAA,MAC3E,iBAAiB,CAAC;AAAA,QAChB;AAAA,QACA,UAAU;AAAA,QACV,KAAK;AAAA,MACP,CAAC;AAAA,MACD,UAAU,KAAK,iBAAiB,OAAO,UAAU,MAAM;AAAA,MACvD,aAAa,KAAK,iBAAiB,OAAO,SAAS;AAAA,MACnD,iBAAiB;AAAA,MACjB;AAAA,IACF;AAEA,UAAM,qBAAqB,KAAK,iBAAiB,OAAO,oBAAoB;AAC5E,UAAM,mBAAmB,KAAK,iBAAiB,OAAO,kBAAkB;AAExE,QAAI,mBAAoB,UAAS,qBAAqB;AACtD,QAAI,iBAAkB,UAAS,mBAAmB;AAElD,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,iBAAiB,OAAY,KAAkB;AACrD,QAAI,CAAC,MAAM,GAAG,EAAG,QAAO;AACxB,UAAM,OAAO,MAAM,QAAQ,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM,GAAG;AAClE,WAAO,MAAM,SAAS;AAAA,EACxB;AAAA;AAAA,EAGA,MAAc,gCAAgC,oBAAkD;AAC9F,UAAM,cAA4B,CAAC;AAEnC,eAAW,UAAU,oBAAoB;AACvC,YAAM,KAAK,KAAK,iBAAiB,OAAO,cAAc,CAAC,GAAG,IAAI;AAG9D,YAAM,qBAAqB,MAAM,KAAK,EACnC,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,IAAI,WAAW,EACf,IAAI,YAAY,EAChB,OAAO;AAEV,YAAM,cAAc,mBAAmB;AAAA,QAAI,CAAC,MAC1C,KAAK,iBAAiB,EAAE,cAAc,CAAC,GAAG,MAAM;AAAA,MAClD,EAAE,OAAO,OAAO;AAEhB,kBAAY,KAAK,KAAK,mBAAmB,QAAQ,WAAW,CAAC;AAAA,IAC/D;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,mBAAmB,QAAa,cAAwB,CAAC,GAAe;AAC9E,UAAM,QAAQ,OAAO,cAAc,CAAC;AAGpC,UAAM,aAAa,KAAK,iBAAiB,OAAO,YAAY,KAAK;AAGjE,UAAM,cAAc,KAAK,iBAAiB,OAAO,SAAS;AAC1D,UAAM,UAAU,KAAK,MAAM,WAAW;AAGtC,UAAM,YAA8I,CAAC;AAGrJ,eAAW,cAAc,aAAa;AACpC,UAAI,YAAY;AACd,kBAAU,KAAK;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,aAAa,KAAK,iBAAiB,OAAO,QAAQ;AACxD,QAAI,YAAY;AACd,gBAAU,KAAK;AAAA,QACb,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,aAAyB;AAAA,MAC7B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,IAAI,KAAK,iBAAiB,OAAO,IAAI;AAAA,MACrC;AAAA,MACA,QAAQ;AAAA,QACN,QAAQ,KAAK,iBAAiB,OAAO,YAAY;AAAA,QACjD,UAAU,KAAK,MAAM,KAAK,iBAAiB,OAAO,UAAU,KAAK,IAAI;AAAA,MACvE;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,SAAS,KAAK,iBAAiB,OAAO,SAAS;AAAA;AAAA,IACjD;AAGA,UAAM,WAAW,KAAK,iBAAiB,OAAO,UAAU;AACxD,QAAI,UAAU;AACZ,iBAAW,WAAW;AAAA,IACxB;AAEA,UAAM,gBAAgB,KAAK,iBAAiB,OAAO,WAAW;AAC9D,QAAI,eAAe;AACjB,UAAI;AACF,mBAAW,YAAY,KAAK,MAAM,aAAa;AAAA,MACjD,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,UAA2D;AAC9E,UAAM,KAAKG,eAAc,QAAQ;AACjC,UAAM,aAAaD,0BAAyB,QAAQ;AACpD,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAGA,UAAM,SAAS,KAAK,EACjB,KAAK,UAAU,EACf,SAAS,MAAM,EAAE,EACjB,SAAS,QAAQ,SAAS,IAAI,EAC9B,SAAS,eAAe,KAAK,UAAU,SAAS,WAAW,CAAC,EAC5D,SAAS,eAAe,WAAW,SAAS,EAC5C,SAAS,YAAY,SAAS,YAAY,KAAK,EAC/C,SAAS,WAAW,SAAS,WAAW,EACxC,SAAS,WAAW,KAAK,UAAU,SAAS,eAAe,CAAC,EAC5D,SAAS,kBAAkB,SAAS,cAAc,EAClD,SAAS,mBAAmB,WAAW,QAAQ;AAElD,QAAI,SAAS,oBAAoB;AAC/B,aAAO,SAAS,sBAAsB,SAAS,kBAAkB;AAAA,IACnE;AACA,QAAI,SAAS,kBAAkB;AAC7B,aAAO,SAAS,oBAAoB,SAAS,gBAAgB;AAAA,IAC/D;AAEA,UAAM,OAAO,KAAK;AAElB,YAAQ,IAAI,0CAA0C,EAAE;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,IAAqD;AACrE,UAAM,WAAW,MAAM,KAAK,EACzB,EAAE,EACF,IAAI,YAAY,MAAM,EAAE,EACxB,OAAO;AAEV,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,iBAAiB,SAAS,CAAC,CAAQ;AAAA,EACjD;AAAA,EAEA,MAAM,eAAe,IAAiB,OAAyD;AAE7F,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,MAAM,aAAa,QAAW;AACnE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,KAAK,EACR,EAAE,EACF,IAAI,YAAY,MAAM,EAAE,EACxB,SAAS,YAAY,MAAM,QAAQ,EACnC,KAAK;AAER,UAAM,kBAAkB,MAAM,KAAK,YAAY,EAAE;AACjD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,IAAgC;AAEnD,UAAM,KAAK,EACR,EAAE,EACF,IAAI,YAAY,MAAM,EAAE,EACxB,KAAK,EACL,KAAK;AAER,YAAQ,IAAI,qCAAqC,EAAE;AAAA,EACrD;AAAA,EAEA,MAAM,cAAc,QAAqF;AACvG,QAAI,iBAAiB,KAAK,EAAG,EAAE,EAAE,SAAS,UAAU;AAGpD,QAAI,OAAO,QAAQ;AAGjB,uBAAiB,eAAe,IAAI,QAAQF,SAAQ,QAAQ,MAAM,WAAW,OAAO,MAAM,CAAC;AAAA,IAC7F;AAEA,UAAM,OAAO,MAAM,eAAe,OAAO;AACzC,QAAI,YAAY,KAAK,IAAI,CAAC,MAAW,KAAK,iBAAiB,CAAC,CAAC;AAG7D,QAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AACvD,kBAAY,UAAU;AAAA,QAAO,SAC3B,OAAO,YAAa,KAAK,CAAC,SAAiB,IAAI,aAAa,SAAS,IAAI,CAAC;AAAA,MAC5E;AAAA,IACF;AAEA,UAAM,QAAQ,UAAU;AACxB,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,QAAQ,OAAO,SAAS;AAE9B,WAAO;AAAA,MACL,WAAW,UAAU,MAAM,QAAQ,SAAS,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,OAAe,OAA+C;AAClF,UAAM,SAAS,MAAM,KAAK,cAAc,EAAE,QAAQ,OAAO,OAAO,SAAS,GAAG,CAAC;AAC7E,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,iBAAiB,OAAsD;AAC3E,UAAM,KAAK,KAAK,WAAW;AAG3B,UAAM,aAAa,MAAM;AAEzB,UAAM,aAAyB;AAAA,MAC7B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAGA,UAAM,aAAaC,eAAc,MAAM,IAAI;AAC3C,UAAM,cAAcI,gBAAe,KAAK;AACxC,UAAM,WAAW,MAAM,QAAQ,MAAM,IAAI,IAAI,qBAAqB,MAAM,KAAK;AAG7E,UAAM,eAAe,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS,MAAM,OAAO;AACpF,UAAM,iBAAiB,OAAO,MAAM,WAAW,WAAW,SAAY,MAAM,OAAO;AAGnF,UAAM,SAAS,KAAK,EACjB,KAAK,YAAY,EACjB,SAAS,MAAM,EAAE,EACjB,SAAS,cAAc,YAAY,EACnC,SAAS,QAAQ,iBAAiBD,cAAa,cAAc,IAAI,EAAE,EACnE,SAAS,YAAY,KAAK,UAAU,kBAAkB,CAAC,CAAC,CAAC,EACzD,SAAS,QAAQ,QAAQ,EACzB,SAAS,cAAc,UAAU,EACjC,SAAS,WAAW,KAAK,UAAU,MAAM,OAAO,CAAC,EACjD,SAAS,WAAW,WAAW,OAAO;AAEzC,QAAI,YAAY;AACd,aAAO,SAAS,UAAU,UAAU;AAAA,IACtC;AAEA,UAAM,YAAY,MAAM,OAAO,KAAK;AAGpC,UAAM,KAAK,EACR,EAAE,UAAU,KAAK,EACjB,KAAK,YAAY,EACjB,GAAG,KAAK,EAAG,EAAE,EAAE,IAAI,YAAY,MAAM,YAAY,CAAC,EAClD,KAAK;AAGR,QAAI,YAAY;AACd,YAAM,KAAK,EACR,EAAE,UAAU,KAAK,EACjB,KAAK,YAAY,EACjB,GAAG,KAAK,EAAG,EAAE,EAAE,IAAI,YAAY,MAAM,UAAU,CAAC,EAChD,KAAK;AAAA,IACV;AAGA,eAAW,cAAc,aAAa;AAEpC,YAAM,YAAY,MAAM,KAAK,EAC1B,EAAE,EACF,IAAI,cAAc,QAAQ,UAAU,EACpC,OAAO;AAEV,UAAI;AACJ,UAAI,UAAU,WAAW,GAAG;AAE1B,mBAAW,MAAM,KAAK,EACnB,KAAK,YAAY,EACjB,SAAS,QAAQ,UAAU,EAC3B,KAAK;AAAA,MACV,OAAO;AACL,mBAAW,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,MACnC;AAGA,YAAM,KAAK,EACR,EAAE,UAAU,KAAK,EACjB,KAAK,WAAW,EAChB,GAAG,KAAK,EAAG,EAAE,SAAS,KAAK,CAAC,EAC5B,KAAK;AAAA,IACV;AAEA,YAAQ,IAAI,qCAAqC,EAAE;AACnD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,IAA+C;AACjE,UAAM,WAAW,MAAM,KAAK,EACzB,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,OAAO;AAEV,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,IACT;AAGA,UAAM,qBAAqB,MAAM,KAAK,EACnC,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,IAAI,WAAW,EACf,IAAI,YAAY,EAChB,OAAO;AAEV,UAAM,cAAc,mBAAmB;AAAA,MAAI,CAAC,MAC1C,KAAK,iBAAiB,EAAE,cAAc,CAAC,GAAG,MAAM;AAAA,IAClD,EAAE,OAAO,OAAO;AAEhB,WAAO,KAAK,mBAAmB,SAAS,CAAC,GAAU,WAAW;AAAA,EAChE;AAAA,EAEA,MAAM,iBAAiB,IAAmB,SAAmD;AAC3F,UAAM,iBAAiB,KAAK,EACzB,EAAE,EACF,IAAI,cAAc,MAAM,EAAE;AAG7B,QAAI,QAAQ,WAAW,UAAa,OAAO,QAAQ,WAAW,UAAU;AACtE,UAAI,QAAQ,OAAO,aAAa,QAAW;AACzC,cAAM,eAAe,SAAS,QAAQA,cAAa,QAAQ,OAAO,QAAQ,CAAC,EAAE,KAAK;AAClF,cAAM,eAAe,SAAS,YAAY,KAAK,UAAU,QAAQ,OAAO,QAAQ,CAAC,EAAE,KAAK;AAAA,MAC1F;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,QAAW;AAC9B,YAAM,aAAaH,eAAc,QAAQ,IAAI;AAC7C,YAAM,cAAcI,gBAAe,EAAE,MAAM,QAAQ,KAAK,CAAC;AAEzD,UAAI,YAAY;AACd,cAAM,eAAe,SAAS,UAAU,UAAU,EAAE,KAAK;AAAA,MAC3D;AAGA,UAAI,YAAY,UAAU,GAAG;AAE3B,cAAM,KAAK,EACR,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,KAAK,WAAW,EAChB,KAAK,EACL,QAAQ;AAGX,mBAAW,cAAc,aAAa;AAEpC,gBAAM,YAAY,MAAM,KAAK,EAC1B,EAAE,EACF,IAAI,cAAc,QAAQ,UAAU,EACpC,OAAO;AAEV,cAAI;AACJ,cAAI,UAAU,WAAW,GAAG;AAE1B,uBAAW,MAAM,KAAK,EACnB,KAAK,YAAY,EACjB,SAAS,QAAQ,UAAU,EAC3B,KAAK;AAAA,UACV,OAAO;AACL,uBAAW,EAAE,OAAO,UAAU,CAAC,EAAE;AAAA,UACnC;AAGA,gBAAM,cAAc,MAAM,KAAK,EAC5B,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,OAAO;AAEV,cAAI,YAAY,SAAS,GAAG;AAC1B,kBAAM,KAAK,EACR,EAAE,YAAY,CAAC,CAAC,EAChB,KAAK,WAAW,EAChB,GAAG,KAAK,EAAG,EAAE,SAAS,KAAK,CAAC,EAC5B,KAAK;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,aAAa,QAAW;AAClC,YAAM,eAAe,SAAS,YAAY,QAAQ,QAAQ,EAAE,KAAK;AAAA,IACnE;AACA,QAAI,QAAQ,cAAc,QAAW;AACnC,YAAM,eAAe,SAAS,aAAa,KAAK,UAAU,QAAQ,SAAS,CAAC,EAAE,KAAK;AAAA,IACrF;AAEA,UAAM,oBAAoB,MAAM,KAAK,cAAc,EAAE;AACrD,QAAI,CAAC,mBAAmB;AACtB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAAkC;AACvD,UAAM,KAAK,EACR,EAAE,EACF,IAAI,cAAc,MAAM,EAAE,EAC1B,KAAK,EACL,KAAK;AAER,YAAQ,IAAI,uCAAuC,EAAE;AAAA,EACvD;AAAA,EAEA,MAAM,gBAAgB,QAAuH;AAC3I,QAAI,iBAAiB,KAAK,EAAG,EAAE,EAAE,SAAS,YAAY;AAGtD,QAAI,OAAO,YAAY;AACrB,uBAAiB,eAAe,IAAI,cAAc,OAAO,UAAU;AAAA,IACrE;AAEA,QAAI,OAAO,MAAM;AACf,YAAM,UAAU,OAAO,SAAS,cAAc,gBAAgB;AAC9D,uBAAiB,eAAe,IAAI,QAAQ,OAAO;AAAA,IACrD;AAEA,UAAM,WAAW,MAAM,eAAe,OAAO;AAC7C,UAAM,cAAc,MAAM,KAAK,gCAAgC,QAAQ;AAEvE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,YAAY;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,gBAAgB;AAAA,MACjD;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,cAA4B,QAAyC;AAC1F,UAAM,YAAY,KAAK,UAAU,SAAS,QAAS;AACnD,UAAM,aAAa,MAAM,KAAK,cAAc,kBAAkB,cAAc,SAAS,CAAC;AACtF,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sBAAsB;AAIvD,UAAM,KAAK,iBAAiB,kBAAkB,cAAc,SAAS,GAAG;AAAA,MACtE,MAAM;AAAA,QACJ;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,KAAK,EACR,EAAE,EACF,IAAI,cAAc,MAAM,YAAY,EACpC,KAAK,YAAY,EACjB,GAAG,KAAK,EAAG,EAAE,EAAE,IAAI,YAAY,MAAM,MAAM,CAAC,EAC5C,KAAK;AAER,UAAM,oBAAoB,MAAM,KAAK,cAAc,kBAAkB,cAAc,SAAS,CAAC;AAC7F,QAAI,CAAC,mBAAmB;AACtB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,gBAAgB;AAAA,MACjD;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBAAoB,YAAwB,aAA+C;AAC/F,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,gBAAgB;AAAA,MACjD;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAGD,QAAI,eAAe,YAAY,SAAS,GAAG;AACzC,aAAO,YAAY,OAAO,SAAO;AAC/B,cAAM,iBAAiBA,gBAAe,GAAG;AACzC,eAAO,eAAe,KAAK,CAAC,SAAiB,YAAY,SAAS,IAAI,CAAC;AAAA,MACzE,CAAC;AAAA,IACH;AAEA,WAAO,YAAY,OAAO,SAAOA,gBAAe,GAAG,EAAE,SAAS,CAAC;AAAA,EACjE;AAAA,EAEA,MAAM,uBAAuB,YAA+C;AAC1E,UAAM,EAAE,YAAY,IAAI,MAAM,KAAK,gBAAgB,EAAE,WAAW,CAAC;AACjE,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,wBAAwBE,cAA0B,aAA6C;AAEnG,UAAM,WAAW,MAAM,KAAK,EACzB,EAAE,EACF,SAAS,YAAY,EACrB,IAAI,UAAUA,YAAW,EACzB,OAAO;AAEV,WAAO,MAAM,KAAK,gCAAgC,QAAQ;AAAA,EAC5D;AAAA,EAEA,MAAM,uBAAuB,YAAoD;AAE/E,UAAM,QAAQ,MAAM,KAAK,EACtB,EAAE,EACF,IAAI,YAAY,MAAM,UAAU,EAChC,IAAI,YAAY,EAChB,KAAK,EACL,KAAK,YAAY,EACjB,IAAI,EACJ,KAAK,EACL,OAAO;AAIV,YAAQ,IAAI,gBAAgB,MAAM,MAAM;AAGxC,UAAM,cAAiC,CAAC;AACxC,UAAM,OAAO,MAAM,KAAK,cAAc,UAAU;AAEhD,eAAW,OAAO,MAAM;AAEtB,YAAM,aAAaN,eAAc,IAAI,IAAI;AACzC,UAAI,YAAY;AACd,cAAM,YAAY,MAAM,KAAK,YAAY,YAAY,UAAU,CAAC;AAChE,YAAI,WAAW;AACb,gBAAM,WAAW,YAAY,KAAK,OAAK,EAAE,eAAe,OAAO,UAAU,EAAE;AAC3E,cAAI,UAAU;AACZ,qBAAS,YAAY,KAAK,GAAG;AAAA,UAC/B,OAAO;AACL,wBAAY,KAAK;AAAA,cACf,gBAAgB;AAAA,cAChB,aAAa,CAAC,GAAG;AAAA,cACjB,kBAAkB;AAAA,cAClB,eAAe;AAAA,YACjB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,iBAAyB,eAAuB,WAA0C;AAGvG,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,qBAAiD;AACrD,UAAM,OAAO,MAAM,KAAK,EAAG,EAAE,EAAE,SAAS,UAAU,EAAE,OAAO;AAC3D,UAAM,YAAY,KAAK,IAAI,CAAC,MAAW,KAAK,iBAAiB,CAAC,CAAC;AAE/D,UAAM,QAAQ,oBAAI,IAAoB;AAEtC,eAAW,OAAO,WAAW;AAC3B,iBAAW,QAAQ,IAAI,eAAe,CAAC,GAAG;AACxC,cAAM,IAAI,OAAO,MAAM,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAC5C;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,MAAM,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,MAAM,EAAE;AAAA,EAC7E;AAAA,EAEA,MAAM,WAAyB;AAC7B,UAAM,cAAsC,CAAC;AAC7C,UAAM,eAAuC,CAAC;AAG9C,UAAM,OAAO,MAAM,KAAK,EAAG,EAAE,EAAE,SAAS,UAAU,EAAE,OAAO;AAC3D,UAAM,YAAY,KAAK,IAAI,CAAC,MAAW,KAAK,iBAAiB,CAAC,CAAC;AAE/D,eAAW,OAAO,WAAW;AAC3B,iBAAW,QAAQ,IAAI,eAAe,CAAC,GAAG;AACxC,oBAAY,IAAI,KAAK,YAAY,IAAI,KAAK,KAAK;AAAA,MACjD;AACA,YAAM,aAAaC,0BAAyB,GAAG;AAC/C,UAAI,YAAY,WAAW;AACzB,qBAAa,WAAW,SAAS,KAAK,aAAa,WAAW,SAAS,KAAK,KAAK;AAAA,MACnF;AAAA,IACF;AAGA,UAAM,OAAO,MAAM,KAAK,EAAG,EAAE,EAAE,SAAS,YAAY,EAAE,OAAO;AAC7D,UAAM,cAAc,MAAM,KAAK,gCAAgC,IAAI;AAEnE,UAAM,aAAa,YAAY,OAAO,OAAK,EAAE,eAAe,cAAc;AAC1E,UAAM,aAAa,YAAY,OAAO,OAAK,EAAE,eAAe,SAAS;AACrE,UAAM,mBAAmB,WAAW,OAAO,OAAKG,gBAAe,CAAC,EAAE,SAAS,CAAC;AAE5E,WAAO;AAAA,MACL,eAAe,UAAU;AAAA,MACzB,iBAAiB,YAAY;AAAA,MAC7B,gBAAgB,WAAW;AAAA,MAC3B,gBAAgB,WAAW;AAAA,MAC3B,sBAAsB,iBAAiB;AAAA,MACvC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAA2D;AACjF,UAAM,UAAU,CAAC;AACjB,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,KAAK,CAAC;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,QAA0F;AAChH,UAAM,UAAU,CAAC;AACjB,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,MAAM,cAAc,MAAM,MAAM,CAAC;AAAA,IAC5E;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,aAAgD;AAEtE,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,iBAAoC;AACxC,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,WAAO,MAAM,KAAK,KAAK,qBAAsB,EAAE,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,cAAc,KAA4B;AAC9C,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,sBAAuB,IAAI,GAAG;AAGnC,QAAI;AAEF,YAAM,WAAW,MAAM,KAAK,EAAG,EAAE,EAC9B,SAAS,eAAe,EACxB,IAAI,QAAQ,cAAc,EAC1B,OAAO;AAEV,UAAI,SAAS,SAAS,GAAG;AAEvB,cAAM,KAAK,EAAG,EAAE,SAAS,CAAC,CAAC,EACxB,SAAS,QAAQ,KAAK,UAAU,MAAM,KAAK,KAAK,qBAAsB,CAAC,CAAC,EACxE,KAAK;AAAA,MACV,OAAO;AAEL,cAAM,KAAK,EAAG,KAAK,eAAe,EAC/B,SAAS,QAAQ,cAAc,EAC/B,SAAS,QAAQ,KAAK,UAAU,MAAM,KAAK,KAAK,qBAAsB,CAAC,CAAC,EACxE,KAAK;AAAA,MACV;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,MAA+B;AAClD,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,QAAQ,SAAO,KAAK,sBAAuB,IAAI,GAAG,CAAC;AAGxD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,EAAG,EAAE,EAC9B,SAAS,eAAe,EACxB,IAAI,QAAQ,cAAc,EAC1B,OAAO;AAEV,UAAI,SAAS,SAAS,GAAG;AACvB,cAAM,KAAK,EAAG,EAAE,SAAS,CAAC,CAAC,EACxB,SAAS,QAAQ,KAAK,UAAU,MAAM,KAAK,KAAK,qBAAsB,CAAC,CAAC,EACxE,KAAK;AAAA,MACV,OAAO;AACL,cAAM,KAAK,EAAG,KAAK,eAAe,EAC/B,SAAS,QAAQ,cAAc,EAC/B,SAAS,QAAQ,KAAK,UAAU,MAAM,KAAK,KAAK,qBAAsB,CAAC,CAAC,EACxE,KAAK;AAAA,MACV;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA+B,KAAK;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAc,2BAA0C;AAEtD,UAAM,cAAc,MAAM,KAAK,EAAG,EAAE,EACjC,SAAS,eAAe,EACxB,OAAO;AAEV,QAAI,oBAA8B,CAAC;AAEnC,eAAW,UAAU,aAAa;AAChC,YAAM,QAAS,OAAe,cAAc,CAAC;AAC7C,YAAM,OAAO,KAAK,iBAAiB,OAAO,MAAM;AAChD,YAAM,WAAW,KAAK,iBAAiB,OAAO,MAAM;AACpD,YAAM,OAAO,WAAW,KAAK,MAAM,QAAQ,IAAI,CAAC;AAEhD,UAAI,SAAS,gBAAgB;AAC3B,4BAAoB;AAAA,MACtB;AAAA,IACF;AAGA,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,mBAAmB;AAGjE,SAAK,wBAAwB,oBAAI,IAAI,CAAC,GAAG,sBAAsB,GAAG,iBAAiB,CAAC;AAGpF,QAAI,kBAAkB,WAAW,GAAG;AAClC,YAAM,KAAK,eAAe,CAAC,CAAC;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,aAAqB;AACnB,WAAOC,QAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,UAAU,GAAG,EAAE;AAAA,EACnD;AAAA,EAEA,MAAM,gBAA+B;AAEnC,UAAM,KAAK,EAAG,EAAE,EAAE,KAAK,EAAE,KAAK;AAE9B,SAAK,wBAAwB;AAC7B,YAAQ,IAAI,6BAA6B;AAAA,EAC3C;AACF;;;ACn4BA,SAAS,8BAA8B;AACvC,SAAS,kBAAAE,uBAAsB;AAa/B,SAAS,cAAc,sBAAsB;AAE7C,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,MAAMC,eAAc;AAC7B,SAAS,iBAAAC,gBAAe,mBAAAC,wBAAuB;AAC/C,SAAS,iBAAAC,gBAAe,4BAAAC,iCAAgC;AAQjD,IAAM,sBAAN,MAAmD;AAAA,EAChD,YAAqB;AAAA;AAAA,EAGrB,YAA6C,oBAAI,IAAI;AAAA,EACrD,cAAuC,oBAAI,IAAI;AAAA,EAEvD,YAAY,SAAc,CAAC,GAAG;AAE5B,SAAK;AAAA,EACP;AAAA,EAEA,MAAM,UAAyB;AAE7B,YAAQ,IAAI,mCAAmC;AAC/C,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,aAA4B;AAEhC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,eAAe,UAA2D;AAC9E,UAAM,KAAKD,eAAc,QAAQ;AACjC,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,0BAA0B;AAAA,IAC5C;AAeA,SAAK,UAAU,IAAI,IAAI,QAAQ;AAC/B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,IAAqD;AAMrE,WAAO,KAAK,UAAU,IAAI,EAAE,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,eAAe,IAAiB,OAAyD;AAE7F,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,MAAM,aAAa,QAAW;AACnE,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,UAAM,MAAM,KAAK,UAAU,IAAI,EAAE;AACjC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,oBAAoB;AAE9C,QAAI,WAAW,MAAM;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,IAAgC;AAQnD,SAAK,UAAU,OAAO,EAAE;AAGxB,eAAW,CAAC,OAAO,GAAG,KAAK,KAAK,aAAa;AAC3C,UAAID,iBAAgB,IAAI,MAAM,MAAM,MAAMD,eAAc,IAAI,IAAI,MAAM,IAAI;AACxE,aAAK,YAAY,OAAO,KAAK;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAAqF;AACvG,QAAI,OAAO,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC;AAE7C,QAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AACvD,aAAO,KAAK;AAAA,QAAO,SACjB,IAAI,eAAe,IAAI,YAAY,KAAK,CAAC,SAAiB,OAAO,YAAa,SAAS,IAAI,CAAC;AAAA,MAC9F;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ;AACjB,YAAM,cAAc,OAAO,OAAO,YAAY;AAC9C,aAAO,KAAK;AAAA,QAAO,SACjB,IAAI,KAAK,YAAY,EAAE,SAAS,WAAW;AAAA,MAC7C;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK;AACnB,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,QAAQ,OAAO,SAAS;AAC9B,WAAO,KAAK,MAAM,QAAQ,SAAS,KAAK;AAExC,WAAO,EAAE,WAAW,MAAM,MAAM;AAAA,EAClC;AAAA,EAEA,MAAM,gBAAgB,OAAe,QAAgB,IAAmC;AAMtF,UAAM,cAAc,MAAM,YAAY;AACtC,UAAM,UAAU,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC,EAC/C,OAAO,SAAO,IAAI,KAAK,YAAY,EAAE,SAAS,WAAW,CAAC,EAC1D,MAAM,GAAG,KAAK;AAEjB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,OAAsD;AAC3E,UAAM,KAAK,KAAK,WAAW;AAG3B,UAAM,aAAyB;AAAA,MAC7B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,QAAQ,MAAM;AAAA,MACd,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,UAAS,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC;AAEA,SAAK,YAAY,IAAI,IAAI,UAAU;AACnC,YAAQ,IAAI,+BAA+B;AAAA,MACzC;AAAA,MACA,YAAY,WAAW;AAAA,MACvB,WAAW,CAAC,CAACA,eAAc,WAAW,IAAI;AAAA,MAC1C,cAAcC,iBAAgB,WAAW,MAAM;AAAA,IACjD,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,IAA+C;AACjE,WAAO,KAAK,YAAY,IAAI,EAAE,KAAK;AAAA,EACrC;AAAA,EAEA,MAAM,iBAAiB,IAAmB,SAAmD;AAC3F,UAAM,aAAa,KAAK,YAAY,IAAI,EAAE;AAC1C,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sBAAsB;AAEvD,UAAM,UAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAKA,SAAK,YAAY,IAAI,IAAI,OAAO;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAAkC;AACvD,SAAK,YAAY,OAAO,EAAE;AAAA,EAC5B;AAAA,EAEA,MAAM,gBAAgB,QAAuH;AAC3I,QAAI,UAAU,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC;AAElD,QAAI,OAAO,YAAY;AACrB,YAAM,gBAAgB,OAAO,OAAO,UAAU;AAC9C,gBAAU,QAAQ,OAAO,OAAK;AAC5B,cAAM,eAAeA,iBAAgB,EAAE,MAAM;AAC7C,eAAO,iBAAiB,iBAAiB,iBAAiBH,aAAY,aAAa;AAAA,MACrF,CAAC;AAAA,IACH;AAGA,QAAI,OAAO,MAAM;AACf,YAAM,aAAa,OAAO,SAAS,cAAc,iBAAiB;AAClE,gBAAU,QAAQ,OAAO,OAAK,EAAE,eAAe,UAAU;AAAA,IAC3D;AAEA,WAAO,EAAE,aAAa,SAAS,OAAO,QAAQ,OAAO;AAAA,EACvD;AAAA,EAGA,MAAM,cAAc,YAA+C;AACjE,UAAM,gBAAgB,OAAO,UAAU;AACvC,UAAM,aAAa,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,EACpD,OAAO,SAAO;AACb,YAAM,eAAeG,iBAAgB,IAAI,MAAM;AAC/C,cAAQ,iBAAiB,iBAAiB,iBAAiBH,aAAY,aAAa,MAAM,IAAI,eAAe;AAAA,IAC/G,CAAC;AACH,YAAQ,IAAI,6BAA6B,UAAU,UAAU,WAAW,MAAM,aAAa;AAC3F,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,cAA4B,QAAyC;AAC1F,UAAM,aAAa,KAAK,YAAY,IAAI,YAAY;AACpD,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sBAAsB;AAGvD,UAAM,UAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,MAAM;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAEA,SAAK,YAAY,IAAI,cAAc,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,YAA+C;AACjE,UAAM,gBAAgB,OAAO,UAAU;AACvC,UAAM,aAAa,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,EACpD,OAAO,SAAO;AACb,YAAM,eAAeG,iBAAgB,IAAI,MAAM;AAC/C,cAAQ,iBAAiB,iBAAiB,iBAAiBH,aAAY,aAAa,MAAM,IAAI,eAAe;AAAA,IAC/G,CAAC;AACH,YAAQ,IAAI,6BAA6B,UAAU,UAAU,WAAW,MAAM,aAAa;AAC3F,eAAW,QAAQ,SAAO;AACxB,cAAQ,IAAI,gBAAgB;AAAA,QAC1B,IAAI,IAAI;AAAA,QACR,QAAQE,eAAc,IAAI,IAAI;AAAA,QAC9B,aAAaH,gBAAe,GAAG;AAAA;AAAA,MACjC,CAAC;AAAA,IACH,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBAAoB,YAAwB,aAA+C;AAE/F,UAAM,gBAAgB,OAAO,UAAU;AACvC,QAAI,OAAO,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,EAC5C,OAAO,SAAO;AACb,YAAM,iBAAiBA,gBAAe,GAAG;AACzC,YAAM,eAAeI,iBAAgB,IAAI,MAAM;AAC/C,cAAQ,iBAAiB,iBAAiB,iBAAiBH,aAAY,aAAa,MAAM,eAAe,SAAS;AAAA,IACpH,CAAC;AAEH,QAAI,eAAe,YAAY,SAAS,GAAG;AACzC,aAAO,KAAK,OAAO,SAAO;AACxB,cAAM,iBAAiBD,gBAAe,GAAG;AACzC,eAAO,eAAe,KAAK,CAAC,SAAiB,YAAY,SAAS,IAAI,CAAC;AAAA,MACzE,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,uBAAuB,YAA+C;AAC1E,UAAM,gBAAgB,OAAO,UAAU;AACvC,WAAO,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,EACxC,OAAO,SAAO;AACb,YAAM,eAAeI,iBAAgB,IAAI,MAAM;AAC/C,aAAO,iBAAiB,iBAAiB,iBAAiBH,aAAY,aAAa;AAAA,IACrF,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,wBAAwBA,cAA0B,aAA6C;AACnG,WAAO,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,EACxC,OAAO,SAAOE,eAAc,IAAI,IAAI,MAAMF,YAAW;AAAA,EAC1D;AAAA,EAEA,MAAM,uBAAuB,YAAoD;AAS/E,UAAM,cAAiC,CAAC;AACxC,UAAM,OAAO,MAAM,KAAK,cAAc,UAAU;AAEhD,eAAW,OAAO,MAAM;AACtB,YAAM,aAAaE,eAAc,IAAI,IAAI;AACzC,UAAI,YAAY;AACd,cAAM,YAAY,MAAM,KAAK,YAAYF,aAAY,UAAU,CAAC;AAChE,YAAI,WAAW;AACb,gBAAM,cAAc,MAAM,KAAK,cAAc,eAAe,UAAU,CAAC;AACvE,gBAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAM,gBAAgB,YAAY,KAAK,OAAK;AAC1C,kBAAM,oBAAoBE,eAAc,EAAE,IAAI;AAC9C,mBAAO,sBAAsB,iBAAiB,sBAAsBF,aAAY,aAAa;AAAA,UAC/F,CAAC;AAED,sBAAY,KAAK;AAAA,YACf,gBAAgB;AAAA,YAChB,aAAa,CAAC,GAAG;AAAA,YACjB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,gBAAwB,cAAsB,WAAmB,GAAyB;AAYvG,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,QAA6E,CAAC;AACpF,UAAM,UAAU,MAAM,KAAK,YAAYA,aAAY,cAAc,CAAC;AAElE,QAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,UAAM,KAAK,EAAE,OAAO,gBAAgB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;AAC/D,YAAQ,IAAI,cAAc;AAE1B,UAAM,QAAqB,CAAC;AAE5B,WAAO,MAAM,SAAS,KAAK,MAAM,SAAS,IAAI;AAC5C,YAAM,EAAE,OAAO,MAAM,KAAK,IAAI,MAAM,MAAM;AAE1C,UAAI,KAAK,SAAS,SAAU;AAE5B,UAAI,UAAU,cAAc;AAC1B,cAAM,KAAK,EAAE,WAAW,MAAM,aAAa,KAAK,CAAC;AACjD;AAAA,MACF;AAEA,YAAM,cAAc,MAAM,KAAK,uBAAuB,eAAe,KAAK,CAAC;AAE3E,iBAAW,QAAQ,aAAa;AAC9B,cAAM,WAAWI,eAAc,KAAK,cAAc;AAClD,YAAI,YAAY,CAAC,QAAQ,IAAI,QAAQ,GAAG;AACtC,kBAAQ,IAAI,QAAQ;AACpB,gBAAM,KAAK;AAAA,YACT,OAAO;AAAA,YACP,MAAM,CAAC,GAAG,MAAM,KAAK,cAAc;AAAA,YACnC,MAAM,CAAC,GAAG,MAAM,GAAG,KAAK,WAAW;AAAA,UACrC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,qBAAiD;AAQrD,UAAM,aAAa,oBAAI,IAAoB;AAE3C,eAAW,OAAO,KAAK,UAAU,OAAO,GAAG;AACzC,YAAM,QAAQ,uBAAuB,GAAG;AACxC,iBAAW,QAAQ,OAAO;AACxB,mBAAW,IAAI,OAAO,WAAW,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MACtD;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,WAAW,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,MAC9D;AAAA,MACA;AAAA,IACF,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,WAQH;AACD,UAAM,cAAsC,CAAC;AAC7C,UAAM,eAAuC,CAAC;AAE9C,eAAW,OAAO,KAAK,UAAU,OAAO,GAAG;AACzC,iBAAW,QAAQ,IAAI,eAAe,CAAC,GAAG;AACxC,oBAAY,IAAI,KAAK,YAAY,IAAI,KAAK,KAAK;AAAA,MACjD;AACA,YAAM,aAAaC,0BAAyB,GAAG;AAC/C,UAAI,YAAY,WAAW;AACzB,qBAAa,WAAW,SAAS,KAAK,aAAa,WAAW,SAAS,KAAK,KAAK;AAAA,MACnF;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC;AAExD,UAAM,iBAAiB,YAAY,OAAO,OAAK,EAAE,eAAe,cAAc,EAAE;AAChF,UAAM,iBAAiB,YAAY,OAAO,OAAK,EAAE,eAAe,SAAS,EAAE;AAE3E,UAAM,uBAAuB,YAAY,OAAO,OAAK,EAAE,eAAe,aAAaN,gBAAe,CAAC,EAAE,SAAS,CAAC,EAAE;AAEjH,WAAO;AAAA,MACL,eAAe,KAAK,UAAU;AAAA,MAC9B,iBAAiB,KAAK,YAAY;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAA2D;AAOjF,UAAM,UAAwB,CAAC;AAC/B,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,KAAK,CAAC;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAGA,MAAM,kBAAkB,QAAqF;AAC3G,UAAM,UAAwB,CAAC;AAC/B,eAAW,SAAS,QAAQ;AAC1B,cAAQ,KAAK,MAAM,KAAK,iBAAiB,MAAM,cAAc,MAAM,MAAM,CAAC;AAAA,IAC5E;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,aAAgD;AAGtE,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGQ,wBAA4C;AAAA,EAEpD,MAAM,iBAAoC;AAExC,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,WAAO,MAAM,KAAK,KAAK,qBAAsB,EAAE,KAAK;AAAA,EACtD;AAAA,EAEA,MAAM,cAAc,KAA4B;AAC9C,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,sBAAuB,IAAI,GAAG;AAAA,EAIrC;AAAA,EAEA,MAAM,eAAe,MAA+B;AAClD,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,KAAK,yBAAyB;AAAA,IACtC;AACA,SAAK,QAAQ,SAAO,KAAK,sBAAuB,IAAI,GAAG,CAAC;AAAA,EAE1D;AAAA,EAEA,MAAc,2BAA0C;AAQtD,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,mBAAmB;AACjE,WAAK,wBAAwB,IAAI,IAAI,oBAAoB;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,aAAqB;AACnB,WAAOE,QAAO,EAAE,QAAQ,MAAM,EAAE,EAAE,UAAU,GAAG,EAAE;AAAA,EACnD;AAAA,EAEA,MAAM,gBAA+B;AAGnC,SAAK,UAAU,MAAM;AACrB,SAAK,YAAY,MAAM;AACvB,SAAK,wBAAwB;AAAA,EAC/B;AACF;;;AC9fA,IAAI,wBAA8C;AAE3C,SAAS,oBAAoB,QAA6B,WAA6C;AAC5G,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK,WAAW;AACd,YAAM,gBAAqB,CAAC;AAC5B,UAAI,OAAO,oBAAoB,OAAW,eAAc,WAAW,OAAO;AAC1E,UAAI,OAAO,gBAAgB,OAAW,eAAc,OAAO,OAAO;AAClE,UAAI,OAAO,kBAAkB,OAAW,eAAc,SAAS,OAAO;AACtE,aAAO,IAAI,qBAAqB,aAAa;AAAA,IAC/C;AAAA,IAEA,KAAK,SAAS;AACZ,YAAM,cAAmB,CAAC;AAC1B,UAAI,OAAO,aAAa,OAAW,aAAY,MAAM,OAAO;AAC5D,UAAI,OAAO,kBAAkB,OAAW,aAAY,WAAW,OAAO;AACtE,UAAI,OAAO,kBAAkB,OAAW,aAAY,WAAW,OAAO;AACtE,UAAI,OAAO,kBAAkB,OAAW,aAAY,WAAW,OAAO;AACtE,aAAO,IAAI,mBAAmB,WAAW;AAAA,IAC3C;AAAA,IAEA,KAAK,cAAc;AACjB,YAAM,cAAmB,CAAC;AAC1B,UAAI,OAAO,cAAc,OAAW,aAAY,OAAO,OAAO;AAC9D,UAAI,OAAO,cAAc,OAAW,aAAY,OAAO,OAAO;AAC9D,UAAI,OAAO,wBAAwB,OAAW,aAAY,iBAAiB,OAAO;AAClF,UAAI,OAAO,sBAAsB,OAAW,aAAY,eAAe,OAAO;AAC9E,aAAO,IAAI,mBAAmB,aAAa,SAAS;AAAA,IACtD;AAAA,IAEA,KAAK;AACH,aAAO,IAAI,oBAAoB,CAAC,CAAC;AAAA,IAEnC;AACE,YAAM,IAAI,MAAM,oCAAoC,OAAO,IAAI,EAAE;AAAA,EACrE;AACF;AAGA,SAAS,eAAe,OAA+C;AACrE,MAAI,CAAC,MAAO,QAAO;AAGnB,SAAO,MAAM,QAAQ,kBAAkB,CAAC,OAAO,YAAY;AACzD,UAAM,WAAW,QAAQ,IAAI,OAAO;AACpC,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,wBAAwB,OAAO,+CAA+C,KAAK,EAAE;AAAA,IACvG;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,eAAsB,iBAAiB,WAAsD;AAC3F,MAAI,CAAC,uBAAuB;AAC1B,UAAM,cAAc,UAAU,SAAS;AAEvC,UAAM,SAA8B;AAAA,MAClC,MAAM,YAAY;AAAA,IACpB;AAGA,QAAI,YAAY,SAAS,cAAc;AACrC,UAAI,YAAY,MAAM;AACpB,eAAO,YAAY,YAAY;AAAA,MACjC;AACA,UAAI,YAAY,MAAM;AACpB,eAAO,YAAY,YAAY;AAAA,MACjC;AACA,UAAI,YAAY,SAAS;AACvB,eAAO,sBAAsB,YAAY;AAAA,MAC3C;AACA,UAAI,YAAY,SAAS,YAAY,UAAU,QAAQ;AACrD,eAAO,oBAAoB,YAAY;AAAA,MACzC;AAAA,IACF,WAAW,YAAY,SAAS,WAAW;AACzC,UAAI,YAAY,UAAU;AACxB,eAAO,kBAAkB,YAAY;AAAA,MACvC;AACA,UAAI,YAAY,MAAM;AACpB,eAAO,cAAc,YAAY;AAAA,MACnC;AACA,UAAI,YAAY,QAAQ;AACtB,eAAO,gBAAgB,YAAY;AAAA,MACrC;AAAA,IACF,WAAW,YAAY,SAAS,SAAS;AACvC,UAAI,YAAY,KAAK;AACnB,eAAO,WAAW,eAAe,YAAY,GAAG;AAAA,MAClD;AACA,UAAI,YAAY,UAAU;AACxB,eAAO,gBAAgB,eAAe,YAAY,QAAQ;AAAA,MAC5D;AACA,UAAI,YAAY,UAAU;AACxB,eAAO,gBAAgB,eAAe,YAAY,QAAQ;AAAA,MAC5D;AACA,UAAI,YAAY,UAAU;AACxB,eAAO,gBAAgB,eAAe,YAAY,QAAQ;AAAA,MAC5D;AAAA,IACF;AAEA,4BAAwB,oBAAoB,QAAQ,SAAS;AAC7D,UAAM,sBAAsB,QAAQ;AAAA,EACtC;AAEA,MAAI,CAAC,sBAAsB,YAAY,GAAG;AACxC,UAAM,sBAAsB,QAAQ;AAAA,EACtC;AAEA,SAAO;AACT;AAEA,eAAsB,qBAAoC;AACxD,MAAI,uBAAuB;AACzB,UAAM,sBAAsB,WAAW;AACvC,4BAAwB;AAAA,EAC1B;AACF;","names":["process","traversal","DriverRemoteConnection","entityTypes","resourceUri","targetDocId","getExactText","uuidv4","getBodySource","getTargetSource","getTargetSelector","getEntityTypes","getPrimaryRepresentation","resourceUri","gremlin","getBodySource","getPrimaryRepresentation","getResourceId","getExactText","getEntityTypes","uuidv4","resourceUri","getEntityTypes","resourceUri","uuidv4","getBodySource","getTargetSource","getResourceId","getPrimaryRepresentation"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@semiont/graph",
|
|
3
|
+
"version": "0.2.28-build.40",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Graph database abstraction with Neo4j, Neptune, JanusGraph, and in-memory implementations",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npm run typecheck && tsup",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@semiont/api-client": "*",
|
|
27
|
+
"@semiont/core": "*",
|
|
28
|
+
"@semiont/ontology": "*",
|
|
29
|
+
"uuid": "^9.0.1"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@aws-sdk/client-neptune": "^3.600.0",
|
|
33
|
+
"gremlin": "^3.7.4",
|
|
34
|
+
"neo4j-driver": "^5.28.2"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"neo4j-driver": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"gremlin": {
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
"@aws-sdk/client-neptune": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/uuid": "^9.0.8",
|
|
49
|
+
"tsup": "^8.0.1",
|
|
50
|
+
"typescript": "^5.6.3",
|
|
51
|
+
"vitest": "^3.2.4"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
},
|
|
56
|
+
"keywords": [
|
|
57
|
+
"graph-database",
|
|
58
|
+
"neo4j",
|
|
59
|
+
"neptune",
|
|
60
|
+
"janusgraph",
|
|
61
|
+
"gremlin",
|
|
62
|
+
"knowledge-graph",
|
|
63
|
+
"semantic-web"
|
|
64
|
+
],
|
|
65
|
+
"author": "The AI Alliance",
|
|
66
|
+
"license": "Apache-2.0",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "https://github.com/The-AI-Alliance/semiont.git",
|
|
70
|
+
"directory": "packages/graph"
|
|
71
|
+
}
|
|
72
|
+
}
|