@mblaney/holster 1.0.36 → 2.0.1
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/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/dist/holster.js +3 -3
- package/dist/holster.js.map +3 -3
- package/package.json +4 -5
- package/src/dup.js +4 -5
- package/src/get.js +4 -1
- package/src/ham.js +5 -2
- package/src/holster.js +78 -47
- package/src/index.js +1 -1
- package/src/radisk.js +90 -87
- package/src/sea-utils.js +1 -1
- package/src/store.js +1 -1
- package/src/user.js +0 -4
- package/src/wire.js +204 -80
- package/ts/src/dup.ts +6 -17
- package/ts/src/ham.ts +5 -1
- package/ts/src/holster.ts +66 -33
- package/ts/src/radisk.ts +87 -81
- package/ts/src/schemas.ts +1 -5
- package/ts/src/sea-utils.ts +1 -1
- package/ts/src/store.ts +1 -1
- package/ts/src/user.ts +0 -4
- package/ts/src/wire.ts +201 -69
package/dist/holster.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../ts/src/utils.ts", "../ts/src/dup.ts", "../ts/src/get.ts", "../ts/src/array.ts", "../ts/src/buffer.ts", "../ts/src/sea-utils.ts", "../ts/src/sea.ts", "../ts/src/ham.ts", "../ts/src/radix.ts", "../ts/src/radisk.ts", "../ts/src/store.ts", "../ts/src/wire.ts", "../ts/src/user.ts", "../ts/src/holster.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Utility functions for Holster\n * Provides helpers for type checking, graph manipulation, and pattern matching\n */\n\nimport type { Soul, Relation, Graph, GraphNode, LexFilter, GraphValue } from \"./schemas.ts\"\n\n// ============================================================================\n// Number Utilities\n// ============================================================================\n\nexport const num = {\n /**\n * Check if value is a valid number\n */\n is: (n: unknown): n is number => {\n if (n instanceof Array) return false\n if (typeof n === \"number\") return !isNaN(n)\n if (typeof n === \"string\") {\n const parsed = parseFloat(n)\n return !isNaN(parsed) && isFinite(parsed)\n }\n return false\n },\n}\n\n// ============================================================================\n// Object Utilities\n// ============================================================================\n\ntype PlainObject = Record<string, unknown>\n\nexport const obj = {\n /**\n * Check if value is a plain object\n */\n is: (o: unknown): o is PlainObject => {\n if (!o || typeof o !== \"object\") return false\n const toString = Object.prototype.toString.call(o)\n const match = toString.match(/^\\[object (\\w+)\\]$/)\n return (\n (o as Record<string, unknown>).constructor === Object ||\n (match !== null && match[1] === \"Object\")\n )\n },\n\n /**\n * Map over object keys with early return support\n */\n map: <T, R>(\n list: Record<string, T>,\n cb: (value: T, key: string, o?: Record<string, unknown>) => R | undefined,\n o?: Record<string, unknown>\n ): R | undefined => {\n const keys = Object.keys(list)\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n const result = cb(list[key]!, key, o)\n if (typeof result !== \"undefined\") return result\n }\n return undefined\n },\n\n /**\n * Set a property on an object\n */\n put: (o: Record<string, unknown> | undefined, key: string, value: unknown): Record<string, unknown> => {\n const target = o || {}\n target[key] = value\n return target\n },\n\n /**\n * Delete a property from an object\n */\n del: <T>(o: Record<string, T> | undefined, key: string): Record<string, T> | undefined => {\n if (!o) return undefined\n o[key] = null as T\n delete o[key]\n return o\n },\n}\n\n// ============================================================================\n// Relation Utilities\n// ============================================================================\n\nconst map_soul = (soul: unknown, key: string, o: { id: string | false }): void => {\n // If id is already defined AND we're still looping through the object,\n // then it is considered invalid\n if (o.id) {\n o.id = false\n return\n }\n\n if (key === \"#\" && typeof soul === \"string\") {\n o.id = soul\n return\n }\n\n // If there exists anything else on the object that isn't the soul,\n // then it is considered invalid\n o.id = false\n}\n\nexport const rel = {\n /**\n * Check if value is a soul relation and return the soul ID\n */\n is: (value: unknown): string | false => {\n if (\n value &&\n typeof value === \"object\" &&\n \"#\" in value &&\n !(\"_\" in value) &&\n obj.is(value)\n ) {\n const o: { id: string | false } = { id: \"\" }\n obj.map(value as Record<string, unknown>, map_soul as (value: unknown, key: string, o?: Record<string, unknown>) => void, o)\n if (o.id) return o.id\n }\n return false\n },\n\n /**\n * Convert a soul into a relation and return it\n */\n ify: (soul: Soul): Relation => obj.put({}, \"#\", soul) as Relation,\n}\n\n// ============================================================================\n// User Metadata Keys\n// ============================================================================\n\nexport const userSignature = \"_holster_user_signature\"\nexport const userPublicKey = \"_holster_user_public_key\"\n\n// ============================================================================\n// Graph Construction\n// ============================================================================\n\n/**\n * Create a graph from soul and data with optional signature metadata\n */\nexport const graph = (\n soul: Soul,\n data: Record<string, GraphValue>,\n sig?: string,\n pub?: string,\n timestamp?: number\n): Graph => {\n const ts = timestamp || Date.now()\n const stateVector: Record<string, number> = {}\n const node: GraphNode = {\n _: { \"#\": soul, \">\": stateVector },\n }\n\n for (const [key, value] of Object.entries(data)) {\n if (key !== \"_\" && key !== userPublicKey && key !== userSignature) {\n node[key] = value\n stateVector[key] = ts\n }\n }\n\n if (sig && pub && timestamp) {\n if (!node._[\"s\"]) {\n node._[\"s\"] = {}\n }\n node._[\"s\"][timestamp.toString()] = sig\n node[userPublicKey] = pub\n stateVector[userPublicKey] = timestamp\n }\n\n return { [soul]: node }\n}\n\n// ============================================================================\n// Pattern Matching\n// ============================================================================\n\n/**\n * Match a lex filter against a key\n */\nexport const match = (lex: LexFilter, key?: string): boolean => {\n // Null is used to match listeners on souls, which don't provide a key\n if (typeof key === \"undefined\") return lex === null\n\n if (typeof lex === \"undefined\") return true\n\n if (typeof lex === \"string\") return lex === key\n\n // Array support: check if key is in the array\n if (Array.isArray(lex)) return lex.includes(key)\n\n if (!obj.is(lex) || !key) return false\n\n // Prefix match\n if (\"*\" in lex) {\n const prefix = lex[\"*\"] as string\n return key.slice(0, prefix.length) === prefix\n }\n\n // Range match\n const gt = \">\" in lex ? (lex[\">\"] as string) : undefined\n const lt = \"<\" in lex ? (lex[\"<\"] as string) : undefined\n\n if (gt && lt) return key >= gt && key <= lt\n if (gt) return key >= gt\n if (lt) return key <= lt\n\n return false\n}\n\n// ============================================================================\n// Text Utilities\n// ============================================================================\n\nexport const text = {\n /**\n * Generate a random string of specified length\n */\n random: (length?: number): string => {\n let s = \"\"\n const c = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n const len = length || 24\n for (let i = 0; i < len; i++) {\n s += c.charAt(Math.floor(Math.random() * c.length))\n }\n return s\n },\n}\n\n", "/**\n * Dup - Duplicate message tracking for wire protocol\n * Prevents processing the same message multiple times\n */\n\nexport interface DupInterface {\n store: Record<string, number>\n check: (id: string) => string | false\n track: (id: string) => string\n expiry: NodeJS.Timeout | null\n}\n\n/**\n * Create a duplicate message tracker\n * @param maxAge - Maximum age of tracked messages in milliseconds (default: 9000)\n * @returns Dup interface for checking and tracking message IDs\n */\nconst Dup = (maxAge?: number): DupInterface => {\n const maxAgeMs = maxAge || 9000\n const dup: DupInterface = {\n store: {},\n expiry: null,\n check: (id: string): string | false => {\n return dup.store[id] ? dup.track(id) : false\n },\n track: (id: string): string => {\n // Keep the liveliness of the message up while it is being received\n dup.store[id] = Date.now()\n if (!dup.expiry) {\n dup.expiry = setTimeout(() => {\n if (!dup.expiry) return\n\n const now = Date.now()\n Object.keys(dup.store).forEach(id => {\n if (now - dup.store[id]! > maxAgeMs) {\n delete dup.store[id]\n }\n })\n dup.expiry = null\n }, maxAgeMs)\n }\n return id\n },\n }\n return dup\n}\n\nexport default Dup\n\n", "/**\n * Get - Query data from the graph\n * Extracts nodes and properties based on lex queries\n */\n\nimport { match, userPublicKey } from \"./utils.ts\"\nimport type { Lex, Graph } from \"./schemas.ts\"\nimport type { GraphNode } from \"./schemas.ts\"\n\n/**\n * Get data from graph based on lex query\n * @param lex - Query specification with soul and optional property filter\n * @param graph - In-memory graph\n * @param fast - If true, return current data; if false, return undefined to trigger store lookup\n */\nconst Get = (lex: Lex, graph: Graph, fast?: boolean): Graph | undefined => {\n if (!lex || typeof lex !== \"object\") {\n throw new TypeError(\"lex must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n\n const soul = lex[\"#\"]\n if (!soul || typeof soul !== \"string\") {\n throw new TypeError(\"soul must be a string\")\n }\n\n if (!graph[soul]) return undefined\n\n const stateVector: Record<string, number> = {}\n const node: GraphNode = { _: { \"#\": soul, \">\": stateVector } }\n const signatures: Record<string, string> = {}\n\n if (typeof lex[\".\"] === \"string\") {\n const key = lex[\".\"]\n if (typeof graph[soul]![key] === \"undefined\") return undefined\n\n node[key] = graph[soul]![key]\n node._[\">\"][key] = graph[soul]!._[\">\"][key]!\n const state = graph[soul]!._[\">\"][key]!\n const sigs = graph[soul]!._[\"s\"]\n if (sigs && sigs[state]) {\n signatures[state.toString()] = sigs[state]!\n }\n\n // Always include userPublicKey for verification, regardless of filter\n if (userPublicKey && typeof graph[soul]![userPublicKey] !== \"undefined\") {\n node[userPublicKey] = graph[soul]![userPublicKey]\n node._[\">\"][userPublicKey] = graph[soul]!._[\">\"][userPublicKey]!\n const pkState = graph[soul]!._[\">\"][userPublicKey]!\n const pkSigs = graph[soul]!._[\"s\"]\n if (pkSigs && pkSigs[pkState]) {\n signatures[pkState.toString()] = pkSigs[pkState]!\n }\n }\n } else {\n // For fast requests, return properties currently in the graph. Otherwise\n // return undefined to ensure we get all matching properties from store.\n if (!fast) return undefined\n\n for (const key of Object.keys(graph[soul]!)) {\n // Always include userPublicKey for verification, regardless of filter\n if (key === userPublicKey || match(lex[\".\"], key)) {\n node[key] = graph[soul]![key]!\n node._[\">\"][key] = graph[soul]!._[\">\"][key]!\n const state = graph[soul]!._[\">\"][key]!\n const sigs = graph[soul]!._[\"s\"]\n if (sigs && sigs[state]) {\n signatures[state.toString()] = sigs[state]!\n }\n }\n }\n }\n\n if (Object.keys(signatures).length > 0) {\n node._[\"s\"] = signatures\n }\n return { [soul]: node }\n}\n\nexport default Get\n\n", "/**\n * SeaArray - Extended Array with custom toString for encoding support\n * Supports utf8, hex, and base64 encoding\n */\n\nif (typeof btoa === \"undefined\") {\n globalThis.btoa = (data: string): string =>\n Buffer.from(data, \"binary\").toString(\"base64\")\n globalThis.atob = (data: string): string =>\n Buffer.from(data, \"base64\").toString(\"binary\")\n}\n\ntype Encoding = \"utf8\" | \"hex\" | \"base64\"\n\n/**\n * SeaArray extends Array to provide encoding capabilities\n */\nclass SeaArray extends Array<number> {\n /**\n * Convert array to string with specified encoding\n * @param enc - Encoding type (utf8, hex, or base64)\n * @param start - Start index (default: 0)\n * @param end - End index (default: array length)\n */\n override toString(enc?: Encoding, start?: number, end?: number): string {\n const encoding = enc || \"utf8\"\n const startIdx = start || 0\n const endIdx = end ? Math.min(Math.max(end, startIdx), this.length) : this.length\n\n if (encoding === \"hex\") {\n const buf = new Uint8Array(this.slice(startIdx, endIdx))\n return Array.from(buf, byte => byte.toString(16).padStart(2, \"0\")).join(\"\")\n }\n\n if (encoding === \"utf8\") {\n return Array.from({ length: endIdx - startIdx }, (_, i) => {\n const charCode = this[i + startIdx]\n // Use unicode replacement character for invalid character codes\n if (\n charCode === undefined ||\n charCode < 0 ||\n charCode > 0x10ffff\n ) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n }\n\n if (encoding === \"base64\") {\n const utf8String = Array.from({ length: endIdx - startIdx }, (_, i) => {\n const charCode = this[i + startIdx]\n if (charCode === undefined || charCode < 0 || charCode > 255) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n return btoa(utf8String)\n }\n\n // Default to utf8\n return this.toString(\"utf8\", startIdx, endIdx)\n }\n\n /**\n * Create SeaArray from iterable or array-like\n */\n static override from<T>(\n arrayLike: ArrayLike<T> | Iterable<T>\n ): SeaArray {\n const arr = Array.from(arrayLike) as number[]\n const seaArray = new SeaArray(...arr)\n return seaArray\n }\n}\n\nexport default SeaArray\n\n", "/**\n * SafeBuffer - Secure Buffer implementation with validation\n * Compatible with Node.js Buffer API but with enhanced security checks\n */\n\nimport SeaArray from \"./array.ts\"\n\ntype Encoding = \"utf8\" | \"utf-8\" | \"hex\" | \"base64\" | \"binary\" | \"latin1\" | \"ascii\"\n\n// Security constants\nconst SECURITY_LIMITS = {\n MAX_BUFFER_SIZE: 10 * 1024 * 1024, // 10MB limit\n MAX_STRING_LENGTH: 1024 * 1024, // 1MB string limit\n}\n\n// Type definition for SafeBuffer static interface\ninterface SafeBufferConstructor {\n (...props: unknown[]): SeaArray\n prototype: typeof Array.prototype\n from(input: string, encoding?: Encoding): SeaArray\n from(input: ArrayBuffer | ArrayBufferView | number[]): SeaArray\n from(...args: unknown[]): SeaArray\n alloc(length: number, fill?: number | string): SeaArray\n concat(arr: ArrayLike<unknown>[]): SeaArray\n isBuffer(obj: unknown): obj is SeaArray\n byteLength(string: string, encoding?: Encoding): number\n}\n\n/**\n * SafeBuffer constructor (deprecated - use SafeBuffer.from())\n */\nconst SafeBuffer = function SafeBuffer(..._props: unknown[]): SeaArray {\n console.warn(\"new SafeBuffer() is deprecated, please use SafeBuffer.from()\")\n // Will be implemented after from() is defined\n return SeaArray.from([])\n} as SafeBufferConstructor\n\nSafeBuffer.prototype = Object.create(Array.prototype)\n\n// ============================================================================\n// Input Validation Helpers\n// ============================================================================\n\nconst validateStringInput = (input: string, _encoding: Encoding): void => {\n if (input.length > SECURITY_LIMITS.MAX_STRING_LENGTH) {\n throw new RangeError(\n `String too large: ${input.length} > ${SECURITY_LIMITS.MAX_STRING_LENGTH}`\n )\n }\n}\n\nconst validateBufferSize = (size: number, operation = \"buffer operation\"): void => {\n if (size > SECURITY_LIMITS.MAX_BUFFER_SIZE) {\n throw new RangeError(\n `Buffer size too large for ${operation}: ${size} > ${SECURITY_LIMITS.MAX_BUFFER_SIZE}`\n )\n }\n}\n\n// ============================================================================\n// Encoding Parsers\n// ============================================================================\n\nconst parseHexString = (hexString: string): Uint8Array => {\n validateStringInput(hexString, \"hex\")\n\n const cleanHex = hexString.replace(/\\s/g, \"\").toLowerCase()\n\n if (!/^[0-9a-f]*$/.test(cleanHex)) {\n throw new TypeError(\"Invalid hex string: contains non-hex characters\")\n }\n\n if (cleanHex.length % 2 !== 0) {\n throw new TypeError(\"Invalid hex string: must have even length\")\n }\n\n if (cleanHex.length === 0) {\n return new Uint8Array(0)\n }\n\n validateBufferSize(cleanHex.length / 2, \"hex parsing\")\n\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n const hexByte = cleanHex.substr(i, 2)\n bytes[i / 2] = parseInt(hexByte, 16)\n }\n return bytes\n}\n\nconst encodeUtf8String = (str: string): Uint8Array => {\n validateStringInput(str, \"utf8\")\n\n try {\n const encoder = new TextEncoder()\n const bytes = encoder.encode(str)\n validateBufferSize(bytes.length, \"UTF-8 encoding\")\n return bytes\n } catch (err) {\n throw new TypeError(`Failed to encode UTF-8 string: ${(err as Error).message}`)\n }\n}\n\nconst encodeBinaryString = (str: string): Uint8Array => {\n validateStringInput(str, \"binary\")\n validateBufferSize(str.length, \"binary encoding\")\n\n const bytes = new Uint8Array(str.length)\n for (let i = 0; i < str.length; i++) {\n const charCode = str.charCodeAt(i)\n if (charCode > 255) {\n throw new TypeError(\n `Invalid binary string: character at position ${i} exceeds byte range (${charCode} > 255)`\n )\n }\n bytes[i] = charCode\n }\n return bytes\n}\n\nconst parseBase64String = (base64String: string): Uint8Array => {\n validateStringInput(base64String, \"base64\")\n\n const cleanBase64 = base64String.replace(/\\s/g, \"\")\n\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\n throw new TypeError(\"Invalid base64 string: contains invalid characters\")\n }\n\n try {\n const decodedString = atob(cleanBase64)\n validateBufferSize(decodedString.length, \"base64 decoding\")\n\n const bytes = new Uint8Array(decodedString.length)\n for (let i = 0; i < decodedString.length; i++) {\n bytes[i] = decodedString.charCodeAt(i)\n }\n return bytes\n } catch (err) {\n throw new TypeError(`Failed to decode base64 string: ${(err as Error).message}`)\n }\n}\n\nconst processArrayLikeInput = (input: unknown): Uint8Array => {\n if (input instanceof ArrayBuffer) {\n validateBufferSize(input.byteLength, \"ArrayBuffer processing\")\n return new Uint8Array(input)\n }\n\n if (ArrayBuffer.isView(input)) {\n validateBufferSize(input.byteLength, \"TypedArray processing\")\n return new Uint8Array(input.buffer, input.byteOffset, input.byteLength)\n }\n\n if (Array.isArray(input)) {\n validateBufferSize(input.length, \"Array processing\")\n\n for (let i = 0; i < input.length; i++) {\n const val = input[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`\n )\n }\n }\n return new Uint8Array(input)\n }\n\n if (\n typeof input === \"object\" &&\n input !== null &&\n \"byteLength\" in input &&\n typeof (input as { byteLength: unknown }).byteLength === \"number\"\n ) {\n validateBufferSize((input as { byteLength: number }).byteLength, \"ArrayBuffer-like processing\")\n return new Uint8Array(input as ArrayBuffer)\n }\n\n if (\n typeof input === \"object\" &&\n input !== null &&\n \"length\" in input &&\n typeof (input as { length: unknown }).length === \"number\"\n ) {\n const arrayLike = input as ArrayLike<unknown>\n validateBufferSize(arrayLike.length, \"array-like processing\")\n\n const arr = Array.from(arrayLike)\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`\n )\n }\n }\n return new Uint8Array(arr as number[])\n }\n\n throw new TypeError(\"Unsupported input type: \" + typeof input)\n}\n\n// ============================================================================\n// SafeBuffer Static Methods\n// ============================================================================\n\nObject.assign(SafeBuffer, {\n from(...args: unknown[]): SeaArray {\n const argCount = args.length\n\n if (argCount === 0) {\n throw new TypeError(\"SafeBuffer.from() requires at least one argument\")\n }\n\n const input = args[0]\n\n if (input === null || input === undefined) {\n throw new TypeError(\"First argument must not be null or undefined\")\n }\n\n let bytes: Uint8Array\n\n if (typeof input === \"string\") {\n const encoding = ((args[1] as string) || \"utf8\").toLowerCase() as Encoding\n\n switch (encoding) {\n case \"hex\":\n bytes = parseHexString(input)\n break\n\n case \"utf8\":\n case \"utf-8\":\n bytes = encodeUtf8String(input)\n break\n\n case \"binary\":\n case \"latin1\":\n bytes = encodeBinaryString(input)\n break\n\n case \"base64\":\n bytes = parseBase64String(input)\n break\n\n case \"ascii\":\n validateStringInput(input, \"ascii\")\n for (let i = 0; i < input.length; i++) {\n if (input.charCodeAt(i) > 127) {\n throw new TypeError(\n `Invalid ASCII character at position ${i}: ${input.charCodeAt(i)} > 127`\n )\n }\n }\n bytes = encodeUtf8String(input)\n break\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n } else {\n bytes = processArrayLikeInput(input)\n }\n\n if (!bytes || bytes.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n try {\n return SeaArray.from(bytes)\n } catch (err) {\n throw new Error(`Failed to create SafeBuffer: ${(err as Error).message}`)\n }\n },\n\n alloc(length: number, fill: number | string = 0): SeaArray {\n if (typeof length !== \"number\" || !Number.isInteger(length) || length < 0) {\n throw new TypeError(\"Length must be a non-negative integer\")\n }\n\n validateBufferSize(length, \"buffer allocation\")\n\n let fillValue: number\n if (typeof fill === \"number\") {\n if (fill < 0 || fill > 255 || !Number.isInteger(fill)) {\n throw new TypeError(\"Fill value must be an integer between 0 and 255\")\n }\n fillValue = fill\n } else if (typeof fill === \"string\") {\n if (fill.length !== 1) {\n throw new TypeError(\"Fill string must be exactly one character\")\n }\n fillValue = fill.charCodeAt(0)\n if (fillValue > 255) {\n throw new TypeError(\"Fill character code must be <= 255\")\n }\n } else {\n throw new TypeError(\"Fill must be a number or single character string\")\n }\n\n try {\n const buffer = new Uint8Array(length)\n if (fillValue !== 0) {\n buffer.fill(fillValue)\n }\n return SeaArray.from(buffer)\n } catch (err) {\n throw new Error(`Failed to allocate buffer: ${(err as Error).message}`)\n }\n },\n\n concat(arr: ArrayLike<unknown>[]): SeaArray {\n if (!Array.isArray(arr)) {\n throw new TypeError(\"First argument must be an array\")\n }\n\n if (arr.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n let totalLength = 0\n const validatedBuffers: Uint8Array[] = []\n\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]\n\n if (!item) {\n throw new TypeError(`Array element at index ${i} is null or undefined`)\n }\n\n let bytes: Uint8Array\n try {\n bytes = processArrayLikeInput(item)\n } catch (err) {\n throw new TypeError(\n `Invalid array element at index ${i}: ${(err as Error).message}`\n )\n }\n\n totalLength += bytes.length\n validateBufferSize(totalLength, \"buffer concatenation\")\n validatedBuffers.push(bytes)\n }\n\n try {\n const result = new Uint8Array(totalLength)\n let offset = 0\n\n for (const buffer of validatedBuffers) {\n result.set(buffer, offset)\n offset += buffer.length\n }\n\n return SeaArray.from(result)\n } catch (err) {\n throw new Error(`Failed to concatenate buffers: ${(err as Error).message}`)\n }\n },\n\n isBuffer(obj: unknown): obj is SeaArray {\n return (\n obj instanceof SeaArray ||\n (obj !== null &&\n typeof obj === \"object\" &&\n (obj as { constructor?: unknown }).constructor === SafeBuffer)\n )\n },\n\n byteLength(string: string, encoding: Encoding = \"utf8\"): number {\n if (typeof string !== \"string\") {\n throw new TypeError(\"First argument must be a string\")\n }\n\n switch (encoding.toLowerCase()) {\n case \"utf8\":\n case \"utf-8\":\n return new TextEncoder().encode(string).length\n\n case \"ascii\":\n case \"binary\":\n case \"latin1\":\n return string.length\n\n case \"base64\": {\n const clean = string.replace(/\\s/g, \"\")\n return (\n Math.floor((clean.length * 3) / 4) - (clean.match(/=/g) || []).length\n )\n }\n\n case \"hex\":\n return Math.floor(string.replace(/\\s/g, \"\").length / 2)\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n },\n})\n\n// Add instance method for toString\nSafeBuffer.prototype.toString = function (\n this: SeaArray,\n encoding: Encoding = \"utf8\",\n start = 0,\n end = this.length\n): string {\n if (typeof encoding !== \"string\") {\n throw new TypeError(\"Encoding must be a string\")\n }\n\n if (typeof start !== \"number\" || !Number.isInteger(start) || start < 0) {\n throw new TypeError(\"Start must be a non-negative integer\")\n }\n\n if (typeof end !== \"number\" || !Number.isInteger(end) || end < start) {\n throw new TypeError(\"End must be an integer >= start\")\n }\n\n try {\n return SeaArray.prototype.toString.call(\n this,\n encoding as \"utf8\" | \"hex\" | \"base64\",\n start,\n end\n )\n } catch (err) {\n throw new Error(`Failed to convert buffer to string: ${(err as Error).message}`)\n }\n}\n\nexport default SafeBuffer\n\n", "/**\n * SEA Utilities - Cryptographic utility functions\n * Provides helpers for encryption, hashing, and key management\n */\n\nimport SafeBuffer from \"./buffer.ts\"\nimport type { JWK } from \"./schemas.ts\"\n\nconst isNode = typeof document === \"undefined\"\n\n// Get crypto based on environment - dynamic import for Node.js compatibility\nconst crypto: Crypto = isNode\n ? ((await import(/*webpackIgnore: true*/ \"node:crypto\")).webcrypto as Crypto)\n : globalThis.crypto\n\nexport const subtle = crypto.subtle\n\n/**\n * Convert data to string format for cryptographic operations\n */\nexport const stringify = (data: unknown): string => {\n return typeof data === \"string\" ? data : JSON.stringify(data)\n}\n\n/**\n * Parse JSON text safely\n */\nexport const parse = (text: string): unknown => {\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/**\n * Generate cryptographically secure random bytes\n */\nexport const random = (length: number): SeaArray => {\n const array = new Uint8Array(length)\n const filled = crypto.getRandomValues(array)\n return SafeBuffer.from(filled)\n}\n\n/**\n * Create JWK from public and optional private key components\n */\nexport const jwk = (pub: string, priv?: string): JWK => {\n const [x, y] = pub.split(\".\")\n const ops = priv ? [\"sign\"] : [\"verify\"]\n return {\n kty: \"EC\",\n crv: \"P-256\",\n x: x!,\n y: y!,\n d: priv,\n ext: true,\n key_ops: ops,\n }\n}\n\n/**\n * SHA-256 hash of data\n */\nexport const sha256 = async (data: unknown): Promise<SeaArray> => {\n const hash = await subtle.digest(\n { name: \"SHA-256\" },\n new TextEncoder().encode(stringify(data))\n )\n return SafeBuffer.from(new Uint8Array(hash))\n}\n\n/**\n * Derive AES key from password and salt \n */\nexport const aeskey = async (\n key: string,\n salt: SeaArray\n) => {\n const combined = key + salt.toString(\"utf8\")\n const hashResult = await sha256(combined)\n const jwkKey = keyToJwk(hashResult)\n return await subtle.importKey(\"jwk\", jwkKey, { name: \"AES-GCM\" }, false, [\n \"encrypt\",\n \"decrypt\",\n ])\n}\n\n/**\n * Convert key buffer to JWK format for AES\n */\nconst keyToJwk = (key: SeaArray): JWK => {\n const k = key\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\")\n return { kty: \"oct\", k: k, ext: false, alg: \"A256GCM\" }\n}\n\n// Re-export SeaArray type for convenience\nimport type SeaArray from \"./array.ts\"\n\n", "/**\n * SEA - Security, Encryption, and Authorization\n * Cryptographic functions for signing, verification, encryption, and decryption\n */\n\nimport { userPublicKey, userSignature } from \"./utils.ts\"\nimport * as utils from \"./sea-utils.ts\"\nimport SafeBuffer from \"./buffer.ts\"\nimport type {\n UserPair,\n EncryptedData,\n SignedData,\n} from \"./schemas.ts\"\n\ntype Callback<T> = (result: T) => void\n\n/**\n * SEA cryptographic operations\n */\nconst SEA = {\n /**\n * Generate a new ECDSA + ECDH key pair\n */\n pair: async (cb?: Callback<UserPair>): Promise<UserPair> => {\n // ECDSA keys for signing/verifying\n const ecdsa = await utils.subtle\n .generateKey({ name: \"ECDSA\", namedCurve: \"P-256\" }, true, [\n \"sign\",\n \"verify\",\n ])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n priv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d!,\n pub: pub.x! + \".\" + pub.y!,\n }\n })\n\n // ECDH keys for encryption/decryption\n const ecdh = await utils.subtle\n .generateKey({ name: \"ECDH\", namedCurve: \"P-256\" }, true, [\"deriveKey\"])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n epriv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d!,\n epub: pub.x! + \".\" + pub.y!,\n }\n })\n\n const pair: UserPair = {\n pub: ecdsa.pub,\n priv: ecdsa.priv,\n epub: ecdh.epub,\n epriv: ecdh.epriv,\n }\n if (cb) cb(pair)\n return pair\n },\n\n /**\n * Encrypt data with a key pair\n */\n encrypt: async (\n data: unknown,\n pair: Partial<UserPair> | null,\n cb?: Callback<EncryptedData | null>\n ): Promise<EncryptedData | null> => {\n if (!pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const rand = { s: utils.random(9), iv: utils.random(15) }\n const ct = await utils.aeskey(pair.epriv, rand.s).then(aes => {\n return utils.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(rand.iv),\n },\n aes,\n new TextEncoder().encode(utils.stringify(data))\n )\n })\n const enc: EncryptedData = {\n ct: SafeBuffer.from(ct, \"binary\").toString(\"base64\"),\n iv: rand.iv.toString(\"base64\"),\n s: rand.s.toString(\"base64\"),\n }\n if (cb) cb(enc)\n return enc\n },\n\n /**\n * Decrypt data with a key pair\n */\n decrypt: async (\n enc: Partial<EncryptedData> | null,\n pair: Partial<UserPair> | null,\n cb?: Callback<unknown | null>\n ): Promise<unknown | null> => {\n if (!enc || !enc.ct || !enc.iv || !enc.s || !pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const data = {\n ct: SafeBuffer.from(enc.ct, \"base64\"),\n iv: SafeBuffer.from(enc.iv, \"base64\"),\n s: SafeBuffer.from(enc.s, \"base64\"),\n }\n try {\n const ct = await utils.aeskey(pair.epriv, data.s).then(aes => {\n return utils.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(data.iv),\n tagLength: 128,\n },\n aes,\n new Uint8Array(data.ct)\n )\n })\n const dec = utils.parse(new TextDecoder(\"utf8\").decode(ct))\n if (cb) cb(dec)\n return dec\n } catch (err) {\n // An error will be thrown if the wrong key is used\n if (cb) cb(null)\n return null\n }\n },\n\n /**\n * Verify a signed message\n */\n verify: async (\n data: string | SignedData,\n pair: Partial<UserPair> | null,\n cb?: Callback<unknown | null>\n ): Promise<unknown | null> => {\n if (!pair || !pair.pub) {\n if (cb) cb(null)\n return null\n }\n\n const signed = (\n typeof data === \"string\" ? utils.parse(data) : data\n ) as SignedData\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(pair.pub),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"]\n )\n\n let msg: string | Record<string, unknown> = {}\n if (typeof signed.m === \"string\") {\n msg = signed.m\n } else {\n // Allow data to be passed in with graph meta data,\n // (which should not be part of signature, so not verified)\n for (const k of Object.keys(signed.m).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n (msg as Record<string, unknown>)[k] = signed.m[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const sig = new Uint8Array(SafeBuffer.from(signed.s, \"base64\"))\n const alg = { name: \"ECDSA\", hash: { name: \"SHA-256\" } }\n if (await utils.subtle.verify(alg, key, sig, new Uint8Array(hash))) {\n const verified = utils.parse(signed.m as string)\n if (cb) cb(verified)\n return verified\n }\n\n if (cb) cb(null)\n return null\n },\n\n /**\n * Sign data with a key pair\n */\n sign: async (\n data: string | Record<string, unknown>,\n pair: Partial<UserPair> | null,\n cb?: Callback<SignedData | null>\n ): Promise<SignedData | null> => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n let msg: string | Record<string, unknown> = {}\n if (typeof data === \"string\") {\n msg = data\n } else {\n const check = utils.parse(data as never) as Record<string, unknown>\n for (const k of Object.keys(check).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n (msg as Record<string, unknown>)[k] = check[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = { name: \"ECDSA\", namedCurve: \"P-256\" }\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n { name: \"ECDSA\", hash: { name: \"SHA-256\" } },\n key,\n new Uint8Array(hash)\n )\n )\n const signed: SignedData = {\n m: msg,\n s: SafeBuffer.from(sig, \"binary\").toString(\"base64\"),\n }\n\n if (cb) cb(signed)\n return signed\n },\n\n /**\n * Sign a timestamp to prove ownership of an update\n */\n signTimestamp: async (\n timestamp: number,\n pair: Partial<UserPair> | null,\n cb?: Callback<string | null>\n ): Promise<string | null> => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = { name: \"ECDSA\", namedCurve: \"P-256\" }\n\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n { name: \"ECDSA\", hash: { name: \"SHA-256\" } },\n key,\n new Uint8Array(hash)\n )\n )\n\n const signature = SafeBuffer.from(sig, \"binary\").toString(\"base64\")\n\n if (cb) cb(signature)\n return signature\n },\n\n /**\n * Verify a timestamp signature to confirm ownership of update\n */\n verifyTimestamp: async (\n timestamp: number,\n signature: string,\n publicKey: string,\n cb?: Callback<boolean>\n ): Promise<boolean> => {\n if (!publicKey || !timestamp || !signature) {\n if (cb) cb(false)\n return false\n }\n\n try {\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(publicKey),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"]\n )\n\n const sig = new Uint8Array(SafeBuffer.from(signature, \"base64\"))\n const alg = { name: \"ECDSA\", hash: { name: \"SHA-256\" } }\n\n const isValid = await utils.subtle.verify(\n alg,\n key,\n sig,\n new Uint8Array(hash)\n )\n\n if (cb) cb(isValid)\n return isValid\n } catch (err) {\n console.log(`error verifying timestamp signature: ${(err as Error).message}`)\n if (cb) cb(false)\n return false\n }\n },\n\n /**\n * Key derivation using PBKDF2\n */\n work: async (\n data: unknown,\n salt?: unknown,\n cb?: Callback<{ epriv: string }>\n ): Promise<{ epriv: string }> => {\n let _cb = cb\n let _salt = salt\n\n if (typeof salt === \"function\") {\n _cb = salt as Callback<{ epriv: string }>\n _salt = undefined\n }\n if (typeof _salt === \"undefined\") _salt = utils.random(9)\n\n const key = await utils.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(utils.stringify(data)),\n { name: \"PBKDF2\" },\n false,\n [\"deriveBits\"]\n )\n const alg = {\n name: \"PBKDF2\",\n iterations: 100000,\n salt: new TextEncoder().encode(_salt as string),\n hash: { name: \"SHA-256\" },\n }\n const work = await utils.subtle.deriveBits(alg, key, 512)\n // Use \"pair\" format so that work can be used as epriv by decrypt\n const pair = { epriv: SafeBuffer.from(work, \"binary\").toString(\"base64\") }\n if (_cb) _cb(pair)\n return pair\n },\n\n /**\n * Derive shared secret using ECDH\n */\n secret: async (\n to: Partial<UserPair> | null,\n from: Partial<UserPair> | null,\n cb?: Callback<{ epriv: string } | null>\n ): Promise<{ epriv: string } | null> => {\n if (!to || !to.epub || !from || !from.epub || !from.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const alg = { name: \"ECDH\", namedCurve: \"P-256\" }\n const pub = utils.jwk(to.epub)\n const pubKey = await utils.subtle.importKey(\"jwk\", pub, alg, true, [])\n const priv = utils.jwk(from.epub, from.epriv)\n // utils.jwk provides default key_ops but it shouldn't be used here\n delete (priv as { key_ops?: unknown }).key_ops\n const derived = await utils.subtle\n .importKey(\"jwk\", priv, alg, false, [\"deriveBits\"])\n .then(async key => {\n const derivedBits = await utils.subtle.deriveBits(\n { public: pubKey, name: \"ECDH\", namedCurve: \"P-256\" } as never,\n key,\n 256\n )\n const derivedKey = await utils.subtle.importKey(\n \"raw\",\n new Uint8Array(derivedBits),\n { name: \"AES-GCM\", length: 256 },\n true,\n [\"encrypt\", \"decrypt\"]\n )\n return utils.subtle.exportKey(\"jwk\", derivedKey).then(({ k }) => k!)\n })\n // Use \"pair\" format so that secret can be used as epriv by encrypt\n if (cb) cb({ epriv: derived })\n return { epriv: derived }\n },\n}\n\nexport default SEA\n\n", "/**\n * HAM - Hypothetical Amnesia Machine\n * Conflict resolution algorithm for distributed data synchronization\n */\n\nimport * as utils from \"./utils.ts\"\nimport SEA from \"./sea.ts\"\nimport type {\n Graph,\n GraphNode,\n GraphValue,\n HamResult,\n HamMixResult,\n ListenMap,\n Timestamp,\n} from \"./schemas.ts\"\n\n// Maximum number of souls to keep in memory\nconst MAX_GRAPH_SIZE = 10000\n\n/**\n * Compare incoming state with current state to determine which value wins\n * @param state - Incoming timestamp\n * @param currentState - Current timestamp\n * @param value - Incoming value\n * @param currentValue - Current value\n * @param signed - Whether the update has a verified signature\n */\nconst Ham = (\n state: Timestamp,\n currentState: Timestamp,\n value: GraphValue,\n currentValue: GraphValue,\n signed = false\n): HamResult => {\n if (state < currentState) return { historical: true }\n\n if (state > currentState) return { incoming: true }\n\n // state is equal to currentState. Old data is expected to propagate through\n // the network, but conflicting values with same signed timestamp are ignored\n // since the owner can only create one value per timestamp.\n if (signed && value !== currentValue) {\n return { historical: true }\n }\n\n // Lexically compare to resolve conflict (for unsigned or matching values)\n let valueStr = typeof value !== \"string\" ? JSON.stringify(value) || \"\" : value\n let currentValueStr =\n typeof currentValue !== \"string\"\n ? JSON.stringify(currentValue) || \"\"\n : currentValue\n\n // No update required\n if (valueStr === currentValueStr) return { state: true }\n\n // Keep the current value\n if (valueStr < currentValueStr) return { current: true }\n\n // Otherwise update using the incoming value\n return { incoming: true }\n}\n\n/**\n * Mix incoming changes into the graph with conflict resolution\n */\nHam.mix = async (\n change: Graph,\n graph: Graph,\n secure: boolean,\n listen: ListenMap\n): Promise<HamMixResult> => {\n if (!change || typeof change !== \"object\") {\n throw new TypeError(\"change must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n if (!listen || typeof listen !== \"object\") {\n throw new TypeError(\"listen must be an object\")\n }\n\n const machine = Date.now()\n const now: Graph = {}\n const defer: Graph = {}\n const listeners: Array<() => void> = []\n const validProperties = new Map<string, Set<string>>()\n const validTimestamps = new Map<string, Set<number>>()\n let wait = 0\n\n for (const soul of Object.keys(change)) {\n const node = change[soul]\n if (!node || !node._) continue\n\n let updated = false\n let alias = false\n let verify = secure\n\n const pub = node[utils.userPublicKey] as string | undefined\n // If timestamp signatures and public key are provided then always verify\n if (node._[\"s\"] && pub) verify = true\n\n // Special case if soul starts with \"~\". Node must be system data ie,\n // ~@alias or ~publickey. For aliases, key and value must be a self\n // identifying rel. For public keys, data needs to be signed and verified.\n if (soul.length > 1 && soul[0] === \"~\") {\n if (soul[1] === \"@\") {\n alias = true\n verify = false\n } else {\n if (pub && soul !== \"~\" + pub) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n verify = true\n }\n }\n\n if (verify) {\n if (!pub || !node._) {\n continue\n }\n\n const signedTimestamps = new Set<number>()\n const signedProperties = new Set<string>()\n\n const incomingTimestamps = Object.entries(node._[\">\"] || {})\n\n for (const [key, sig] of Object.entries(node._[\"s\"] || {})) {\n const asNumber = Number(key)\n if (!isNaN(asNumber) && asNumber > 0) {\n const propsForTimestamp = incomingTimestamps.filter(\n ([, ts]) => Number(ts) === asNumber,\n )\n const allNewerInGraph =\n propsForTimestamp.length > 0 &&\n propsForTimestamp.every(([prop]) => {\n const graphState =\n graph[soul] && graph[soul]!._[\">\"] ? graph[soul]!._[\">\"][prop] : 0\n return graphState !== undefined && graphState > asNumber\n })\n\n if (allNewerInGraph) {\n continue\n }\n\n const isValid = await SEA.verifyTimestamp(asNumber, sig as string, pub)\n if (isValid) {\n signedTimestamps.add(asNumber)\n for (const [prop, ts] of incomingTimestamps) {\n if (Number(ts) === asNumber) {\n signedProperties.add(prop)\n }\n }\n }\n }\n }\n\n if (signedProperties.size === 0) {\n continue\n }\n\n validProperties.set(soul, signedProperties)\n validTimestamps.set(soul, signedTimestamps)\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n if (validProperties.has(soul) && !validProperties.get(soul)!.has(key)) {\n continue\n }\n\n const value = node[key]!\n const state = (node._ && node._[\">\"] ? node._[\">\"][key] : 0) || 0\n const currentValue = graph[soul] ? graph[soul][key] : undefined\n const currentState = graph[soul] ? (graph[soul]._[\">\"][key] || 0) : 0\n\n if (alias && key !== utils.rel.is(value)) {\n console.log(`error alias ${alias}: ${key} !== ${utils.rel.is(value)}`)\n continue\n }\n\n const skew = state - machine\n if (skew > 0) {\n if (skew > 86400000) continue\n\n if (wait === 0 || skew < wait) wait = skew\n if (!defer[soul]) {\n const stateVector: Record<string, number> = {}\n const signatures: Record<string, string> | undefined = {}\n defer[soul] = { _: { \"#\": soul, \">\": stateVector, s: signatures } } as GraphNode\n }\n defer[soul]![key] = value\n defer[soul]!._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n defer[soul]!._[\"s\"]![state] = node._[\"s\"][state]\n }\n } else {\n const isSigned =\n validTimestamps.has(soul) && validTimestamps.get(soul)!.has(state)\n const result = Ham(state, currentState, value, currentValue ?? null, isSigned)\n if (result.incoming) {\n if (!now[soul]) {\n const stateVector1: Record<string, number> = {}\n const signatures1: Record<string, string> | undefined = {}\n now[soul] = { _: { \"#\": soul, \">\": stateVector1, s: signatures1 } } as GraphNode\n }\n if (!graph[soul]) {\n const stateVector2: Record<string, number> = {}\n const signatures2: Record<string, string> | undefined = {}\n graph[soul] = { _: { \"#\": soul, \">\": stateVector2, s: signatures2 } } as GraphNode\n }\n graph[soul]![key] = now[soul]![key] = value\n graph[soul]!._[\">\"][key] = now[soul]!._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n graph[soul]!._[\"s\"]![state] = now[soul]!._[\"s\"]![state] = node._[\"s\"][state]\n }\n\n if (listen[soul]) {\n listen[soul]!\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => listeners.push(l.cb as () => void))\n }\n updated = true\n }\n }\n }\n\n if (updated && listen[soul]) {\n listen[soul]!\n .filter(l => utils.match(l[\".\"]))\n .forEach(l => listeners.push(l.cb as () => void))\n }\n }\n\n const souls = Object.keys(graph)\n if (souls.length > MAX_GRAPH_SIZE) {\n const soulsByAge = souls\n .map(soul => {\n const states = graph[soul]!._ && graph[soul]!._[\">\"]\n const maxState = states ? Math.max(...Object.values(states)) : 0\n return { soul, maxState }\n })\n .sort((a, b) => a.maxState - b.maxState)\n const remove = soulsByAge.slice(0, souls.length - MAX_GRAPH_SIZE)\n remove.forEach(({ soul }) => delete graph[soul])\n }\n\n return { now, defer, wait, listeners }\n}\n\nexport default Ham\n\n", "/**\n * Radix - Radix tree implementation for efficient key-value storage\n * Supports prefix-based key compression\n */\n\nimport * as utils from \"./utils.ts\"\nimport type { EncodedValue, RadixFunction } from \"./schemas.ts\"\n\n// ASCII character for group separator\nconst group = String.fromCharCode(29)\n// ASCII character for record separator\nconst record = String.fromCharCode(30)\n\n// Local type for internal radix tree structure (different from schemas.RadixValue)\n// This represents the internal node structure with dynamic keys\ninterface RadixValue {\n [key: string]: RadixTree | EncodedValue | undefined\n}\n\n// RadixTree is the internal tree structure (also known as RadixNode in schemas)\ntype RadixTree = Record<string, RadixValue>\n// Alias for compatibility with schema types\ntype RadixNode = RadixTree\n\n// Type guard to check if a value is a RadixTree (object)\nconst isRadixTree = (value: unknown): value is RadixTree => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/**\n * Create a new Radix tree\n */\nconst Radix = (): RadixFunction => {\n const radix = ((\n keys?: string,\n value?: EncodedValue,\n tree?: RadixTree\n ): RadixNode | EncodedValue | undefined | Record<string, EncodedValue> => {\n if (!tree) {\n if (!(radix as Record<string, unknown>)[group]) (radix as Record<string, unknown>)[group] = {}\n tree = (radix as Record<string, RadixTree>)[group]!\n }\n if (!keys) return tree\n\n let i = 0\n let tmp: Record<string, RadixValue> = {}\n let key = keys[i]!\n const max = keys.length - 1\n const noValue = typeof value === \"undefined\"\n\n // Find a matching value using the shortest string from keys\n let found: RadixValue | undefined = tree![key]\n while (!found && i < max) {\n key += keys[++i]\n found = tree![key]\n }\n\n if (!found) {\n // If not found from the provided keys try matching with an existing key\n const result = utils.obj.map(tree!, (hasValue: RadixValue, hasKey: string) => {\n let j = 0\n let matchingKey = \"\"\n while (hasKey[j] === keys[j]) {\n matchingKey += hasKey[j]\n j++\n }\n if (matchingKey) {\n if (noValue) {\n // matchingKey has to be as long as the original keys when reading\n if (j <= max) return undefined\n\n tmp[hasKey.slice(j)] = hasValue\n return hasValue\n }\n\n const replace: RadixTree = {\n [hasKey.slice(j)]: hasValue,\n [keys.slice(j)]: { [record]: value! },\n }\n tree![matchingKey] = { [group]: replace }\n delete tree![hasKey]\n return true\n }\n return undefined\n })\n\n if (!result) {\n if (noValue) return undefined\n\n if (!tree![key]) tree![key] = {}\n tree![key]![record] = value!\n } else if (noValue) {\n return tmp\n }\n } else if (i === max) {\n // If no value use the key provided to return a whole group or record\n if (noValue) {\n // If an individual record isn't found then return the whole group\n return typeof found[record] === \"undefined\" ? found[group] : found[record]\n }\n // Otherwise create a new record at the provided key for value\n found[record] = value!\n } else {\n // Found at a shorter key, try again\n if (!found[group] && !noValue) found[group] = {}\n const nextTree = found[group]\n if (isRadixTree(nextTree)) {\n return radix(keys.slice(++i), value, nextTree as RadixTree) as RadixNode\n }\n }\n\n return undefined\n }) as RadixFunction\n\n return radix\n}\n\n/**\n * Map over all values in a radix tree\n */\nRadix.map = function map(\n radix: RadixFunction | RadixNode,\n cb: (value: EncodedValue, fullKey: string, key: string, pre: string[]) => unknown,\n opt?: boolean,\n pre: string[] = []\n): unknown {\n const tree = ((radix as Record<string, RadixTree>)[group] || radix) as RadixTree\n const keys = Object.keys(tree).sort()\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n const found = tree[key]\n if (!found) continue\n \n const recordValue = found[record]\n\n if (typeof recordValue !== \"undefined\") {\n const result = cb(recordValue as EncodedValue, pre.join(\"\") + key, key, pre)\n if (typeof result !== \"undefined\") return result\n } else if (opt) {\n cb(undefined as never, pre.join(\"\"), key, pre)\n }\n\n const groupValue = found[group]\n if (isRadixTree(groupValue)) {\n pre.push(key)\n const result = map(groupValue, cb, opt, pre)\n if (typeof result !== \"undefined\") return result\n pre.pop()\n }\n }\n\n return undefined\n}\n\nexport default Radix\n\n", "/**\n * Radisk - Persistent radix tree storage\n * Provides disk-backed radix tree with caching and batching\n */\n\nimport Radix from \"./radix.ts\"\nimport type { RadixFunction } from \"./schemas.ts\"\nimport * as utils from \"./utils.ts\"\nimport type { EncodedValue, RadiskOptions, GraphValue, Relation } from \"./schemas.ts\"\n\n// ASCII character for end of text\nconst etx = String.fromCharCode(3)\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n\nexport interface RadiskInterface extends RadixFunction {\n // Override call signature to support both get (with callback) and put (with value and optional callback)\n // Accepts GraphValue (raw values) OR EncodedValue (tuples) - see src/radisk.js and tests\n (key?: string, value?: GraphValue | EncodedValue | ((err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void), cb?: (err?: string | null) => void): void\n \n batch: RadixFunction & {\n acks: Array<(err?: string | null) => void>\n ed: number\n timeout?: NodeJS.Timeout\n }\n thrash: {\n (): void\n at?: RadixFunction\n ing?: boolean\n more?: boolean\n }\n save: (rad: RadixFunction, cb: (err?: string | null) => void) => void\n write: (file: string, rad: RadixFunction, cb: (err?: string | null) => void) => void\n read: (key: string, cb: (err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void) => void\n parse: (file: string, cb: (err?: string | null, disk?: RadixFunction) => void) => void\n}\n\n/**\n * Create a Radisk instance with persistent storage\n */\nconst Radisk = (opt: RadiskOptions) => {\n const cache = new Map<string, RadixFunction>()\n let fileListCache: string[] | null = null\n let fileListCacheTime = 0\n const FILE_LIST_CACHE_TTL = 10000\n\n const pendingReads = new Map<\n string,\n {\n callbacks: Array<(err?: string, result?: EncodedValue | Record<string, EncodedValue>) => void>\n fired: boolean\n timeoutId: NodeJS.Timeout | null\n }\n >()\n\n let lastMemoryCheck = 0\n const MEMORY_CHECK_INTERVAL = 30000\n const HEAP_WARNING_THRESHOLD = 0.8\n const HEAP_CLEANUP_THRESHOLD = 0.9\n\n const options = {\n log: opt.log || console.log,\n batch: opt.batch || 100,\n write: opt.write || 1,\n size: opt.size || 1024 * 1024,\n memoryLimit: opt.memoryLimit || 500,\n readTimeout: opt.readTimeout || 1000,\n cache: opt.cache !== undefined ? opt.cache : true,\n store: opt.store,\n }\n\n if (!options.store) {\n throw new Error(\"Radisk needs `store` interface with `{get: fn, put: fn, list: fn}`\")\n }\n if (!options.store.get) {\n throw new Error(\"Radisk needs `store.get` interface with `(file, cb)`\")\n }\n if (!options.store.put) {\n throw new Error(\"Radisk needs `store.put` interface with `(file, data, cb)`\")\n }\n if (!options.store.list) {\n throw new Error(\"Radisk needs a streaming `store.list` interface with `(cb)`\")\n }\n\n // After validation, store is guaranteed to be defined\n const store = options.store\n\n const perfLog = (operation: string, startTime: number, key: string, size?: number): void => {\n const duration = Date.now() - startTime\n if (duration > 2000) {\n console.log(\n `[RADISK-SLOW] ${operation}: ${duration}ms for ${key}${size ? ` (${size} bytes)` : \"\"}`\n )\n }\n }\n\n const checkMemoryUsage = (): void => {\n if (typeof process === \"undefined\" || !process.memoryUsage) return\n\n const now = Date.now()\n if (now - lastMemoryCheck < MEMORY_CHECK_INTERVAL) return\n lastMemoryCheck = now\n\n const memUsage = process.memoryUsage()\n const heapUsed = memUsage.heapUsed\n const maxHeapSize = options.memoryLimit * 1024 * 1024\n const heapUsageRatio = heapUsed / maxHeapSize\n\n if (heapUsageRatio > HEAP_CLEANUP_THRESHOLD) {\n const cacheSize = cache.size\n console.log(\n `[RADISK-MEMORY] High memory usage: ${Math.round(heapUsageRatio * 100)}% of heap limit. Clearing ${cacheSize} cached files.`\n )\n cache.clear()\n if ((global as { gc?: () => void }).gc) {\n (global as { gc: () => void }).gc()\n }\n lastMemoryCheck = now + MEMORY_CHECK_INTERVAL\n } else if (heapUsageRatio > HEAP_WARNING_THRESHOLD) {\n console.log(\n `[RADISK-MEMORY] Memory warning: ${Math.round(heapUsageRatio * 100)}% of heap limit used. Cache size: ${cache.size} files.`\n )\n }\n }\n\n const radisk = ((key?: string, value?: GraphValue | EncodedValue | ((err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void), cb?: (err?: string | null) => void) => {\n if (typeof key !== \"string\") return undefined\n\n if (typeof value === \"function\") {\n const callback = value\n const batchValue = radisk.batch(key)\n if (typeof batchValue !== \"undefined\") {\n return callback(undefined, batchValue as EncodedValue)\n }\n\n if (radisk.thrash.at) {\n const thrashValue = radisk.thrash.at(key)\n if (typeof thrashValue !== \"undefined\") {\n return callback(undefined, thrashValue as EncodedValue)\n }\n }\n\n if (pendingReads.has(key)) {\n pendingReads.get(key)!.callbacks.push(callback)\n return\n }\n\n const pending: {\n callbacks: Array<(err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void>\n fired: boolean\n timeoutId: NodeJS.Timeout | null\n } = { callbacks: [callback], fired: false, timeoutId: null }\n pendingReads.set(key, pending)\n\n pending.timeoutId = setTimeout(() => {\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n const err = \"radisk read timeout\"\n pending.callbacks.forEach(cb => cb(err, undefined))\n }\n }, options.readTimeout)\n\n const readStart = Date.now()\n return radisk.read(key, (err, result) => {\n if (pending.timeoutId) clearTimeout(pending.timeoutId)\n perfLog(\"read\", readStart, key)\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n pending.callbacks.forEach(callback => callback(err, result))\n }\n })\n }\n\n radisk.batch(key, value as EncodedValue)\n checkMemoryUsage()\n if (cb) {\n radisk.batch.acks.push(cb)\n }\n if (++radisk.batch.ed >= options.batch) {\n return radisk.thrash()\n }\n\n clearTimeout(radisk.batch.timeout)\n radisk.batch.timeout = setTimeout(radisk.thrash, options.write)\n return undefined\n }) as unknown as RadiskInterface\n\n radisk.batch = Radix() as RadiskInterface[\"batch\"]\n radisk.batch.acks = []\n radisk.batch.ed = 0\n\n radisk.thrash = (() => {\n if (radisk.thrash.ing) {\n radisk.thrash.more = true\n return\n }\n\n const thrashStart = Date.now()\n clearTimeout(radisk.batch.timeout)\n radisk.thrash.more = false\n radisk.thrash.ing = true\n const batch = (radisk.thrash.at = radisk.batch)\n radisk.batch = Radix() as RadiskInterface[\"batch\"]\n radisk.batch.acks = []\n radisk.batch.ed = 0\n let i = 0\n radisk.save(batch, err => {\n if (++i > 1) return\n\n perfLog(\"thrash\", thrashStart, `batch-${batch.ed}`)\n if (err) options.log(err)\n batch.acks.forEach(cb => cb(err))\n radisk.thrash.at = undefined\n radisk.thrash.ing = false\n if (radisk.thrash.more) radisk.thrash()\n })\n }) as RadiskInterface[\"thrash\"]\n\n radisk.save = (rad, cb) => {\n const save = {\n find: (_tree: unknown, key: string): boolean | undefined => {\n if (key < (save.start || \"\")) return undefined\n save.start = key\n store.list(save.lex)\n return true\n },\n lex: (file?: string): void => {\n if (!file || file > (save.start || \"\")) {\n save.end = file\n if (save.start) save.mix(save.file || \"!\", save.start, save.end)\n } else {\n save.file = file\n }\n },\n mix: (file: string, start: string, end?: string): void => {\n save.start = save.end = save.file = undefined\n if (cache.has(file)) {\n const disk = cache.get(file)!\n Radix.map(rad, (value, key) => {\n if (key < start) return undefined\n if (end && end < key) {\n save.start = key\n return undefined\n }\n disk(key, value)\n return undefined\n })\n radisk.write(file, disk, save.next)\n } else {\n radisk.parse(file, (err, disk) => {\n if (err) return cb(err)\n Radix.map(rad, (value, key) => {\n if (key < start) return undefined\n if (end && end < key) {\n save.start = key\n return undefined\n }\n disk!(key, value)\n return undefined\n })\n radisk.write(file, disk!, save.next)\n })\n }\n },\n next: (err?: string | null): void => {\n if (err) return cb(err)\n if (save.start) {\n Radix.map(rad, save.find)\n return\n }\n cb(err)\n },\n start: undefined as string | undefined,\n end: undefined as string | undefined,\n file: undefined as string | undefined,\n }\n Radix.map(rad, save.find)\n }\n\n radisk.write = (file, rad, cb) => {\n const write = {\n text: \"\",\n limit: \"\",\n done: false,\n count: 0,\n sub: undefined as RadixFunction | undefined,\n each: (value: EncodedValue, _key: string, k: string, pre: string[]): void | boolean => {\n if (write.done) return\n write.count++\n const valueStr =\n typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)\n const enc =\n Radisk.encode(pre.length) + \"#\" + Radisk.encode(k) + valueStr + \"\\n\"\n\n if (\n write.count > 1 &&\n pre.length === 0 &&\n write.text.length + enc.length > options.size\n ) {\n const endIdx = k.indexOf(enq)\n write.limit = endIdx === -1 ? k : k.substring(0, endIdx)\n if (write.limit !== file) {\n write.done = true\n write.sub = Radix()\n Radix.map(rad, write.slice)\n radisk.write(write.limit, write.sub, cb)\n return undefined\n }\n }\n write.text += enc\n },\n slice: (value: EncodedValue, key: string): void => {\n if (key < write.limit) return\n write.sub!(key, value)\n },\n }\n Radix.map(rad, write.each, true)\n const writeStart = Date.now()\n store.put(file, write.text, err => {\n perfLog(\"file-write\", writeStart, file, write.text.length)\n cb(err)\n })\n }\n\n radisk.read = (key, cb) => {\n const endIdx = key.indexOf(enq)\n const soul = endIdx === -1 ? key : key.substring(0, endIdx)\n\n const read = {\n lex: (file?: string): void => {\n if (!file) {\n if (!read.file) {\n cb(\"no file found\", undefined)\n return\n }\n\n if (options.cache && cache.has(read.file)) {\n const cachedRadix = cache.get(read.file)!\n read.value = cachedRadix(key) as EncodedValue | Record<string, EncodedValue> | undefined\n return cb(undefined, read.value)\n }\n\n radisk.parse(read.file, read.it)\n return\n }\n\n if (file > soul || file < (read.file || \"\")) return\n read.file = file\n },\n it: (err?: string | null, disk?: RadixFunction): void => {\n if (err) options.log(err)\n if (disk) {\n if (options.cache) {\n cache.set(read.file!, disk)\n checkMemoryUsage()\n }\n read.value = disk(key) as EncodedValue | Record<string, EncodedValue> | undefined\n }\n cb(err, read.value)\n },\n file: undefined as string | undefined,\n value: undefined as EncodedValue | Record<string, EncodedValue> | undefined,\n }\n\n const now = Date.now()\n if (\n options.cache &&\n fileListCache &&\n now - fileListCacheTime < FILE_LIST_CACHE_TTL\n ) {\n fileListCache.forEach(file => read.lex(file))\n read.lex()\n } else {\n const files: string[] = []\n const originalLex = read.lex\n read.lex = (file?: string): void => {\n if (file) files.push(file)\n return originalLex(file)\n }\n\n store.list((file?: string) => {\n read.lex(file)\n if (!file && options.cache) {\n fileListCache = files\n fileListCacheTime = now\n }\n })\n }\n }\n\n radisk.parse = (file, cb) => {\n const parse = {\n disk: Radix(),\n read: (err?: string | null, data?: string | EncodedValue | Record<string, unknown>): void => {\n if (err) return cb(err)\n if (!data) return cb(null, parse.disk)\n\n let pre: string[] = []\n let preString = \"\"\n let tmp = parse.split(data as string)\n while (tmp) {\n let key: string | undefined\n let value: EncodedValue | undefined\n const tmpVal = tmp[1]\n const i = typeof tmpVal === \"number\" ? tmpVal : (typeof tmpVal === \"string\" ? parseInt(tmpVal, 10) : 0)\n tmp = parse.split(tmp[2]) || (\"\" as never)\n if (tmp[0] === \"#\") {\n const tmpKey = tmp[1]\n key = typeof tmpKey === \"string\" ? tmpKey : String(tmpKey)\n if (i < pre.length) {\n pre.length = i\n }\n if (i <= pre.length) {\n pre[i] = key\n pre.length = i + 1\n }\n preString = pre.join(\"\")\n }\n tmp = parse.split(tmp[2]) || (\"\" as never)\n if (tmp[0] === \"\\n\") continue\n\n if (tmp[0] === \"=\") {\n value = tmp[1] as EncodedValue\n }\n if (typeof key !== \"undefined\" && typeof value !== \"undefined\") {\n parse.disk(preString, value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(null, parse.disk)\n },\n split: (\n data: string\n ): [string, unknown, string] | undefined => {\n if (!data) return undefined\n\n const i = data.indexOf(unit)\n if (i === -1) return undefined\n\n const a = data.slice(0, i)\n const o: { i?: number } = {}\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i!)]\n },\n }\n store.get(file, parse.read)\n }\n\n // TypeScript can't verify all properties are added dynamically, but they are at runtime\n return radisk as unknown as RadiskInterface\n}\n\n/**\n * Encode value for storage\n */\nRadisk.encode = (input: EncodedValue | GraphValue): string => {\n let state = \"\"\n let sig = \"\"\n let data: GraphValue\n \n if (Array.isArray(input) && (input.length === 2 || input.length === 3)) {\n // input is EncodedValue - extract the GraphValue and metadata\n state = etx + input[1]\n if (input.length === 3 && input[2]) {\n sig = etx + input[2]\n }\n data = input[0]!\n } else {\n // input is already a GraphValue\n data = input as GraphValue\n }\n\n if (typeof data === \"string\") {\n let i = 0\n let current: string | undefined = undefined\n let text = unit\n while ((current = data[i++])) {\n if (current === unit) text += unit\n }\n return text + '\"' + data + state + sig + unit\n }\n\n const relId = utils.rel.is(data)\n if (relId) return unit + \"#\" + relId + state + sig + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + sig + unit\n\n if (data === true) return unit + \"+\" + state + sig + unit\n\n if (data === false) return unit + \"-\" + state + sig + unit\n\n if (data === null) return unit + \" \" + state + sig + unit\n\n return undefined as never\n}\n\n/**\n * Decode value from storage\n */\nRadisk.decode = (data: string, obj?: { i?: number }): EncodedValue | GraphValue | Relation | null | undefined => {\n let i = -1\n let n = 0\n let current: string | undefined = undefined\n let previous: string | undefined = undefined\n let textStart = -1\n let textEnd = -1\n if (data[0] !== unit) return undefined\n\n while ((current = data[++i])) {\n if (previous) {\n if (textStart === -1) textStart = i\n if (current === unit) {\n if (--n <= 0) {\n textEnd = i\n break\n }\n }\n } else if (current === unit) {\n n++\n } else {\n previous = current || \"true\"\n }\n }\n\n const text =\n textStart !== -1 ? data.slice(textStart, textEnd !== -1 ? textEnd : i) : \"\"\n\n if (obj) obj.i = i + 1\n\n const parts = text.split(etx)\n const value = parts[0]!\n const state = parts[1]\n const sig = parts[2]\n\n if (!state) {\n if (previous === '\"') return text\n\n if (previous === \"#\") return utils.rel.ify(text)\n\n if (previous === \"+\") {\n if (text.length === 0) return true\n return parseFloat(text)\n }\n\n if (previous === \"-\") return false\n\n if (previous === \" \") return null\n } else {\n const stateNum = parseFloat(state)\n if (sig) {\n if (previous === '\"') return [value, stateNum, sig]\n\n if (previous === \"#\") return [utils.rel.ify(value), stateNum, sig]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, stateNum, sig]\n return [parseFloat(value), stateNum, sig]\n }\n\n if (previous === \"-\") return [false, stateNum, sig]\n\n if (previous === \" \") return [null, stateNum, sig]\n } else {\n if (previous === '\"') return [value, stateNum]\n\n if (previous === \"#\") return [utils.rel.ify(value), stateNum]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, stateNum]\n return [parseFloat(value), stateNum]\n }\n\n if (previous === \"-\") return [false, stateNum]\n\n if (previous === \" \") return [null, stateNum]\n }\n }\n return undefined\n}\n\nexport default Radisk\n\n", "/**\n * Store - Storage interface for graph data\n * Provides get and put methods with filesystem or IndexedDB backend\n */\n\nimport Radisk from \"./radisk.ts\"\nimport Radix from \"./radix.ts\"\nimport * as utils from \"./utils.ts\"\nimport type {\n Lex,\n Graph,\n GraphNode,\n StoreOptions,\n FileSystemInterface,\n EncodedValue,\n} from \"./schemas.ts\"\n\nconst isNode = typeof document === \"undefined\"\n\n// Dynamic import for Node.js fs module - won't execute in browser/service worker\nconst fs = isNode\n ? await import(/*webpackIgnore: true*/ \"node:fs\")\n : undefined\n\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n// On-disk root node format\nconst root = unit + \"+0\" + unit + \"#\" + unit + '\"root' + unit\n\n/**\n * Create file system storage backend\n */\nconst fileSystem = (opt: StoreOptions): FileSystemInterface => {\n const dir = opt.file!\n\n if (isNode) {\n if (!fs!.existsSync(dir)) fs!.mkdirSync(dir)\n if (!fs!.existsSync(dir + \"/!\")) fs!.writeFileSync(dir + \"/!\", root)\n\n return {\n get: (file, cb) => {\n fs!.readFile(dir + \"/\" + file, (err: NodeJS.ErrnoException | null, data?: Buffer) => {\n if (err) {\n if ((err as { code?: string }).code === \"ENOENT\") {\n cb()\n return\n }\n console.log(\"fs.readFile error:\", err)\n }\n const dataStr = data ? data.toString() : undefined\n cb(err as never, dataStr)\n })\n },\n put: (file, data, cb) => {\n const tmp = file + \".\" + utils.text.random(9) + \".tmp\"\n fs!.writeFile(tmp, data as string, (err: NodeJS.ErrnoException | null) => {\n if (err) {\n console.log(\"fs.writeFile error:\", err)\n cb(err as never)\n return\n }\n fs!.rename(tmp, dir + \"/\" + file, cb as never)\n })\n },\n list: cb => {\n fs!.readdir(dir, (err: NodeJS.ErrnoException | null, files?: string[]) => {\n if (err) {\n console.log(\"fs.readdir error:\", err)\n cb()\n return\n }\n if (files) files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db: IDBDatabase\n const dbReady = new Promise<void>((resolve, reject) => {\n const o = indexedDB.open(dir, 1)\n o.onupgradeneeded = event => {\n ;(event.target as IDBOpenDBRequest).result.createObjectStore(dir)\n }\n o.onerror = event => {\n console.log(event)\n reject(event)\n }\n o.onsuccess = () => {\n db = o.result\n if (db) {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getKey(\"!\")\n req.onerror = () => {\n console.log(`error getting key ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n if (!req.result) {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(root, \"!\")\n req.onerror = () => {\n console.log(`error putting root on ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n resolve()\n }\n } else {\n resolve()\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n reject(new Error(\"indexedDB not available\"))\n }\n }\n })\n\n return {\n get: (file, cb) => {\n const _get = (file: string, cb: (err?: string | null, data?: string) => void) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).get(file)\n req.onerror = () => {\n console.log(`error getting ${dir}/${file}`)\n cb(req.error as unknown as string)\n }\n req.onsuccess = () => {\n cb(null, req.result)\n }\n }\n\n dbReady\n .then(() => {\n _get(file, cb)\n })\n .catch(err => {\n cb(err as string)\n })\n },\n put: (file, data, cb) => {\n const _put = (\n file: string,\n data: string,\n cb: (err?: string | null) => void\n ) => {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(data, file)\n req.onerror = () => {\n console.log(`error putting data on ${dir}/${file}`)\n cb(req.error as unknown as string)\n }\n req.onsuccess = () => {\n cb(null)\n }\n }\n\n dbReady\n .then(() => {\n _put(file, data as string, cb)\n })\n .catch(err => {\n cb(err as string)\n })\n },\n list: cb => {\n const _list = (cb: (file?: string) => void) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getAllKeys()\n req.onerror = () => {\n console.log(\"error getting keys for\", dir)\n cb()\n }\n req.onsuccess = () => {\n ;(req.result as string[]).forEach(cb)\n cb()\n }\n }\n\n dbReady\n .then(() => {\n _list(cb)\n })\n .catch(err => {\n console.log(\"error indexedDB not available:\", err)\n cb()\n })\n },\n }\n }\n\n // No browser storage\n return {\n get: (_file, cb) => {\n cb(null, root)\n },\n put: (_file, _data, cb) => {\n cb(null)\n },\n list: cb => {\n cb(\"!\")\n cb()\n },\n }\n}\n\nexport interface StoreInterface {\n get: (\n lex: Lex,\n cb: (err?: string | null, graph?: Graph) => void,\n _opt?: { secure?: boolean }\n ) => void\n put: (graph: Graph, cb: (err?: string | null) => void) => void\n}\n\n/**\n * Create Store with get and put methods\n */\nconst Store = (opt?: StoreOptions): StoreInterface => {\n const options = opt || {}\n options.file = String(options.file || \"radata\")\n if (!options.store) options.store = fileSystem(options)\n const radisk = Radisk(options as never)\n\n return {\n get: (lex, cb, _opt) => {\n if (!lex || !utils.obj.is(lex)) {\n cb(\"lex required\")\n return\n }\n if (!lex[\"#\"]) {\n cb(\"soul required in lex\")\n return\n }\n\n const opts = _opt || {}\n const soul = lex[\"#\"]\n const key =\n !opts.secure && typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n let node: GraphNode | undefined\n const signatures: Record<string, string> = {}\n\n const each = (value: EncodedValue, key: string): void => {\n // Always include userPublicKey for verification, regardless of filter\n if (key !== utils.userPublicKey && !utils.match(lex[\".\"], key)) return\n\n if (!node) node = { _: { \"#\": soul, \">\": {} } }\n node[key] = value[0]\n node._[\">\"][key] = value[1]\n // If signature is present, store it in _[\"s\"]\n if (value.length === 3 && value[2]) {\n signatures[value[1].toString()] = value[2]\n }\n }\n\n radisk(soul + enq + key, (err, value) => {\n let graph: Graph | undefined\n if (utils.obj.is(value)) {\n Radix.map(value as never, each)\n if (!node) each(value as never, key)\n graph = { [soul]: node! }\n } else if (value) {\n each(value as EncodedValue, key)\n graph = { [soul]: node! }\n }\n // Only add _[\"s\"] if we found any signatures\n if (graph && graph[soul] && Object.keys(signatures).length > 0) {\n graph[soul]._[\"s\"] = signatures\n }\n cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n let count = 0\n let finished = false\n const ack = (err?: string | null): void => {\n count--\n if (finished) return\n\n if (err) {\n finished = true\n cb(err)\n return\n }\n\n if (count === 0) {\n finished = true\n cb(null)\n }\n }\n\n Object.keys(graph).forEach(soul => {\n const node = graph[soul]!\n Object.keys(node).forEach(key => {\n if (key === \"_\") return\n\n count++\n const value = node[key]!\n const state = node._[\">\"][key]!\n const sig = node._[\"s\"] && node._[\"s\"][state]\n const data: EncodedValue = sig\n ? [value, state, sig]\n : [value, state]\n radisk(soul + enq + key, data, ack)\n })\n })\n },\n }\n}\n\nexport default Store\n\n", "/**\n * Wire - WebSocket-based network protocol\n * Handles message routing, rate limiting, and graph synchronization\n */\n\nimport Dup from \"./dup.ts\"\nimport Get from \"./get.ts\"\nimport Ham from \"./ham.ts\"\nimport Store from \"./store.ts\"\nimport * as utils from \"./utils.ts\"\nimport type {\n Graph,\n WireMessage,\n WireOptions,\n Lex,\n ListenMap,\n HolsterOptions,\n GraphValue,\n} from \"./schemas.ts\"\n\n// Unified WebSocket type that works for both Node.js ws and browser WebSocket\ntype UnifiedWebSocket = WebSocket & {\n _retryHandler?: ReturnType<typeof createRetryHandler>\n on?: (event: string, cb: (...args: unknown[]) => void) => void\n send: (data: string | Buffer | ArrayBuffer | Uint8Array, options?: unknown, cb?: (err?: Error) => void) => void\n}\n\nconst isNode = typeof document === \"undefined\"\n\n// Dynamic import for Node.js ws module - won't execute in browser/service worker\nconst wsModule = isNode ? await import(\"ws\") : undefined\n\nif (typeof globalThis.WebSocket === \"undefined\" && wsModule) {\n globalThis.WebSocket = wsModule.WebSocket as unknown as typeof WebSocket\n}\n\n// ============================================================================\n// Rate Limiting\n// ============================================================================\n\ninterface RateLimiterClient {\n requests: number[]\n lastCleanup: number\n throttleCount: number\n}\n\nconst createRateLimiter = (isTestEnv: boolean) => {\n const clients = new Map<string, RateLimiterClient>()\n const maxRequests = 1500\n const windowMs = 60000\n const disconnectThreshold = 10\n let cleanupInterval: NodeJS.Timeout | null = null\n\n const cleanup = (): void => {\n const now = Date.now()\n for (const [_clientId, data] of Array.from(clients.entries())) {\n if (now - data.lastCleanup > windowMs) {\n data.requests = []\n data.lastCleanup = now\n }\n data.requests = data.requests.filter(time => now - time < windowMs)\n if (now - data.lastCleanup > windowMs * 10) {\n data.throttleCount = 0\n }\n }\n }\n\n if (!isTestEnv) {\n cleanupInterval = setInterval(cleanup, windowMs / 4)\n }\n\n return {\n getDelay: (clientId: string): number => {\n const now = Date.now()\n const client = clients.get(clientId) || {\n requests: [],\n lastCleanup: now,\n throttleCount: 0,\n }\n\n client.requests = client.requests.filter(time => now - time < windowMs)\n\n if (client.requests.length >= maxRequests) {\n const oldestRequest = Math.min(...client.requests)\n const delay = windowMs - (now - oldestRequest)\n client.throttleCount = (client.throttleCount || 0) + 1\n clients.set(clientId, client)\n return Math.max(0, delay)\n }\n\n client.requests.push(now)\n clients.set(clientId, client)\n return 0\n },\n\n getRemainingRequests: (clientId: string): number => {\n const client = clients.get(clientId)\n if (!client) return maxRequests\n\n const now = Date.now()\n const validRequests = client.requests.filter(time => now - time < windowMs)\n return Math.max(0, maxRequests - validRequests.length)\n },\n\n getThrottleCount: (clientId: string): number => {\n const client = clients.get(clientId)\n return client ? client.throttleCount || 0 : 0\n },\n\n shouldDisconnect: (clientId: string): boolean => {\n const client = clients.get(clientId)\n if (!client) return false\n return client.throttleCount >= disconnectThreshold\n },\n\n destroy: (): void => {\n if (cleanupInterval) {\n clearInterval(cleanupInterval)\n cleanupInterval = null\n }\n clients.clear()\n },\n }\n}\n\n// ============================================================================\n// Message Validation\n// ============================================================================\n\nconst safeJSONParse = (\n data: string | Buffer,\n maxSize = 1024 * 1024\n): { success: boolean; data?: WireMessage; error?: string } => {\n try {\n if (typeof data === \"string\" && data.length > maxSize) {\n throw new Error(\"Message too large\")\n }\n return { success: true, data: JSON.parse(data.toString()) }\n } catch (error) {\n return { success: false, error: (error as Error).message }\n }\n}\n\nconst validateMessage = (\n data: string | Buffer,\n maxSize = 1024 * 1024\n): { valid: boolean; error?: string } => {\n if (typeof data === \"string\" && data.length > maxSize) {\n return { valid: false, error: \"Message too large\" }\n }\n if (Buffer.isBuffer && Buffer.isBuffer(data) && data.length > maxSize) {\n return { valid: false, error: \"Message too large\" }\n }\n return { valid: true }\n}\n\n// ============================================================================\n// Connection Management\n// ============================================================================\n\nconst createConnectionManager = (maxConnections = 1000) => {\n const connections = new Set<WebSocket>()\n\n return {\n add: (ws: WebSocket): boolean => {\n if (connections.size >= maxConnections) {\n return false\n }\n connections.add(ws)\n\n const originalClose = ws.close.bind(ws)\n ws.close = ((...args: unknown[]) => {\n connections.delete(ws)\n return originalClose(...(args as [number?, string?]))\n }) as typeof ws.close\n\n return true\n },\n\n remove: (ws: WebSocket): void => {\n connections.delete(ws)\n },\n\n count: (): number => connections.size,\n\n isFull: (): boolean => connections.size >= maxConnections,\n }\n}\n\n// ============================================================================\n// Retry Handler\n// ============================================================================\n\nconst createRetryHandler = (maxRetries = 5) => {\n let retryCount = 0\n\n return {\n shouldRetry: (): boolean => retryCount < maxRetries,\n getDelay: (): number => Math.min(1000 * Math.pow(2, retryCount), 30000),\n increment: (): void => {\n retryCount++\n },\n reset: (): void => {\n retryCount = 0\n },\n }\n}\n\n// ============================================================================\n// Wire Protocol\n// ============================================================================\n\nexport interface WireAPI {\n get: (lex: Lex, cb: (msg: WireMessage) => void, _opt?: WireOptions) => void\n put: (data: Graph, cb?: (err?: string | null) => void) => Promise<void> | void\n on: (lex: Lex, cb: () => void, _get?: boolean, _opt?: WireOptions) => void\n off: (lex: Lex, cb: () => void) => void\n}\n\nconst Wire = (opt: HolsterOptions): WireAPI => {\n const options = opt || {}\n const dup = Dup(options.maxAge)\n const store = Store(options as never)\n const graph: Graph = {}\n const queue: Record<string, (msg: WireMessage) => void> = {}\n const listen: ListenMap = {}\n\n const pendingReferences = new Set<string>()\n const pendingTimeouts = new Map<\n string,\n { lex: Lex; wait: number; timeoutId?: NodeJS.Timeout }\n >()\n\n const hasSoul = async (soul: string): Promise<boolean> => {\n if (graph[soul]) return true\n return new Promise(resolve => {\n store.get({ \"#\": soul }, (err, data) => {\n resolve(!err && !!data && !!data[soul])\n })\n })\n }\n\n const isTestEnv = options.wss && (options.wss as { constructor?: { name?: string } }).constructor?.name === \"Server\"\n const rateLimiter = createRateLimiter(isTestEnv)\n const connectionManager = createConnectionManager(options.maxConnections || 1000)\n\n const check = async (\n data: Graph,\n send: (msg: string) => { err?: string } | void,\n cb?: (err?: string | null) => void\n ): Promise<boolean> => {\n const key = utils.userPublicKey\n\n for (const soul of Object.keys(data)) {\n const msg = await new Promise<WireMessage>(res => {\n getWithCallback({ \"#\": soul, \".\": key }, res, send)\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n const node = data[soul]!\n if (\n !msg.put ||\n !msg.put[soul] ||\n node[key] === undefined ||\n msg.put[soul]![key] === node[key]\n ) {\n continue\n }\n\n if (cb) {\n cb(`error in wire check public key does not match for soul: ${soul}`)\n }\n return false\n }\n\n return true\n }\n\n const get = (msg: { get: Lex; \"#\": string }, send: (msg: string) => void): void => {\n const ack = Get(msg.get, graph)\n if (ack) {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n })\n )\n } else {\n store.get(\n msg.get,\n (err, ack) => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n err: err,\n })\n )\n },\n { secure: true }\n )\n }\n }\n\n const put = async (\n msg: { put: Graph; \"#\": string },\n send: (msg: string) => void\n ): Promise<void> => {\n const update = await Ham.mix(msg.put, graph, options.secure || false, listen)\n if (Object.keys(update.now).length === 0) {\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(() => put({ put: update.defer, \"#\": msg[\"#\"] }, send), update.wait)\n }\n return\n }\n\n if (!(await check(update.now, send as never))) return\n\n store.put(update.now, err => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: err,\n })\n )\n update.listeners.forEach(cb => cb())\n })\n\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(() => put({ put: update.defer, \"#\": msg[\"#\"] }, send), update.wait)\n }\n }\n\n const getWithCallback = (\n lex: Lex,\n cb: (msg: WireMessage) => void,\n send: (msg: string) => { err?: string } | void,\n _opt?: WireOptions\n ): void => {\n if (!cb) return\n\n const opts = _opt || {}\n const ack = Get(lex, graph, opts.fast)\n const track = utils.text.random(9)\n const request = JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n })\n\n if (ack) {\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n cb({ put: ack })\n return\n }\n\n store.get(\n lex,\n (err, ack) => {\n if (ack) {\n // Populate in-memory graph from store data before sending the server\n // request, so stale server responses with older state are correctly\n // rejected by ham.mix.\n for (const [soul, node] of Object.entries(ack)) {\n if (!graph[soul] && node) graph[soul] = {...node} as unknown as Graph[string]\n }\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n cb(err ? { put: ack, err: err } : { put: ack })\n return\n }\n\n if (err) console.log(err)\n\n queue[track] = cb\n\n pendingTimeouts.set(track, {\n lex: lex,\n wait: opts.wait || 100,\n })\n\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n delete queue[track]\n pendingTimeouts.delete(track)\n return\n }\n },\n opts\n )\n }\n\n const api = (send: (msg: string) => { err?: string } | void): WireAPI => {\n return {\n get: (lex, cb, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = { ...lex, \".\": String(lex[\".\"]) }\n }\n if (lex && lex[\"#\"]) {\n pendingReferences.add(lex[\"#\"])\n }\n getWithCallback(lex, cb, send, _opt)\n },\n put: async (data, cb) => {\n const update = await Ham.mix(data, graph, options.secure || false, listen)\n if (Object.keys(update.now).length === 0) {\n if (cb) cb(null)\n return\n }\n\n if (!(await check(update.now, send as never, cb))) {\n return\n }\n\n for (const [_soul, node] of Object.entries(update.now)) {\n if (node && typeof node === \"object\") {\n for (const [_key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value as GraphValue)\n if (soulId) {\n pendingReferences.add(soulId)\n }\n }\n }\n }\n\n store.put(update.now, err => {\n if (cb) cb(err)\n update.listeners.forEach(l => l())\n })\n\n const sendResult = send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n })\n )\n if (sendResult && sendResult.err) {\n if (cb) cb(sendResult.err)\n return\n }\n },\n on: (lex, cb, _get, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = { ...lex, \".\": String(lex[\".\"]) }\n }\n const soul = lex && lex[\"#\"]\n if (!soul || !cb) return\n\n if (listen[soul]) {\n listen[soul]!.push({ \".\": lex[\".\"], cb: cb as never })\n } else {\n listen[soul] = [{ \".\": lex[\".\"], cb: cb as never }]\n }\n if (_get) getWithCallback(lex, cb as never, send, _opt)\n },\n off: (lex, cb) => {\n const soul = lex && lex[\"#\"]\n if (!soul || !listen[soul]) return\n\n if (cb) {\n const found = listen[soul]!.find(l => l.cb === (cb as never))\n if (found) {\n listen[soul]!.splice(listen[soul]!.indexOf(found), 1)\n }\n } else {\n delete listen[soul]\n }\n },\n }\n }\n\n if (isNode) {\n let wss = options.wss\n let clients = (): WebSocket[] =>\n (wss as { clients?: () => WebSocket[] }).clients?.() || []\n if (!wss) {\n const config = options.server\n ? { server: options.server }\n : { port: options.port || 8765 }\n wss = new wsModule!.WebSocketServer(config)\n clients = () => Array.from((wss as { clients: Set<WebSocket> }).clients || [])\n }\n\n const send = (data: string, isBinary?: boolean): void => {\n const msg = JSON.parse(data) as WireMessage\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)!\n pendingTimeouts.delete(trackId)\n\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack: Graph = { [id]: null as never }\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = { [timeoutConfig.lex[\".\"]]: null } as never\n }\n cb({ \"#\": trackId, put: ack })\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n\n clients().forEach(client => {\n const ws = client as UnifiedWebSocket\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data, { binary: isBinary })\n } else if (ws) {\n const retryHandler = ws._retryHandler || createRetryHandler()\n ws._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n ws.send(data, { binary: isBinary })\n }\n }, delay)\n }\n }\n })\n }\n\n ;(wss as unknown as { on: (event: string, cb: (ws: UnifiedWebSocket) => void) => void }).on(\n \"connection\",\n (ws: UnifiedWebSocket) => {\n if (!connectionManager.add(ws)) {\n console.log(\"Connection limit reached, rejecting connection\")\n ws.close(1013, \"Connection limit reached - try again later\")\n return\n }\n\n const clientId = utils.text.random(9)\n console.log(`New WebSocket client connected: ${clientId}`)\n\n ws.on?.(\"error\", ((...args: unknown[]) => {\n const error = args[0] as Error\n console.log(\"WebSocket error:\", error)\n connectionManager.remove(ws)\n }) as (...args: unknown[]) => void)\n\n ws.on?.(\"close\", (() => {\n console.log(`WebSocket client disconnected: ${clientId}`)\n connectionManager.remove(ws)\n }) as (...args: unknown[]) => void)\n\n ws.on?.(\"message\", ((...args: unknown[]) => {\n const data = args[0] as Buffer\n const isBinary = args[1] as boolean\n const validation = validateMessage(data, options.maxMessageSize)\n if (!validation.valid) {\n console.warn(`Invalid message: ${validation.error}`)\n ws.send(JSON.stringify({ error: validation.error }))\n return\n }\n\n const parseResult = safeJSONParse(data, options.maxMessageSize)\n if (!parseResult.success) {\n console.warn(`JSON parse error: ${parseResult.error}`)\n ws.send(JSON.stringify({ error: \"Invalid JSON\" }))\n return\n }\n\n const msg = parseResult.data!\n if (!msg[\"#\"]) return // Incoming messages must have '#'\n if (dup.check(msg[\"#\"])) return\n\n const delay = rateLimiter.getDelay(clientId)\n if (delay > 0) {\n const throttleCount = rateLimiter.getThrottleCount(clientId)\n console.log(\n `Client ${clientId}: rate limit exceeded, delay would be ${delay}ms, dropping message (throttle count: ${throttleCount})`\n )\n if (rateLimiter.shouldDisconnect(clientId)) {\n console.log(\n `Client ${clientId}: Disconnecting after ${throttleCount} throttle violations`\n )\n ws.close(1008, \"Rate limit violations\")\n return\n }\n\n ws.send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: `Rate limit exceeded. Slow down requests. Wait ${Math.ceil(delay / 1000)}s`,\n throttle: delay,\n })\n )\n return\n }\n\n const processMessage = async (): Promise<void> => {\n dup.track(msg[\"#\"]!)\n\n if (msg.get) get(msg as never, send)\n if (msg.put) await put(msg as never, send)\n send(data.toString(), isBinary)\n\n const id = msg[\"@\"]\n const cb = queue[id!]\n if (cb) {\n delete (msg as { \"#\"?: string })[\"#\"]\n delete (msg as { \"@\"?: string })[\"@\"]\n cb(msg)\n delete queue[id!]\n }\n }\n\n if (delay > 0) {\n setTimeout(processMessage, delay)\n } else {\n processMessage()\n }\n }) as (...args: unknown[]) => void)\n }\n )\n return api(send)\n }\n\n // Browser logic\n const peers: WebSocket[] = []\n let clientThrottled = false\n let throttleUntil = 0\n let messageQueue: string[] = []\n let queueProcessor: NodeJS.Timeout | null = null\n const maxQueueLength = options.maxQueueLength || 10000\n\n const processQueue = (): void => {\n if (messageQueue.length === 0) {\n queueProcessor = null\n return\n }\n\n const now = Date.now()\n if (clientThrottled && now < throttleUntil) {\n queueProcessor = setTimeout(processQueue, Math.min(1000, throttleUntil - now))\n return\n }\n\n if (clientThrottled && now >= throttleUntil) {\n console.log(`Throttle period ended, resuming queue processing`)\n clientThrottled = false\n throttleUntil = 0\n }\n\n const data = messageQueue[0]!\n const sent = sendToPeers(data)\n\n if (sent) {\n messageQueue.shift()\n\n const msg = JSON.parse(data) as WireMessage\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)!\n pendingTimeouts.delete(trackId)\n\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack: Graph = { [id]: null as never }\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = { [timeoutConfig.lex[\".\"]]: null } as never\n }\n cb({ \"#\": trackId, put: ack })\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n }\n\n if (messageQueue.length > 0) {\n queueProcessor = setTimeout(processQueue, 50)\n } else {\n queueProcessor = null\n }\n }\n\n const sendToPeers = (data: string): boolean => {\n let sentToAtLeastOne = false\n peers.forEach(peer => {\n const ws = peer as UnifiedWebSocket\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data)\n sentToAtLeastOne = true\n } else if (ws) {\n const retryHandler = ws._retryHandler || createRetryHandler()\n ws._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n peer.send(data)\n }\n }, delay)\n }\n }\n })\n return sentToAtLeastOne\n }\n\n const send = (data: string): { err?: string } | void => {\n if (messageQueue.length >= maxQueueLength) {\n return {\n err: `Message queue exceeded maximum length (${maxQueueLength}). Update query logic to request less data.`,\n }\n }\n\n messageQueue.push(data)\n if (!queueProcessor) {\n queueProcessor = setTimeout(processQueue, 50)\n }\n }\n\n if (!(options.peers instanceof Array) || options.peers.length === 0) {\n options.peers = [`ws://localhost:${options.port || 8765}`]\n }\n\n options.peers.forEach((peer: string) => {\n const start = (): void => {\n let ws: WebSocket | null = new WebSocket(peer)\n peers.push(ws)\n const retryHandler = createRetryHandler()\n\n ws.onclose = () => {\n if (ws && peers.indexOf(ws) !== -1) {\n peers.splice(peers.indexOf(ws), 1)\n }\n ws = null\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n setTimeout(start, delay)\n }\n }\n\n ws.onopen = () => {\n retryHandler.reset()\n }\n\n ws.onerror = (e: Event) => {\n console.log(e)\n }\n\n ws.onmessage = async (m: MessageEvent) => {\n const msg = JSON.parse(m.data as string) as WireMessage\n if (!msg[\"#\"]) return // Incoming messages must have '#'\n if (dup.check(msg[\"#\"])) return\n\n if (msg.throttle && msg.err) {\n console.log(`Server throttling: ${msg.err}`)\n clientThrottled = true\n throttleUntil = Date.now() + msg.throttle\n return\n }\n\n dup.track(msg[\"#\"]!)\n if (msg.get) get(msg as never, send as never)\n if (msg.put) {\n const filteredPut: Graph = {}\n for (const [soul, node] of Object.entries(msg.put)) {\n let shouldStore = false\n if (await hasSoul(soul)) {\n shouldStore = true\n if (node && typeof node === \"object\") {\n for (const [_key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value as GraphValue)\n if (soulId) {\n pendingReferences.add(soulId)\n }\n }\n }\n }\n if (pendingReferences.has(soul)) {\n shouldStore = true\n pendingReferences.delete(soul)\n }\n if (shouldStore) {\n filteredPut[soul] = node\n }\n }\n if (Object.keys(filteredPut).length > 0) {\n const filteredMsg = { put: filteredPut, \"#\": msg[\"#\"]! }\n await put(filteredMsg, send as never)\n }\n }\n\n const id = msg[\"@\"]\n const cb = queue[id!]\n if (cb) {\n delete (msg as { \"#\"?: string })[\"#\"]\n delete (msg as { \"@\"?: string })[\"@\"]\n cb(msg)\n delete queue[id!]\n }\n }\n }\n start()\n })\n\n return api(send)\n}\n\nexport default Wire\n\n", "/**\n * User - User authentication and management\n * Provides user creation, authentication, and password management\n */\n\nimport * as utils from \"./utils.ts\"\nimport Wire from \"./wire.ts\"\nimport SEA from \"./sea.ts\"\nimport type { UserIdentity, HolsterOptions, LexFilter, WireOptions } from \"./schemas.ts\"\nimport type { HolsterAPI } from \"./holster.ts\"\n\ntype WireInterface = ReturnType<typeof Wire>\n\nexport interface UserInterface {\n is?: UserIdentity | null\n create: (username: string, password: string, cb?: (err?: string | null) => void) => void\n auth: (username: string, password: string, cb?: (err?: string | null) => void) => void\n change: (\n username: string,\n password: string,\n newPassword: string,\n cb?: (err?: string | null) => void\n ) => void\n store: (localStorage?: boolean) => void\n recall: () => void\n leave: () => void\n delete: (username: string, password: string, cb?: (err?: string | null) => void) => void\n get?(\n keys: string | string[],\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI\n}\n\n/**\n * Create User management interface\n */\nconst User = (opt: HolsterOptions | undefined, wire?: WireInterface): UserInterface => {\n if (!wire) wire = Wire(opt as HolsterOptions)\n const wait = opt?.wait ?? 5000\n let pubs: string[] = []\n let creating = false\n let authing = false\n let retries = 0\n\n const auth = (\n username: string,\n password: string,\n newPassword: string,\n ack: (err?: string | null) => void\n ): void => {\n const retry = (username: string): void => {\n retries++\n auth(username, password, newPassword, ack)\n }\n const done = (err?: string | null): void => {\n pubs = []\n retries = 0\n authing = false\n ack(err)\n }\n const next = (): void => {\n if (pubs.length === 0) {\n done(\"Wrong username or password\")\n return\n }\n\n const pub = pubs.shift()!\n wire.get(\n { \"#\": pub, \".\": [\"auth\", \"pub\", \"epub\"] },\n async msg => {\n if (msg.err) {\n done(`error getting ${pub}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[pub]\n if (!data || !data.auth) return next()\n\n const authData = JSON.parse(data.auth as string) as {\n enc: { ct: string; iv: string; s: string }\n salt: string\n }\n const work = await SEA.work(password, authData.salt)\n const dec = (await SEA.decrypt(authData.enc, work)) as\n | { priv: string; epriv: string }\n | null\n if (!dec) return next()\n\n user.is = {\n username: username,\n pub: data.pub as string,\n epub: data.epub as string,\n priv: dec.priv,\n epriv: dec.epriv,\n }\n if (newPassword !== \"\") {\n const salt = utils.text.random(64)\n const newWork = await SEA.work(newPassword, salt)\n const enc = await SEA.encrypt(dec, newWork)\n const update = {\n auth: JSON.stringify({ enc: enc, salt: salt }),\n }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const graph = utils.graph(pub, update, sig!, data.pub as string, timestamp)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${JSON.stringify(update)} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n done(null)\n },\n { wait: wait }\n )\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get(\n { \"#\": soul },\n async msg => {\n if (msg.err) {\n done(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[soul]\n if (!data) return retry(username)\n\n delete (data as { _?: unknown })._\n pubs = Object.keys(data)\n next()\n },\n { wait: wait }\n )\n }\n\n const user: UserInterface = {\n is: null,\n create: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (creating) {\n ack(\"User is already being created\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n creating = true\n\n const soul = \"~@\" + username\n wire.get(\n { \"#\": soul },\n async msg => {\n if (msg.err) {\n creating = false\n ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n if (msg.put && msg.put[soul]) {\n creating = false\n ack(\"Username already exists\")\n return\n }\n\n const salt = utils.text.random(64)\n const work = await SEA.work(password, salt)\n const pair = await SEA.pair()\n const priv = { priv: pair.priv, epriv: pair.epriv }\n const enc = await SEA.encrypt(priv, work)\n const data = {\n username: username,\n pub: pair.pub,\n epub: pair.epub,\n auth: JSON.stringify({ enc: enc, salt: salt }),\n }\n\n const pub = \"~\" + pair.pub\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, pair)\n const graph = utils.graph(pub, data, sig!, pair.pub, timestamp)\n wire.put(graph, err => {\n creating = false\n if (err) {\n ack(`error putting ${JSON.stringify(data)} on ${pub}: ${err}`)\n return\n }\n\n const rel = { [pub]: { \"#\": pub } }\n wire.put(utils.graph(soul, rel as never), err => {\n if (err) {\n ack(`error putting ${JSON.stringify(rel)} on ${soul}: ${err}`)\n return\n }\n\n if (cb) cb(null)\n })\n })\n },\n { wait: wait }\n )\n },\n auth: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", ack)\n },\n change: (username, password, newPassword, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n if (newPassword === \"\") {\n ack(\"Please provide a new password\")\n return\n }\n\n authing = true\n auth(username, password, newPassword, ack)\n },\n store: (localStorage = false) => {\n if (!user.is) {\n console.log(\"Please authenticate before calling store\")\n return\n }\n\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n },\n recall: () => {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n return\n }\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n const is = globalThis.sessionStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n }\n }\n },\n leave: () => {\n user.is = null\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n },\n delete: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", async err => {\n if (err) {\n ack(err)\n return\n }\n\n const data = { username: null, pub: null, epub: null, auth: null }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is!)\n const pub = \"~\" + user.is!.pub\n const graph = utils.graph(pub, data as never, sig!, user.is!.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n ack(`error putting null on ${pub}: ${err}`)\n return\n }\n\n user.is = null\n if (cb) cb(null)\n })\n })\n },\n }\n return user\n}\n\nexport default User\n\n", "/**\n * Holster - Main API for graph database operations\n * Provides chainable interface for get, put, on, off operations\n */\n\nimport * as utils from \"./utils.ts\"\nimport Wire, { type WireAPI } from \"./wire.ts\"\nimport User, { type UserInterface } from \"./user.ts\"\nimport SEA from \"./sea.ts\"\nimport type {\n HolsterOptions,\n ChainItem,\n ApiContext,\n Graph,\n GraphValue,\n Lex,\n LexFilter,\n LexWithDot,\n UserIdentity,\n WireOptions,\n} from \"./schemas.ts\"\n\n/**\n * Holster API interface\n */\nexport interface HolsterAPI {\n get: {\n (key: string | null, lex?: LexWithDot, cb?: (data: unknown) => void, _opt?: WireOptions): HolsterAPI\n (\n key: string | null,\n cb?: (data: unknown) => void,\n _opt?: WireOptions\n ): HolsterAPI\n }\n next: {\n (key: string | null, lex?: LexWithDot, cb?: (data: unknown) => void, _opt?: WireOptions): HolsterAPI\n (\n key: string | null,\n cb?: (data: unknown) => void,\n _opt?: WireOptions\n ): HolsterAPI\n }\n put: (\n data: GraphValue | Record<string, GraphValue>,\n set?: boolean | ((data?: string | null) => void),\n cb?: (data?: string | null) => void\n ) => HolsterAPI | void\n on: (\n lex: LexWithDot | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | boolean,\n _get?: boolean,\n _opt?: WireOptions\n ) => void\n off: (cb?: (data: unknown) => void) => HolsterAPI | void\n user: () => UserInterface & HolsterAPI\n wire: WireAPI\n SEA: typeof SEA\n}\n\nconst Holster = (opt?: HolsterOptions | string | string[]): HolsterAPI => {\n let options: HolsterOptions\n if (typeof opt === \"string\") options = { peers: [opt] }\n else if (opt instanceof Array) options = { peers: opt }\n else if (!utils.obj.is(opt)) options = {}\n else options = opt\n\n const wire = Wire(options)\n const user = User(options, wire as never)\n const map = new Map<(data: unknown) => void, () => void>()\n const allctx = new Map<string, ApiContext>()\n\n const ok = (data: GraphValue): boolean => {\n return (\n data === null ||\n data === true ||\n data === false ||\n typeof data === \"string\" ||\n !!utils.rel.is(data) ||\n utils.num.is(data)\n )\n }\n\n const check = (\n data: GraphValue | Record<string, GraphValue>\n ): true | string | string[] => {\n if (ok(data as GraphValue)) return true\n\n if (utils.obj.is(data)) {\n const keys: string[] = []\n for (const [key, value] of Object.entries(data)) {\n if (key === \"_\") {\n return \"error underscore cannot be used as a property name\"\n }\n if (utils.obj.is(value) || ok(value as GraphValue)) {\n keys.push(key)\n continue\n }\n if (typeof value === \"undefined\") {\n return `error undefined ${key} cannot be converted to a graph`\n }\n const error = JSON.stringify({ [key]: value })\n return `error ${error} cannot be converted to a graph`\n }\n if (keys.length !== 0) return keys\n }\n const error = JSON.stringify(data)\n return `error ${error} cannot be converted to a graph`\n }\n\n const api = (initCtxid?: string): HolsterAPI => {\n let ctxid = initCtxid\n const get = (\n lex: LexFilter,\n soul: string,\n ack: (data: unknown) => void,\n _opt?: WireOptions\n ): void => {\n wire.get(\n utils.obj.put(lex as never, \"#\", soul) as Lex,\n async msg => {\n if (msg.err) console.log(msg.err)\n if (msg.put && msg.put[soul]) {\n delete (msg.put[soul] as { _?: unknown })._\n delete (msg.put[soul] as Record<string, unknown>)[utils.userPublicKey]\n delete (msg.put[soul] as Record<string, unknown>)[utils.userSignature]\n for (const key of Object.keys(msg.put[soul]!)) {\n const id = utils.rel.is(msg.put[soul]![key] as GraphValue)\n if (id) {\n const attemptRead = async (retries = 0): Promise<unknown> => {\n const data = await new Promise<unknown>(res => {\n const _ctxid = utils.text.random()\n const ctx = allctx.get(ctxid!)\n allctx.set(_ctxid, {\n chain: [{ item: null, soul: id }],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null as never, res as never, _opt)\n })\n if (data !== null || retries >= 5) {\n return data\n }\n await new Promise(resolve => setTimeout(resolve, 50))\n return attemptRead(retries + 1)\n }\n msg.put[soul]![key] = (await attemptRead()) as GraphValue\n }\n }\n ack(msg.put[soul])\n } else {\n ack(null)\n }\n },\n _opt\n )\n }\n\n const graph = async (\n soul: string,\n data: Record<string, GraphValue>,\n userctx?: UserIdentity | null,\n cb?: (err?: string) => void\n ): Promise<Graph | null> => {\n if (userctx) {\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, userctx)\n return utils.graph(soul, data, sig!, userctx.pub, timestamp)\n }\n\n if (options.secure) {\n if (!cb) cb = console.log\n cb(`error putting data on ${soul}: user required in secure mode`)\n return null\n }\n\n return utils.graph(soul, data)\n }\n\n const done = (ctxid: string) => {\n return (data: unknown): void => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") {\n setTimeout(() => ctx.cb!(data as never), 1)\n } else if (data) {\n console.log(\"error no callback for data\", data, \"ctx\", ctx)\n }\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n }\n\n const watchForRel = (\n soul: string,\n item: string,\n ctx: ApiContext,\n i: number,\n request: { on?: LexFilter; _get?: boolean; _opt?: WireOptions },\n cb: (data: unknown) => void\n ): void => {\n const handler = (): void => {\n // Bail out if the context was removed by off().\n if (!allctx.has(ctxid!)) {\n wire.off({ \"#\": soul, \".\": item }, handler)\n return\n }\n wire.get(\n { \"#\": soul, \".\": item },\n msg => {\n const node = msg.put && msg.put[soul]\n const id = utils.rel.is(node && node[item] as GraphValue)\n if (!id) return\n wire.off({ \"#\": soul, \".\": item }, handler)\n ctx.chain[i]!.soul = id\n allctx.set(ctxid!, { ...ctx })\n api(ctxid).on(request.on!, cb, request._get, request._opt)\n },\n { ...request._opt, secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n }\n wire.on({ \"#\": soul, \".\": item }, handler, false, request._opt)\n }\n\n const resolve = (\n request: {\n get?: LexFilter\n put?: GraphValue | Record<string, GraphValue>\n on?: LexFilter\n off?: boolean\n _opt?: WireOptions\n _get?: boolean\n },\n cb?: (data: unknown) => void\n ): ChainItem | false => {\n if (!request) {\n console.log(\"error resolve request parameter required\")\n return false\n }\n\n const get = typeof request.get !== \"undefined\"\n const put = typeof request.put !== \"undefined\"\n const on = typeof request.on !== \"undefined\"\n const off = typeof request.off !== \"undefined\"\n\n let found = false\n const ctx = allctx.get(ctxid!)!\n for (let i = 1; i < ctx.chain.length; i++) {\n if (ctx.chain[i]!.soul !== null) continue\n found = true\n break\n }\n\n if (found) {\n let i = 1\n while (i < ctx.chain.length && ctx.chain[i]!.soul !== null) i++\n const { item, soul } = ctx.chain[i - 1]!\n wire.get(\n { \"#\": soul!, \".\": item! },\n async msg => {\n if (msg.err) {\n console.log(`error getting ${item} on ${soul}: ${msg.err}`)\n if (cb) cb(null)\n return\n }\n\n let node = msg.put && msg.put[soul!]\n if (node && typeof node[item!] !== \"undefined\") {\n let id = utils.rel.is(node[item!] as GraphValue)\n if (id) {\n ctx.chain[i]!.soul = id\n allctx.set(ctxid!, { ...ctx })\n if (get) {\n api(ctxid).next(null as never, request.get as never, cb as never, request._opt)\n } else if (put) {\n api(ctxid).put(request.put!, cb as never)\n } else if (on) {\n api(ctxid).on(request.on!, cb!, request._get, request._opt)\n } else if (off) {\n api(ctxid).off(cb as never)\n }\n } else if (get) {\n cb!(node[item!])\n } else if (put) {\n id = utils.text.random()\n node[item!] = utils.rel.ify(id)\n const g = await graph(soul!, node as never, ctx.user, cb as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n (cb as (err: string) => void)(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n if (id) {\n ctx.chain[i]!.soul = id\n }\n api(ctxid).put(request.put!, cb as never)\n })\n } else if (on) {\n // Item is not a rel yet \u2014 watch the parent soul for when it\n // becomes one, then retry chain resolution.\n watchForRel(soul!, item!, ctx, i, request, cb!)\n if (request._get) cb!(null)\n } else if (off) {\n if (cb) cb(null)\n }\n } else if (put) {\n const id = utils.text.random()\n if (!node) node = {} as never\n node[item!] = utils.rel.ify(id)\n const g = await graph(soul!, node as never, ctx.user, cb as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n (cb as (err: string) => void)(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n ctx.chain[i]!.soul = id\n api(ctxid).put(request.put!, cb as never)\n })\n } else {\n if (on) {\n // Node doesn't exist yet \u2014 watch for it to appear.\n watchForRel(soul!, item!, ctx, i, request, cb!)\n if (request._get) cb!(null)\n } else {\n if (cb) cb(null)\n }\n }\n },\n { ...request._opt, secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n return false\n }\n\n if (get && ctx.chain[ctx.chain.length - 1]!.item !== null) {\n ctx.chain.push({ item: null, soul: null })\n api(ctxid).next(null as never, request.get as never, cb as never, request._opt)\n return false\n }\n\n return ctx.chain[ctx.chain.length - 1]!\n }\n\n return {\n get: function (\n this: HolsterAPI,\n key: string | null,\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (callback) callback(null)\n return this\n }\n\n if (lexFilter && typeof callback !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n ctxid = utils.text.random()\n allctx.set(ctxid, {\n chain: [{ item: String(key), soul: \"root\" }],\n cb: callback,\n })\n if (!callback) return api(ctxid)\n\n const _done = done(ctxid)\n const result = resolve({ get: lexFilter, _opt: opts }, _done)\n if (result) get(lexFilter as never, result.soul!, _done, opts)\n return this\n } as HolsterAPI[\"get\"],\n\n next: function (\n this: HolsterAPI,\n key: string | null,\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n const ack = (ctxid: string) => {\n return (data: unknown): void => {\n if (callback) {\n callback(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (callback) callback(null)\n return this\n }\n\n const _ack = ack(ctxid)\n if (key === \"\" || key === \"_\") {\n _ack(null)\n return this\n }\n\n if (lexFilter && typeof callback !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n const ctx = allctx.get(ctxid)\n if (!ctx) return this\n\n if (callback && typeof ctx.cb === \"undefined\") {\n ctx.cb = callback\n callback = undefined\n }\n\n if (key !== null) ctx.chain.push({ item: String(key), soul: null })\n if (!ctx.cb) return api(ctxid)\n\n const result = resolve({ get: lexFilter, _opt: opts }, _ack)\n if (result) get(lexFilter as never, result.soul!, _ack, opts)\n return this\n } as HolsterAPI[\"next\"],\n\n put: function (\n data: GraphValue | Record<string, GraphValue>,\n set?: boolean | ((data?: string | null) => void),\n cb?: (data?: string | null) => void\n ): HolsterAPI | void {\n let isSet = false\n let callback: ((data?: string | null) => void) | undefined\n\n if (typeof set === \"function\") {\n callback = set\n isSet = false\n } else {\n isSet = set || false\n callback = cb\n }\n\n const ack = (ctxid: string) => {\n return (data?: string | null): void => {\n if (callback) {\n callback(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n\n if (!ctxid) {\n if (callback) callback(\"error please provide a key using get(key)\")\n return\n }\n\n const ctx = allctx.get(ctxid!)\n if (!ctx) return\n\n if (!ctx.cb) {\n if (!callback) return\n ctx.cb = callback as never\n callback = undefined\n }\n\n if (isSet) data = { [utils.text.random()]: data } as Record<string, GraphValue>\n\n const _ack = ack(ctxid)\n const result = check(data)\n if (typeof result === \"string\") {\n _ack(result)\n return\n }\n\n const resolved = resolve({ put: data }, _ack as never)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n if (result === true) {\n wire.get(\n { \"#\": soul, \".\": item! },\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item!]\n const id = utils.rel.is(current as GraphValue)\n if (!id) {\n if (!node) node = {} as never\n node[item!] = (isSet ? data : data) as GraphValue\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n return\n }\n\n wire.get({ \"#\": id }, async msg => {\n if (msg.err) {\n _ack(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n _ack(`error ${id} not found`)\n return\n }\n\n for (const key of Object.keys(msg.put[id]!)) {\n if (\n key === \"_\" ||\n key === utils.userPublicKey ||\n key === utils.userSignature\n ) {\n continue\n }\n\n const err = await new Promise<string | null | undefined>(res => {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: key, soul: id }]\n allctx.set(_ctxid, { chain: chain, user: ctx.user })\n api(_ctxid).put(null!, res as never)\n })\n if (err) {\n _ack(err)\n return\n }\n }\n if (!node) node = {} as never\n node[item!] = data as GraphValue\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n })\n },\n { secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n return\n }\n\n const attemptRead = (retries = 0): void => {\n wire.get(\n { \"#\": soul, \".\": item! },\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item!]\n\n if (!current && retries < 5) {\n await new Promise(r => setTimeout(r, 50))\n return attemptRead(retries + 1)\n }\n\n const id = utils.rel.is(current as GraphValue)\n if (!id) {\n if (!node) node = {} as never\n node[item!] = utils.rel.ify(utils.text.random())\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n _ack(`error putting ${item} on ${soul}: ${err}`)\n } else {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: item!, soul: soul }]\n allctx.set(_ctxid, {\n chain: chain,\n user: ctx.user,\n cb: ctx.cb,\n })\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n const update: string[] = []\n for (const key of result as string[]) {\n const err = await new Promise<string | null | undefined>(res => {\n if (\n utils.obj.is((data as Record<string, unknown>)[key]) &&\n !utils.rel.is((data as Record<string, GraphValue>)[key])\n ) {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: key, soul: id }]\n allctx.set(_ctxid, { chain: chain, user: ctx.user })\n api(_ctxid).put((data as Record<string, GraphValue>)[key]!, res as never)\n } else {\n update.push(key)\n res(null)\n }\n })\n if (err) {\n _ack(err)\n return\n }\n }\n\n if (update.length === 0) {\n _ack(null)\n return\n }\n\n // Only write the primitive update keys. Rels created by the\n // recursive puts above are already in the in-memory graph.\n const updateNode: Record<string, GraphValue> = {}\n update.forEach(key => {\n updateNode[key] = (data as Record<string, GraphValue>)[key]!\n })\n const g = await graph(id, updateNode as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n },\n { secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n }\n attemptRead()\n },\n\n on: function (\n lex: LexWithDot | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | boolean,\n _get?: boolean,\n _opt?: WireOptions\n ): void {\n let lexFilter: LexFilter | undefined\n let callback: (data: unknown) => void\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = _get as never\n _get = cb as never\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex as LexFilter\n callback = (typeof cb === \"function\" ? cb : undefined)!\n opts = _opt\n }\n\n if (typeof callback !== \"function\") {\n console.log(\"error on() requires a callback function\")\n return\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n callback(null)\n return\n }\n\n const resolved = resolve({ on: lexFilter, _get: _get, _opt: opts }, callback)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n const ctx = allctx.get(ctxid)\n\n allctx.set(ctxid, {\n chain: [{ item: item, soul: soul }],\n on: true,\n user: ctx ? ctx.user : null,\n })\n\n // Shared retry state for this on() subscription.\n let retryCount = 0\n const maxRetries = 5\n const retryDelay = 1000\n let retryTimer: ReturnType<typeof setTimeout> | null = null\n\n map.set(callback, () => {\n // Bail out if off() has already cleaned up this context \u2014 the mapped\n // callback can fire twice (once from wire.on and once from the _get\n // immediate-read path) and the second call after async context cleanup\n // would crash in resolve(). Matches the guard in watchForRel.\n if (!allctx.has(ctxid!)) return\n // Cancel any pending retry \u2014 the persistent listener firing means we\n // have an update and should not call callback twice.\n clearTimeout(retryTimer!)\n retryTimer = null\n wire.get(\n { \"#\": soul, \".\": item! },\n msg => {\n const node = msg.put && msg.put[soul]\n const current = node && node[item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) {\n const attemptRead = async (retries = 0): Promise<void> => {\n const data = await new Promise<unknown>(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {\n chain: [{ item: null, soul: id }],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null as never, res as never, (retries === 0 ? utils.obj.put(opts, \"fast\", true) : opts) as never)\n })\n if (data !== null || retries >= 5) {\n retryCount = 0\n callback(data)\n } else {\n await new Promise(resolve => setTimeout(resolve, 50))\n attemptRead(retries + 1)\n }\n }\n attemptRead()\n } else {\n const nodeExists = !!node\n if (nodeExists) {\n retryCount = 0\n callback(current !== undefined ? current : null)\n } else if (retryCount < maxRetries) {\n // No data yet \u2014 keep polling until we get a response or\n // exhaust retries. on() with _get can return null on a cache\n // miss and never fire again if the data doesn't change while\n // the listener is attached, so we must poll for initial load.\n const secureOpt = { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n const retry = (): void => {\n const delay = Math.min(retryDelay * Math.pow(2, retryCount), 30000)\n retryCount++\n retryTimer = setTimeout(() => {\n wire.get(\n { \"#\": soul, \".\": item! },\n retryMsg => {\n const retryNode = retryMsg.put && retryMsg.put[soul]\n if (retryNode) {\n retryCount = 0\n retryTimer = null\n const retryValue = retryNode[item!]\n callback(retryValue !== undefined ? retryValue : null)\n } else if (retryCount < maxRetries) {\n retry()\n } else {\n retryTimer = null\n callback(null)\n }\n },\n secureOpt,\n )\n }, delay)\n }\n retry()\n } else {\n callback(null)\n }\n }\n },\n { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n )\n })\n\n let initialLex: { \"#\": string; \".\"?: string | number } = lexFilter\n ? (utils.obj.put(lexFilter as never, \"#\", soul) as { \"#\": string; \".\"?: string | number })\n : { \"#\": soul, \".\": item! }\n if (initialLex[\".\"] != null && typeof initialLex[\".\"] === \"number\") {\n initialLex = { ...initialLex, \".\": String(initialLex[\".\"]) }\n }\n wire.on(initialLex as never, map.get(callback)!, false, opts)\n\n wire.get(\n { \"#\": soul, \".\": item! },\n msg => {\n if (msg.err) {\n console.log(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul]![item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) {\n wire.off(initialLex as never, map.get(callback)!)\n const relLex = (lexFilter\n ? utils.obj.put(initialLex as never, \"#\", id)\n : { \"#\": id, \".\": null }) as Lex\n wire.on(relLex, map.get(callback)!, false, opts)\n if (_get) map.get(callback)!()\n } else if (_get) {\n // Not a rel, but _get was requested, so trigger callback.\n map.get(callback)!()\n }\n },\n { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n )\n },\n\n off: function (cb?: (data: unknown) => void): HolsterAPI | void {\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n const resolved = resolve({ off: true }, cb)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n wire.off({ \"#\": soul } as never, map.get(cb!)!)\n\n wire.get({ \"#\": soul, \".\": item! }, msg => {\n if (msg.err) {\n map.delete(cb!)\n allctx.delete(ctxid!)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul]![item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) wire.off({ \"#\": id } as never, map.get(cb!)!)\n map.delete(cb!)\n allctx.delete(ctxid!)\n })\n },\n\n user: () => {\n if (!(user as { get?: unknown }).get) {\n Object.assign(user, api())\n ;(user as UserInterface & HolsterAPI).get = function (\n this: HolsterAPI,\n keys: string | string[],\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n let pub: string | null = null\n let key: string | null = null\n if (user.is) pub = user.is.pub\n if (typeof keys === \"string\") {\n key = keys\n } else if (keys instanceof Array) {\n if (keys.length === 2 && keys[0] && keys[1]) {\n pub = keys[0]\n key = keys[1]\n } else if (keys.length === 1 && keys[0]) {\n key = keys[0]\n }\n }\n if (!pub) {\n console.log(\"error please log in or provide a public key\")\n if (callback) callback(null)\n return this\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (callback) callback(null)\n return this\n }\n\n if (lexFilter && !callback) {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: String(key), soul: \"~\" + pub }]\n allctx.set(ctxid, { chain: chain, user: user.is, cb: callback as never })\n if (!callback) return api(ctxid)\n\n const _done = done(ctxid)\n const resolved = resolve({ get: lexFilter, _opt: opts }, _done)\n if (resolved) get(lexFilter as never, resolved.soul!, _done, opts)\n return this\n } as never\n }\n return user as UserInterface & HolsterAPI\n },\n\n wire: wire,\n SEA: SEA,\n }\n }\n return api()\n}\n\nexport default Holster\n\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["num", "n", "parsed", "obj", "o", "match", "list", "cb", "keys", "key", "result", "value", "target", "map_soul", "soul", "rel", "userSignature", "userPublicKey", "graph", "data", "sig", "pub", "timestamp", "ts", "stateVector", "node", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "len", "Dup", "
|
|
4
|
+
"sourcesContent": ["/**\n * Utility functions for Holster\n * Provides helpers for type checking, graph manipulation, and pattern matching\n */\n\nimport type { Soul, Relation, Graph, GraphNode, LexFilter, GraphValue } from \"./schemas.ts\"\n\n// ============================================================================\n// Number Utilities\n// ============================================================================\n\nexport const num = {\n /**\n * Check if value is a valid number\n */\n is: (n: unknown): n is number => {\n if (n instanceof Array) return false\n if (typeof n === \"number\") return !isNaN(n)\n if (typeof n === \"string\") {\n const parsed = parseFloat(n)\n return !isNaN(parsed) && isFinite(parsed)\n }\n return false\n },\n}\n\n// ============================================================================\n// Object Utilities\n// ============================================================================\n\ntype PlainObject = Record<string, unknown>\n\nexport const obj = {\n /**\n * Check if value is a plain object\n */\n is: (o: unknown): o is PlainObject => {\n if (!o || typeof o !== \"object\") return false\n const toString = Object.prototype.toString.call(o)\n const match = toString.match(/^\\[object (\\w+)\\]$/)\n return (\n (o as Record<string, unknown>).constructor === Object ||\n (match !== null && match[1] === \"Object\")\n )\n },\n\n /**\n * Map over object keys with early return support\n */\n map: <T, R>(\n list: Record<string, T>,\n cb: (value: T, key: string, o?: Record<string, unknown>) => R | undefined,\n o?: Record<string, unknown>\n ): R | undefined => {\n const keys = Object.keys(list)\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n const result = cb(list[key]!, key, o)\n if (typeof result !== \"undefined\") return result\n }\n return undefined\n },\n\n /**\n * Set a property on an object\n */\n put: (o: Record<string, unknown> | undefined, key: string, value: unknown): Record<string, unknown> => {\n const target = o || {}\n target[key] = value\n return target\n },\n\n /**\n * Delete a property from an object\n */\n del: <T>(o: Record<string, T> | undefined, key: string): Record<string, T> | undefined => {\n if (!o) return undefined\n o[key] = null as T\n delete o[key]\n return o\n },\n}\n\n// ============================================================================\n// Relation Utilities\n// ============================================================================\n\nconst map_soul = (soul: unknown, key: string, o: { id: string | false }): void => {\n // If id is already defined AND we're still looping through the object,\n // then it is considered invalid\n if (o.id) {\n o.id = false\n return\n }\n\n if (key === \"#\" && typeof soul === \"string\") {\n o.id = soul\n return\n }\n\n // If there exists anything else on the object that isn't the soul,\n // then it is considered invalid\n o.id = false\n}\n\nexport const rel = {\n /**\n * Check if value is a soul relation and return the soul ID\n */\n is: (value: unknown): string | false => {\n if (\n value &&\n typeof value === \"object\" &&\n \"#\" in value &&\n !(\"_\" in value) &&\n obj.is(value)\n ) {\n const o: { id: string | false } = { id: \"\" }\n obj.map(value as Record<string, unknown>, map_soul as (value: unknown, key: string, o?: Record<string, unknown>) => void, o)\n if (o.id) return o.id\n }\n return false\n },\n\n /**\n * Convert a soul into a relation and return it\n */\n ify: (soul: Soul): Relation => obj.put({}, \"#\", soul) as Relation,\n}\n\n// ============================================================================\n// User Metadata Keys\n// ============================================================================\n\nexport const userSignature = \"_holster_user_signature\"\nexport const userPublicKey = \"_holster_user_public_key\"\n\n// ============================================================================\n// Graph Construction\n// ============================================================================\n\n/**\n * Create a graph from soul and data with optional signature metadata\n */\nexport const graph = (\n soul: Soul,\n data: Record<string, GraphValue>,\n sig?: string,\n pub?: string,\n timestamp?: number\n): Graph => {\n const ts = timestamp || Date.now()\n const stateVector: Record<string, number> = {}\n const node: GraphNode = {\n _: { \"#\": soul, \">\": stateVector },\n }\n\n for (const [key, value] of Object.entries(data)) {\n if (key !== \"_\" && key !== userPublicKey && key !== userSignature) {\n node[key] = value\n stateVector[key] = ts\n }\n }\n\n if (sig && pub && timestamp) {\n if (!node._[\"s\"]) {\n node._[\"s\"] = {}\n }\n node._[\"s\"][timestamp.toString()] = sig\n node[userPublicKey] = pub\n stateVector[userPublicKey] = timestamp\n }\n\n return { [soul]: node }\n}\n\n// ============================================================================\n// Pattern Matching\n// ============================================================================\n\n/**\n * Match a lex filter against a key\n */\nexport const match = (lex: LexFilter, key?: string): boolean => {\n // Null is used to match listeners on souls, which don't provide a key\n if (typeof key === \"undefined\") return lex === null\n\n if (typeof lex === \"undefined\") return true\n\n if (typeof lex === \"string\") return lex === key\n\n // Array support: check if key is in the array\n if (Array.isArray(lex)) return lex.includes(key)\n\n if (!obj.is(lex) || !key) return false\n\n // Prefix match\n if (\"*\" in lex) {\n const prefix = lex[\"*\"] as string\n return key.slice(0, prefix.length) === prefix\n }\n\n // Range match\n const gt = \">\" in lex ? (lex[\">\"] as string) : undefined\n const lt = \"<\" in lex ? (lex[\"<\"] as string) : undefined\n\n if (gt && lt) return key >= gt && key <= lt\n if (gt) return key >= gt\n if (lt) return key <= lt\n\n return false\n}\n\n// ============================================================================\n// Text Utilities\n// ============================================================================\n\nexport const text = {\n /**\n * Generate a random string of specified length\n */\n random: (length?: number): string => {\n let s = \"\"\n const c = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n const len = length || 24\n for (let i = 0; i < len; i++) {\n s += c.charAt(Math.floor(Math.random() * c.length))\n }\n return s\n },\n}\n\n", "export interface DupInterface {\n store: Record<string, number>\n check: (id: string) => string | false\n track: (id: string) => string\n expiry: NodeJS.Timeout | null\n}\n\nconst Dup = (): DupInterface => {\n const maxAge = 9000\n const dup: DupInterface = {\n store: {},\n expiry: null,\n check: (id: string): string | false => {\n return dup.store[id] ? dup.track(id) : false\n },\n track: (id: string): string => {\n // Keep the liveliness of the message up while it is being received\n dup.store[id] = Date.now()\n if (!dup.expiry) {\n dup.expiry = setTimeout(() => {\n const now = Date.now()\n Object.keys(dup.store).forEach(id => {\n if (now - dup.store[id]! > maxAge) {\n delete dup.store[id]\n }\n })\n dup.expiry = null\n }, maxAge)\n // Don't block process exit \u2014 cleanup is best-effort.\n if (dup.expiry.unref) dup.expiry.unref()\n }\n return id\n },\n }\n return dup\n}\n\nexport default Dup\n", "/**\n * Get - Query data from the graph\n * Extracts nodes and properties based on lex queries\n */\n\nimport { match, userPublicKey } from \"./utils.ts\"\nimport type { Lex, Graph } from \"./schemas.ts\"\nimport type { GraphNode } from \"./schemas.ts\"\n\n/**\n * Get data from graph based on lex query\n * @param lex - Query specification with soul and optional property filter\n * @param graph - In-memory graph\n * @param fast - If true, return current data; if false, return undefined to trigger store lookup\n */\nconst Get = (lex: Lex, graph: Graph, fast?: boolean): Graph | undefined => {\n if (!lex || typeof lex !== \"object\") {\n throw new TypeError(\"lex must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n\n const soul = lex[\"#\"]\n if (!soul || typeof soul !== \"string\") {\n throw new TypeError(\"soul must be a string\")\n }\n\n if (!graph[soul]) return undefined\n\n const stateVector: Record<string, number> = {}\n const node: GraphNode = { _: { \"#\": soul, \">\": stateVector } }\n const signatures: Record<string, string> = {}\n\n if (typeof lex[\".\"] === \"string\") {\n const key = lex[\".\"]\n if (typeof graph[soul]![key] === \"undefined\") return undefined\n\n node[key] = graph[soul]![key]\n node._[\">\"][key] = graph[soul]!._[\">\"][key]!\n const state = graph[soul]!._[\">\"][key]!\n const sigs = graph[soul]!._[\"s\"]\n if (sigs && sigs[state]) {\n signatures[state.toString()] = sigs[state]!\n }\n\n // Always include userPublicKey for verification, regardless of filter\n if (userPublicKey && typeof graph[soul]![userPublicKey] !== \"undefined\") {\n node[userPublicKey] = graph[soul]![userPublicKey]\n node._[\">\"][userPublicKey] = graph[soul]!._[\">\"][userPublicKey]!\n const pkState = graph[soul]!._[\">\"][userPublicKey]!\n const pkSigs = graph[soul]!._[\"s\"]\n if (pkSigs && pkSigs[pkState]) {\n signatures[pkState.toString()] = pkSigs[pkState]!\n }\n }\n } else {\n // For fast requests, return properties currently in the graph. Otherwise\n // return undefined to ensure we get all matching properties from store.\n if (!fast) return undefined\n\n for (const key of Object.keys(graph[soul]!)) {\n // Always include userPublicKey for verification, regardless of filter\n if (key === userPublicKey || match(lex[\".\"], key)) {\n node[key] = graph[soul]![key]!\n node._[\">\"][key] = graph[soul]!._[\">\"][key]!\n const state = graph[soul]!._[\">\"][key]!\n const sigs = graph[soul]!._[\"s\"]\n if (sigs && sigs[state]) {\n signatures[state.toString()] = sigs[state]!\n }\n }\n }\n }\n\n if (Object.keys(signatures).length > 0) {\n node._[\"s\"] = signatures\n }\n return { [soul]: node }\n}\n\nexport default Get\n\n", "/**\n * SeaArray - Extended Array with custom toString for encoding support\n * Supports utf8, hex, and base64 encoding\n */\n\nif (typeof btoa === \"undefined\") {\n globalThis.btoa = (data: string): string =>\n Buffer.from(data, \"binary\").toString(\"base64\")\n globalThis.atob = (data: string): string =>\n Buffer.from(data, \"base64\").toString(\"binary\")\n}\n\ntype Encoding = \"utf8\" | \"hex\" | \"base64\"\n\n/**\n * SeaArray extends Array to provide encoding capabilities\n */\nclass SeaArray extends Array<number> {\n /**\n * Convert array to string with specified encoding\n * @param enc - Encoding type (utf8, hex, or base64)\n * @param start - Start index (default: 0)\n * @param end - End index (default: array length)\n */\n override toString(enc?: Encoding, start?: number, end?: number): string {\n const encoding = enc || \"utf8\"\n const startIdx = start || 0\n const endIdx = end ? Math.min(Math.max(end, startIdx), this.length) : this.length\n\n if (encoding === \"hex\") {\n const buf = new Uint8Array(this.slice(startIdx, endIdx))\n return Array.from(buf, byte => byte.toString(16).padStart(2, \"0\")).join(\"\")\n }\n\n if (encoding === \"utf8\") {\n return Array.from({ length: endIdx - startIdx }, (_, i) => {\n const charCode = this[i + startIdx]\n // Use unicode replacement character for invalid character codes\n if (\n charCode === undefined ||\n charCode < 0 ||\n charCode > 0x10ffff\n ) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n }\n\n if (encoding === \"base64\") {\n const utf8String = Array.from({ length: endIdx - startIdx }, (_, i) => {\n const charCode = this[i + startIdx]\n if (charCode === undefined || charCode < 0 || charCode > 255) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n return btoa(utf8String)\n }\n\n // Default to utf8\n return this.toString(\"utf8\", startIdx, endIdx)\n }\n\n /**\n * Create SeaArray from iterable or array-like\n */\n static override from<T>(\n arrayLike: ArrayLike<T> | Iterable<T>\n ): SeaArray {\n const arr = Array.from(arrayLike) as number[]\n const seaArray = new SeaArray(...arr)\n return seaArray\n }\n}\n\nexport default SeaArray\n\n", "/**\n * SafeBuffer - Secure Buffer implementation with validation\n * Compatible with Node.js Buffer API but with enhanced security checks\n */\n\nimport SeaArray from \"./array.ts\"\n\ntype Encoding = \"utf8\" | \"utf-8\" | \"hex\" | \"base64\" | \"binary\" | \"latin1\" | \"ascii\"\n\n// Security constants\nconst SECURITY_LIMITS = {\n MAX_BUFFER_SIZE: 10 * 1024 * 1024, // 10MB limit\n MAX_STRING_LENGTH: 1024 * 1024, // 1MB string limit\n}\n\n// Type definition for SafeBuffer static interface\ninterface SafeBufferConstructor {\n (...props: unknown[]): SeaArray\n prototype: typeof Array.prototype\n from(input: string, encoding?: Encoding): SeaArray\n from(input: ArrayBuffer | ArrayBufferView | number[]): SeaArray\n from(...args: unknown[]): SeaArray\n alloc(length: number, fill?: number | string): SeaArray\n concat(arr: ArrayLike<unknown>[]): SeaArray\n isBuffer(obj: unknown): obj is SeaArray\n byteLength(string: string, encoding?: Encoding): number\n}\n\n/**\n * SafeBuffer constructor (deprecated - use SafeBuffer.from())\n */\nconst SafeBuffer = function SafeBuffer(..._props: unknown[]): SeaArray {\n console.warn(\"new SafeBuffer() is deprecated, please use SafeBuffer.from()\")\n // Will be implemented after from() is defined\n return SeaArray.from([])\n} as SafeBufferConstructor\n\nSafeBuffer.prototype = Object.create(Array.prototype)\n\n// ============================================================================\n// Input Validation Helpers\n// ============================================================================\n\nconst validateStringInput = (input: string, _encoding: Encoding): void => {\n if (input.length > SECURITY_LIMITS.MAX_STRING_LENGTH) {\n throw new RangeError(\n `String too large: ${input.length} > ${SECURITY_LIMITS.MAX_STRING_LENGTH}`\n )\n }\n}\n\nconst validateBufferSize = (size: number, operation = \"buffer operation\"): void => {\n if (size > SECURITY_LIMITS.MAX_BUFFER_SIZE) {\n throw new RangeError(\n `Buffer size too large for ${operation}: ${size} > ${SECURITY_LIMITS.MAX_BUFFER_SIZE}`\n )\n }\n}\n\n// ============================================================================\n// Encoding Parsers\n// ============================================================================\n\nconst parseHexString = (hexString: string): Uint8Array => {\n validateStringInput(hexString, \"hex\")\n\n const cleanHex = hexString.replace(/\\s/g, \"\").toLowerCase()\n\n if (!/^[0-9a-f]*$/.test(cleanHex)) {\n throw new TypeError(\"Invalid hex string: contains non-hex characters\")\n }\n\n if (cleanHex.length % 2 !== 0) {\n throw new TypeError(\"Invalid hex string: must have even length\")\n }\n\n if (cleanHex.length === 0) {\n return new Uint8Array(0)\n }\n\n validateBufferSize(cleanHex.length / 2, \"hex parsing\")\n\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n const hexByte = cleanHex.substr(i, 2)\n bytes[i / 2] = parseInt(hexByte, 16)\n }\n return bytes\n}\n\nconst encodeUtf8String = (str: string): Uint8Array => {\n validateStringInput(str, \"utf8\")\n\n try {\n const encoder = new TextEncoder()\n const bytes = encoder.encode(str)\n validateBufferSize(bytes.length, \"UTF-8 encoding\")\n return bytes\n } catch (err) {\n throw new TypeError(`Failed to encode UTF-8 string: ${(err as Error).message}`)\n }\n}\n\nconst encodeBinaryString = (str: string): Uint8Array => {\n validateStringInput(str, \"binary\")\n validateBufferSize(str.length, \"binary encoding\")\n\n const bytes = new Uint8Array(str.length)\n for (let i = 0; i < str.length; i++) {\n const charCode = str.charCodeAt(i)\n if (charCode > 255) {\n throw new TypeError(\n `Invalid binary string: character at position ${i} exceeds byte range (${charCode} > 255)`\n )\n }\n bytes[i] = charCode\n }\n return bytes\n}\n\nconst parseBase64String = (base64String: string): Uint8Array => {\n validateStringInput(base64String, \"base64\")\n\n const cleanBase64 = base64String.replace(/\\s/g, \"\")\n\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\n throw new TypeError(\"Invalid base64 string: contains invalid characters\")\n }\n\n try {\n const decodedString = atob(cleanBase64)\n validateBufferSize(decodedString.length, \"base64 decoding\")\n\n const bytes = new Uint8Array(decodedString.length)\n for (let i = 0; i < decodedString.length; i++) {\n bytes[i] = decodedString.charCodeAt(i)\n }\n return bytes\n } catch (err) {\n throw new TypeError(`Failed to decode base64 string: ${(err as Error).message}`)\n }\n}\n\nconst processArrayLikeInput = (input: unknown): Uint8Array => {\n if (input instanceof ArrayBuffer) {\n validateBufferSize(input.byteLength, \"ArrayBuffer processing\")\n return new Uint8Array(input)\n }\n\n if (ArrayBuffer.isView(input)) {\n validateBufferSize(input.byteLength, \"TypedArray processing\")\n return new Uint8Array(input.buffer, input.byteOffset, input.byteLength)\n }\n\n if (Array.isArray(input)) {\n validateBufferSize(input.length, \"Array processing\")\n\n for (let i = 0; i < input.length; i++) {\n const val = input[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`\n )\n }\n }\n return new Uint8Array(input)\n }\n\n if (\n typeof input === \"object\" &&\n input !== null &&\n \"byteLength\" in input &&\n typeof (input as { byteLength: unknown }).byteLength === \"number\"\n ) {\n validateBufferSize((input as { byteLength: number }).byteLength, \"ArrayBuffer-like processing\")\n return new Uint8Array(input as ArrayBuffer)\n }\n\n if (\n typeof input === \"object\" &&\n input !== null &&\n \"length\" in input &&\n typeof (input as { length: unknown }).length === \"number\"\n ) {\n const arrayLike = input as ArrayLike<unknown>\n validateBufferSize(arrayLike.length, \"array-like processing\")\n\n const arr = Array.from(arrayLike)\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`\n )\n }\n }\n return new Uint8Array(arr as number[])\n }\n\n throw new TypeError(\"Unsupported input type: \" + typeof input)\n}\n\n// ============================================================================\n// SafeBuffer Static Methods\n// ============================================================================\n\nObject.assign(SafeBuffer, {\n from(...args: unknown[]): SeaArray {\n const argCount = args.length\n\n if (argCount === 0) {\n throw new TypeError(\"SafeBuffer.from() requires at least one argument\")\n }\n\n const input = args[0]\n\n if (input === null || input === undefined) {\n throw new TypeError(\"First argument must not be null or undefined\")\n }\n\n let bytes: Uint8Array\n\n if (typeof input === \"string\") {\n const encoding = ((args[1] as string) || \"utf8\").toLowerCase() as Encoding\n\n switch (encoding) {\n case \"hex\":\n bytes = parseHexString(input)\n break\n\n case \"utf8\":\n case \"utf-8\":\n bytes = encodeUtf8String(input)\n break\n\n case \"binary\":\n case \"latin1\":\n bytes = encodeBinaryString(input)\n break\n\n case \"base64\":\n bytes = parseBase64String(input)\n break\n\n case \"ascii\":\n validateStringInput(input, \"ascii\")\n for (let i = 0; i < input.length; i++) {\n if (input.charCodeAt(i) > 127) {\n throw new TypeError(\n `Invalid ASCII character at position ${i}: ${input.charCodeAt(i)} > 127`\n )\n }\n }\n bytes = encodeUtf8String(input)\n break\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n } else {\n bytes = processArrayLikeInput(input)\n }\n\n if (!bytes || bytes.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n try {\n return SeaArray.from(bytes)\n } catch (err) {\n throw new Error(`Failed to create SafeBuffer: ${(err as Error).message}`)\n }\n },\n\n alloc(length: number, fill: number | string = 0): SeaArray {\n if (typeof length !== \"number\" || !Number.isInteger(length) || length < 0) {\n throw new TypeError(\"Length must be a non-negative integer\")\n }\n\n validateBufferSize(length, \"buffer allocation\")\n\n let fillValue: number\n if (typeof fill === \"number\") {\n if (fill < 0 || fill > 255 || !Number.isInteger(fill)) {\n throw new TypeError(\"Fill value must be an integer between 0 and 255\")\n }\n fillValue = fill\n } else if (typeof fill === \"string\") {\n if (fill.length !== 1) {\n throw new TypeError(\"Fill string must be exactly one character\")\n }\n fillValue = fill.charCodeAt(0)\n if (fillValue > 255) {\n throw new TypeError(\"Fill character code must be <= 255\")\n }\n } else {\n throw new TypeError(\"Fill must be a number or single character string\")\n }\n\n try {\n const buffer = new Uint8Array(length)\n if (fillValue !== 0) {\n buffer.fill(fillValue)\n }\n return SeaArray.from(buffer)\n } catch (err) {\n throw new Error(`Failed to allocate buffer: ${(err as Error).message}`)\n }\n },\n\n concat(arr: ArrayLike<unknown>[]): SeaArray {\n if (!Array.isArray(arr)) {\n throw new TypeError(\"First argument must be an array\")\n }\n\n if (arr.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n let totalLength = 0\n const validatedBuffers: Uint8Array[] = []\n\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]\n\n if (!item) {\n throw new TypeError(`Array element at index ${i} is null or undefined`)\n }\n\n let bytes: Uint8Array\n try {\n bytes = processArrayLikeInput(item)\n } catch (err) {\n throw new TypeError(\n `Invalid array element at index ${i}: ${(err as Error).message}`\n )\n }\n\n totalLength += bytes.length\n validateBufferSize(totalLength, \"buffer concatenation\")\n validatedBuffers.push(bytes)\n }\n\n try {\n const result = new Uint8Array(totalLength)\n let offset = 0\n\n for (const buffer of validatedBuffers) {\n result.set(buffer, offset)\n offset += buffer.length\n }\n\n return SeaArray.from(result)\n } catch (err) {\n throw new Error(`Failed to concatenate buffers: ${(err as Error).message}`)\n }\n },\n\n isBuffer(obj: unknown): obj is SeaArray {\n return (\n obj instanceof SeaArray ||\n (obj !== null &&\n typeof obj === \"object\" &&\n (obj as { constructor?: unknown }).constructor === SafeBuffer)\n )\n },\n\n byteLength(string: string, encoding: Encoding = \"utf8\"): number {\n if (typeof string !== \"string\") {\n throw new TypeError(\"First argument must be a string\")\n }\n\n switch (encoding.toLowerCase()) {\n case \"utf8\":\n case \"utf-8\":\n return new TextEncoder().encode(string).length\n\n case \"ascii\":\n case \"binary\":\n case \"latin1\":\n return string.length\n\n case \"base64\": {\n const clean = string.replace(/\\s/g, \"\")\n return (\n Math.floor((clean.length * 3) / 4) - (clean.match(/=/g) || []).length\n )\n }\n\n case \"hex\":\n return Math.floor(string.replace(/\\s/g, \"\").length / 2)\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n },\n})\n\n// Add instance method for toString\nSafeBuffer.prototype.toString = function (\n this: SeaArray,\n encoding: Encoding = \"utf8\",\n start = 0,\n end = this.length\n): string {\n if (typeof encoding !== \"string\") {\n throw new TypeError(\"Encoding must be a string\")\n }\n\n if (typeof start !== \"number\" || !Number.isInteger(start) || start < 0) {\n throw new TypeError(\"Start must be a non-negative integer\")\n }\n\n if (typeof end !== \"number\" || !Number.isInteger(end) || end < start) {\n throw new TypeError(\"End must be an integer >= start\")\n }\n\n try {\n return SeaArray.prototype.toString.call(\n this,\n encoding as \"utf8\" | \"hex\" | \"base64\",\n start,\n end\n )\n } catch (err) {\n throw new Error(`Failed to convert buffer to string: ${(err as Error).message}`)\n }\n}\n\nexport default SafeBuffer\n\n", "/**\n * SEA Utilities - Cryptographic utility functions\n * Provides helpers for encryption, hashing, and key management\n */\n\nimport SafeBuffer from \"./buffer.ts\"\nimport type { JWK } from \"./schemas.ts\"\n\nconst isNode = typeof process !== \"undefined\" && process.versions?.node != null\n\n// Get crypto based on environment - dynamic import for Node.js compatibility\nconst crypto: Crypto = isNode\n ? ((await import(/*webpackIgnore: true*/ \"node:crypto\")).webcrypto as Crypto)\n : globalThis.crypto\n\nexport const subtle = crypto.subtle\n\n/**\n * Convert data to string format for cryptographic operations\n */\nexport const stringify = (data: unknown): string => {\n return typeof data === \"string\" ? data : JSON.stringify(data)\n}\n\n/**\n * Parse JSON text safely\n */\nexport const parse = (text: string): unknown => {\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/**\n * Generate cryptographically secure random bytes\n */\nexport const random = (length: number): SeaArray => {\n const array = new Uint8Array(length)\n const filled = crypto.getRandomValues(array)\n return SafeBuffer.from(filled)\n}\n\n/**\n * Create JWK from public and optional private key components\n */\nexport const jwk = (pub: string, priv?: string): JWK => {\n const [x, y] = pub.split(\".\")\n const ops = priv ? [\"sign\"] : [\"verify\"]\n return {\n kty: \"EC\",\n crv: \"P-256\",\n x: x!,\n y: y!,\n d: priv,\n ext: true,\n key_ops: ops,\n }\n}\n\n/**\n * SHA-256 hash of data\n */\nexport const sha256 = async (data: unknown): Promise<SeaArray> => {\n const hash = await subtle.digest(\n { name: \"SHA-256\" },\n new TextEncoder().encode(stringify(data))\n )\n return SafeBuffer.from(new Uint8Array(hash))\n}\n\n/**\n * Derive AES key from password and salt \n */\nexport const aeskey = async (\n key: string,\n salt: SeaArray\n) => {\n const combined = key + salt.toString(\"utf8\")\n const hashResult = await sha256(combined)\n const jwkKey = keyToJwk(hashResult)\n return await subtle.importKey(\"jwk\", jwkKey, { name: \"AES-GCM\" }, false, [\n \"encrypt\",\n \"decrypt\",\n ])\n}\n\n/**\n * Convert key buffer to JWK format for AES\n */\nconst keyToJwk = (key: SeaArray): JWK => {\n const k = key\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\")\n return { kty: \"oct\", k: k, ext: false, alg: \"A256GCM\" }\n}\n\n// Re-export SeaArray type for convenience\nimport type SeaArray from \"./array.ts\"\n\n", "/**\n * SEA - Security, Encryption, and Authorization\n * Cryptographic functions for signing, verification, encryption, and decryption\n */\n\nimport { userPublicKey, userSignature } from \"./utils.ts\"\nimport * as utils from \"./sea-utils.ts\"\nimport SafeBuffer from \"./buffer.ts\"\nimport type {\n UserPair,\n EncryptedData,\n SignedData,\n} from \"./schemas.ts\"\n\ntype Callback<T> = (result: T) => void\n\n/**\n * SEA cryptographic operations\n */\nconst SEA = {\n /**\n * Generate a new ECDSA + ECDH key pair\n */\n pair: async (cb?: Callback<UserPair>): Promise<UserPair> => {\n // ECDSA keys for signing/verifying\n const ecdsa = await utils.subtle\n .generateKey({ name: \"ECDSA\", namedCurve: \"P-256\" }, true, [\n \"sign\",\n \"verify\",\n ])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n priv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d!,\n pub: pub.x! + \".\" + pub.y!,\n }\n })\n\n // ECDH keys for encryption/decryption\n const ecdh = await utils.subtle\n .generateKey({ name: \"ECDH\", namedCurve: \"P-256\" }, true, [\"deriveKey\"])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n epriv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d!,\n epub: pub.x! + \".\" + pub.y!,\n }\n })\n\n const pair: UserPair = {\n pub: ecdsa.pub,\n priv: ecdsa.priv,\n epub: ecdh.epub,\n epriv: ecdh.epriv,\n }\n if (cb) cb(pair)\n return pair\n },\n\n /**\n * Encrypt data with a key pair\n */\n encrypt: async (\n data: unknown,\n pair: Partial<UserPair> | null,\n cb?: Callback<EncryptedData | null>\n ): Promise<EncryptedData | null> => {\n if (!pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const rand = { s: utils.random(9), iv: utils.random(15) }\n const ct = await utils.aeskey(pair.epriv, rand.s).then(aes => {\n return utils.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(rand.iv),\n },\n aes,\n new TextEncoder().encode(utils.stringify(data))\n )\n })\n const enc: EncryptedData = {\n ct: SafeBuffer.from(ct, \"binary\").toString(\"base64\"),\n iv: rand.iv.toString(\"base64\"),\n s: rand.s.toString(\"base64\"),\n }\n if (cb) cb(enc)\n return enc\n },\n\n /**\n * Decrypt data with a key pair\n */\n decrypt: async (\n enc: Partial<EncryptedData> | null,\n pair: Partial<UserPair> | null,\n cb?: Callback<unknown | null>\n ): Promise<unknown | null> => {\n if (!enc || !enc.ct || !enc.iv || !enc.s || !pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const data = {\n ct: SafeBuffer.from(enc.ct, \"base64\"),\n iv: SafeBuffer.from(enc.iv, \"base64\"),\n s: SafeBuffer.from(enc.s, \"base64\"),\n }\n try {\n const ct = await utils.aeskey(pair.epriv, data.s).then(aes => {\n return utils.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(data.iv),\n tagLength: 128,\n },\n aes,\n new Uint8Array(data.ct)\n )\n })\n const dec = utils.parse(new TextDecoder(\"utf8\").decode(ct))\n if (cb) cb(dec)\n return dec\n } catch (err) {\n // An error will be thrown if the wrong key is used\n if (cb) cb(null)\n return null\n }\n },\n\n /**\n * Verify a signed message\n */\n verify: async (\n data: string | SignedData,\n pair: Partial<UserPair> | null,\n cb?: Callback<unknown | null>\n ): Promise<unknown | null> => {\n if (!pair || !pair.pub) {\n if (cb) cb(null)\n return null\n }\n\n const signed = (\n typeof data === \"string\" ? utils.parse(data) : data\n ) as SignedData\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(pair.pub),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"]\n )\n\n let msg: string | Record<string, unknown> = {}\n if (typeof signed.m === \"string\") {\n msg = signed.m\n } else {\n // Allow data to be passed in with graph meta data,\n // (which should not be part of signature, so not verified)\n for (const k of Object.keys(signed.m).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n (msg as Record<string, unknown>)[k] = signed.m[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const sig = new Uint8Array(SafeBuffer.from(signed.s, \"base64\"))\n const alg = { name: \"ECDSA\", hash: { name: \"SHA-256\" } }\n if (await utils.subtle.verify(alg, key, sig, new Uint8Array(hash))) {\n const verified = utils.parse(signed.m as string)\n if (cb) cb(verified)\n return verified\n }\n\n if (cb) cb(null)\n return null\n },\n\n /**\n * Sign data with a key pair\n */\n sign: async (\n data: string | Record<string, unknown>,\n pair: Partial<UserPair> | null,\n cb?: Callback<SignedData | null>\n ): Promise<SignedData | null> => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n let msg: string | Record<string, unknown> = {}\n if (typeof data === \"string\") {\n msg = data\n } else {\n const check = utils.parse(data as never) as Record<string, unknown>\n for (const k of Object.keys(check).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n (msg as Record<string, unknown>)[k] = check[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = { name: \"ECDSA\", namedCurve: \"P-256\" }\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n { name: \"ECDSA\", hash: { name: \"SHA-256\" } },\n key,\n new Uint8Array(hash)\n )\n )\n const signed: SignedData = {\n m: msg,\n s: SafeBuffer.from(sig, \"binary\").toString(\"base64\"),\n }\n\n if (cb) cb(signed)\n return signed\n },\n\n /**\n * Sign a timestamp to prove ownership of an update\n */\n signTimestamp: async (\n timestamp: number,\n pair: Partial<UserPair> | null,\n cb?: Callback<string | null>\n ): Promise<string | null> => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = { name: \"ECDSA\", namedCurve: \"P-256\" }\n\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n { name: \"ECDSA\", hash: { name: \"SHA-256\" } },\n key,\n new Uint8Array(hash)\n )\n )\n\n const signature = SafeBuffer.from(sig, \"binary\").toString(\"base64\")\n\n if (cb) cb(signature)\n return signature\n },\n\n /**\n * Verify a timestamp signature to confirm ownership of update\n */\n verifyTimestamp: async (\n timestamp: number,\n signature: string,\n publicKey: string,\n cb?: Callback<boolean>\n ): Promise<boolean> => {\n if (!publicKey || !timestamp || !signature) {\n if (cb) cb(false)\n return false\n }\n\n try {\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(publicKey),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"verify\"]\n )\n\n const sig = new Uint8Array(SafeBuffer.from(signature, \"base64\"))\n const alg = { name: \"ECDSA\", hash: { name: \"SHA-256\" } }\n\n const isValid = await utils.subtle.verify(\n alg,\n key,\n sig,\n new Uint8Array(hash)\n )\n\n if (cb) cb(isValid)\n return isValid\n } catch (err) {\n console.log(`error verifying timestamp signature: ${(err as Error).message}`)\n if (cb) cb(false)\n return false\n }\n },\n\n /**\n * Key derivation using PBKDF2\n */\n work: async (\n data: unknown,\n salt?: unknown,\n cb?: Callback<{ epriv: string }>\n ): Promise<{ epriv: string }> => {\n let _cb = cb\n let _salt = salt\n\n if (typeof salt === \"function\") {\n _cb = salt as Callback<{ epriv: string }>\n _salt = undefined\n }\n if (typeof _salt === \"undefined\") _salt = utils.random(9)\n\n const key = await utils.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(utils.stringify(data)),\n { name: \"PBKDF2\" },\n false,\n [\"deriveBits\"]\n )\n const alg = {\n name: \"PBKDF2\",\n iterations: 100000,\n salt: new TextEncoder().encode(_salt as string),\n hash: { name: \"SHA-256\" },\n }\n const work = await utils.subtle.deriveBits(alg, key, 512)\n // Use \"pair\" format so that work can be used as epriv by decrypt\n const pair = { epriv: SafeBuffer.from(work, \"binary\").toString(\"base64\") }\n if (_cb) _cb(pair)\n return pair\n },\n\n /**\n * Derive shared secret using ECDH\n */\n secret: async (\n to: Partial<UserPair> | null,\n from: Partial<UserPair> | null,\n cb?: Callback<{ epriv: string } | null>\n ): Promise<{ epriv: string } | null> => {\n if (!to || !to.epub || !from || !from.epub || !from.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const alg = { name: \"ECDH\", namedCurve: \"P-256\" }\n const pub = utils.jwk(to.epub)\n const pubKey = await utils.subtle.importKey(\"jwk\", pub, alg, true, [])\n const priv = utils.jwk(from.epub, from.epriv)\n // utils.jwk provides default key_ops but it shouldn't be used here\n delete (priv as { key_ops?: unknown }).key_ops\n const derived = await utils.subtle\n .importKey(\"jwk\", priv, alg, false, [\"deriveBits\"])\n .then(async key => {\n const derivedBits = await utils.subtle.deriveBits(\n { public: pubKey, name: \"ECDH\", namedCurve: \"P-256\" } as never,\n key,\n 256\n )\n const derivedKey = await utils.subtle.importKey(\n \"raw\",\n new Uint8Array(derivedBits),\n { name: \"AES-GCM\", length: 256 },\n true,\n [\"encrypt\", \"decrypt\"]\n )\n return utils.subtle.exportKey(\"jwk\", derivedKey).then(({ k }) => k!)\n })\n // Use \"pair\" format so that secret can be used as epriv by encrypt\n if (cb) cb({ epriv: derived })\n return { epriv: derived }\n },\n}\n\nexport default SEA\n\n", "/**\n * HAM - Hypothetical Amnesia Machine\n * Conflict resolution algorithm for distributed data synchronization\n */\n\nimport * as utils from \"./utils.ts\"\nimport SEA from \"./sea.ts\"\nimport type {\n Graph,\n GraphNode,\n GraphValue,\n HamResult,\n HamMixResult,\n ListenMap,\n Timestamp,\n} from \"./schemas.ts\"\n\n// Maximum number of souls to keep in memory\nconst MAX_GRAPH_SIZE = 10000\n\n/**\n * Compare incoming state with current state to determine which value wins\n * @param state - Incoming timestamp\n * @param currentState - Current timestamp\n * @param value - Incoming value\n * @param currentValue - Current value\n * @param signed - Whether the update has a verified signature\n */\nconst Ham = (\n state: Timestamp,\n currentState: Timestamp,\n value: GraphValue,\n currentValue: GraphValue,\n signed = false\n): HamResult => {\n if (state < currentState) return { historical: true }\n\n if (state > currentState) return { incoming: true }\n\n // state is equal to currentState. Old data is expected to propagate through\n // the network, but conflicting values with same signed timestamp are ignored\n // since the owner can only create one value per timestamp.\n if (signed && value !== currentValue) {\n return { historical: true }\n }\n\n // Lexically compare to resolve conflict (for unsigned or matching values)\n let valueStr = typeof value !== \"string\" ? JSON.stringify(value) || \"\" : value\n let currentValueStr =\n typeof currentValue !== \"string\"\n ? JSON.stringify(currentValue) || \"\"\n : currentValue\n\n // No update required\n if (valueStr === currentValueStr) return { state: true }\n\n // Keep the current value\n if (valueStr < currentValueStr) return { current: true }\n\n // Otherwise update using the incoming value\n return { incoming: true }\n}\n\n/**\n * Mix incoming changes into the graph with conflict resolution\n */\nHam.mix = async (\n change: Graph,\n graph: Graph,\n hasNode: Set<string> | undefined,\n secure: boolean,\n listen: ListenMap\n): Promise<HamMixResult> => {\n if (!change || typeof change !== \"object\") {\n throw new TypeError(\"change must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n if (!listen || typeof listen !== \"object\") {\n throw new TypeError(\"listen must be an object\")\n }\n\n const machine = Date.now()\n const now: Graph = {}\n const defer: Graph = {}\n const listeners: Array<() => void> = []\n const validProperties = new Map<string, Set<string>>()\n const validTimestamps = new Map<string, Set<number>>()\n let wait = 0\n\n for (const soul of Object.keys(change)) {\n const node = change[soul]\n if (!node || !node._) continue\n\n let updated = false\n let alias = false\n let verify = secure\n\n const pub = node[utils.userPublicKey] as string | undefined\n // If timestamp signatures and public key are provided then always verify\n if (node._[\"s\"] && pub) verify = true\n\n // Special case if soul starts with \"~\". Node must be system data ie,\n // ~@alias or ~publickey. For aliases, key and value must be a self\n // identifying rel. For public keys, data needs to be signed and verified.\n if (soul.length > 1 && soul[0] === \"~\") {\n if (soul[1] === \"@\") {\n alias = true\n verify = false\n } else {\n if (pub && soul !== \"~\" + pub) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n verify = true\n }\n }\n\n if (verify) {\n if (!pub || !node._) {\n continue\n }\n\n const signedTimestamps = new Set<number>()\n const signedProperties = new Set<string>()\n\n const incomingTimestamps = Object.entries(node._[\">\"] || {})\n\n for (const [key, sig] of Object.entries(node._[\"s\"] || {})) {\n const asNumber = Number(key)\n if (!isNaN(asNumber) && asNumber > 0) {\n const propsForTimestamp = incomingTimestamps.filter(\n ([, ts]) => Number(ts) === asNumber,\n )\n const allNewerInGraph =\n propsForTimestamp.length > 0 &&\n propsForTimestamp.every(([prop]) => {\n const graphState =\n graph[soul] && graph[soul]!._[\">\"] ? graph[soul]!._[\">\"][prop] : 0\n return graphState !== undefined && graphState > asNumber\n })\n\n if (allNewerInGraph) {\n continue\n }\n\n const isValid = await SEA.verifyTimestamp(asNumber, sig as string, pub)\n if (isValid) {\n signedTimestamps.add(asNumber)\n for (const [prop, ts] of incomingTimestamps) {\n if (Number(ts) === asNumber) {\n signedProperties.add(prop)\n }\n }\n }\n }\n }\n\n if (signedProperties.size === 0) {\n continue\n }\n\n validProperties.set(soul, signedProperties)\n validTimestamps.set(soul, signedTimestamps)\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n if (validProperties.has(soul) && !validProperties.get(soul)!.has(key)) {\n continue\n }\n\n const value = node[key]!\n const state = (node._ && node._[\">\"] ? node._[\">\"][key] : 0) || 0\n const currentValue = graph[soul] ? graph[soul][key] : undefined\n const currentState = graph[soul] ? (graph[soul]._[\">\"][key] || 0) : 0\n\n if (alias && key !== utils.rel.is(value)) {\n console.log(`error alias ${alias}: ${key} !== ${utils.rel.is(value)}`)\n continue\n }\n\n const skew = state - machine\n if (skew > 0) {\n if (skew > 86400000) continue\n\n if (wait === 0 || skew < wait) wait = skew\n if (!defer[soul]) {\n const stateVector: Record<string, number> = {}\n const signatures: Record<string, string> | undefined = {}\n defer[soul] = { _: { \"#\": soul, \">\": stateVector, s: signatures } } as GraphNode\n }\n defer[soul]![key] = value\n defer[soul]!._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n defer[soul]!._[\"s\"]![state] = node._[\"s\"][state]\n }\n } else {\n const isSigned =\n validTimestamps.has(soul) && validTimestamps.get(soul)!.has(state)\n const result = Ham(state, currentState, value, currentValue ?? null, isSigned)\n if (result.incoming) {\n if (!now[soul]) {\n const stateVector1: Record<string, number> = {}\n const signatures1: Record<string, string> | undefined = {}\n now[soul] = { _: { \"#\": soul, \">\": stateVector1, s: signatures1 } } as GraphNode\n }\n if (!graph[soul]) {\n const stateVector2: Record<string, number> = {}\n const signatures2: Record<string, string> | undefined = {}\n graph[soul] = { _: { \"#\": soul, \">\": stateVector2, s: signatures2 } } as GraphNode\n }\n graph[soul]![key] = now[soul]![key] = value\n graph[soul]!._[\">\"][key] = now[soul]!._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n graph[soul]!._[\"s\"]![state] = now[soul]!._[\"s\"]![state] = node._[\"s\"][state]\n }\n\n if (listen[soul]) {\n listen[soul]!\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => listeners.push(l.cb as () => void))\n }\n updated = true\n }\n }\n }\n\n if (updated && listen[soul]) {\n listen[soul]!\n .filter(l => utils.match(l[\".\"]))\n .forEach(l => listeners.push(l.cb as () => void))\n }\n }\n\n const souls = Object.keys(graph)\n if (souls.length > MAX_GRAPH_SIZE) {\n const soulsByAge = souls\n .map(soul => {\n const states = graph[soul]!._ && graph[soul]!._[\">\"]\n const maxState = states ? Math.max(...Object.values(states)) : 0\n return { soul, maxState }\n })\n .sort((a, b) => a.maxState - b.maxState)\n const remove = soulsByAge.slice(0, souls.length - MAX_GRAPH_SIZE)\n remove.forEach(({ soul }) => {\n delete graph[soul]\n if (hasNode) hasNode.delete(soul)\n })\n }\n\n return { now, defer, wait, listeners }\n}\n\nexport default Ham\n\n", "/**\n * Radix - Radix tree implementation for efficient key-value storage\n * Supports prefix-based key compression\n */\n\nimport * as utils from \"./utils.ts\"\nimport type { EncodedValue, RadixFunction } from \"./schemas.ts\"\n\n// ASCII character for group separator\nconst group = String.fromCharCode(29)\n// ASCII character for record separator\nconst record = String.fromCharCode(30)\n\n// Local type for internal radix tree structure (different from schemas.RadixValue)\n// This represents the internal node structure with dynamic keys\ninterface RadixValue {\n [key: string]: RadixTree | EncodedValue | undefined\n}\n\n// RadixTree is the internal tree structure (also known as RadixNode in schemas)\ntype RadixTree = Record<string, RadixValue>\n// Alias for compatibility with schema types\ntype RadixNode = RadixTree\n\n// Type guard to check if a value is a RadixTree (object)\nconst isRadixTree = (value: unknown): value is RadixTree => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/**\n * Create a new Radix tree\n */\nconst Radix = (): RadixFunction => {\n const radix = ((\n keys?: string,\n value?: EncodedValue,\n tree?: RadixTree\n ): RadixNode | EncodedValue | undefined | Record<string, EncodedValue> => {\n if (!tree) {\n if (!(radix as Record<string, unknown>)[group]) (radix as Record<string, unknown>)[group] = {}\n tree = (radix as Record<string, RadixTree>)[group]!\n }\n if (!keys) return tree\n\n let i = 0\n let tmp: Record<string, RadixValue> = {}\n let key = keys[i]!\n const max = keys.length - 1\n const noValue = typeof value === \"undefined\"\n\n // Find a matching value using the shortest string from keys\n let found: RadixValue | undefined = tree![key]\n while (!found && i < max) {\n key += keys[++i]\n found = tree![key]\n }\n\n if (!found) {\n // If not found from the provided keys try matching with an existing key\n const result = utils.obj.map(tree!, (hasValue: RadixValue, hasKey: string) => {\n let j = 0\n let matchingKey = \"\"\n while (hasKey[j] === keys[j]) {\n matchingKey += hasKey[j]\n j++\n }\n if (matchingKey) {\n if (noValue) {\n // matchingKey has to be as long as the original keys when reading\n if (j <= max) return undefined\n\n tmp[hasKey.slice(j)] = hasValue\n return hasValue\n }\n\n const replace: RadixTree = {\n [hasKey.slice(j)]: hasValue,\n [keys.slice(j)]: { [record]: value! },\n }\n tree![matchingKey] = { [group]: replace }\n delete tree![hasKey]\n return true\n }\n return undefined\n })\n\n if (!result) {\n if (noValue) return undefined\n\n if (!tree![key]) tree![key] = {}\n tree![key]![record] = value!\n } else if (noValue) {\n return tmp\n }\n } else if (i === max) {\n // If no value use the key provided to return a whole group or record\n if (noValue) {\n // If an individual record isn't found then return the whole group\n return typeof found[record] === \"undefined\" ? found[group] : found[record]\n }\n // Otherwise create a new record at the provided key for value\n found[record] = value!\n } else {\n // Found at a shorter key, try again\n if (!found[group] && !noValue) found[group] = {}\n const nextTree = found[group]\n if (isRadixTree(nextTree)) {\n return radix(keys.slice(++i), value, nextTree as RadixTree) as RadixNode\n }\n }\n\n return undefined\n }) as RadixFunction\n\n return radix\n}\n\n/**\n * Map over all values in a radix tree\n */\nRadix.map = function map(\n radix: RadixFunction | RadixNode,\n cb: (value: EncodedValue, fullKey: string, key: string, pre: string[]) => unknown,\n opt?: boolean,\n pre: string[] = []\n): unknown {\n const tree = ((radix as Record<string, RadixTree>)[group] || radix) as RadixTree\n const keys = Object.keys(tree).sort()\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]!\n const found = tree[key]\n if (!found) continue\n \n const recordValue = found[record]\n\n if (typeof recordValue !== \"undefined\") {\n const result = cb(recordValue as EncodedValue, pre.join(\"\") + key, key, pre)\n if (typeof result !== \"undefined\") return result\n } else if (opt) {\n cb(undefined as never, pre.join(\"\"), key, pre)\n }\n\n const groupValue = found[group]\n if (isRadixTree(groupValue)) {\n pre.push(key)\n const result = map(groupValue, cb, opt, pre)\n if (typeof result !== \"undefined\") return result\n pre.pop()\n }\n }\n\n return undefined\n}\n\nexport default Radix\n\n", "/**\n * Radisk - Persistent radix tree storage\n * Provides disk-backed radix tree with caching and batching\n */\n\nimport Radix from \"./radix.ts\"\nimport type { RadixFunction } from \"./schemas.ts\"\nimport * as utils from \"./utils.ts\"\nimport type { EncodedValue, RadiskOptions, GraphValue, Relation } from \"./schemas.ts\"\n\n// ASCII character for end of text\nconst etx = String.fromCharCode(3)\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n\nexport interface RadiskInterface extends RadixFunction {\n // Override call signature to support both get (with callback) and put (with value and optional callback)\n // Accepts GraphValue (raw values) OR EncodedValue (tuples) - see src/radisk.js and tests\n (key?: string, value?: GraphValue | EncodedValue | ((err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void), cb?: (err?: string | null) => void): void\n \n batch: RadixFunction & {\n acks: Array<(err?: string | null) => void>\n ed: number\n timeout?: NodeJS.Timeout\n }\n thrash: {\n (): void\n at?: RadixFunction\n ing?: boolean\n more?: boolean\n }\n save: (rad: RadixFunction, cb: (err?: string | null) => void) => void\n write: (file: string, rad: RadixFunction, cb: (err?: string | null) => void) => void\n read: (key: string, cb: (err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void) => void\n parse: (file: string, cb: (err?: string | null, disk?: RadixFunction) => void) => void\n}\n\n/**\n * Create a Radisk instance with persistent storage\n */\nconst Radisk = (opt: RadiskOptions) => {\n const cache = new Map<string, RadixFunction>()\n let fileListCache: string[] | null = null\n let fileListCacheTime = 0\n const FILE_LIST_CACHE_TTL = 10000\n\n const pendingReads = new Map<\n string,\n Array<(err?: string | null, result?: EncodedValue | Record<string, EncodedValue>) => void>\n >()\n\n let lastMemoryCheck = 0\n const MEMORY_CHECK_INTERVAL = 30000\n const HEAP_WARNING_THRESHOLD = 0.8\n const HEAP_CLEANUP_THRESHOLD = 0.9\n\n const options = {\n log: opt.log || console.log,\n batch: opt.batch || 100,\n write: opt.write || 1,\n size: opt.size || 1024 * 1024,\n memoryLimit: opt.memoryLimit || 500,\n cache: opt.cache !== undefined ? opt.cache : true,\n store: opt.store,\n }\n\n if (!options.store) {\n throw new Error(\"Radisk needs `store` interface with `{get: fn, put: fn, list: fn}`\")\n }\n if (!options.store.get) {\n throw new Error(\"Radisk needs `store.get` interface with `(file, cb)`\")\n }\n if (!options.store.put) {\n throw new Error(\"Radisk needs `store.put` interface with `(file, data, cb)`\")\n }\n if (!options.store.list) {\n throw new Error(\"Radisk needs a streaming `store.list` interface with `(cb)`\")\n }\n\n // After validation, store is guaranteed to be defined\n const store = options.store\n\n const perfLog = (operation: string, startTime: number, key: string, size?: number): void => {\n const duration = Date.now() - startTime\n if (duration > 3000) {\n console.log(\n `[RADISK-SLOW] ${operation}: ${duration}ms for ${key}${size ? ` (${size} bytes)` : \"\"}`\n )\n }\n }\n\n const checkMemoryUsage = (): void => {\n if (typeof process === \"undefined\" || !process.memoryUsage) return\n\n const now = Date.now()\n if (now - lastMemoryCheck < MEMORY_CHECK_INTERVAL) return\n lastMemoryCheck = now\n\n const memUsage = process.memoryUsage()\n const heapUsed = memUsage.heapUsed\n const maxHeapSize = options.memoryLimit * 1024 * 1024\n const heapUsageRatio = heapUsed / maxHeapSize\n\n if (heapUsageRatio > HEAP_CLEANUP_THRESHOLD) {\n const cacheSize = cache.size\n console.log(\n `[RADISK-MEMORY] High memory usage: ${Math.round(heapUsageRatio * 100)}% of heap limit. Clearing ${cacheSize} cached files.`\n )\n cache.clear()\n if ((global as { gc?: () => void }).gc) {\n (global as { gc: () => void }).gc()\n }\n lastMemoryCheck = now + MEMORY_CHECK_INTERVAL\n } else if (heapUsageRatio > HEAP_WARNING_THRESHOLD) {\n console.log(\n `[RADISK-MEMORY] Memory warning: ${Math.round(heapUsageRatio * 100)}% of heap limit used. Cache size: ${cache.size} files.`\n )\n }\n }\n\n const radisk = ((key?: string, value?: GraphValue | EncodedValue | ((err?: string | null, value?: EncodedValue | Record<string, EncodedValue>) => void), cb?: (err?: string | null) => void) => {\n if (typeof key !== \"string\") return undefined\n\n if (typeof value === \"function\") {\n const callback = value\n const batchValue = radisk.batch(key)\n if (typeof batchValue !== \"undefined\") {\n return callback(undefined, batchValue as EncodedValue)\n }\n\n if (radisk.thrash.at) {\n const thrashValue = radisk.thrash.at(key)\n if (typeof thrashValue !== \"undefined\") {\n return callback(undefined, thrashValue as EncodedValue)\n }\n }\n\n if (pendingReads.has(key)) {\n pendingReads.get(key)!.push(callback)\n return\n }\n\n pendingReads.set(key, [callback])\n const readStart = Date.now()\n const timeout = setTimeout(() => {\n const callbacks = pendingReads.get(key)\n if (!callbacks) return\n options.log(`radisk read hang detected for key: ${key}`)\n pendingReads.delete(key)\n callbacks.forEach(cb => cb(null, null as unknown as undefined))\n }, 30000)\n return radisk.read(key, (err, result) => {\n clearTimeout(timeout)\n perfLog(\"read\", readStart, key)\n const callbacks = pendingReads.get(key) || []\n pendingReads.delete(key)\n callbacks.forEach(callback => callback(err, result))\n })\n }\n\n radisk.batch(key, value as EncodedValue)\n checkMemoryUsage()\n if (cb) {\n radisk.batch.acks.push(cb)\n }\n if (++radisk.batch.ed >= options.batch) {\n return radisk.thrash()\n }\n\n clearTimeout(radisk.batch.timeout)\n radisk.batch.timeout = setTimeout(radisk.thrash, options.write)\n return undefined\n }) as unknown as RadiskInterface\n\n radisk.batch = Radix() as RadiskInterface[\"batch\"]\n radisk.batch.acks = []\n radisk.batch.ed = 0\n\n radisk.thrash = (() => {\n if (radisk.thrash.ing) {\n radisk.thrash.more = true\n return\n }\n\n const thrashStart = Date.now()\n clearTimeout(radisk.batch.timeout)\n radisk.thrash.more = false\n radisk.thrash.ing = true\n const batch = (radisk.thrash.at = radisk.batch)\n radisk.batch = Radix() as RadiskInterface[\"batch\"]\n radisk.batch.acks = []\n radisk.batch.ed = 0\n let i = 0\n radisk.save(batch, err => {\n if (++i > 1) return\n\n perfLog(\"thrash\", thrashStart, `batch-${batch.ed}`)\n if (err) options.log(err)\n batch.acks.forEach(cb => cb(err))\n radisk.thrash.at = undefined\n radisk.thrash.ing = false\n if (radisk.thrash.more) radisk.thrash()\n })\n }) as RadiskInterface[\"thrash\"]\n\n radisk.save = (rad, cb) => {\n const save = {\n find: (_tree: unknown, key: string): boolean | undefined => {\n if (key < (save.start || \"\")) return undefined\n save.start = key\n store.list(save.lex)\n return true\n },\n lex: (file?: string): void => {\n if (!file || file > (save.start || \"\")) {\n save.end = file\n if (save.start) save.mix(save.file || \"!\", save.start, save.end)\n } else {\n save.file = file\n }\n },\n mix: (file: string, start: string, end?: string): void => {\n save.start = save.end = save.file = undefined\n if (cache.has(file)) {\n const disk = cache.get(file)!\n Radix.map(rad, (value, key) => {\n if (key < start) return undefined\n if (end && end < key) {\n save.start = key\n return undefined\n }\n disk(key, value)\n return undefined\n })\n radisk.write(file, disk, save.next)\n } else {\n radisk.parse(file, (err, disk) => {\n if (err) return cb(err)\n Radix.map(rad, (value, key) => {\n if (key < start) return undefined\n if (end && end < key) {\n save.start = key\n return undefined\n }\n disk!(key, value)\n return undefined\n })\n radisk.write(file, disk!, save.next)\n })\n }\n },\n next: (err?: string | null): void => {\n if (err) return cb(err)\n if (save.start) {\n Radix.map(rad, save.find)\n return\n }\n cb(err)\n },\n start: undefined as string | undefined,\n end: undefined as string | undefined,\n file: undefined as string | undefined,\n }\n Radix.map(rad, save.find)\n }\n\n radisk.write = (file, rad, cb) => {\n const write = {\n text: \"\",\n limit: \"\",\n done: false,\n count: 0,\n sub: undefined as RadixFunction | undefined,\n halfKey: \"\", // soul ID at the ~options.size/2 mark for a balanced split\n halfOffset: 0, // write.text.length before that entry\n each: (\n value: EncodedValue,\n _key: string,\n k: string,\n pre: string[],\n ): void | boolean => {\n if (write.done) return\n write.count++\n const valueStr =\n typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)\n const enc =\n Radisk.encode(pre.length) + \"#\" + Radisk.encode(k) + valueStr + \"\\n\"\n const validBoundary =\n pre.length === 0 || (pre.length === 1 && k.includes(enq))\n\n // Record the first valid split boundary past the halfway mark so a\n // full overflow can split here instead of at the tail, keeping both\n // halves near options.size/2 rather than leaving the file always full.\n if (\n !write.halfKey &&\n write.count > 1 &&\n write.text.length > options.size / 2 &&\n validBoundary\n ) {\n const fullKey = pre.join(\"\") + k\n const endIdx = fullKey.indexOf(enq)\n write.halfKey =\n endIdx === -1 ? fullKey : fullKey.substring(0, endIdx)\n write.halfOffset = write.text.length\n }\n\n if (\n write.count > 1 &&\n write.text.length + enc.length > options.size &&\n validBoundary\n ) {\n const fullKey = pre.join(\"\") + k\n const endIdx = fullKey.indexOf(enq)\n write.limit =\n write.halfKey ||\n (endIdx === -1 ? fullKey : fullKey.substring(0, endIdx))\n if (write.limit !== file) {\n // Truncate to the balanced split point \u2014 text after halfOffset is\n // handled by the write.slice call below, which reads from rad.\n if (write.halfKey) {\n write.text = write.text.substring(0, write.halfOffset)\n }\n write.done = true\n write.sub = Radix()\n Radix.map(rad, write.slice)\n radisk.write(write.limit, write.sub, cb)\n return undefined\n }\n }\n write.text += enc\n },\n slice: (value: EncodedValue, key: string): void => {\n if (key < write.limit) return\n write.sub!(key, value)\n },\n }\n Radix.map(rad, write.each, true)\n const writeStart = Date.now()\n store.put(file, write.text, err => {\n // If a split occurred the cached radix tree still contains entries that\n // were moved to the sub-file. Invalidate so the next save.mix re-reads\n // from disk rather than re-writing those entries back to this file.\n if (write.done) {\n cache.delete(file)\n fileListCache = null\n }\n perfLog(\"file-write\", writeStart, file, write.text.length)\n cb(err)\n })\n }\n\n radisk.read = (key, cb) => {\n const endIdx = key.indexOf(enq)\n const soul = endIdx === -1 ? key : key.substring(0, endIdx)\n\n const findFile = (files: string[]): string | null => {\n let lo = 0, hi = files.length - 1, result: string | null = null\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const f = files[mid]!\n if (f <= soul) { result = f; lo = mid + 1 }\n else { hi = mid - 1 }\n }\n return result\n }\n\n const read = (file: string | null): void => {\n if (!file) { cb(\"no file found\", undefined); return }\n if (options.cache && cache.has(file)) {\n return cb(undefined, cache.get(file)!(key) as EncodedValue | Record<string, EncodedValue> | undefined)\n }\n radisk.parse(file, (err, disk) => {\n if (err) options.log(err)\n if (disk && options.cache) {\n cache.set(file, disk)\n checkMemoryUsage()\n }\n cb(err, disk ? disk(key) as EncodedValue | Record<string, EncodedValue> | undefined : undefined)\n })\n }\n\n const now = Date.now()\n if (options.cache && fileListCache && now - fileListCacheTime < FILE_LIST_CACHE_TTL) {\n read(findFile(fileListCache))\n } else {\n const files: string[] = []\n store.list((file?: string) => {\n if (file) { files.push(file); return }\n files.sort()\n if (options.cache) {\n fileListCache = files\n fileListCacheTime = now\n }\n read(findFile(files))\n })\n }\n }\n\n radisk.parse = (file, cb) => {\n const parse = {\n disk: Radix(),\n read: (err?: string | null, data?: string | EncodedValue | Record<string, unknown>): void => {\n if (err) return cb(err)\n if (!data) return cb(null, parse.disk)\n\n let pre: string[] = []\n let preString = \"\"\n let tmp = parse.split(data as string)\n while (tmp) {\n let key: string | undefined\n let value: EncodedValue | undefined\n const tmpVal = tmp[1]\n const i = typeof tmpVal === \"number\" ? tmpVal : (typeof tmpVal === \"string\" ? parseInt(tmpVal, 10) : 0)\n tmp = parse.split(tmp[2]) || (\"\" as never)\n if (tmp[0] === \"#\") {\n const tmpKey = tmp[1]\n key = typeof tmpKey === \"string\" ? tmpKey : String(tmpKey)\n if (i < pre.length) {\n pre.length = i\n }\n if (i <= pre.length) {\n pre[i] = key\n pre.length = i + 1\n }\n preString = pre.join(\"\")\n }\n tmp = parse.split(tmp[2]) || (\"\" as never)\n if (tmp[0] === \"\\n\") continue\n\n if (tmp[0] === \"=\") {\n value = tmp[1] as EncodedValue\n }\n if (typeof key !== \"undefined\" && typeof value !== \"undefined\") {\n parse.disk(preString, value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(null, parse.disk)\n },\n split: (\n data: string\n ): [string, unknown, string] | undefined => {\n if (!data) return undefined\n\n const i = data.indexOf(unit)\n if (i === -1) return undefined\n\n const a = data.slice(0, i)\n const o: { i?: number } = {}\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i!)]\n },\n }\n store.get(file, parse.read)\n }\n\n // TypeScript can't verify all properties are added dynamically, but they are at runtime\n return radisk as unknown as RadiskInterface\n}\n\n/**\n * Encode value for storage\n */\nRadisk.encode = (input: EncodedValue | GraphValue): string => {\n let state = \"\"\n let sig = \"\"\n let data: GraphValue\n \n if (Array.isArray(input) && (input.length === 2 || input.length === 3)) {\n // input is EncodedValue - extract the GraphValue and metadata\n state = etx + input[1]\n if (input.length === 3 && input[2]) {\n sig = etx + input[2]\n }\n data = input[0]!\n } else {\n // input is already a GraphValue\n data = input as GraphValue\n }\n\n if (typeof data === \"string\") {\n let i = 0\n let current: string | undefined = undefined\n let text = unit\n while ((current = data[i++])) {\n if (current === unit) text += unit\n }\n return text + '\"' + data + state + sig + unit\n }\n\n const relId = utils.rel.is(data)\n if (relId) return unit + \"#\" + relId + state + sig + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + sig + unit\n\n if (data === true) return unit + \"+\" + state + sig + unit\n\n if (data === false) return unit + \"-\" + state + sig + unit\n\n if (data === null) return unit + \" \" + state + sig + unit\n\n return undefined as never\n}\n\n/**\n * Decode value from storage\n */\nRadisk.decode = (data: string, obj?: { i?: number }): EncodedValue | GraphValue | Relation | null | undefined => {\n let i = -1\n let n = 0\n let current: string | undefined = undefined\n let previous: string | undefined = undefined\n let textStart = -1\n let textEnd = -1\n if (data[0] !== unit) return undefined\n\n while ((current = data[++i])) {\n if (previous) {\n if (textStart === -1) textStart = i\n if (current === unit) {\n if (--n <= 0) {\n textEnd = i\n break\n }\n }\n } else if (current === unit) {\n n++\n } else {\n previous = current || \"true\"\n }\n }\n\n const text =\n textStart !== -1 ? data.slice(textStart, textEnd !== -1 ? textEnd : i) : \"\"\n\n if (obj) obj.i = i + 1\n\n const parts = text.split(etx)\n const value = parts[0]!\n const state = parts[1]\n const sig = parts[2]\n\n if (!state) {\n if (previous === '\"') return text\n\n if (previous === \"#\") return utils.rel.ify(text)\n\n if (previous === \"+\") {\n if (text.length === 0) return true\n return parseFloat(text)\n }\n\n if (previous === \"-\") return false\n\n if (previous === \" \") return null\n } else {\n const stateNum = parseFloat(state)\n if (sig) {\n if (previous === '\"') return [value, stateNum, sig]\n\n if (previous === \"#\") return [utils.rel.ify(value), stateNum, sig]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, stateNum, sig]\n return [parseFloat(value), stateNum, sig]\n }\n\n if (previous === \"-\") return [false, stateNum, sig]\n\n if (previous === \" \") return [null, stateNum, sig]\n } else {\n if (previous === '\"') return [value, stateNum]\n\n if (previous === \"#\") return [utils.rel.ify(value), stateNum]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, stateNum]\n return [parseFloat(value), stateNum]\n }\n\n if (previous === \"-\") return [false, stateNum]\n\n if (previous === \" \") return [null, stateNum]\n }\n }\n return undefined\n}\n\nexport default Radisk\n\n", "/**\n * Store - Storage interface for graph data\n * Provides get and put methods with filesystem or IndexedDB backend\n */\n\nimport Radisk from \"./radisk.ts\"\nimport Radix from \"./radix.ts\"\nimport * as utils from \"./utils.ts\"\nimport type {\n Lex,\n Graph,\n GraphNode,\n StoreOptions,\n FileSystemInterface,\n EncodedValue,\n} from \"./schemas.ts\"\n\nconst isNode = typeof process !== \"undefined\" && process.versions?.node != null\n\n// Dynamic import for Node.js fs module - won't execute in browser/service worker\nconst fs = isNode\n ? await import(/*webpackIgnore: true*/ \"node:fs\")\n : undefined\n\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n// On-disk root node format\nconst root = unit + \"+0\" + unit + \"#\" + unit + '\"root' + unit\n\n/**\n * Create file system storage backend\n */\nconst fileSystem = (opt: StoreOptions): FileSystemInterface => {\n const dir = opt.file!\n\n if (isNode) {\n if (!fs!.existsSync(dir)) fs!.mkdirSync(dir)\n if (!fs!.existsSync(dir + \"/!\")) fs!.writeFileSync(dir + \"/!\", root)\n\n return {\n get: (file, cb) => {\n fs!.readFile(dir + \"/\" + file, (err: NodeJS.ErrnoException | null, data?: Buffer) => {\n if (err) {\n if ((err as { code?: string }).code === \"ENOENT\") {\n cb()\n return\n }\n console.log(\"fs.readFile error:\", err)\n }\n const dataStr = data ? data.toString() : undefined\n cb(err as never, dataStr)\n })\n },\n put: (file, data, cb) => {\n const tmp = file + \".\" + utils.text.random(9) + \".tmp\"\n fs!.writeFile(tmp, data as string, (err: NodeJS.ErrnoException | null) => {\n if (err) {\n console.log(\"fs.writeFile error:\", err)\n cb(err as never)\n return\n }\n fs!.rename(tmp, dir + \"/\" + file, cb as never)\n })\n },\n list: cb => {\n fs!.readdir(dir, (err: NodeJS.ErrnoException | null, files?: string[]) => {\n if (err) {\n console.log(\"fs.readdir error:\", err)\n cb()\n return\n }\n if (files) files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db: IDBDatabase\n const dbReady = new Promise<void>((resolve, reject) => {\n const o = indexedDB.open(dir, 1)\n o.onupgradeneeded = event => {\n ;(event.target as IDBOpenDBRequest).result.createObjectStore(dir)\n }\n o.onerror = event => {\n console.log(event)\n reject(event)\n }\n o.onsuccess = () => {\n db = o.result\n if (db) {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getKey(\"!\")\n req.onerror = () => {\n console.log(`error getting key ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n if (!req.result) {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(root, \"!\")\n req.onerror = () => {\n console.log(`error putting root on ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n resolve()\n }\n } else {\n resolve()\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n reject(new Error(\"indexedDB not available\"))\n }\n }\n })\n\n return {\n get: (file, cb) => {\n const _get = (file: string, cb: (err?: string | null, data?: string) => void) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).get(file)\n req.onerror = () => {\n console.log(`error getting ${dir}/${file}`)\n cb(req.error as unknown as string)\n }\n req.onsuccess = () => {\n cb(null, req.result)\n }\n }\n\n dbReady\n .then(() => {\n _get(file, cb)\n })\n .catch(err => {\n cb(err as string)\n })\n },\n put: (file, data, cb) => {\n const _put = (\n file: string,\n data: string,\n cb: (err?: string | null) => void\n ) => {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(data, file)\n req.onerror = () => {\n console.log(`error putting data on ${dir}/${file}`)\n cb(req.error as unknown as string)\n }\n req.onsuccess = () => {\n cb(null)\n }\n }\n\n dbReady\n .then(() => {\n _put(file, data as string, cb)\n })\n .catch(err => {\n cb(err as string)\n })\n },\n list: cb => {\n const _list = (cb: (file?: string) => void) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getAllKeys()\n req.onerror = () => {\n console.log(\"error getting keys for\", dir)\n cb()\n }\n req.onsuccess = () => {\n ;(req.result as string[]).forEach(cb)\n cb()\n }\n }\n\n dbReady\n .then(() => {\n _list(cb)\n })\n .catch(err => {\n console.log(\"error indexedDB not available:\", err)\n cb()\n })\n },\n }\n }\n\n // No browser storage\n return {\n get: (_file, cb) => {\n cb(null, root)\n },\n put: (_file, _data, cb) => {\n cb(null)\n },\n list: cb => {\n cb(\"!\")\n cb()\n },\n }\n}\n\nexport interface StoreInterface {\n get: (\n lex: Lex,\n cb: (err?: string | null, graph?: Graph) => void,\n _opt?: { secure?: boolean }\n ) => void\n put: (graph: Graph, cb: (err?: string | null) => void) => void\n}\n\n/**\n * Create Store with get and put methods\n */\nconst Store = (opt?: StoreOptions): StoreInterface => {\n const options = opt || {}\n options.file = String(options.file || \"radata\")\n if (!options.store) options.store = fileSystem(options)\n const radisk = Radisk(options as never)\n\n return {\n get: (lex, cb, _opt) => {\n if (!lex || !utils.obj.is(lex)) {\n cb(\"lex required\")\n return\n }\n if (!lex[\"#\"]) {\n cb(\"soul required in lex\")\n return\n }\n\n const opts = _opt || {}\n const soul = lex[\"#\"]\n const key =\n !opts.secure && typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n let node: GraphNode | undefined\n const signatures: Record<string, string> = {}\n\n const each = (value: EncodedValue, key: string): void => {\n // Always include userPublicKey for verification, regardless of filter\n if (key !== utils.userPublicKey && !utils.match(lex[\".\"], key)) return\n\n if (!node) node = { _: { \"#\": soul, \">\": {} } }\n node[key] = value[0]\n node._[\">\"][key] = value[1]\n // If signature is present, store it in _[\"s\"]\n if (value.length === 3 && value[2]) {\n signatures[value[1].toString()] = value[2]\n }\n }\n\n radisk(soul + enq + key, (err, value) => {\n let graph: Graph | undefined\n if (utils.obj.is(value)) {\n Radix.map(value as never, each)\n if (!node) each(value as never, key)\n graph = { [soul]: node! }\n } else if (value) {\n each(value as EncodedValue, key)\n graph = { [soul]: node! }\n }\n // Only add _[\"s\"] if we found any signatures\n if (graph && graph[soul] && Object.keys(signatures).length > 0) {\n graph[soul]._[\"s\"] = signatures\n }\n cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n let count = 0\n let finished = false\n const ack = (err?: string | null): void => {\n count--\n if (finished) return\n\n if (err) {\n finished = true\n cb(err)\n return\n }\n\n if (count === 0) {\n finished = true\n cb(null)\n }\n }\n\n Object.keys(graph).forEach(soul => {\n const node = graph[soul]!\n Object.keys(node).forEach(key => {\n if (key === \"_\") return\n\n count++\n const value = node[key]!\n const state = node._[\">\"][key]!\n const sig = node._[\"s\"] && node._[\"s\"][state]\n const data: EncodedValue = sig\n ? [value, state, sig]\n : [value, state]\n radisk(soul + enq + key, data, ack)\n })\n })\n },\n }\n}\n\nexport default Store\n\n", "/**\n * Wire - WebSocket-based network protocol\n * Handles message routing, rate limiting, and graph synchronization\n */\n\nimport Dup from \"./dup.ts\"\nimport Get from \"./get.ts\"\nimport Ham from \"./ham.ts\"\nimport Store from \"./store.ts\"\nimport * as utils from \"./utils.ts\"\nimport type {\n Graph,\n GraphNode,\n WireMessage,\n WireOptions,\n Lex,\n ListenMap,\n HolsterOptions,\n GraphValue,\n} from \"./schemas.ts\"\n\n// Unified WebSocket type that works for both Node.js ws and browser WebSocket\ntype UnifiedWebSocket = WebSocket & {\n _retryHandler?: ReturnType<typeof createRetryHandler>\n on?: (event: string, cb: (...args: unknown[]) => void) => void\n send: (data: string | Buffer | ArrayBuffer | Uint8Array, options?: unknown, cb?: (err?: Error) => void) => void\n}\n\nconst isNode = typeof process !== \"undefined\" && process.versions?.node != null\n\n// Dynamic import for Node.js ws module - won't execute in browser/service worker\nconst wsModule = isNode ? await import(\"ws\") : undefined\n\nif (typeof globalThis.WebSocket === \"undefined\" && wsModule) {\n globalThis.WebSocket = wsModule.WebSocket as unknown as typeof WebSocket\n}\n\n// ============================================================================\n// Rate Limiting\n// ============================================================================\n\ninterface RateLimiterClient {\n requests: number[]\n lastCleanup: number\n throttleCount: number\n}\n\nconst createRateLimiter = (isTestEnv: boolean) => {\n const clients = new Map<string, RateLimiterClient>()\n const maxRequests = 1500\n const windowMs = 60000\n const disconnectThreshold = 10\n let cleanupInterval: NodeJS.Timeout | null = null\n\n const cleanup = (): void => {\n const now = Date.now()\n for (const [_clientId, data] of Array.from(clients.entries())) {\n if (now - data.lastCleanup > windowMs) {\n data.requests = []\n data.lastCleanup = now\n }\n data.requests = data.requests.filter(time => now - time < windowMs)\n if (now - data.lastCleanup > windowMs * 10) {\n data.throttleCount = 0\n }\n }\n }\n\n if (!isTestEnv) {\n cleanupInterval = setInterval(cleanup, windowMs / 4)\n }\n\n return {\n getDelay: (clientId: string): number => {\n const now = Date.now()\n const client = clients.get(clientId) || {\n requests: [],\n lastCleanup: now,\n throttleCount: 0,\n }\n\n client.requests = client.requests.filter(time => now - time < windowMs)\n\n if (client.requests.length >= maxRequests) {\n const oldestRequest = Math.min(...client.requests)\n const delay = windowMs - (now - oldestRequest)\n client.throttleCount = (client.throttleCount || 0) + 1\n clients.set(clientId, client)\n return Math.max(0, delay)\n }\n\n client.requests.push(now)\n clients.set(clientId, client)\n return 0\n },\n\n getRemainingRequests: (clientId: string): number => {\n const client = clients.get(clientId)\n if (!client) return maxRequests\n\n const now = Date.now()\n const validRequests = client.requests.filter(time => now - time < windowMs)\n return Math.max(0, maxRequests - validRequests.length)\n },\n\n getThrottleCount: (clientId: string): number => {\n const client = clients.get(clientId)\n return client ? client.throttleCount || 0 : 0\n },\n\n shouldDisconnect: (clientId: string): boolean => {\n const client = clients.get(clientId)\n if (!client) return false\n return client.throttleCount >= disconnectThreshold\n },\n\n destroy: (): void => {\n if (cleanupInterval) {\n clearInterval(cleanupInterval)\n cleanupInterval = null\n }\n clients.clear()\n },\n }\n}\n\n// ============================================================================\n// Message Validation\n// ============================================================================\n\nconst safeJSONParse = (\n data: string | Buffer,\n maxSize = 1024 * 1024\n): { success: boolean; data?: WireMessage; error?: string } => {\n try {\n if (typeof data === \"string\" && data.length > maxSize) {\n throw new Error(\"Message too large\")\n }\n return { success: true, data: JSON.parse(data.toString()) }\n } catch (error) {\n return { success: false, error: (error as Error).message }\n }\n}\n\nconst validateMessage = (\n data: string | Buffer,\n maxSize = 1024 * 1024\n): { valid: boolean; error?: string } => {\n if (typeof data === \"string\" && data.length > maxSize) {\n return { valid: false, error: \"Message too large\" }\n }\n if (Buffer.isBuffer && Buffer.isBuffer(data) && data.length > maxSize) {\n return { valid: false, error: \"Message too large\" }\n }\n return { valid: true }\n}\n\n// ============================================================================\n// Connection Management\n// ============================================================================\n\nconst createConnectionManager = (maxConnections = 1000) => {\n const connections = new Set<WebSocket>()\n\n return {\n add: (ws: WebSocket): boolean => {\n if (connections.size >= maxConnections) {\n return false\n }\n connections.add(ws)\n\n const originalClose = ws.close.bind(ws)\n ws.close = ((...args: unknown[]) => {\n connections.delete(ws)\n return originalClose(...(args as [number?, string?]))\n }) as typeof ws.close\n\n return true\n },\n\n remove: (ws: WebSocket): void => {\n connections.delete(ws)\n },\n\n count: (): number => connections.size,\n\n isFull: (): boolean => connections.size >= maxConnections,\n }\n}\n\n// ============================================================================\n// Retry Handler\n// ============================================================================\n\nconst createRetryHandler = (maxRetries = 5) => {\n let retryCount = 0\n\n return {\n shouldRetry: (): boolean => retryCount < maxRetries,\n getDelay: (): number => Math.min(1000 * Math.pow(2, retryCount), 30000),\n increment: (): void => {\n retryCount++\n },\n reset: (): void => {\n retryCount = 0\n },\n }\n}\n\n// ============================================================================\n// Wire Protocol\n// ============================================================================\n\nexport interface WireAPI {\n get: (lex: Lex, cb: (msg: WireMessage) => void, _opt?: WireOptions) => void\n put: (data: Graph, cb?: (err?: string | null) => void) => Promise<void> | void\n on: (lex: Lex, cb: () => void, _get?: boolean, _opt?: WireOptions) => void\n off: (lex: Lex, cb: () => void) => void\n}\n\nconst Wire = (opt: HolsterOptions): WireAPI => {\n const options = opt || {}\n const dup = Dup()\n const store = Store(options as never)\n const graph: Graph = {}\n const queue: Record<string, (msg: WireMessage) => void> = {}\n const listen: ListenMap = {}\n\n const pendingReferences = new Set<string>()\n const hasNode = new Set<string>()\n\n // Debounce client-side wire update checks: skip if the same lex was checked\n // recently. Keyed by \"soul\" or \"soul.property\".\n const recentChecks = new Map<string, number>()\n const recentCheckTTL = 10000 // 10 seconds\n\n const pendingTimeouts = new Map<string, Lex>()\n const offlineTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n\n const hasSoul = async (soul: string): Promise<boolean> => {\n if (graph[soul]) return true\n return new Promise(resolve => {\n store.get({ \"#\": soul }, (err, data) => {\n resolve(!err && !!data && !!data[soul])\n })\n })\n }\n\n const isTestEnv = options.wss && (options.wss as { constructor?: { name?: string } }).constructor?.name === \"Server\"\n const rateLimiter = createRateLimiter(isTestEnv)\n const connectionManager = createConnectionManager(options.maxConnections || 1000)\n\n const check = async (\n data: Graph,\n send: (msg: string) => { err?: string } | void,\n cb?: (err?: string | null) => void\n ): Promise<boolean> => {\n const key = utils.userPublicKey\n\n for (const soul of Object.keys(data)) {\n const node = data[soul]!\n // If the incoming update doesn't include a userPublicKey property at all,\n // allow it - the update is not trying to change the public key.\n if (node[key] === undefined) continue\n\n const msg = await new Promise<WireMessage>(res => {\n getWithCallback({ \"#\": soul, \".\": key }, res, send, {put: true})\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n // If there is no current node then the data is ok to write without\n // matching public keys, as the provided soul also needs a rel on the\n // parent node which then also requires checking. Otherwise public keys\n // need to match for existing data.\n if (\n !msg.put ||\n !msg.put[soul] ||\n msg.put[soul]![key] === node[key]\n ) {\n continue\n }\n\n if (cb) {\n cb(`error in wire check public key does not match for soul: ${soul}`)\n }\n return false\n }\n\n return true\n }\n\n const get = (msg: { get: Lex; \"#\": string }, send: (msg: string) => void): void => {\n const ack = Get(msg.get, graph)\n if (ack) {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n })\n )\n } else {\n store.get(\n msg.get,\n (err, ack) => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n err: err,\n })\n )\n },\n { secure: true }\n )\n }\n }\n\n const put = async (\n msg: { put: Graph; \"#\": string },\n send: (msg: string) => void\n ): Promise<void> => {\n const update = await Ham.mix(msg.put, graph, hasNode, options.secure || false, listen)\n if (Object.keys(update.now).length === 0) {\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(() => put({ put: update.defer, \"#\": msg[\"#\"] }, send), update.wait)\n }\n return\n }\n\n if (!(await check(update.now, send as never))) return\n\n store.put(update.now, err => {\n if (err) console.warn(\"store.put\", err)\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: err,\n })\n )\n update.listeners.forEach(cb => cb())\n })\n\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(() => put({ put: update.defer, \"#\": msg[\"#\"] }, send), update.wait)\n }\n }\n\n const getWithCallback = (\n lex: Lex,\n cb: (msg: WireMessage) => void,\n send: (msg: string) => { err?: string } | void,\n _opt?: WireOptions\n ): void => {\n if (!cb) return\n\n const opts = _opt || {}\n const fast = opts.fast || (!lex[\".\"] && hasNode.has(lex[\"#\"]))\n const ack = Get(lex, graph, fast)\n const track = utils.text.random(9)\n const request = JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n })\n\n if (ack) {\n if (!isNode) {\n // Client: send request on the wire to check for updates,\n // since it may have missed puts while disconnected.\n // Skip if the same lex was checked recently to avoid flooding.\n if (!lex[\".\"] || typeof lex[\".\"] === \"string\") {\n const checkKey = lex[\"#\"] + (lex[\".\"] ? \".\" + lex[\".\"] : \"\")\n const now = Date.now()\n const lastCheck = recentChecks.get(checkKey)\n if (!lastCheck || now - lastCheck > recentCheckTTL) {\n recentChecks.set(checkKey, now)\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n }\n } else {\n // Don't skip checks for other types of lex queries.\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n }\n }\n cb({ put: ack })\n return\n }\n\n store.get(\n lex,\n (err, ack) => {\n if (ack) {\n // Populate in-memory graph from store data before sending the server\n // request, so stale server responses with older state are correctly\n // rejected by ham.mix.\n for (const [soul, node] of Object.entries(ack)) {\n if (!node) continue\n if (!graph[soul]) {\n graph[soul] = {...node} as unknown as Graph[string]\n continue\n }\n for (const [key, value] of Object.entries(node)) {\n if (key === \"_\") continue\n const gNode = graph[soul] as unknown as Record<string, unknown>\n if (typeof gNode[key] !== \"undefined\") continue\n gNode[key] = value\n const meta = (node as unknown as GraphNode)._\n if (meta?.[\">\"] && typeof meta[\">\"][key] !== \"undefined\") {\n const state = meta[\">\"][key]\n const gMeta = (graph[soul] as unknown as GraphNode)._\n gMeta[\">\"][key] = state\n if (meta[\"s\"]?.[state]) {\n if (!gMeta[\"s\"]) gMeta[\"s\"] = {}\n gMeta[\"s\"]![state] = meta[\"s\"][state]\n }\n }\n }\n }\n // Full-node fetch: the graph is now complete for this soul.\n if (!lex[\".\"] && ack[lex[\"#\"]]) hasNode.add(lex[\"#\"])\n // Only serve from store if the requested property is present.\n const node = ack[lex[\"#\"]]\n const hasProperty =\n node &&\n Object.keys(node).some(\n key => key !== \"_\" && utils.match(lex[\".\"], key),\n )\n if (hasProperty) {\n // Public keys are immutable once written \u2014 never need a wire check.\n if (!isNode && lex[\".\"] !== utils.userPublicKey) {\n if (!lex[\".\"] || typeof lex[\".\"] === \"string\") {\n const checkKey = lex[\"#\"] + (lex[\".\"] ? \".\" + lex[\".\"] : \"\")\n const now = Date.now()\n const lastCheck = recentChecks.get(checkKey)\n if (!lastCheck || now - lastCheck > recentCheckTTL) {\n recentChecks.set(checkKey, now)\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n }\n } else {\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n return\n }\n }\n }\n cb(err ? { put: ack, err: err } : { put: ack })\n return\n }\n }\n\n if (err) console.log(err)\n\n // Put requests only need a local answer \u2014 skip the wire round-trip.\n if (opts && opts.put) {\n const id = lex[\"#\"]\n const ack: Record<string, null | Record<string, null>> = {[id]: null}\n if (typeof lex[\".\"] === \"string\") {\n ack[id] = {[lex[\".\"]]: null}\n }\n cb({put: ack as never})\n return\n }\n\n queue[track] = cb\n\n pendingTimeouts.set(track, lex)\n\n // Ensure the requested soul is stored when the response arrives.\n pendingReferences.add(lex[\"#\"])\n\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({ err: sendResult.err })\n delete queue[track]\n pendingTimeouts.delete(track)\n return\n }\n },\n opts\n )\n }\n\n const api = (send: (msg: string) => { err?: string } | void): WireAPI => {\n return {\n get: (lex, cb, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = { ...lex, \".\": String(lex[\".\"]) }\n }\n if (lex && lex[\"#\"]) {\n pendingReferences.add(lex[\"#\"])\n }\n getWithCallback(lex, cb, send, _opt)\n },\n put: async (data, cb) => {\n const update = await Ham.mix(data, graph, hasNode, options.secure || false, listen)\n if (Object.keys(update.now).length === 0) {\n if (cb) cb(null)\n return\n }\n\n if (!(await check(update.now, send as never, cb))) {\n return\n }\n\n for (const [_soul, node] of Object.entries(update.now)) {\n if (node && typeof node === \"object\") {\n for (const [_key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value as GraphValue)\n if (soulId) {\n pendingReferences.add(soulId)\n }\n }\n }\n }\n\n store.put(update.now, err => {\n if (cb) cb(err)\n update.listeners.forEach(l => l())\n })\n\n const sendResult = send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n })\n )\n if (sendResult && sendResult.err) {\n if (cb) cb(sendResult.err)\n return\n }\n },\n on: (lex, cb, _get, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = { ...lex, \".\": String(lex[\".\"]) }\n }\n const soul = lex && lex[\"#\"]\n if (!soul || !cb) return\n\n if (listen[soul]) {\n listen[soul]!.push({ \".\": lex[\".\"], cb: cb as never })\n } else {\n listen[soul] = [{ \".\": lex[\".\"], cb: cb as never }]\n }\n if (_get) getWithCallback(lex, cb as never, send, _opt)\n },\n off: (lex, cb) => {\n const soul = lex && lex[\"#\"]\n if (!soul || !listen[soul]) return\n\n if (cb) {\n const found = listen[soul]!.find(l => l.cb === (cb as never))\n if (found) {\n listen[soul]!.splice(listen[soul]!.indexOf(found), 1)\n }\n } else {\n delete listen[soul]\n }\n },\n }\n }\n\n if (isNode && (options.wss || options.server || options.port != null)) {\n let wss = options.wss\n let clients = (): WebSocket[] =>\n (wss as { clients?: () => WebSocket[] }).clients?.() || []\n if (!wss) {\n const config = options.server\n ? { server: options.server }\n : { port: options.port }\n wss = new wsModule!.WebSocketServer(config)\n clients = () => Array.from((wss as { clients: Set<WebSocket> }).clients || [])\n }\n\n const send = (data: string, isBinary?: boolean): void => {\n const msg = JSON.parse(data) as WireMessage\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const lex = pendingTimeouts.get(trackId)!\n pendingTimeouts.delete(trackId)\n\n setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = lex[\"#\"]\n const ack: Graph = { [id]: null as never }\n if (typeof lex[\".\"] === \"string\") {\n ack[id] = { [lex[\".\"]]: null } as never\n }\n cb({ \"#\": trackId, put: ack })\n delete queue[trackId]\n }\n }, isTestEnv ? 100 : 10000)\n }\n\n clients().forEach(client => {\n const ws = client as UnifiedWebSocket\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data, { binary: isBinary })\n } else if (ws) {\n const retryHandler = ws._retryHandler || createRetryHandler()\n ws._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n ws.send(data, { binary: isBinary })\n }\n }, delay)\n }\n }\n })\n }\n\n ;(wss as unknown as { on: (event: string, cb: (ws: UnifiedWebSocket) => void) => void }).on(\n \"connection\",\n (ws: UnifiedWebSocket) => {\n if (!connectionManager.add(ws)) {\n console.log(\"Connection limit reached, rejecting connection\")\n ws.close(1013, \"Connection limit reached - try again later\")\n return\n }\n\n const clientId = utils.text.random(9)\n console.log(`New WebSocket client connected: ${clientId}`)\n\n ws.on?.(\"error\", ((...args: unknown[]) => {\n const error = args[0] as Error\n console.log(\"WebSocket error:\", error)\n connectionManager.remove(ws)\n }) as (...args: unknown[]) => void)\n\n ws.on?.(\"close\", (() => {\n console.log(`WebSocket client disconnected: ${clientId}`)\n connectionManager.remove(ws)\n }) as (...args: unknown[]) => void)\n\n ws.on?.(\"message\", ((...args: unknown[]) => {\n const data = args[0] as Buffer\n const isBinary = args[1] as boolean\n const validation = validateMessage(data, options.maxMessageSize)\n if (!validation.valid) {\n console.warn(`Invalid message: ${validation.error}`)\n ws.send(JSON.stringify({ error: validation.error }))\n return\n }\n\n const parseResult = safeJSONParse(data, options.maxMessageSize)\n if (!parseResult.success) {\n console.warn(`JSON parse error: ${parseResult.error}`)\n ws.send(JSON.stringify({ error: \"Invalid JSON\" }))\n return\n }\n\n const msg = parseResult.data!\n if (!msg[\"#\"]) return // Incoming messages must have '#'\n if (dup.check(msg[\"#\"])) return\n\n const delay = rateLimiter.getDelay(clientId)\n if (delay > 0) {\n const throttleCount = rateLimiter.getThrottleCount(clientId)\n console.log(\n `Client ${clientId}: rate limit exceeded, delay would be ${delay}ms, dropping message (throttle count: ${throttleCount})`\n )\n if (rateLimiter.shouldDisconnect(clientId)) {\n console.log(\n `Client ${clientId}: Disconnecting after ${throttleCount} throttle violations`\n )\n ws.close(1008, \"Rate limit violations\")\n return\n }\n\n ws.send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: `Rate limit exceeded. Slow down requests. Wait ${Math.ceil(delay / 1000)}s`,\n throttle: delay,\n })\n )\n return\n }\n\n const processMessage = async (): Promise<void> => {\n dup.track(msg[\"#\"]!)\n\n if (msg.get) get(msg as never, send)\n if (msg.put) await put(msg as never, send)\n send(data.toString(), isBinary)\n\n const id = msg[\"@\"]\n const cb = queue[id!]\n if (cb) {\n delete (msg as { \"#\"?: string })[\"#\"]\n delete (msg as { \"@\"?: string })[\"@\"]\n cb(msg)\n delete queue[id!]\n }\n }\n\n if (delay > 0) {\n setTimeout(processMessage, delay)\n } else {\n processMessage()\n }\n }) as (...args: unknown[]) => void)\n }\n )\n return api(send)\n }\n\n // Browser logic\n const peers: WebSocket[] = []\n let clientThrottled = false\n let throttleUntil = 0\n let messageQueue: string[] = []\n let queueProcessor: NodeJS.Timeout | null = null\n const maxQueueLength = options.maxQueueLength || 10000\n\n const startResponseTimeout = (trackId: string, lex: Lex, delay = isTestEnv ? 100 : 10000): ReturnType<typeof setTimeout> => {\n return setTimeout(() => {\n offlineTimeouts.delete(trackId)\n pendingTimeouts.delete(trackId)\n const cb = queue[trackId]\n if (cb) {\n const id = lex[\"#\"]\n const ack: Graph = { [id]: null as never }\n if (typeof lex[\".\"] === \"string\") {\n ack[id] = { [lex[\".\"]]: null } as never\n }\n cb({ \"#\": trackId, put: ack })\n delete queue[trackId]\n }\n }, delay)\n }\n\n const processQueue = (): void => {\n if (messageQueue.length === 0) {\n queueProcessor = null\n return\n }\n\n const now = Date.now()\n if (clientThrottled && now < throttleUntil) {\n queueProcessor = setTimeout(processQueue, Math.min(1000, throttleUntil - now))\n return\n }\n\n if (clientThrottled && now >= throttleUntil) {\n console.log(`Throttle period ended, resuming queue processing`)\n clientThrottled = false\n throttleUntil = 0\n }\n\n const data = messageQueue[0]!\n const sent = sendToPeers(data)\n\n const msg = JSON.parse(data) as WireMessage\n const trackId = msg[\"#\"]\n\n // Drop GET messages with no pending callback \u2014 these were already served\n // from local store so no caller is waiting for the wire response.\n const isStaleCheckMessage = !sent && !!msg.get && !pendingTimeouts.has(trackId!)\n\n if (sent || isStaleCheckMessage) {\n messageQueue.shift()\n }\n\n if (trackId && pendingTimeouts.has(trackId)) {\n const lex = pendingTimeouts.get(trackId)!\n if (sent) {\n if (offlineTimeouts.has(trackId)) {\n clearTimeout(offlineTimeouts.get(trackId)!)\n offlineTimeouts.delete(trackId)\n }\n startResponseTimeout(trackId, lex)\n } else if (!offlineTimeouts.has(trackId)) {\n offlineTimeouts.set(trackId, startResponseTimeout(trackId, lex, 0))\n }\n }\n\n if (messageQueue.length > 0) {\n queueProcessor = setTimeout(processQueue, 50)\n } else {\n queueProcessor = null\n }\n }\n\n const sendToPeers = (data: string): boolean => {\n let sentToAtLeastOne = false\n peers.forEach(peer => {\n const ws = peer as UnifiedWebSocket\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data)\n sentToAtLeastOne = true\n } else if (ws) {\n const retryHandler = ws._retryHandler || createRetryHandler()\n ws._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n peer.send(data)\n }\n }, delay)\n }\n }\n })\n return sentToAtLeastOne\n }\n\n const send = (data: string): { err?: string } | void => {\n if (messageQueue.length >= maxQueueLength) {\n return {\n err: `Message queue exceeded maximum length (${maxQueueLength}). Update query logic to request less data.`,\n }\n }\n\n messageQueue.push(data)\n if (!queueProcessor) {\n queueProcessor = setTimeout(processQueue, 50)\n }\n }\n\n if (!(options.peers instanceof Array) || options.peers.length === 0) {\n options.peers = [`ws://localhost:${options.port || 8765}`]\n }\n\n options.peers.forEach((peer: string) => {\n const start = (): void => {\n let ws: WebSocket | null = new WebSocket(peer)\n peers.push(ws)\n const retryHandler = createRetryHandler()\n\n ws.onclose = () => {\n if (ws && peers.indexOf(ws) !== -1) {\n peers.splice(peers.indexOf(ws), 1)\n }\n ws = null\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n setTimeout(start, delay)\n }\n }\n\n ws.onopen = () => {\n retryHandler.reset()\n }\n\n ws.onerror = (e: Event) => {\n console.log(e)\n }\n\n ws.onmessage = async (m: MessageEvent) => {\n const msg = JSON.parse(m.data as string) as WireMessage\n if (!msg[\"#\"]) return // Incoming messages must have '#'\n if (dup.check(msg[\"#\"])) return\n\n if (msg.throttle && msg.err) {\n console.log(`Server throttling: ${msg.err}`)\n clientThrottled = true\n throttleUntil = Date.now() + msg.throttle\n return\n }\n\n dup.track(msg[\"#\"]!)\n if (msg.get) get(msg as never, send as never)\n if (msg.put) {\n // Pre-pass: expand pendingReferences to include rels of every soul\n // that will be stored in this batch. This handles the case where a\n // server batch contains both a parent soul (e.g. day_soul with item\n // rels) and its child souls (item_souls), in any order \u2014 without the\n // pre-pass, a child soul that appears before its parent in the batch\n // would be missed because pendingReferences hasn't been updated yet.\n const hasSoulMap = new Map<string, boolean>()\n for (const [soul, node] of Object.entries(msg.put)) {\n const known = await hasSoul(soul)\n hasSoulMap.set(soul, known)\n if ((!known && !pendingReferences.has(soul)) || !node || typeof node !== \"object\") continue\n for (const [, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value as GraphValue)\n if (soulId) pendingReferences.add(soulId)\n }\n }\n\n // Main pass: filter using cached hasSoul results and the now-complete\n // pendingReferences set.\n const filteredPut: Graph = {}\n const pendingToDelete: string[] = []\n for (const [soul, node] of Object.entries(msg.put)) {\n let shouldStore = hasSoulMap.get(soul)\n if (pendingReferences.has(soul)) {\n shouldStore = true\n // Don't delete from pendingReferences yet \u2014 concurrent onmessage\n // handlers for the same soul may have yielded at await hasSoul()\n // before this pass ran. Deleting here would cause those handlers\n // to see shouldStore=false and skip storing the soul's data.\n // Instead, defer the delete until after put() updates the graph,\n // so any concurrent handler can find the soul via hasSoul(graph).\n pendingToDelete.push(soul)\n }\n if (shouldStore) filteredPut[soul] = node\n }\n\n // Store filtered data if any\n if (Object.keys(filteredPut).length > 0) {\n // Create filtered message for Ham.mix with original message ID\n const filteredMsg = { put: filteredPut, \"#\": msg[\"#\"]! }\n await put(filteredMsg, send as never)\n }\n\n // Safe to delete now \u2014 put() has run Ham.mix which updates graph\n // in-place, so hasSoul() will return true for these souls going\n // forward, making pendingReferences no longer needed for them.\n pendingToDelete.forEach(soul => pendingReferences.delete(soul))\n }\n\n const id = msg[\"@\"]\n const cb = queue[id!]\n if (cb) {\n delete (msg as { \"#\"?: string })[\"#\"]\n delete (msg as { \"@\"?: string })[\"@\"]\n cb(msg)\n delete queue[id!]\n }\n }\n }\n start()\n })\n\n return api(send)\n}\n\nexport default Wire\n\n", "/**\n * User - User authentication and management\n * Provides user creation, authentication, and password management\n */\n\nimport * as utils from \"./utils.ts\"\nimport Wire from \"./wire.ts\"\nimport SEA from \"./sea.ts\"\nimport type { UserIdentity, HolsterOptions, LexFilter, WireOptions } from \"./schemas.ts\"\nimport type { HolsterAPI } from \"./holster.ts\"\n\ntype WireInterface = ReturnType<typeof Wire>\n\nexport interface UserInterface {\n is?: UserIdentity | null\n create: (username: string, password: string, cb?: (err?: string | null) => void) => void\n auth: (username: string, password: string, cb?: (err?: string | null) => void) => void\n change: (\n username: string,\n password: string,\n newPassword: string,\n cb?: (err?: string | null) => void\n ) => void\n store: (localStorage?: boolean) => void\n recall: () => void\n leave: () => void\n delete: (username: string, password: string, cb?: (err?: string | null) => void) => void\n get?(\n keys: string | string[],\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI\n}\n\n/**\n * Create User management interface\n */\nconst User = (opt: HolsterOptions | undefined, wire?: WireInterface): UserInterface => {\n if (!wire) wire = Wire(opt as HolsterOptions)\n let pubs: string[] = []\n let creating = false\n let authing = false\n let retries = 0\n\n const auth = (\n username: string,\n password: string,\n newPassword: string,\n ack: (err?: string | null) => void\n ): void => {\n const retry = (username: string): void => {\n retries++\n auth(username, password, newPassword, ack)\n }\n const done = (err?: string | null): void => {\n pubs = []\n retries = 0\n authing = false\n ack(err)\n }\n const next = (): void => {\n if (pubs.length === 0) {\n done(\"Wrong username or password\")\n return\n }\n\n const pub = pubs.shift()!\n wire.get(\n { \"#\": pub, \".\": [\"auth\", \"pub\", \"epub\"] },\n async msg => {\n if (msg.err) {\n done(`error getting ${pub}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[pub]\n if (!data || !data.auth) return next()\n\n const authData = JSON.parse(data.auth as string) as {\n enc: { ct: string; iv: string; s: string }\n salt: string\n }\n const work = await SEA.work(password, authData.salt)\n const dec = (await SEA.decrypt(authData.enc, work)) as\n | { priv: string; epriv: string }\n | null\n if (!dec) return next()\n\n user.is = {\n username: username,\n pub: data.pub as string,\n epub: data.epub as string,\n priv: dec.priv,\n epriv: dec.epriv,\n }\n if (newPassword !== \"\") {\n const salt = utils.text.random(64)\n const newWork = await SEA.work(newPassword, salt)\n const enc = await SEA.encrypt(dec, newWork)\n const update = {\n auth: JSON.stringify({ enc: enc, salt: salt }),\n }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const graph = utils.graph(pub, update, sig!, data.pub as string, timestamp)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${JSON.stringify(update)} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n done(null)\n },\n )\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get(\n { \"#\": soul },\n async msg => {\n if (msg.err) {\n done(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[soul]\n if (!data) return retry(username)\n\n delete (data as { _?: unknown })._\n pubs = Object.keys(data)\n next()\n },\n )\n }\n\n const user: UserInterface = {\n is: null,\n create: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (creating) {\n ack(\"User is already being created\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n creating = true\n\n const soul = \"~@\" + username\n wire.get(\n { \"#\": soul },\n async msg => {\n if (msg.err) {\n creating = false\n ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n if (msg.put && msg.put[soul]) {\n creating = false\n ack(\"Username already exists\")\n return\n }\n\n const salt = utils.text.random(64)\n const work = await SEA.work(password, salt)\n const pair = await SEA.pair()\n const priv = { priv: pair.priv, epriv: pair.epriv }\n const enc = await SEA.encrypt(priv, work)\n const data = {\n username: username,\n pub: pair.pub,\n epub: pair.epub,\n auth: JSON.stringify({ enc: enc, salt: salt }),\n }\n\n const pub = \"~\" + pair.pub\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, pair)\n const graph = utils.graph(pub, data, sig!, pair.pub, timestamp)\n wire.put(graph, err => {\n creating = false\n if (err) {\n ack(`error putting ${JSON.stringify(data)} on ${pub}: ${err}`)\n return\n }\n\n const rel = { [pub]: { \"#\": pub } }\n wire.put(utils.graph(soul, rel as never), err => {\n if (err) {\n ack(`error putting ${JSON.stringify(rel)} on ${soul}: ${err}`)\n return\n }\n\n if (cb) cb(null)\n })\n })\n },\n )\n },\n auth: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", ack)\n },\n change: (username, password, newPassword, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n if (newPassword === \"\") {\n ack(\"Please provide a new password\")\n return\n }\n\n authing = true\n auth(username, password, newPassword, ack)\n },\n store: (localStorage = false) => {\n if (!user.is) {\n console.log(\"Please authenticate before calling store\")\n return\n }\n\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n },\n recall: () => {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n return\n }\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n const is = globalThis.sessionStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n }\n }\n },\n leave: () => {\n user.is = null\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n },\n delete: (username, password, cb) => {\n const ack = (err?: string | null): void => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", async err => {\n if (err) {\n ack(err)\n return\n }\n\n const data = { username: null, pub: null, epub: null, auth: null }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is!)\n const pub = \"~\" + user.is!.pub\n const graph = utils.graph(pub, data as never, sig!, user.is!.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n ack(`error putting null on ${pub}: ${err}`)\n return\n }\n\n user.is = null\n if (cb) cb(null)\n })\n })\n },\n }\n return user\n}\n\nexport default User\n\n", "/**\n * Holster - Main API for graph database operations\n * Provides chainable interface for get, put, on, off operations\n */\n\nimport * as utils from \"./utils.ts\"\nimport Wire, { type WireAPI } from \"./wire.ts\"\nimport User, { type UserInterface } from \"./user.ts\"\nimport SEA from \"./sea.ts\"\nimport type {\n HolsterOptions,\n ChainItem,\n ApiContext,\n Graph,\n GraphValue,\n Lex,\n LexFilter,\n LexWithDot,\n UserIdentity,\n WireOptions,\n} from \"./schemas.ts\"\n\n/**\n * Holster API interface\n */\nexport interface HolsterAPI {\n get: {\n (key: string | null, lex?: LexWithDot, cb?: (data: unknown) => void, _opt?: WireOptions): HolsterAPI\n (\n key: string | null,\n cb?: (data: unknown) => void,\n _opt?: WireOptions\n ): HolsterAPI\n }\n next: {\n (key: string | null, lex?: LexWithDot, cb?: (data: unknown) => void, _opt?: WireOptions): HolsterAPI\n (\n key: string | null,\n cb?: (data: unknown) => void,\n _opt?: WireOptions\n ): HolsterAPI\n }\n put: (\n data: GraphValue | Record<string, GraphValue>,\n set?: boolean | ((data?: string | null) => void),\n cb?: (data?: string | null) => void\n ) => HolsterAPI | void\n on: (\n lex: LexWithDot | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | boolean,\n _get?: boolean,\n _opt?: WireOptions\n ) => void\n off: (cb?: (data: unknown) => void) => HolsterAPI | void\n user: () => UserInterface & HolsterAPI\n wire: WireAPI\n SEA: typeof SEA\n}\n\nconst Holster = (opt?: HolsterOptions | string | string[]): HolsterAPI => {\n let options: HolsterOptions\n if (typeof opt === \"string\") options = { peers: [opt] }\n else if (opt instanceof Array) options = { peers: opt }\n else if (!utils.obj.is(opt)) options = {}\n else options = opt\n\n const wire = Wire(options)\n const user = User(options, wire as never)\n const map = new Map<(data: unknown) => void, () => void>()\n const allctx = new Map<string, ApiContext>()\n\n const ok = (data: GraphValue): boolean => {\n return (\n data === null ||\n data === true ||\n data === false ||\n typeof data === \"string\" ||\n !!utils.rel.is(data) ||\n utils.num.is(data)\n )\n }\n\n const check = (\n data: GraphValue | Record<string, GraphValue>\n ): true | string | string[] => {\n if (ok(data as GraphValue)) return true\n\n if (utils.obj.is(data)) {\n const keys: string[] = []\n for (const [key, value] of Object.entries(data)) {\n if (key === \"_\") {\n return \"error underscore cannot be used as a property name\"\n }\n if (utils.obj.is(value) || ok(value as GraphValue)) {\n keys.push(key)\n continue\n }\n if (typeof value === \"undefined\") {\n return `error undefined ${key} cannot be converted to a graph`\n }\n const error = JSON.stringify({ [key]: value })\n return `error ${error} cannot be converted to a graph`\n }\n if (keys.length !== 0) return keys\n }\n const error = JSON.stringify(data)\n return `error ${error} cannot be converted to a graph`\n }\n\n const api = (initCtxid?: string): HolsterAPI => {\n let ctxid = initCtxid\n const get = (\n lex: LexFilter,\n soul: string,\n ack: (data: unknown) => void,\n _opt?: WireOptions\n ): void => {\n wire.get(\n utils.obj.put(lex as never, \"#\", soul) as Lex,\n async msg => {\n if (msg.err) console.log(msg.err)\n if (msg.put && msg.put[soul]) {\n delete (msg.put[soul] as { _?: unknown })._\n delete (msg.put[soul] as Record<string, unknown>)[utils.userPublicKey]\n delete (msg.put[soul] as Record<string, unknown>)[utils.userSignature]\n const node = msg.put[soul]!\n await Promise.all(Object.keys(node).map(async key => {\n const id = utils.rel.is(node[key] as GraphValue)\n if (!id) return\n const attemptRead = async (retries = 0): Promise<unknown> => {\n const data = await new Promise<unknown>(res => {\n const _ctxid = utils.text.random()\n const ctx = allctx.get(ctxid!)\n allctx.set(_ctxid, {\n chain: [{ item: null, soul: id }],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null as never, res as never, _opt)\n })\n if (data !== null || retries >= 5) {\n return data\n }\n await new Promise(resolve => setTimeout(resolve, 50))\n return attemptRead(retries + 1)\n }\n node[key] = (await attemptRead()) as GraphValue\n }))\n ack(msg.put[soul])\n } else {\n ack(null)\n }\n },\n _opt\n )\n }\n\n const graph = async (\n soul: string,\n data: Record<string, GraphValue>,\n userctx?: UserIdentity | null,\n cb?: (err?: string) => void\n ): Promise<Graph | null> => {\n if (userctx) {\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, userctx)\n return utils.graph(soul, data, sig!, userctx.pub, timestamp)\n }\n\n if (options.secure) {\n if (!cb) cb = console.log\n cb(`error putting data on ${soul}: user required in secure mode`)\n return null\n }\n\n return utils.graph(soul, data)\n }\n\n const done = (ctxid: string) => {\n return (data: unknown): void => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") {\n setTimeout(() => ctx.cb!(data as never), 1)\n } else if (data) {\n console.log(\"error no callback for data\", data, \"ctx\", ctx)\n }\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n }\n\n const watchForRel = (\n soul: string,\n item: string,\n ctx: ApiContext,\n i: number,\n request: { on?: LexFilter; get?: LexFilter; _get?: boolean; _opt?: WireOptions },\n cb: (data: unknown) => void,\n on = true\n ): void => {\n let timer: ReturnType<typeof setTimeout> | null = null\n const handler = (): void => {\n // Bail out if the context was removed by off().\n if (!allctx.has(ctxid!)) {\n wire.off({ \"#\": soul, \".\": item }, handler)\n if (timer) clearTimeout(timer)\n return\n }\n wire.get(\n { \"#\": soul, \".\": item },\n msg => {\n const node = msg.put && msg.put[soul]\n const id = utils.rel.is(node && node[item] as GraphValue)\n if (!id) {\n // If it's a plain value (not a rel) and this is a get, deliver it.\n // node._ guards against timeout null-acks which lack metadata.\n if (!on && node && node._ && typeof node[item] !== \"undefined\") {\n if (timer) clearTimeout(timer)\n wire.off({ \"#\": soul, \".\": item }, handler)\n cb(node[item])\n }\n return\n }\n if (timer) clearTimeout(timer)\n wire.off({ \"#\": soul, \".\": item }, handler)\n ctx.chain[i]!.soul = id\n allctx.set(ctxid!, { ...ctx })\n if (on) {\n api(ctxid).on(request.on!, cb, request._get, request._opt)\n } else {\n api(ctxid).next(null as never, request.get as never, cb as never, request._opt)\n }\n },\n { ...request._opt, secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n }\n wire.on({ \"#\": soul, \".\": item }, handler, false, request._opt)\n // Time out after the same total duration as the on() retry loop\n // (1+2+4+8+16 = 31s) so callers are not blocked forever if the node\n // genuinely doesn't exist.\n if (!on) {\n timer = setTimeout(() => {\n wire.off({ \"#\": soul, \".\": item }, handler)\n if (cb) cb(null)\n }, 31000)\n }\n }\n\n const resolve = (\n request: {\n get?: LexFilter\n put?: GraphValue | Record<string, GraphValue>\n on?: LexFilter\n off?: boolean\n _opt?: WireOptions\n _get?: boolean\n },\n cb?: (data: unknown) => void\n ): ChainItem | false => {\n if (!request) {\n console.log(\"error resolve request parameter required\")\n return false\n }\n\n const get = typeof request.get !== \"undefined\"\n const put = typeof request.put !== \"undefined\"\n const on = typeof request.on !== \"undefined\"\n const off = typeof request.off !== \"undefined\"\n\n let found = false\n const ctx = allctx.get(ctxid!)\n if (!ctx) return {item: null, soul: null}\n for (let i = 1; i < ctx.chain.length; i++) {\n if (ctx.chain[i]!.soul !== null) continue\n found = true\n break\n }\n\n if (found) {\n let i = 1\n while (i < ctx.chain.length && ctx.chain[i]!.soul !== null) i++\n const { item, soul } = ctx.chain[i - 1]!\n wire.get(\n { \"#\": soul!, \".\": item! },\n async msg => {\n if (msg.err) {\n console.log(`error getting ${item} on ${soul}: ${msg.err}`)\n if (cb) cb(null)\n return\n }\n\n let node = msg.put && msg.put[soul!]\n if (node && typeof node[item!] !== \"undefined\") {\n let id = utils.rel.is(node[item!] as GraphValue)\n if (id) {\n ctx.chain[i]!.soul = id\n allctx.set(ctxid!, { ...ctx })\n if (get) {\n api(ctxid).next(null as never, request.get as never, cb as never, request._opt)\n } else if (put) {\n api(ctxid).put(request.put!, cb as never)\n } else if (on) {\n api(ctxid).on(request.on!, cb!, request._get, request._opt)\n } else if (off) {\n api(ctxid).off(cb as never)\n }\n } else if (get) {\n cb!(node[item!])\n } else if (put) {\n id = utils.text.random()\n node[item!] = utils.rel.ify(id)\n const g = await graph(soul!, node as never, ctx.user, cb as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n (cb as (err: string) => void)(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n if (id) {\n ctx.chain[i]!.soul = id\n }\n api(ctxid).put(request.put!, cb as never)\n })\n } else if (on) {\n // Item is not a rel yet \u2014 watch the parent soul for when it\n // becomes one, then retry chain resolution.\n watchForRel(soul!, item!, ctx, i, request, cb!)\n if (request._get) cb!(null)\n } else if (off) {\n if (cb) cb(null)\n }\n } else if (put) {\n const id = utils.text.random()\n if (!node) node = {} as never\n node[item!] = utils.rel.ify(id)\n const g = await graph(soul!, node as never, ctx.user, cb as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n (cb as (err: string) => void)(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n ctx.chain[i]!.soul = id\n api(ctxid).put(request.put!, cb as never)\n })\n } else {\n if (on) {\n // Node doesn't exist yet \u2014 watch for it to appear.\n watchForRel(soul!, item!, ctx, i, request, cb!)\n if (request._get) cb!(null)\n } else if (get && node) {\n const sv = (node as Record<string, unknown> & {_?: {\">\": Record<string, unknown>}})._?.[\">\"]\n if (sv && Object.keys(sv).length > 0 && typeof sv[item!] === \"undefined\") {\n // State vector has other properties but not this one \u2014 never written.\n if (cb) cb(null)\n } else {\n // Empty state vector or item is tracked \u2014 may arrive via push.\n watchForRel(soul!, item!, ctx, i, request, cb!, false)\n }\n } else {\n // Soul doesn't exist or no get \u2014 return null.\n if (cb) cb(null)\n }\n }\n },\n { ...request._opt, secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure }\n )\n return false\n }\n\n if (get && ctx.chain[ctx.chain.length - 1]!.item !== null) {\n ctx.chain.push({ item: null, soul: null })\n api(ctxid).next(null as never, request.get as never, cb as never, request._opt)\n return false\n }\n\n return ctx.chain[ctx.chain.length - 1]!\n }\n\n return {\n get: function (\n this: HolsterAPI,\n key: string | null,\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (callback) callback(null)\n return this\n }\n\n if (lexFilter && typeof callback !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n ctxid = utils.text.random()\n allctx.set(ctxid, {\n chain: [{ item: String(key), soul: \"root\" }],\n cb: callback,\n })\n if (!callback) return api(ctxid)\n\n const _done = done(ctxid)\n const result = resolve({ get: lexFilter, _opt: opts }, _done)\n if (result) get(lexFilter as never, result.soul!, _done, opts)\n return this\n } as HolsterAPI[\"get\"],\n\n next: function (\n this: HolsterAPI,\n key: string | null,\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n const ack = (ctxid: string) => {\n return (data: unknown): void => {\n if (callback) {\n callback(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (callback) callback(null)\n return this\n }\n\n const _ack = ack(ctxid)\n if (key === \"\" || key === \"_\") {\n _ack(null)\n return this\n }\n\n if (lexFilter && typeof callback !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n const ctx = allctx.get(ctxid)\n if (!ctx) return this\n\n if (callback && typeof ctx.cb === \"undefined\") {\n ctx.cb = callback\n callback = undefined\n }\n\n if (key !== null) ctx.chain.push({ item: String(key), soul: null })\n if (!ctx.cb) return api(ctxid)\n\n const result = resolve({ get: lexFilter, _opt: opts }, _ack)\n if (result) get(lexFilter as never, result.soul!, _ack, opts)\n return this\n } as HolsterAPI[\"next\"],\n\n put: function (\n data: GraphValue | Record<string, GraphValue>,\n set?: boolean | ((data?: string | null) => void),\n cb?: (data?: string | null) => void\n ): HolsterAPI | void {\n let isSet = false\n let callback: ((data?: string | null) => void) | undefined\n\n if (typeof set === \"function\") {\n callback = set\n isSet = false\n } else {\n isSet = set || false\n callback = cb\n }\n\n const ack = (ctxid: string) => {\n return (data?: string | null): void => {\n if (callback) {\n callback(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n\n if (!ctxid) {\n if (callback) callback(\"error please provide a key using get(key)\")\n return\n }\n\n const ctx = allctx.get(ctxid!)\n if (!ctx) return\n\n if (!ctx.cb && callback) {\n ctx.cb = callback as never\n callback = undefined\n }\n\n if (isSet) data = { [utils.text.random()]: data } as Record<string, GraphValue>\n\n const _ack = ack(ctxid)\n const result = check(data)\n if (typeof result === \"string\") {\n _ack(result)\n return\n }\n\n const resolved = resolve({ put: data, _opt: {put: true} }, _ack as never)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n if (result === true) {\n wire.get(\n { \"#\": soul, \".\": item! },\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item!]\n const id = utils.rel.is(current as GraphValue)\n if (!id) {\n if (!node) node = {} as never\n node[item!] = (isSet ? data : data) as GraphValue\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n return\n }\n\n wire.get({ \"#\": id }, async msg => {\n if (msg.err) {\n _ack(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n _ack(`error ${id} not found`)\n return\n }\n\n for (const key of Object.keys(msg.put[id]!)) {\n if (\n key === \"_\" ||\n key === utils.userPublicKey ||\n key === utils.userSignature\n ) {\n continue\n }\n\n const err = await new Promise<string | null | undefined>(res => {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: key, soul: id }]\n allctx.set(_ctxid, { chain: chain, user: ctx.user })\n api(_ctxid).put(null!, res as never)\n })\n if (err) {\n _ack(err)\n return\n }\n }\n if (!node) node = {} as never\n node[item!] = data as GraphValue\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n })\n },\n { secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure, put: true }\n )\n return\n }\n\n const attemptRead = (retries = 0): void => {\n wire.get(\n { \"#\": soul, \".\": item! },\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item!]\n\n if (!current && retries < 5) {\n await new Promise(r => setTimeout(r, 50))\n return attemptRead(retries + 1)\n }\n\n const id = utils.rel.is(current as GraphValue)\n if (!id) {\n if (!node) node = {} as never\n node[item!] = utils.rel.ify(utils.text.random())\n const g = await graph(soul, node as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n _ack(`error putting ${item} on ${soul}: ${err}`)\n } else {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: item!, soul: soul }]\n allctx.set(_ctxid, {\n chain: chain,\n user: ctx.user,\n cb: ctx.cb,\n })\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n const update: string[] = []\n for (const key of result as string[]) {\n const err = await new Promise<string | null | undefined>(res => {\n if (\n utils.obj.is((data as Record<string, unknown>)[key]) &&\n !utils.rel.is((data as Record<string, GraphValue>)[key])\n ) {\n const _ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: key, soul: id }]\n allctx.set(_ctxid, { chain: chain, user: ctx.user })\n api(_ctxid).put((data as Record<string, GraphValue>)[key]!, res as never)\n } else {\n update.push(key)\n res(null)\n }\n })\n if (err) {\n _ack(err)\n return\n }\n }\n\n if (update.length === 0) {\n _ack(null)\n return\n }\n\n // Only write the primitive update keys. Rels created by the\n // recursive puts above are already in the in-memory graph.\n const updateNode: Record<string, GraphValue> = {}\n update.forEach(key => {\n updateNode[key] = (data as Record<string, GraphValue>)[key]!\n })\n const g = await graph(id, updateNode as never, ctx.user, _ack as never)\n if (g === null) return\n\n wire.put(g, _ack as never)\n },\n { secure: (typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure, put: true }\n )\n }\n attemptRead()\n },\n\n on: function (\n lex: LexWithDot | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | boolean,\n _get?: boolean,\n _opt?: WireOptions\n ): void {\n let lexFilter: LexFilter | undefined\n let callback: (data: unknown) => void\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = _get as never\n _get = cb as never\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex as LexFilter\n callback = (typeof cb === \"function\" ? cb : undefined)!\n opts = _opt\n }\n\n if (typeof callback !== \"function\") {\n console.log(\"error on() requires a callback function\")\n return\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n callback(null)\n return\n }\n\n const resolved = resolve({ on: lexFilter, _get: _get, _opt: opts }, callback)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n const ctx = allctx.get(ctxid)\n\n allctx.set(ctxid, {\n chain: [{ item: item, soul: soul }],\n on: true,\n user: ctx ? ctx.user : null,\n })\n\n // Shared retry state for this on() subscription.\n let retryCount = 0\n const maxRetries = 5\n const retryDelay = 1000\n let retryTimer: ReturnType<typeof setTimeout> | null = null\n\n map.set(callback, () => {\n // Bail out if off() has already cleaned up this context \u2014 the mapped\n // callback can fire twice (once from wire.on and once from the _get\n // immediate-read path) and the second call after async context cleanup\n // would crash in resolve(). Matches the guard in watchForRel.\n if (!allctx.has(ctxid!)) return\n // Cancel any pending retry \u2014 the persistent listener firing means we\n // have an update and should not call callback twice.\n clearTimeout(retryTimer!)\n retryTimer = null\n wire.get(\n { \"#\": soul, \".\": item! },\n msg => {\n const node = msg.put && msg.put[soul]\n const current = node && node[item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) {\n const attemptRead = async (retries = 0): Promise<void> => {\n const data = await new Promise<unknown>(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {\n chain: [{ item: null, soul: id }],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null as never, res as never, (retries === 0 ? utils.obj.put(opts, \"fast\", true) : opts) as never)\n })\n if (data !== null || retries >= 5) {\n retryCount = 0\n callback(data)\n } else {\n await new Promise(resolve => setTimeout(resolve, 50))\n attemptRead(retries + 1)\n }\n }\n attemptRead()\n } else {\n const nodeExists = !!node\n if (nodeExists) {\n retryCount = 0\n callback(current !== undefined ? current : null)\n } else if (retryCount < maxRetries) {\n // No data yet \u2014 keep polling until we get a response or\n // exhaust retries. on() with _get can return null on a cache\n // miss and never fire again if the data doesn't change while\n // the listener is attached, so we must poll for initial load.\n const secureOpt = { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n const retry = (): void => {\n const delay = Math.min(retryDelay * Math.pow(2, retryCount), 30000)\n retryCount++\n retryTimer = setTimeout(() => {\n wire.get(\n { \"#\": soul, \".\": item! },\n retryMsg => {\n const retryNode = retryMsg.put && retryMsg.put[soul]\n if (retryNode) {\n retryCount = 0\n retryTimer = null\n const retryValue = retryNode[item!]\n callback(retryValue !== undefined ? retryValue : null)\n } else if (retryCount < maxRetries) {\n retry()\n } else {\n retryTimer = null\n callback(null)\n }\n },\n secureOpt,\n )\n }, delay)\n }\n retry()\n } else {\n callback(null)\n }\n }\n },\n { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n )\n })\n\n let initialLex: { \"#\": string; \".\"?: string | number } = lexFilter\n ? (utils.obj.put(lexFilter as never, \"#\", soul) as { \"#\": string; \".\"?: string | number })\n : { \"#\": soul, \".\": item! }\n if (initialLex[\".\"] != null && typeof initialLex[\".\"] === \"number\") {\n initialLex = { ...initialLex, \".\": String(initialLex[\".\"]) }\n }\n wire.on(initialLex as never, map.get(callback)!, false, opts)\n\n wire.get(\n { \"#\": soul, \".\": item! },\n msg => {\n if (msg.err) {\n console.log(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul]![item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) {\n wire.off(initialLex as never, map.get(callback)!)\n wire.on({ \"#\": id, \".\": null } as never, map.get(callback)!, false, opts)\n if (_get) map.get(callback)!()\n } else if (_get) {\n // Not a rel, but _get was requested, so trigger callback.\n map.get(callback)!()\n }\n },\n { ...opts, secure: ctx ? ((typeof ctx.user === \"boolean\" ? ctx.user : !!ctx.user) || options.secure) : options.secure }\n )\n },\n\n off: function (cb?: (data: unknown) => void): HolsterAPI | void {\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n const resolved = resolve({ off: true }, cb)\n if (!resolved) return\n\n const { item, soul } = resolved\n if (!soul) return\n\n wire.off({ \"#\": soul } as never, map.get(cb!)!)\n\n wire.get({ \"#\": soul, \".\": item! }, msg => {\n if (msg.err) {\n map.delete(cb!)\n allctx.delete(ctxid!)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul]![item!]\n const id = utils.rel.is(current as GraphValue)\n if (id) wire.off({ \"#\": id } as never, map.get(cb!)!)\n map.delete(cb!)\n allctx.delete(ctxid!)\n })\n },\n\n user: () => {\n if (!(user as { get?: unknown }).get) {\n Object.assign(user, api())\n ;(user as UserInterface & HolsterAPI).get = function (\n this: HolsterAPI,\n keys: string | string[],\n lex?: LexFilter | ((data: unknown) => void),\n cb?: ((data: unknown) => void) | WireOptions,\n _opt?: WireOptions\n ): HolsterAPI {\n let lexFilter: LexFilter | null | undefined\n let callback: ((data: unknown) => void) | undefined\n let opts: WireOptions | undefined\n\n if (typeof lex === \"function\") {\n opts = cb as WireOptions\n callback = lex\n lexFilter = null\n } else {\n lexFilter = lex\n callback = cb as (data: unknown) => void\n opts = _opt\n }\n\n let pub: string | null = null\n let key: string | null = null\n if (user.is) pub = user.is.pub\n if (typeof keys === \"string\") {\n key = keys\n } else if (keys instanceof Array) {\n if (keys.length === 2 && keys[0] && keys[1]) {\n pub = keys[0]\n key = keys[1]\n } else if (keys.length === 1 && keys[0]) {\n key = keys[0]\n }\n }\n if (!pub) {\n console.log(\"error please log in or provide a public key\")\n if (callback) callback(null)\n return this\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (callback) callback(null)\n return this\n }\n\n if (lexFilter && !callback) {\n console.log(\"error lex requires a callback function\")\n return this\n }\n\n ctxid = utils.text.random()\n const chain: ChainItem[] = [{ item: String(key), soul: \"~\" + pub }]\n allctx.set(ctxid, { chain: chain, user: user.is, cb: callback as never })\n if (!callback) return api(ctxid)\n\n const _done = done(ctxid)\n const resolved = resolve({ get: lexFilter, _opt: opts }, _done)\n if (resolved) get(lexFilter as never, resolved.soul!, _done, opts)\n return this\n } as never\n }\n return user as UserInterface & HolsterAPI\n },\n\n wire: wire,\n SEA: SEA,\n }\n }\n return api()\n}\n\nexport default Holster\n\n"],
|
|
5
|
+
"mappings": "AAWO,IAAMA,GAAM,CAIjB,GAAKC,GAA4B,CAC/B,GAAIA,aAAa,MAAO,MAAO,GAC/B,GAAI,OAAOA,GAAM,SAAU,MAAO,CAAC,MAAMA,CAAC,EAC1C,GAAI,OAAOA,GAAM,SAAU,CACzB,IAAMC,EAAS,WAAWD,CAAC,EAC3B,MAAO,CAAC,MAAMC,CAAM,GAAK,SAASA,CAAM,CAC1C,CACA,MAAO,EACT,CACF,EAQaC,EAAM,CAIjB,GAAKC,GAAiC,CACpC,GAAI,CAACA,GAAK,OAAOA,GAAM,SAAU,MAAO,GAExC,IAAMC,EADW,OAAO,UAAU,SAAS,KAAKD,CAAC,EAC1B,MAAM,oBAAoB,EACjD,OACGA,EAA8B,cAAgB,QAC9CC,IAAU,MAAQA,EAAM,CAAC,IAAM,QAEpC,EAKA,IAAK,CACHC,EACAC,EACAH,IACkB,CAClB,IAAMI,EAAO,OAAO,KAAKF,CAAI,EAC7B,QAASG,EAAI,EAAGA,EAAID,EAAK,OAAQC,IAAK,CACpC,IAAMC,EAAMF,EAAKC,CAAC,EACZE,EAASJ,EAAGD,EAAKI,CAAG,EAAIA,EAAKN,CAAC,EACpC,GAAI,OAAOO,EAAW,IAAa,OAAOA,CAC5C,CAEF,EAKA,IAAK,CAACP,EAAwCM,EAAaE,IAA4C,CACrG,IAAMC,EAAST,GAAK,CAAC,EACrB,OAAAS,EAAOH,CAAG,EAAIE,EACPC,CACT,EAKA,IAAK,CAAIT,EAAkCM,IAA+C,CACxF,GAAKN,EACL,OAAAA,EAAEM,CAAG,EAAI,KACT,OAAON,EAAEM,CAAG,EACLN,CACT,CACF,EAMMU,GAAW,CAACC,EAAeL,EAAaN,IAAoC,CAGhF,GAAIA,EAAE,GAAI,CACRA,EAAE,GAAK,GACP,MACF,CAEA,GAAIM,IAAQ,KAAO,OAAOK,GAAS,SAAU,CAC3CX,EAAE,GAAKW,EACP,MACF,CAIAX,EAAE,GAAK,EACT,EAEaY,EAAM,CAIjB,GAAKJ,GAAmC,CACtC,GACEA,GACA,OAAOA,GAAU,UACjB,MAAOA,GACP,EAAE,MAAOA,IACTT,EAAI,GAAGS,CAAK,EACZ,CACA,IAAMR,EAA4B,CAAE,GAAI,EAAG,EAE3C,GADAD,EAAI,IAAIS,EAAkCE,GAAgFV,CAAC,EACvHA,EAAE,GAAI,OAAOA,EAAE,EACrB,CACA,MAAO,EACT,EAKA,IAAMW,GAAyBZ,EAAI,IAAI,CAAC,EAAG,IAAKY,CAAI,CACtD,EAMaE,GAAgB,0BAChBC,EAAgB,2BAShBC,GAAQ,CACnBJ,EACAK,EACAC,EACAC,EACAC,IACU,CACV,IAAMC,EAAKD,GAAa,KAAK,IAAI,EAC3BE,EAAsC,CAAC,EACvCC,EAAkB,CACtB,EAAG,CAAE,IAAKX,EAAM,IAAKU,CAAY,CACnC,EAEA,OAAW,CAACf,EAAKE,CAAK,IAAK,OAAO,QAAQQ,CAAI,EACxCV,IAAQ,KAAOA,IAAQQ,GAAiBR,IAAQO,KAClDS,EAAKhB,CAAG,EAAIE,EACZa,EAAYf,CAAG,EAAIc,GAIvB,OAAIH,GAAOC,GAAOC,IACXG,EAAK,EAAE,IACVA,EAAK,EAAE,EAAO,CAAC,GAEjBA,EAAK,EAAE,EAAKH,EAAU,SAAS,CAAC,EAAIF,EACpCK,EAAKR,CAAa,EAAII,EACtBG,EAAYP,CAAa,EAAIK,GAGxB,CAAE,CAACR,CAAI,EAAGW,CAAK,CACxB,EASarB,GAAQ,CAACsB,EAAgBjB,IAA0B,CAE9D,GAAI,OAAOA,EAAQ,IAAa,OAAOiB,IAAQ,KAE/C,GAAI,OAAOA,EAAQ,IAAa,MAAO,GAEvC,GAAI,OAAOA,GAAQ,SAAU,OAAOA,IAAQjB,EAG5C,GAAI,MAAM,QAAQiB,CAAG,EAAG,OAAOA,EAAI,SAASjB,CAAG,EAE/C,GAAI,CAACP,EAAI,GAAGwB,CAAG,GAAK,CAACjB,EAAK,MAAO,GAGjC,GAAI,MAAOiB,EAAK,CACd,IAAMC,EAASD,EAAI,GAAG,EACtB,OAAOjB,EAAI,MAAM,EAAGkB,EAAO,MAAM,IAAMA,CACzC,CAGA,IAAMC,EAAK,MAAOF,EAAOA,EAAI,GAAG,EAAe,OACzCG,EAAK,MAAOH,EAAOA,EAAI,GAAG,EAAe,OAE/C,OAAIE,GAAMC,EAAWpB,GAAOmB,GAAMnB,GAAOoB,EACrCD,EAAWnB,GAAOmB,EAClBC,EAAWpB,GAAOoB,EAEf,EACT,EAMaC,EAAO,CAIlB,OAASC,GAA4B,CACnC,IAAIC,EAAI,GACFC,EAAI,iEACJC,EAAMH,GAAU,GACtB,QAASvB,EAAI,EAAGA,EAAI0B,EAAK1B,IACvBwB,GAAKC,EAAE,OAAO,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAE,MAAM,CAAC,EAEpD,OAAOD,CACT,CACF,EC/NA,IAAMG,GAAM,IAAoB,CAE9B,IAAMC,EAAoB,CACxB,MAAO,CAAC,EACR,OAAQ,KACR,MAAQC,GACCD,EAAI,MAAMC,CAAE,EAAID,EAAI,MAAMC,CAAE,EAAI,GAEzC,MAAQA,IAEND,EAAI,MAAMC,CAAE,EAAI,KAAK,IAAI,EACpBD,EAAI,SACPA,EAAI,OAAS,WAAW,IAAM,CAC5B,IAAME,EAAM,KAAK,IAAI,EACrB,OAAO,KAAKF,EAAI,KAAK,EAAE,QAAQC,GAAM,CAC/BC,EAAMF,EAAI,MAAMC,CAAE,EAAK,KACzB,OAAOD,EAAI,MAAMC,CAAE,CAEvB,CAAC,EACDD,EAAI,OAAS,IACf,EAAG,GAAM,EAELA,EAAI,OAAO,OAAOA,EAAI,OAAO,MAAM,GAElCC,EAEX,EACA,OAAOD,CACT,EAEOG,GAAQJ,GCtBf,IAAMK,GAAM,CAACC,EAAUC,EAAcC,IAAsC,CACzE,GAAI,CAACF,GAAO,OAAOA,GAAQ,SACzB,MAAM,IAAI,UAAU,uBAAuB,EAE7C,GAAI,CAACC,GAAS,OAAOA,GAAU,SAC7B,MAAM,IAAI,UAAU,yBAAyB,EAG/C,IAAME,EAAOH,EAAI,GAAG,EACpB,GAAI,CAACG,GAAQ,OAAOA,GAAS,SAC3B,MAAM,IAAI,UAAU,uBAAuB,EAG7C,GAAI,CAACF,EAAME,CAAI,EAAG,OAGlB,IAAMC,EAAkB,CAAE,EAAG,CAAE,IAAKD,EAAM,IADE,CAAC,CACc,CAAE,EACvDE,EAAqC,CAAC,EAE5C,GAAI,OAAOL,EAAI,GAAG,GAAM,SAAU,CAChC,IAAMM,EAAMN,EAAI,GAAG,EACnB,GAAI,OAAOC,EAAME,CAAI,EAAGG,CAAG,EAAM,IAAa,OAE9CF,EAAKE,CAAG,EAAIL,EAAME,CAAI,EAAGG,CAAG,EAC5BF,EAAK,EAAE,GAAG,EAAEE,CAAG,EAAIL,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEG,CAAG,EAC1C,IAAMC,EAAQN,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEG,CAAG,EAC/BE,EAAOP,EAAME,CAAI,EAAG,EAAE,EAM5B,GALIK,GAAQA,EAAKD,CAAK,IACpBF,EAAWE,EAAM,SAAS,CAAC,EAAIC,EAAKD,CAAK,GAIvCE,GAAiB,OAAOR,EAAME,CAAI,EAAGM,CAAa,EAAM,IAAa,CACvEL,EAAKK,CAAa,EAAIR,EAAME,CAAI,EAAGM,CAAa,EAChDL,EAAK,EAAE,GAAG,EAAEK,CAAa,EAAIR,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEM,CAAa,EAC9D,IAAMC,EAAUT,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEM,CAAa,EAC3CE,EAASV,EAAME,CAAI,EAAG,EAAE,EAC1BQ,GAAUA,EAAOD,CAAO,IAC1BL,EAAWK,EAAQ,SAAS,CAAC,EAAIC,EAAOD,CAAO,EAEnD,CACF,KAAO,CAGL,GAAI,CAACR,EAAM,OAEX,QAAWI,KAAO,OAAO,KAAKL,EAAME,CAAI,CAAE,EAExC,GAAIG,IAAQG,GAAiBG,GAAMZ,EAAI,GAAG,EAAGM,CAAG,EAAG,CACjDF,EAAKE,CAAG,EAAIL,EAAME,CAAI,EAAGG,CAAG,EAC5BF,EAAK,EAAE,GAAG,EAAEE,CAAG,EAAIL,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEG,CAAG,EAC1C,IAAMC,EAAQN,EAAME,CAAI,EAAG,EAAE,GAAG,EAAEG,CAAG,EAC/BE,EAAOP,EAAME,CAAI,EAAG,EAAE,EACxBK,GAAQA,EAAKD,CAAK,IACpBF,EAAWE,EAAM,SAAS,CAAC,EAAIC,EAAKD,CAAK,EAE7C,CAEJ,CAEA,OAAI,OAAO,KAAKF,CAAU,EAAE,OAAS,IACnCD,EAAK,EAAE,EAAOC,GAET,CAAE,CAACF,CAAI,EAAGC,CAAK,CACxB,EAEOS,GAAQd,GC5EX,OAAO,KAAS,MAClB,WAAW,KAAQe,GACjB,OAAO,KAAKA,EAAM,QAAQ,EAAE,SAAS,QAAQ,EAC/C,WAAW,KAAQA,GACjB,OAAO,KAAKA,EAAM,QAAQ,EAAE,SAAS,QAAQ,GAQjD,IAAMC,GAAN,MAAMC,UAAiB,KAAc,CAO1B,SAASC,EAAgBC,EAAgBC,EAAsB,CACtE,IAAMC,EAAWH,GAAO,OAClBI,EAAWH,GAAS,EACpBI,EAASH,EAAM,KAAK,IAAI,KAAK,IAAIA,EAAKE,CAAQ,EAAG,KAAK,MAAM,EAAI,KAAK,OAE3E,GAAID,IAAa,MAAO,CACtB,IAAMG,EAAM,IAAI,WAAW,KAAK,MAAMF,EAAUC,CAAM,CAAC,EACvD,OAAO,MAAM,KAAKC,EAAKC,GAAQA,EAAK,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAC5E,CAEA,GAAIJ,IAAa,OACf,OAAO,MAAM,KAAK,CAAE,OAAQE,EAASD,CAAS,EAAG,CAACI,EAAGC,IAAM,CACzD,IAAMC,EAAW,KAAKD,EAAIL,CAAQ,EAElC,OACEM,IAAa,QACbA,EAAW,GACXA,EAAW,QAEJ,SAEF,OAAO,aAAaA,CAAQ,CACrC,CAAC,EAAE,KAAK,EAAE,EAGZ,GAAIP,IAAa,SAAU,CACzB,IAAMQ,EAAa,MAAM,KAAK,CAAE,OAAQN,EAASD,CAAS,EAAG,CAACI,EAAGC,IAAM,CACrE,IAAMC,EAAW,KAAKD,EAAIL,CAAQ,EAClC,OAAIM,IAAa,QAAaA,EAAW,GAAKA,EAAW,IAChD,SAEF,OAAO,aAAaA,CAAQ,CACrC,CAAC,EAAE,KAAK,EAAE,EACV,OAAO,KAAKC,CAAU,CACxB,CAGA,OAAO,KAAK,SAAS,OAAQP,EAAUC,CAAM,CAC/C,CAKA,OAAgB,KACdO,EACU,CACV,IAAMC,EAAM,MAAM,KAAKD,CAAS,EAEhC,OADiB,IAAIb,EAAS,GAAGc,CAAG,CAEtC,CACF,EAEOC,GAAQhB,GClEf,IAAMiB,GAAkB,CACtB,gBAAiB,GAAK,KAAO,KAC7B,kBAAmB,KAAO,IAC5B,EAkBMC,GAAa,YAAuBC,EAA6B,CACrE,eAAQ,KAAK,8DAA8D,EAEpEC,GAAS,KAAK,CAAC,CAAC,CACzB,EAEAF,GAAW,UAAY,OAAO,OAAO,MAAM,SAAS,EAMpD,IAAMG,GAAsB,CAACC,EAAeC,IAA8B,CACxE,GAAID,EAAM,OAASL,GAAgB,kBACjC,MAAM,IAAI,WACR,qBAAqBK,EAAM,MAAM,MAAML,GAAgB,iBAAiB,EAC1E,CAEJ,EAEMO,GAAqB,CAACC,EAAcC,EAAY,qBAA6B,CACjF,GAAID,EAAOR,GAAgB,gBACzB,MAAM,IAAI,WACR,6BAA6BS,CAAS,KAAKD,CAAI,MAAMR,GAAgB,eAAe,EACtF,CAEJ,EAMMU,GAAkBC,GAAkC,CACxDP,GAAoBO,EAAW,KAAK,EAEpC,IAAMC,EAAWD,EAAU,QAAQ,MAAO,EAAE,EAAE,YAAY,EAE1D,GAAI,CAAC,cAAc,KAAKC,CAAQ,EAC9B,MAAM,IAAI,UAAU,iDAAiD,EAGvE,GAAIA,EAAS,OAAS,IAAM,EAC1B,MAAM,IAAI,UAAU,2CAA2C,EAGjE,GAAIA,EAAS,SAAW,EACtB,OAAO,IAAI,WAAW,CAAC,EAGzBL,GAAmBK,EAAS,OAAS,EAAG,aAAa,EAErD,IAAMC,EAAQ,IAAI,WAAWD,EAAS,OAAS,CAAC,EAChD,QAASE,EAAI,EAAGA,EAAIF,EAAS,OAAQE,GAAK,EAAG,CAC3C,IAAMC,EAAUH,EAAS,OAAOE,EAAG,CAAC,EACpCD,EAAMC,EAAI,CAAC,EAAI,SAASC,EAAS,EAAE,CACrC,CACA,OAAOF,CACT,EAEMG,GAAoBC,GAA4B,CACpDb,GAAoBa,EAAK,MAAM,EAE/B,GAAI,CAEF,IAAMJ,EADU,IAAI,YAAY,EACV,OAAOI,CAAG,EAChC,OAAAV,GAAmBM,EAAM,OAAQ,gBAAgB,EAC1CA,CACT,OAASK,EAAK,CACZ,MAAM,IAAI,UAAU,kCAAmCA,EAAc,OAAO,EAAE,CAChF,CACF,EAEMC,GAAsBF,GAA4B,CACtDb,GAAoBa,EAAK,QAAQ,EACjCV,GAAmBU,EAAI,OAAQ,iBAAiB,EAEhD,IAAMJ,EAAQ,IAAI,WAAWI,EAAI,MAAM,EACvC,QAASH,EAAI,EAAGA,EAAIG,EAAI,OAAQH,IAAK,CACnC,IAAMM,EAAWH,EAAI,WAAWH,CAAC,EACjC,GAAIM,EAAW,IACb,MAAM,IAAI,UACR,gDAAgDN,CAAC,wBAAwBM,CAAQ,SACnF,EAEFP,EAAMC,CAAC,EAAIM,CACb,CACA,OAAOP,CACT,EAEMQ,GAAqBC,GAAqC,CAC9DlB,GAAoBkB,EAAc,QAAQ,EAE1C,IAAMC,EAAcD,EAAa,QAAQ,MAAO,EAAE,EAElD,GAAI,CAAC,yBAAyB,KAAKC,CAAW,EAC5C,MAAM,IAAI,UAAU,oDAAoD,EAG1E,GAAI,CACF,IAAMC,EAAgB,KAAKD,CAAW,EACtChB,GAAmBiB,EAAc,OAAQ,iBAAiB,EAE1D,IAAMX,EAAQ,IAAI,WAAWW,EAAc,MAAM,EACjD,QAASV,EAAI,EAAGA,EAAIU,EAAc,OAAQV,IACxCD,EAAMC,CAAC,EAAIU,EAAc,WAAWV,CAAC,EAEvC,OAAOD,CACT,OAASK,EAAK,CACZ,MAAM,IAAI,UAAU,mCAAoCA,EAAc,OAAO,EAAE,CACjF,CACF,EAEMO,GAAyBpB,GAA+B,CAC5D,GAAIA,aAAiB,YACnB,OAAAE,GAAmBF,EAAM,WAAY,wBAAwB,EACtD,IAAI,WAAWA,CAAK,EAG7B,GAAI,YAAY,OAAOA,CAAK,EAC1B,OAAAE,GAAmBF,EAAM,WAAY,uBAAuB,EACrD,IAAI,WAAWA,EAAM,OAAQA,EAAM,WAAYA,EAAM,UAAU,EAGxE,GAAI,MAAM,QAAQA,CAAK,EAAG,CACxBE,GAAmBF,EAAM,OAAQ,kBAAkB,EAEnD,QAASS,EAAI,EAAGA,EAAIT,EAAM,OAAQS,IAAK,CACrC,IAAMY,EAAMrB,EAAMS,CAAC,EACnB,GACE,OAAOY,GAAQ,UACfA,EAAM,GACNA,EAAM,KACN,CAAC,OAAO,UAAUA,CAAG,EAErB,MAAM,IAAI,UACR,+BAA+BZ,CAAC,KAAKY,CAAG,0BAC1C,CAEJ,CACA,OAAO,IAAI,WAAWrB,CAAK,CAC7B,CAEA,GACE,OAAOA,GAAU,UACjBA,IAAU,MACV,eAAgBA,GAChB,OAAQA,EAAkC,YAAe,SAEzD,OAAAE,GAAoBF,EAAiC,WAAY,6BAA6B,EACvF,IAAI,WAAWA,CAAoB,EAG5C,GACE,OAAOA,GAAU,UACjBA,IAAU,MACV,WAAYA,GACZ,OAAQA,EAA8B,QAAW,SACjD,CACA,IAAMsB,EAAYtB,EAClBE,GAAmBoB,EAAU,OAAQ,uBAAuB,EAE5D,IAAMC,EAAM,MAAM,KAAKD,CAAS,EAChC,QAASb,EAAI,EAAGA,EAAIc,EAAI,OAAQd,IAAK,CACnC,IAAMY,EAAME,EAAId,CAAC,EACjB,GACE,OAAOY,GAAQ,UACfA,EAAM,GACNA,EAAM,KACN,CAAC,OAAO,UAAUA,CAAG,EAErB,MAAM,IAAI,UACR,+BAA+BZ,CAAC,KAAKY,CAAG,0BAC1C,CAEJ,CACA,OAAO,IAAI,WAAWE,CAAe,CACvC,CAEA,MAAM,IAAI,UAAU,2BAA6B,OAAOvB,CAAK,CAC/D,EAMA,OAAO,OAAOJ,GAAY,CACxB,QAAQ4B,EAA2B,CAGjC,GAFiBA,EAAK,SAEL,EACf,MAAM,IAAI,UAAU,kDAAkD,EAGxE,IAAMxB,EAAQwB,EAAK,CAAC,EAEpB,GAAIxB,GAAU,KACZ,MAAM,IAAI,UAAU,8CAA8C,EAGpE,IAAIQ,EAEJ,GAAI,OAAOR,GAAU,SAAU,CAC7B,IAAMyB,GAAaD,EAAK,CAAC,GAAgB,QAAQ,YAAY,EAE7D,OAAQC,EAAU,CAChB,IAAK,MACHjB,EAAQH,GAAeL,CAAK,EAC5B,MAEF,IAAK,OACL,IAAK,QACHQ,EAAQG,GAAiBX,CAAK,EAC9B,MAEF,IAAK,SACL,IAAK,SACHQ,EAAQM,GAAmBd,CAAK,EAChC,MAEF,IAAK,SACHQ,EAAQQ,GAAkBhB,CAAK,EAC/B,MAEF,IAAK,QACHD,GAAoBC,EAAO,OAAO,EAClC,QAAS,EAAI,EAAG,EAAIA,EAAM,OAAQ,IAChC,GAAIA,EAAM,WAAW,CAAC,EAAI,IACxB,MAAM,IAAI,UACR,uCAAuC,CAAC,KAAKA,EAAM,WAAW,CAAC,CAAC,QAClE,EAGJQ,EAAQG,GAAiBX,CAAK,EAC9B,MAEF,QACE,MAAM,IAAI,UAAU,qBAAuByB,CAAQ,CACvD,CACF,MACEjB,EAAQY,GAAsBpB,CAAK,EAGrC,GAAI,CAACQ,GAASA,EAAM,SAAW,EAC7B,OAAOV,GAAS,KAAK,IAAI,WAAW,CAAC,CAAC,EAGxC,GAAI,CACF,OAAOA,GAAS,KAAKU,CAAK,CAC5B,OAASK,EAAK,CACZ,MAAM,IAAI,MAAM,gCAAiCA,EAAc,OAAO,EAAE,CAC1E,CACF,EAEA,MAAMa,EAAgBC,EAAwB,EAAa,CACzD,GAAI,OAAOD,GAAW,UAAY,CAAC,OAAO,UAAUA,CAAM,GAAKA,EAAS,EACtE,MAAM,IAAI,UAAU,uCAAuC,EAG7DxB,GAAmBwB,EAAQ,mBAAmB,EAE9C,IAAIE,EACJ,GAAI,OAAOD,GAAS,SAAU,CAC5B,GAAIA,EAAO,GAAKA,EAAO,KAAO,CAAC,OAAO,UAAUA,CAAI,EAClD,MAAM,IAAI,UAAU,iDAAiD,EAEvEC,EAAYD,CACd,SAAW,OAAOA,GAAS,SAAU,CACnC,GAAIA,EAAK,SAAW,EAClB,MAAM,IAAI,UAAU,2CAA2C,EAGjE,GADAC,EAAYD,EAAK,WAAW,CAAC,EACzBC,EAAY,IACd,MAAM,IAAI,UAAU,oCAAoC,CAE5D,KACE,OAAM,IAAI,UAAU,kDAAkD,EAGxE,GAAI,CACF,IAAMC,EAAS,IAAI,WAAWH,CAAM,EACpC,OAAIE,IAAc,GAChBC,EAAO,KAAKD,CAAS,EAEhB9B,GAAS,KAAK+B,CAAM,CAC7B,OAAShB,EAAK,CACZ,MAAM,IAAI,MAAM,8BAA+BA,EAAc,OAAO,EAAE,CACxE,CACF,EAEA,OAAOU,EAAqC,CAC1C,GAAI,CAAC,MAAM,QAAQA,CAAG,EACpB,MAAM,IAAI,UAAU,iCAAiC,EAGvD,GAAIA,EAAI,SAAW,EACjB,OAAOzB,GAAS,KAAK,IAAI,WAAW,CAAC,CAAC,EAGxC,IAAIgC,EAAc,EACZC,EAAiC,CAAC,EAExC,QAAStB,EAAI,EAAGA,EAAIc,EAAI,OAAQd,IAAK,CACnC,IAAMuB,EAAOT,EAAId,CAAC,EAElB,GAAI,CAACuB,EACH,MAAM,IAAI,UAAU,0BAA0BvB,CAAC,uBAAuB,EAGxE,IAAID,EACJ,GAAI,CACFA,EAAQY,GAAsBY,CAAI,CACpC,OAASnB,EAAK,CACZ,MAAM,IAAI,UACR,kCAAkCJ,CAAC,KAAMI,EAAc,OAAO,EAChE,CACF,CAEAiB,GAAetB,EAAM,OACrBN,GAAmB4B,EAAa,sBAAsB,EACtDC,EAAiB,KAAKvB,CAAK,CAC7B,CAEA,GAAI,CACF,IAAMyB,EAAS,IAAI,WAAWH,CAAW,EACrCI,EAAS,EAEb,QAAWL,KAAUE,EACnBE,EAAO,IAAIJ,EAAQK,CAAM,EACzBA,GAAUL,EAAO,OAGnB,OAAO/B,GAAS,KAAKmC,CAAM,CAC7B,OAASpB,EAAK,CACZ,MAAM,IAAI,MAAM,kCAAmCA,EAAc,OAAO,EAAE,CAC5E,CACF,EAEA,SAASsB,EAA+B,CACtC,OACEA,aAAerC,IACdqC,IAAQ,MACP,OAAOA,GAAQ,UACdA,EAAkC,cAAgBvC,EAEzD,EAEA,WAAWwC,EAAgBX,EAAqB,OAAgB,CAC9D,GAAI,OAAOW,GAAW,SACpB,MAAM,IAAI,UAAU,iCAAiC,EAGvD,OAAQX,EAAS,YAAY,EAAG,CAC9B,IAAK,OACL,IAAK,QACH,OAAO,IAAI,YAAY,EAAE,OAAOW,CAAM,EAAE,OAE1C,IAAK,QACL,IAAK,SACL,IAAK,SACH,OAAOA,EAAO,OAEhB,IAAK,SAAU,CACb,IAAMC,EAAQD,EAAO,QAAQ,MAAO,EAAE,EACtC,OACE,KAAK,MAAOC,EAAM,OAAS,EAAK,CAAC,GAAKA,EAAM,MAAM,IAAI,GAAK,CAAC,GAAG,MAEnE,CAEA,IAAK,MACH,OAAO,KAAK,MAAMD,EAAO,QAAQ,MAAO,EAAE,EAAE,OAAS,CAAC,EAExD,QACE,MAAM,IAAI,UAAU,qBAAuBX,CAAQ,CACvD,CACF,CACF,CAAC,EAGD7B,GAAW,UAAU,SAAW,SAE9B6B,EAAqB,OACrBa,EAAQ,EACRC,EAAM,KAAK,OACH,CACR,GAAI,OAAOd,GAAa,SACtB,MAAM,IAAI,UAAU,2BAA2B,EAGjD,GAAI,OAAOa,GAAU,UAAY,CAAC,OAAO,UAAUA,CAAK,GAAKA,EAAQ,EACnE,MAAM,IAAI,UAAU,sCAAsC,EAG5D,GAAI,OAAOC,GAAQ,UAAY,CAAC,OAAO,UAAUA,CAAG,GAAKA,EAAMD,EAC7D,MAAM,IAAI,UAAU,iCAAiC,EAGvD,GAAI,CACF,OAAOxC,GAAS,UAAU,SAAS,KACjC,KACA2B,EACAa,EACAC,CACF,CACF,OAAS1B,EAAK,CACZ,MAAM,IAAI,MAAM,uCAAwCA,EAAc,OAAO,EAAE,CACjF,CACF,EAEA,IAAO2B,GAAQ5C,GC/af,IAAM6C,GAAS,OAAO,QAAY,KAAe,QAAQ,UAAU,MAAQ,KAGrEC,GAAiBD,IACjB,KAAM,QAA+B,aAAa,GAAG,UACvD,WAAW,OAEFE,EAASD,GAAO,OAKhBE,GAAaC,GACjB,OAAOA,GAAS,SAAWA,EAAO,KAAK,UAAUA,CAAI,EAMjDC,GAASC,GAA0B,CAC9C,GAAI,CACF,OAAO,KAAK,MAAMA,CAAI,CACxB,MAAQ,CACN,OAAOA,CACT,CACF,EAKaC,GAAUC,GAA6B,CAClD,IAAMC,EAAQ,IAAI,WAAWD,CAAM,EAC7BE,EAAST,GAAO,gBAAgBQ,CAAK,EAC3C,OAAOE,GAAW,KAAKD,CAAM,CAC/B,EAKaE,GAAM,CAACC,EAAaC,IAAuB,CACtD,GAAM,CAACC,EAAGC,CAAC,EAAIH,EAAI,MAAM,GAAG,EAE5B,MAAO,CACL,IAAK,KACL,IAAK,QACL,EAAGE,EACH,EAAGC,EACH,EAAGF,EACH,IAAK,GACL,QARUA,EAAO,CAAC,MAAM,EAAI,CAAC,QAAQ,CASvC,CACF,EAKaG,GAAS,MAAOb,GAAqC,CAChE,IAAMc,EAAO,MAAMhB,EAAO,OACxB,CAAE,KAAM,SAAU,EAClB,IAAI,YAAY,EAAE,OAAOC,GAAUC,CAAI,CAAC,CAC1C,EACA,OAAOO,GAAW,KAAK,IAAI,WAAWO,CAAI,CAAC,CAC7C,EAKaC,GAAS,MACpBC,EACAC,IACG,CACH,IAAMC,EAAWF,EAAMC,EAAK,SAAS,MAAM,EACrCE,EAAa,MAAMN,GAAOK,CAAQ,EAClCE,EAASC,GAASF,CAAU,EAClC,OAAO,MAAMrB,EAAO,UAAU,MAAOsB,EAAQ,CAAE,KAAM,SAAU,EAAG,GAAO,CACvE,UACA,SACF,CAAC,CACH,EAKMC,GAAYL,IAMT,CAAE,IAAK,MAAO,EALXA,EACP,SAAS,QAAQ,EACjB,QAAQ,MAAO,GAAG,EAClB,QAAQ,MAAO,GAAG,EAClB,QAAQ,KAAM,EAAE,EACQ,IAAK,GAAO,IAAK,SAAU,GC9ExD,IAAMM,GAAM,CAIV,KAAM,MAAOC,GAA+C,CAE1D,IAAMC,EAAQ,MAAYC,EACvB,YAAY,CAAE,KAAM,QAAS,WAAY,OAAQ,EAAG,GAAM,CACzD,OACA,QACF,CAAC,EACA,KAAK,MAAMC,GAAQ,CAClB,IAAMC,EAAM,MAAYF,EAAO,UAAU,MAAOC,EAAK,SAAS,EAC9D,MAAO,CACL,MAAO,MAAYD,EAAO,UAAU,MAAOC,EAAK,UAAU,GAAG,EAC7D,IAAKC,EAAI,EAAK,IAAMA,EAAI,CAC1B,CACF,CAAC,EAGGC,EAAO,MAAYH,EACtB,YAAY,CAAE,KAAM,OAAQ,WAAY,OAAQ,EAAG,GAAM,CAAC,WAAW,CAAC,EACtE,KAAK,MAAMC,GAAQ,CAClB,IAAMC,EAAM,MAAYF,EAAO,UAAU,MAAOC,EAAK,SAAS,EAC9D,MAAO,CACL,OAAQ,MAAYD,EAAO,UAAU,MAAOC,EAAK,UAAU,GAAG,EAC9D,KAAMC,EAAI,EAAK,IAAMA,EAAI,CAC3B,CACF,CAAC,EAEGE,EAAiB,CACrB,IAAKL,EAAM,IACX,KAAMA,EAAM,KACZ,KAAMI,EAAK,KACX,MAAOA,EAAK,KACd,EACA,OAAIL,GAAIA,EAAGM,CAAI,EACRA,CACT,EAKA,QAAS,MACPC,EACAD,EACAN,IACkC,CAClC,GAAI,CAACM,GAAQ,CAACA,EAAK,MACjB,OAAIN,GAAIA,EAAG,IAAI,EACR,KAGT,IAAMQ,EAAO,CAAE,EAASC,GAAO,CAAC,EAAG,GAAUA,GAAO,EAAE,CAAE,EAClDC,EAAK,MAAYC,GAAOL,EAAK,MAAOE,EAAK,CAAC,EAAE,KAAKI,GACxCV,EAAO,QAClB,CACE,KAAM,UACN,GAAI,IAAI,WAAWM,EAAK,EAAE,CAC5B,EACAI,EACA,IAAI,YAAY,EAAE,OAAaC,GAAUN,CAAI,CAAC,CAChD,CACD,EACKO,EAAqB,CACzB,GAAIC,GAAW,KAAKL,EAAI,QAAQ,EAAE,SAAS,QAAQ,EACnD,GAAIF,EAAK,GAAG,SAAS,QAAQ,EAC7B,EAAGA,EAAK,EAAE,SAAS,QAAQ,CAC7B,EACA,OAAIR,GAAIA,EAAGc,CAAG,EACPA,CACT,EAKA,QAAS,MACPA,EACAR,EACAN,IAC4B,CAC5B,GAAI,CAACc,GAAO,CAACA,EAAI,IAAM,CAACA,EAAI,IAAM,CAACA,EAAI,GAAK,CAACR,GAAQ,CAACA,EAAK,MACzD,OAAIN,GAAIA,EAAG,IAAI,EACR,KAGT,IAAMO,EAAO,CACX,GAAIQ,GAAW,KAAKD,EAAI,GAAI,QAAQ,EACpC,GAAIC,GAAW,KAAKD,EAAI,GAAI,QAAQ,EACpC,EAAGC,GAAW,KAAKD,EAAI,EAAG,QAAQ,CACpC,EACA,GAAI,CACF,IAAMJ,EAAK,MAAYC,GAAOL,EAAK,MAAOC,EAAK,CAAC,EAAE,KAAKK,GACxCV,EAAO,QAClB,CACE,KAAM,UACN,GAAI,IAAI,WAAWK,EAAK,EAAE,EAC1B,UAAW,GACb,EACAK,EACA,IAAI,WAAWL,EAAK,EAAE,CACxB,CACD,EACKS,EAAYC,GAAM,IAAI,YAAY,MAAM,EAAE,OAAOP,CAAE,CAAC,EAC1D,OAAIV,GAAIA,EAAGgB,CAAG,EACPA,CACT,MAAc,CAEZ,OAAIhB,GAAIA,EAAG,IAAI,EACR,IACT,CACF,EAKA,OAAQ,MACNO,EACAD,EACAN,IAC4B,CAC5B,GAAI,CAACM,GAAQ,CAACA,EAAK,IACjB,OAAIN,GAAIA,EAAG,IAAI,EACR,KAGT,IAAMkB,EACJ,OAAOX,GAAS,SAAiBU,GAAMV,CAAI,EAAIA,EAE3CY,EAAM,MAAYjB,EAAO,UAC7B,MACMkB,GAAId,EAAK,GAAG,EAClB,CAAE,KAAM,QAAS,WAAY,OAAQ,EACrC,GACA,CAAC,QAAQ,CACX,EAEIe,EAAwC,CAAC,EAC7C,GAAI,OAAOH,EAAO,GAAM,SACtBG,EAAMH,EAAO,MAIb,SAAWI,KAAK,OAAO,KAAKJ,EAAO,CAAC,EAAE,KAAK,EACrCI,IAAM,KAAOA,IAAMC,GAAiBD,IAAME,KAC3CH,EAAgCC,CAAC,EAAIJ,EAAO,EAAEI,CAAC,GAItD,IAAMG,EAAO,MAAYC,GAAOL,CAAG,EAC7BM,EAAM,IAAI,WAAWZ,GAAW,KAAKG,EAAO,EAAG,QAAQ,CAAC,EACxDU,EAAM,CAAE,KAAM,QAAS,KAAM,CAAE,KAAM,SAAU,CAAE,EACvD,GAAI,MAAY1B,EAAO,OAAO0B,EAAKT,EAAKQ,EAAK,IAAI,WAAWF,CAAI,CAAC,EAAG,CAClE,IAAMI,EAAiBZ,GAAMC,EAAO,CAAW,EAC/C,OAAIlB,GAAIA,EAAG6B,CAAQ,EACZA,CACT,CAEA,OAAI7B,GAAIA,EAAG,IAAI,EACR,IACT,EAKA,KAAM,MACJO,EACAD,EACAN,IAC+B,CAC/B,GAAI,CAACM,GAAQ,CAACA,EAAK,KAAO,CAACA,EAAK,KAC9B,OAAIN,GAAIA,EAAG,IAAI,EACR,KAGT,IAAIqB,EAAwC,CAAC,EAC7C,GAAI,OAAOd,GAAS,SAClBc,EAAMd,MACD,CACL,IAAMuB,EAAcb,GAAMV,CAAa,EACvC,QAAWe,KAAK,OAAO,KAAKQ,CAAK,EAAE,KAAK,EAClCR,IAAM,KAAOA,IAAMC,GAAiBD,IAAME,KAC3CH,EAAgCC,CAAC,EAAIQ,EAAMR,CAAC,EAGnD,CACA,IAAMG,EAAO,MAAYC,GAAOL,CAAG,EAC7BD,EAAYA,GAAId,EAAK,IAAKA,EAAK,IAAI,EACnCsB,EAAM,CAAE,KAAM,QAAS,WAAY,OAAQ,EAC3CD,EAAM,MAAYzB,EACrB,UAAU,MAAOkB,EAAKQ,EAAK,GAAO,CAAC,MAAM,CAAC,EAC1C,KAAKT,GACEjB,EAAO,KACX,CAAE,KAAM,QAAS,KAAM,CAAE,KAAM,SAAU,CAAE,EAC3CiB,EACA,IAAI,WAAWM,CAAI,CACrB,CACF,EACIP,EAAqB,CACzB,EAAGG,EACH,EAAGN,GAAW,KAAKY,EAAK,QAAQ,EAAE,SAAS,QAAQ,CACrD,EAEA,OAAI3B,GAAIA,EAAGkB,CAAM,EACVA,CACT,EAKA,cAAe,MACba,EACAzB,EACAN,IAC2B,CAC3B,GAAI,CAACM,GAAQ,CAACA,EAAK,KAAO,CAACA,EAAK,KAC9B,OAAIN,GAAIA,EAAG,IAAI,EACR,KAIT,IAAMgC,EAAeD,EAAU,SAAS,EAClCN,EAAO,MAAYC,GAAOM,CAAY,EACtCZ,EAAYA,GAAId,EAAK,IAAKA,EAAK,IAAI,EACnCsB,EAAM,CAAE,KAAM,QAAS,WAAY,OAAQ,EAE3CD,EAAM,MAAYzB,EACrB,UAAU,MAAOkB,EAAKQ,EAAK,GAAO,CAAC,MAAM,CAAC,EAC1C,KAAKT,GACEjB,EAAO,KACX,CAAE,KAAM,QAAS,KAAM,CAAE,KAAM,SAAU,CAAE,EAC3CiB,EACA,IAAI,WAAWM,CAAI,CACrB,CACF,EAEIQ,EAAYlB,GAAW,KAAKY,EAAK,QAAQ,EAAE,SAAS,QAAQ,EAElE,OAAI3B,GAAIA,EAAGiC,CAAS,EACbA,CACT,EAKA,gBAAiB,MACfF,EACAE,EACAC,EACAlC,IACqB,CACrB,GAAI,CAACkC,GAAa,CAACH,GAAa,CAACE,EAC/B,OAAIjC,GAAIA,EAAG,EAAK,EACT,GAGT,GAAI,CAEF,IAAMgC,EAAeD,EAAU,SAAS,EAClCN,EAAO,MAAYC,GAAOM,CAAY,EAEtCb,EAAM,MAAYjB,EAAO,UAC7B,MACMkB,GAAIc,CAAS,EACnB,CAAE,KAAM,QAAS,WAAY,OAAQ,EACrC,GACA,CAAC,QAAQ,CACX,EAEMP,EAAM,IAAI,WAAWZ,GAAW,KAAKkB,EAAW,QAAQ,CAAC,EACzDL,EAAM,CAAE,KAAM,QAAS,KAAM,CAAE,KAAM,SAAU,CAAE,EAEjDO,EAAU,MAAYjC,EAAO,OACjC0B,EACAT,EACAQ,EACA,IAAI,WAAWF,CAAI,CACrB,EAEA,OAAIzB,GAAIA,EAAGmC,CAAO,EACXA,CACT,OAASC,EAAK,CACZ,eAAQ,IAAI,wCAAyCA,EAAc,OAAO,EAAE,EACxEpC,GAAIA,EAAG,EAAK,EACT,EACT,CACF,EAKA,KAAM,MACJO,EACA8B,EACArC,IAC+B,CAC/B,IAAIsC,EAAMtC,EACNuC,EAAQF,EAER,OAAOA,GAAS,aAClBC,EAAMD,EACNE,EAAQ,QAEN,OAAOA,EAAU,MAAaA,EAAc9B,GAAO,CAAC,GAExD,IAAMU,EAAM,MAAYjB,EAAO,UAC7B,MACA,IAAI,YAAY,EAAE,OAAaW,GAAUN,CAAI,CAAC,EAC9C,CAAE,KAAM,QAAS,EACjB,GACA,CAAC,YAAY,CACf,EACMqB,EAAM,CACV,KAAM,SACN,WAAY,IACZ,KAAM,IAAI,YAAY,EAAE,OAAOW,CAAe,EAC9C,KAAM,CAAE,KAAM,SAAU,CAC1B,EACMC,EAAO,MAAYtC,EAAO,WAAW0B,EAAKT,EAAK,GAAG,EAElDb,EAAO,CAAE,MAAOS,GAAW,KAAKyB,EAAM,QAAQ,EAAE,SAAS,QAAQ,CAAE,EACzE,OAAIF,GAAKA,EAAIhC,CAAI,EACVA,CACT,EAKA,OAAQ,MACNmC,EACAC,EACA1C,IACsC,CACtC,GAAI,CAACyC,GAAM,CAACA,EAAG,MAAQ,CAACC,GAAQ,CAACA,EAAK,MAAQ,CAACA,EAAK,MAClD,OAAI1C,GAAIA,EAAG,IAAI,EACR,KAGT,IAAM4B,EAAM,CAAE,KAAM,OAAQ,WAAY,OAAQ,EAC1CxB,EAAYgB,GAAIqB,EAAG,IAAI,EACvBE,EAAS,MAAYzC,EAAO,UAAU,MAAOE,EAAKwB,EAAK,GAAM,CAAC,CAAC,EAC/DgB,EAAaxB,GAAIsB,EAAK,KAAMA,EAAK,KAAK,EAE5C,OAAQE,EAA+B,QACvC,IAAMC,EAAU,MAAY3C,EACzB,UAAU,MAAO0C,EAAMhB,EAAK,GAAO,CAAC,YAAY,CAAC,EACjD,KAAK,MAAMT,GAAO,CACjB,IAAM2B,EAAc,MAAY5C,EAAO,WACrC,CAAE,OAAQyC,EAAQ,KAAM,OAAQ,WAAY,OAAQ,EACpDxB,EACA,GACF,EACM4B,EAAa,MAAY7C,EAAO,UACpC,MACA,IAAI,WAAW4C,CAAW,EAC1B,CAAE,KAAM,UAAW,OAAQ,GAAI,EAC/B,GACA,CAAC,UAAW,SAAS,CACvB,EACA,OAAa5C,EAAO,UAAU,MAAO6C,CAAU,EAAE,KAAK,CAAC,CAAE,EAAAzB,CAAE,IAAMA,CAAE,CACrE,CAAC,EAEH,OAAItB,GAAIA,EAAG,CAAE,MAAO6C,CAAQ,CAAC,EACtB,CAAE,MAAOA,CAAQ,CAC1B,CACF,EAEOG,EAAQjD,GChXf,IAAMkD,GAAiB,IAUjBC,GAAM,CACVC,EACAC,EACAC,EACAC,EACAC,EAAS,KACK,CACd,GAAIJ,EAAQC,EAAc,MAAO,CAAE,WAAY,EAAK,EAEpD,GAAID,EAAQC,EAAc,MAAO,CAAE,SAAU,EAAK,EAKlD,GAAIG,GAAUF,IAAUC,EACtB,MAAO,CAAE,WAAY,EAAK,EAI5B,IAAIE,EAAW,OAAOH,GAAU,SAAW,KAAK,UAAUA,CAAK,GAAK,GAAKA,EACrEI,EACF,OAAOH,GAAiB,SACpB,KAAK,UAAUA,CAAY,GAAK,GAChCA,EAGN,OAAIE,IAAaC,EAAwB,CAAE,MAAO,EAAK,EAGnDD,EAAWC,EAAwB,CAAE,QAAS,EAAK,EAGhD,CAAE,SAAU,EAAK,CAC1B,EAKAP,GAAI,IAAM,MACRQ,EACAC,EACAC,EACAC,EACAC,IAC0B,CAC1B,GAAI,CAACJ,GAAU,OAAOA,GAAW,SAC/B,MAAM,IAAI,UAAU,0BAA0B,EAEhD,GAAI,CAACC,GAAS,OAAOA,GAAU,SAC7B,MAAM,IAAI,UAAU,yBAAyB,EAE/C,GAAI,CAACG,GAAU,OAAOA,GAAW,SAC/B,MAAM,IAAI,UAAU,0BAA0B,EAGhD,IAAMC,EAAU,KAAK,IAAI,EACnBC,EAAa,CAAC,EACdC,EAAe,CAAC,EAChBC,EAA+B,CAAC,EAChCC,EAAkB,IAAI,IACtBC,EAAkB,IAAI,IACxBC,EAAO,EAEX,QAAWC,KAAQ,OAAO,KAAKZ,CAAM,EAAG,CACtC,IAAMa,EAAOb,EAAOY,CAAI,EACxB,GAAI,CAACC,GAAQ,CAACA,EAAK,EAAG,SAEtB,IAAIC,EAAU,GACVC,EAAQ,GACRC,EAASb,EAEPc,EAAMJ,EAAWK,CAAa,EAOpC,GALIL,EAAK,EAAE,GAAQI,IAAKD,EAAS,IAK7BJ,EAAK,OAAS,GAAKA,EAAK,CAAC,IAAM,IACjC,GAAIA,EAAK,CAAC,IAAM,IACdG,EAAQ,GACRC,EAAS,OACJ,CACL,GAAIC,GAAOL,IAAS,IAAMK,EAAK,CAC7B,QAAQ,IAAI,6CAA6CL,CAAI,EAAE,EAC/D,QACF,CACAI,EAAS,EACX,CAGF,GAAIA,EAAQ,CACV,GAAI,CAACC,GAAO,CAACJ,EAAK,EAChB,SAGF,IAAMM,EAAmB,IAAI,IACvBC,EAAmB,IAAI,IAEvBC,EAAqB,OAAO,QAAQR,EAAK,EAAE,GAAG,GAAK,CAAC,CAAC,EAE3D,OAAW,CAACS,EAAKC,CAAG,IAAK,OAAO,QAAQV,EAAK,EAAE,GAAQ,CAAC,CAAC,EAAG,CAC1D,IAAMW,EAAW,OAAOF,CAAG,EAC3B,GAAI,CAAC,MAAME,CAAQ,GAAKA,EAAW,EAAG,CACpC,IAAMC,EAAoBJ,EAAmB,OAC3C,CAAC,CAAC,CAAEK,CAAE,IAAM,OAAOA,CAAE,IAAMF,CAC7B,EASA,GAPEC,EAAkB,OAAS,GAC3BA,EAAkB,MAAM,CAAC,CAACE,CAAI,IAAM,CAClC,IAAMC,EACJ3B,EAAMW,CAAI,GAAKX,EAAMW,CAAI,EAAG,EAAE,GAAG,EAAIX,EAAMW,CAAI,EAAG,EAAE,GAAG,EAAEe,CAAI,EAAI,EACnE,OAAOC,IAAe,QAAaA,EAAaJ,CAClD,CAAC,EAGD,SAIF,GADgB,MAAMK,EAAI,gBAAgBL,EAAUD,EAAeN,CAAG,EACzD,CACXE,EAAiB,IAAIK,CAAQ,EAC7B,OAAW,CAACG,EAAMD,CAAE,IAAKL,EACnB,OAAOK,CAAE,IAAMF,GACjBJ,EAAiB,IAAIO,CAAI,CAG/B,CACF,CACF,CAEA,GAAIP,EAAiB,OAAS,EAC5B,SAGFX,EAAgB,IAAIG,EAAMQ,CAAgB,EAC1CV,EAAgB,IAAIE,EAAMO,CAAgB,CAC5C,CAEA,QAAWG,KAAO,OAAO,KAAKT,CAAI,EAAG,CAGnC,GAFIS,IAAQ,KAERb,EAAgB,IAAIG,CAAI,GAAK,CAACH,EAAgB,IAAIG,CAAI,EAAG,IAAIU,CAAG,EAClE,SAGF,IAAM3B,EAAQkB,EAAKS,CAAG,EAChB7B,GAASoB,EAAK,GAAKA,EAAK,EAAE,GAAG,EAAIA,EAAK,EAAE,GAAG,EAAES,CAAG,EAAI,IAAM,EAC1D1B,EAAeK,EAAMW,CAAI,EAAIX,EAAMW,CAAI,EAAEU,CAAG,EAAI,OAChD5B,EAAeO,EAAMW,CAAI,GAAKX,EAAMW,CAAI,EAAE,EAAE,GAAG,EAAEU,CAAG,GAAK,EAE/D,GAAIP,GAASO,IAAcQ,EAAI,GAAGnC,CAAK,EAAG,CACxC,QAAQ,IAAI,eAAeoB,CAAK,KAAKO,CAAG,QAAcQ,EAAI,GAAGnC,CAAK,CAAC,EAAE,EACrE,QACF,CAEA,IAAMoC,EAAOtC,EAAQY,EACrB,GAAI0B,EAAO,EAAG,CACZ,GAAIA,EAAO,MAAU,SAGrB,IADIpB,IAAS,GAAKoB,EAAOpB,KAAMA,EAAOoB,GAClC,CAACxB,EAAMK,CAAI,EAAG,CAChB,IAAMoB,EAAsC,CAAC,EACvCC,EAAiD,CAAC,EACxD1B,EAAMK,CAAI,EAAI,CAAE,EAAG,CAAE,IAAKA,EAAM,IAAKoB,EAAa,EAAGC,CAAW,CAAE,CACpE,CACA1B,EAAMK,CAAI,EAAGU,CAAG,EAAI3B,EACpBY,EAAMK,CAAI,EAAG,EAAE,GAAG,EAAEU,CAAG,EAAI7B,EACvBoB,EAAK,EAAE,GAAQA,EAAK,EAAE,EAAKpB,CAAK,IAClCc,EAAMK,CAAI,EAAG,EAAE,EAAMnB,CAAK,EAAIoB,EAAK,EAAE,EAAKpB,CAAK,EAEnD,KAAO,CACL,IAAMyC,EACJxB,EAAgB,IAAIE,CAAI,GAAKF,EAAgB,IAAIE,CAAI,EAAG,IAAInB,CAAK,EAEnE,GADeD,GAAIC,EAAOC,EAAcC,EAAOC,GAAgB,KAAMsC,CAAQ,EAClE,SAAU,CACnB,GAAI,CAAC5B,EAAIM,CAAI,EAAG,CACd,IAAMuB,EAAuC,CAAC,EACxCC,EAAkD,CAAC,EACzD9B,EAAIM,CAAI,EAAI,CAAE,EAAG,CAAE,IAAKA,EAAM,IAAKuB,EAAc,EAAGC,CAAY,CAAE,CACpE,CACA,GAAI,CAACnC,EAAMW,CAAI,EAAG,CAChB,IAAMyB,EAAuC,CAAC,EACxCC,EAAkD,CAAC,EACzDrC,EAAMW,CAAI,EAAI,CAAE,EAAG,CAAE,IAAKA,EAAM,IAAKyB,EAAc,EAAGC,CAAY,CAAE,CACtE,CACArC,EAAMW,CAAI,EAAGU,CAAG,EAAIhB,EAAIM,CAAI,EAAGU,CAAG,EAAI3B,EACtCM,EAAMW,CAAI,EAAG,EAAE,GAAG,EAAEU,CAAG,EAAIhB,EAAIM,CAAI,EAAG,EAAE,GAAG,EAAEU,CAAG,EAAI7B,EAChDoB,EAAK,EAAE,GAAQA,EAAK,EAAE,EAAKpB,CAAK,IAClCQ,EAAMW,CAAI,EAAG,EAAE,EAAMnB,CAAK,EAAIa,EAAIM,CAAI,EAAG,EAAE,EAAMnB,CAAK,EAAIoB,EAAK,EAAE,EAAKpB,CAAK,GAGzEW,EAAOQ,CAAI,GACbR,EAAOQ,CAAI,EACR,OAAO2B,GAAWC,GAAMD,EAAE,GAAG,EAAGjB,CAAG,CAAC,EACpC,QAAQiB,GAAK/B,EAAU,KAAK+B,EAAE,EAAgB,CAAC,EAEpDzB,EAAU,EACZ,CACF,CACF,CAEIA,GAAWV,EAAOQ,CAAI,GACxBR,EAAOQ,CAAI,EACR,OAAO2B,GAAWC,GAAMD,EAAE,GAAG,CAAC,CAAC,EAC/B,QAAQA,GAAK/B,EAAU,KAAK+B,EAAE,EAAgB,CAAC,CAEtD,CAEA,IAAME,EAAQ,OAAO,KAAKxC,CAAK,EAC/B,OAAIwC,EAAM,OAASlD,IACEkD,EAChB,IAAI7B,GAAQ,CACX,IAAM8B,EAASzC,EAAMW,CAAI,EAAG,GAAKX,EAAMW,CAAI,EAAG,EAAE,GAAG,EAC7C+B,EAAWD,EAAS,KAAK,IAAI,GAAG,OAAO,OAAOA,CAAM,CAAC,EAAI,EAC/D,MAAO,CAAE,KAAA9B,EAAM,SAAA+B,CAAS,CAC1B,CAAC,EACA,KAAK,CAACC,EAAGC,IAAMD,EAAE,SAAWC,EAAE,QAAQ,EACf,MAAM,EAAGJ,EAAM,OAASlD,EAAc,EACzD,QAAQ,CAAC,CAAE,KAAAqB,CAAK,IAAM,CAC3B,OAAOX,EAAMW,CAAI,EACbV,GAASA,EAAQ,OAAOU,CAAI,CAClC,CAAC,EAGI,CAAE,IAAAN,EAAK,MAAAC,EAAO,KAAAI,EAAM,UAAAH,CAAU,CACvC,EAEA,IAAOsC,GAAQtD,GCvPf,IAAMuD,GAAQ,IAERC,GAAS,IAcTC,GAAeC,GACZ,OAAOA,GAAU,UAAYA,IAAU,MAAQ,CAAC,MAAM,QAAQA,CAAK,EAMtEC,GAAQ,IAAqB,CACjC,IAAMC,EAAS,CACbC,EACAH,EACAI,IACwE,CAKxE,GAJKA,IACGF,EAAkCL,EAAK,IAAIK,EAAkCL,EAAK,EAAI,CAAC,GAC7FO,EAAQF,EAAoCL,EAAK,GAE/C,CAACM,EAAM,OAAOC,EAElB,IAAIC,EAAI,EACJC,EAAkC,CAAC,EACnCC,EAAMJ,EAAKE,CAAC,EACVG,EAAML,EAAK,OAAS,EACpBM,EAAU,OAAOT,EAAU,IAG7BU,EAAgCN,EAAMG,CAAG,EAC7C,KAAO,CAACG,GAASL,EAAIG,GACnBD,GAAOJ,EAAK,EAAEE,CAAC,EACfK,EAAQN,EAAMG,CAAG,EAGnB,GAAKG,EAqCE,GAAIL,IAAMG,EAAK,CAEpB,GAAIC,EAEF,OAAO,OAAOC,EAAMZ,EAAM,EAAM,IAAcY,EAAMb,EAAK,EAAIa,EAAMZ,EAAM,EAG3EY,EAAMZ,EAAM,EAAIE,CAClB,KAAO,CAED,CAACU,EAAMb,EAAK,GAAK,CAACY,IAASC,EAAMb,EAAK,EAAI,CAAC,GAC/C,IAAMc,EAAWD,EAAMb,EAAK,EAC5B,GAAIE,GAAYY,CAAQ,EACtB,OAAOT,EAAMC,EAAK,MAAM,EAAEE,CAAC,EAAGL,EAAOW,CAAqB,CAE9D,SAlDuBC,EAAI,IAAIR,EAAO,CAACS,EAAsBC,IAAmB,CAC5E,IAAIC,EAAI,EACJC,EAAc,GAClB,KAAOF,EAAOC,CAAC,IAAMZ,EAAKY,CAAC,GACzBC,GAAeF,EAAOC,CAAC,EACvBA,IAEF,GAAIC,EAAa,CACf,GAAIP,EAEF,OAAIM,GAAKP,EAAK,QAEdF,EAAIQ,EAAO,MAAMC,CAAC,CAAC,EAAIF,EAChBA,GAGT,IAAMI,EAAqB,CACzB,CAACH,EAAO,MAAMC,CAAC,CAAC,EAAGF,EACnB,CAACV,EAAK,MAAMY,CAAC,CAAC,EAAG,CAAE,CAACjB,EAAM,EAAGE,CAAO,CACtC,EACA,OAAAI,EAAMY,CAAW,EAAI,CAAE,CAACnB,EAAK,EAAGoB,CAAQ,EACxC,OAAOb,EAAMU,CAAM,EACZ,EACT,CAEF,CAAC,GAOM,GAAIL,EACT,OAAOH,MANI,CACX,GAAIG,EAAS,OAERL,EAAMG,CAAG,IAAGH,EAAMG,CAAG,EAAI,CAAC,GAC/BH,EAAMG,CAAG,EAAGT,EAAM,EAAIE,CACxB,CAqBJ,EAEA,OAAOE,CACT,EAKAD,GAAM,IAAM,SAASiB,EACnBhB,EACAiB,EACAC,EACAC,EAAgB,CAAC,EACR,CACT,IAAMjB,EAASF,EAAoCL,EAAK,GAAKK,EACvDC,EAAO,OAAO,KAAKC,CAAI,EAAE,KAAK,EAEpC,QAASC,EAAI,EAAGA,EAAIF,EAAK,OAAQE,IAAK,CACpC,IAAME,EAAMJ,EAAKE,CAAC,EACZK,EAAQN,EAAKG,CAAG,EACtB,GAAI,CAACG,EAAO,SAEZ,IAAMY,EAAcZ,EAAMZ,EAAM,EAEhC,GAAI,OAAOwB,EAAgB,IAAa,CACtC,IAAMC,EAASJ,EAAGG,EAA6BD,EAAI,KAAK,EAAE,EAAId,EAAKA,EAAKc,CAAG,EAC3E,GAAI,OAAOE,EAAW,IAAa,OAAOA,CAC5C,MAAWH,GACTD,EAAG,OAAoBE,EAAI,KAAK,EAAE,EAAGd,EAAKc,CAAG,EAG/C,IAAMG,EAAad,EAAMb,EAAK,EAC9B,GAAIE,GAAYyB,CAAU,EAAG,CAC3BH,EAAI,KAAKd,CAAG,EACZ,IAAMgB,EAASL,EAAIM,EAAYL,EAAIC,EAAKC,CAAG,EAC3C,GAAI,OAAOE,EAAW,IAAa,OAAOA,EAC1CF,EAAI,IAAI,CACV,CACF,CAGF,EAEA,IAAOI,GAAQxB,GChJf,IAAMyB,GAAM,IAENC,GAAM,IAENC,EAAO,IA2BPC,GAAUC,GAAuB,CACrC,IAAMC,EAAQ,IAAI,IACdC,EAAiC,KACjCC,EAAoB,EAClBC,EAAsB,IAEtBC,EAAe,IAAI,IAKrBC,EAAkB,EAChBC,EAAwB,IACxBC,EAAyB,GACzBC,EAAyB,GAEzBC,EAAU,CACd,IAAKV,EAAI,KAAO,QAAQ,IACxB,MAAOA,EAAI,OAAS,IACpB,MAAOA,EAAI,OAAS,EACpB,KAAMA,EAAI,MAAQ,KAAO,KACzB,YAAaA,EAAI,aAAe,IAChC,MAAOA,EAAI,QAAU,OAAYA,EAAI,MAAQ,GAC7C,MAAOA,EAAI,KACb,EAEA,GAAI,CAACU,EAAQ,MACX,MAAM,IAAI,MAAM,oEAAoE,EAEtF,GAAI,CAACA,EAAQ,MAAM,IACjB,MAAM,IAAI,MAAM,sDAAsD,EAExE,GAAI,CAACA,EAAQ,MAAM,IACjB,MAAM,IAAI,MAAM,4DAA4D,EAE9E,GAAI,CAACA,EAAQ,MAAM,KACjB,MAAM,IAAI,MAAM,6DAA6D,EAI/E,IAAMC,EAAQD,EAAQ,MAEhBE,EAAU,CAACC,EAAmBC,EAAmBC,EAAaC,IAAwB,CAC1F,IAAMC,EAAW,KAAK,IAAI,EAAIH,EAC1BG,EAAW,KACb,QAAQ,IACN,iBAAiBJ,CAAS,KAAKI,CAAQ,UAAUF,CAAG,GAAGC,EAAO,KAAKA,CAAI,UAAY,EAAE,EACvF,CAEJ,EAEME,EAAmB,IAAY,CACnC,GAAI,OAAO,QAAY,KAAe,CAAC,QAAQ,YAAa,OAE5D,IAAMC,EAAM,KAAK,IAAI,EACrB,GAAIA,EAAMb,EAAkBC,EAAuB,OACnDD,EAAkBa,EAGlB,IAAMC,EADW,QAAQ,YAAY,EACX,SACpBC,EAAcX,EAAQ,YAAc,KAAO,KAC3CY,EAAiBF,EAAWC,EAElC,GAAIC,EAAiBb,EAAwB,CAC3C,IAAMc,EAAYtB,EAAM,KACxB,QAAQ,IACN,sCAAsC,KAAK,MAAMqB,EAAiB,GAAG,CAAC,6BAA6BC,CAAS,gBAC9G,EACAtB,EAAM,MAAM,EACP,OAA+B,IACjC,OAA8B,GAAG,EAEpCK,EAAkBa,EAAMZ,CAC1B,MAAWe,EAAiBd,GAC1B,QAAQ,IACN,mCAAmC,KAAK,MAAMc,EAAiB,GAAG,CAAC,qCAAqCrB,EAAM,IAAI,SACpH,CAEJ,EAEMuB,EAAU,CAACT,EAAcU,EAA0HC,IAAuC,CAC9L,GAAI,OAAOX,GAAQ,SAEnB,IAAI,OAAOU,GAAU,WAAY,CAC/B,IAAME,EAAWF,EACXG,EAAaJ,EAAO,MAAMT,CAAG,EACnC,GAAI,OAAOa,EAAe,IACxB,OAAOD,EAAS,OAAWC,CAA0B,EAGvD,GAAIJ,EAAO,OAAO,GAAI,CACpB,IAAMK,EAAcL,EAAO,OAAO,GAAGT,CAAG,EACxC,GAAI,OAAOc,EAAgB,IACzB,OAAOF,EAAS,OAAWE,CAA2B,CAE1D,CAEA,GAAIxB,EAAa,IAAIU,CAAG,EAAG,CACzBV,EAAa,IAAIU,CAAG,EAAG,KAAKY,CAAQ,EACpC,MACF,CAEAtB,EAAa,IAAIU,EAAK,CAACY,CAAQ,CAAC,EAChC,IAAMG,EAAY,KAAK,IAAI,EACrBC,EAAU,WAAW,IAAM,CAC/B,IAAMC,EAAY3B,EAAa,IAAIU,CAAG,EACjCiB,IACLtB,EAAQ,IAAI,sCAAsCK,CAAG,EAAE,EACvDV,EAAa,OAAOU,CAAG,EACvBiB,EAAU,QAAQN,GAAMA,EAAG,KAAM,IAA4B,CAAC,EAChE,EAAG,GAAK,EACR,OAAOF,EAAO,KAAKT,EAAK,CAACkB,EAAKC,IAAW,CACvC,aAAaH,CAAO,EACpBnB,EAAQ,OAAQkB,EAAWf,CAAG,EAC9B,IAAMiB,EAAY3B,EAAa,IAAIU,CAAG,GAAK,CAAC,EAC5CV,EAAa,OAAOU,CAAG,EACvBiB,EAAU,QAAQL,GAAYA,EAASM,EAAKC,CAAM,CAAC,CACrD,CAAC,CACH,CAOA,GALAV,EAAO,MAAMT,EAAKU,CAAqB,EACvCP,EAAiB,EACbQ,GACFF,EAAO,MAAM,KAAK,KAAKE,CAAE,EAEvB,EAAEF,EAAO,MAAM,IAAMd,EAAQ,MAC/B,OAAOc,EAAO,OAAO,EAGvB,aAAaA,EAAO,MAAM,OAAO,EACjCA,EAAO,MAAM,QAAU,WAAWA,EAAO,OAAQd,EAAQ,KAAK,EAEhE,EAEA,OAAAc,EAAO,MAAQW,GAAM,EACrBX,EAAO,MAAM,KAAO,CAAC,EACrBA,EAAO,MAAM,GAAK,EAElBA,EAAO,OAAU,IAAM,CACrB,GAAIA,EAAO,OAAO,IAAK,CACrBA,EAAO,OAAO,KAAO,GACrB,MACF,CAEA,IAAMY,EAAc,KAAK,IAAI,EAC7B,aAAaZ,EAAO,MAAM,OAAO,EACjCA,EAAO,OAAO,KAAO,GACrBA,EAAO,OAAO,IAAM,GACpB,IAAMa,EAASb,EAAO,OAAO,GAAKA,EAAO,MACzCA,EAAO,MAAQW,GAAM,EACrBX,EAAO,MAAM,KAAO,CAAC,EACrBA,EAAO,MAAM,GAAK,EAClB,IAAIc,EAAI,EACRd,EAAO,KAAKa,EAAOJ,GAAO,CACpB,EAAEK,EAAI,IAEV1B,EAAQ,SAAUwB,EAAa,SAASC,EAAM,EAAE,EAAE,EAC9CJ,GAAKvB,EAAQ,IAAIuB,CAAG,EACxBI,EAAM,KAAK,QAAQX,GAAMA,EAAGO,CAAG,CAAC,EAChCT,EAAO,OAAO,GAAK,OACnBA,EAAO,OAAO,IAAM,GAChBA,EAAO,OAAO,MAAMA,EAAO,OAAO,EACxC,CAAC,CACH,EAEAA,EAAO,KAAO,CAACe,EAAKb,IAAO,CACzB,IAAMc,EAAO,CACX,KAAM,CAACC,EAAgB1B,IAAqC,CAC1D,GAAI,EAAAA,GAAOyB,EAAK,OAAS,KACzB,OAAAA,EAAK,MAAQzB,EACbJ,EAAM,KAAK6B,EAAK,GAAG,EACZ,EACT,EACA,IAAME,GAAwB,CACxB,CAACA,GAAQA,GAAQF,EAAK,OAAS,KACjCA,EAAK,IAAME,EACPF,EAAK,OAAOA,EAAK,IAAIA,EAAK,MAAQ,IAAKA,EAAK,MAAOA,EAAK,GAAG,GAE/DA,EAAK,KAAOE,CAEhB,EACA,IAAK,CAACA,EAAcC,EAAeC,IAAuB,CAExD,GADAJ,EAAK,MAAQA,EAAK,IAAMA,EAAK,KAAO,OAChCvC,EAAM,IAAIyC,CAAI,EAAG,CACnB,IAAMG,EAAO5C,EAAM,IAAIyC,CAAI,EAC3BP,GAAM,IAAII,EAAK,CAACd,EAAOV,IAAQ,CAC7B,GAAI,EAAAA,EAAM4B,GACV,IAAIC,GAAOA,EAAM7B,EAAK,CACpByB,EAAK,MAAQzB,EACb,MACF,CACA8B,EAAK9B,EAAKU,CAAK,EAEjB,CAAC,EACDD,EAAO,MAAMkB,EAAMG,EAAML,EAAK,IAAI,CACpC,MACEhB,EAAO,MAAMkB,EAAM,CAACT,EAAKY,IAAS,CAChC,GAAIZ,EAAK,OAAOP,EAAGO,CAAG,EACtBE,GAAM,IAAII,EAAK,CAACd,EAAOV,IAAQ,CAC7B,GAAI,EAAAA,EAAM4B,GACV,IAAIC,GAAOA,EAAM7B,EAAK,CACpByB,EAAK,MAAQzB,EACb,MACF,CACA8B,EAAM9B,EAAKU,CAAK,EAElB,CAAC,EACDD,EAAO,MAAMkB,EAAMG,EAAOL,EAAK,IAAI,CACrC,CAAC,CAEL,EACA,KAAOP,GAA8B,CACnC,GAAIA,EAAK,OAAOP,EAAGO,CAAG,EACtB,GAAIO,EAAK,MAAO,CACdL,GAAM,IAAII,EAAKC,EAAK,IAAI,EACxB,MACF,CACAd,EAAGO,CAAG,CACR,EACA,MAAO,OACP,IAAK,OACL,KAAM,MACR,EACAE,GAAM,IAAII,EAAKC,EAAK,IAAI,CAC1B,EAEAhB,EAAO,MAAQ,CAACkB,EAAMH,EAAKb,IAAO,CAChC,IAAMoB,EAAQ,CACZ,KAAM,GACN,MAAO,GACP,KAAM,GACN,MAAO,EACP,IAAK,OACL,QAAS,GACT,WAAY,EACZ,KAAM,CACJrB,EACAsB,EACAC,EACAC,IACmB,CACnB,GAAIH,EAAM,KAAM,OAChBA,EAAM,QACN,IAAMI,EACJ,OAAOzB,EAAU,IAAc,GAAK,IAAM1B,GAAO,OAAO0B,CAAK,EACzD0B,EACJpD,GAAO,OAAOkD,EAAI,MAAM,EAAI,IAAMlD,GAAO,OAAOiD,CAAC,EAAIE,EAAW;AAAA,EAC5DE,EACJH,EAAI,SAAW,GAAMA,EAAI,SAAW,GAAKD,EAAE,SAASnD,EAAG,EAKzD,GACE,CAACiD,EAAM,SACPA,EAAM,MAAQ,GACdA,EAAM,KAAK,OAASpC,EAAQ,KAAO,GACnC0C,EACA,CACA,IAAMC,EAAUJ,EAAI,KAAK,EAAE,EAAID,EACzBM,EAASD,EAAQ,QAAQxD,EAAG,EAClCiD,EAAM,QACJQ,IAAW,GAAKD,EAAUA,EAAQ,UAAU,EAAGC,CAAM,EACvDR,EAAM,WAAaA,EAAM,KAAK,MAChC,CAEA,GACEA,EAAM,MAAQ,GACdA,EAAM,KAAK,OAASK,EAAI,OAASzC,EAAQ,MACzC0C,EACA,CACA,IAAMC,EAAUJ,EAAI,KAAK,EAAE,EAAID,EACzBM,EAASD,EAAQ,QAAQxD,EAAG,EAIlC,GAHAiD,EAAM,MACJA,EAAM,UACLQ,IAAW,GAAKD,EAAUA,EAAQ,UAAU,EAAGC,CAAM,GACpDR,EAAM,QAAUJ,EAAM,CAGpBI,EAAM,UACRA,EAAM,KAAOA,EAAM,KAAK,UAAU,EAAGA,EAAM,UAAU,GAEvDA,EAAM,KAAO,GACbA,EAAM,IAAMX,GAAM,EAClBA,GAAM,IAAII,EAAKO,EAAM,KAAK,EAC1BtB,EAAO,MAAMsB,EAAM,MAAOA,EAAM,IAAKpB,CAAE,EACvC,MACF,CACF,CACAoB,EAAM,MAAQK,CAChB,EACA,MAAO,CAAC1B,EAAqBV,IAAsB,CAC7CA,EAAM+B,EAAM,OAChBA,EAAM,IAAK/B,EAAKU,CAAK,CACvB,CACF,EACAU,GAAM,IAAII,EAAKO,EAAM,KAAM,EAAI,EAC/B,IAAMS,EAAa,KAAK,IAAI,EAC5B5C,EAAM,IAAI+B,EAAMI,EAAM,KAAMb,GAAO,CAI7Ba,EAAM,OACR7C,EAAM,OAAOyC,CAAI,EACjBxC,EAAgB,MAElBU,EAAQ,aAAc2C,EAAYb,EAAMI,EAAM,KAAK,MAAM,EACzDpB,EAAGO,CAAG,CACR,CAAC,CACH,EAEAT,EAAO,KAAO,CAACT,EAAKW,IAAO,CACzB,IAAM4B,EAASvC,EAAI,QAAQlB,EAAG,EACxB2D,EAAOF,IAAW,GAAKvC,EAAMA,EAAI,UAAU,EAAGuC,CAAM,EAEpDG,EAAYC,GAAmC,CACnD,IAAIC,EAAK,EAAGC,EAAKF,EAAM,OAAS,EAAGxB,EAAwB,KAC3D,KAAOyB,GAAMC,GAAI,CACf,IAAMC,EAAOF,EAAKC,GAAO,EACnBE,EAAIJ,EAAMG,CAAG,EACfC,GAAKN,GAAQtB,EAAS4B,EAAGH,EAAKE,EAAM,GACjCD,EAAKC,EAAM,CACpB,CACA,OAAO3B,CACT,EAEM6B,EAAQrB,GAA8B,CAC1C,GAAI,CAACA,EAAM,CAAEhB,EAAG,gBAAiB,MAAS,EAAG,MAAO,CACpD,GAAIhB,EAAQ,OAAST,EAAM,IAAIyC,CAAI,EACjC,OAAOhB,EAAG,OAAWzB,EAAM,IAAIyC,CAAI,EAAG3B,CAAG,CAA4D,EAEvGS,EAAO,MAAMkB,EAAM,CAACT,EAAKY,IAAS,CAC5BZ,GAAKvB,EAAQ,IAAIuB,CAAG,EACpBY,GAAQnC,EAAQ,QAClBT,EAAM,IAAIyC,EAAMG,CAAI,EACpB3B,EAAiB,GAEnBQ,EAAGO,EAAKY,EAAOA,EAAK9B,CAAG,EAA+D,MAAS,CACjG,CAAC,CACH,EAEMI,EAAM,KAAK,IAAI,EACrB,GAAIT,EAAQ,OAASR,GAAiBiB,EAAMhB,EAAoBC,EAC9D2D,EAAKN,EAASvD,CAAa,CAAC,MACvB,CACL,IAAMwD,EAAkB,CAAC,EACzB/C,EAAM,KAAM+B,GAAkB,CAC5B,GAAIA,EAAM,CAAEgB,EAAM,KAAKhB,CAAI,EAAG,MAAO,CACrCgB,EAAM,KAAK,EACPhD,EAAQ,QACVR,EAAgBwD,EAChBvD,EAAoBgB,GAEtB4C,EAAKN,EAASC,CAAK,CAAC,CACtB,CAAC,CACH,CACF,EAEAlC,EAAO,MAAQ,CAACkB,EAAMhB,IAAO,CAC3B,IAAMsC,EAAQ,CACZ,KAAM7B,GAAM,EACZ,KAAM,CAACF,EAAqBgC,IAAiE,CAC3F,GAAIhC,EAAK,OAAOP,EAAGO,CAAG,EACtB,GAAI,CAACgC,EAAM,OAAOvC,EAAG,KAAMsC,EAAM,IAAI,EAErC,IAAIf,EAAgB,CAAC,EACjBiB,EAAY,GACZC,EAAMH,EAAM,MAAMC,CAAc,EACpC,KAAOE,GAAK,CACV,IAAIpD,EACAU,EACE2C,EAASD,EAAI,CAAC,EACd7B,EAAI,OAAO8B,GAAW,SAAWA,EAAU,OAAOA,GAAW,SAAW,SAASA,EAAQ,EAAE,EAAI,EAErG,GADAD,EAAMH,EAAM,MAAMG,EAAI,CAAC,CAAC,GAAM,GAC1BA,EAAI,CAAC,IAAM,IAAK,CAClB,IAAME,EAASF,EAAI,CAAC,EACpBpD,EAAM,OAAOsD,GAAW,SAAWA,EAAS,OAAOA,CAAM,EACrD/B,EAAIW,EAAI,SACVA,EAAI,OAASX,GAEXA,GAAKW,EAAI,SACXA,EAAIX,CAAC,EAAIvB,EACTkC,EAAI,OAASX,EAAI,GAEnB4B,EAAYjB,EAAI,KAAK,EAAE,CACzB,CACAkB,EAAMH,EAAM,MAAMG,EAAI,CAAC,CAAC,GAAM,GAC1BA,EAAI,CAAC,IAAM;AAAA,IAEXA,EAAI,CAAC,IAAM,MACb1C,EAAQ0C,EAAI,CAAC,GAEX,OAAOpD,EAAQ,KAAe,OAAOU,EAAU,KACjDuC,EAAM,KAAKE,EAAWzC,CAAK,EAE7B0C,EAAMH,EAAM,MAAMG,EAAI,CAAC,CAAC,EAC1B,CACAzC,EAAG,KAAMsC,EAAM,IAAI,CACrB,EACA,MACEC,GAC0C,CAC1C,GAAI,CAACA,EAAM,OAEX,IAAM3B,EAAI2B,EAAK,QAAQnE,CAAI,EAC3B,GAAIwC,IAAM,GAAI,OAEd,IAAMgC,EAAIL,EAAK,MAAM,EAAG3B,CAAC,EACnBiC,EAAoB,CAAC,EAC3B,MAAO,CAACD,EAAGvE,GAAO,OAAOkE,EAAK,MAAM3B,CAAC,EAAGiC,CAAC,EAAGN,EAAK,MAAM3B,EAAIiC,EAAE,CAAE,CAAC,CAClE,CACF,EACA5D,EAAM,IAAI+B,EAAMsB,EAAM,IAAI,CAC5B,EAGOxC,CACT,EAKAzB,GAAO,OAAUyE,GAA6C,CAC5D,IAAIC,EAAQ,GACRC,EAAM,GACNT,EAcJ,GAZI,MAAM,QAAQO,CAAK,IAAMA,EAAM,SAAW,GAAKA,EAAM,SAAW,IAElEC,EAAQ7E,GAAM4E,EAAM,CAAC,EACjBA,EAAM,SAAW,GAAKA,EAAM,CAAC,IAC/BE,EAAM9E,GAAM4E,EAAM,CAAC,GAErBP,EAAOO,EAAM,CAAC,GAGdP,EAAOO,EAGL,OAAOP,GAAS,SAAU,CAC5B,IAAI,EAAI,EACJU,EACAC,EAAO9E,EACX,KAAQ6E,EAAUV,EAAK,GAAG,GACpBU,IAAY7E,IAAM8E,GAAQ9E,GAEhC,OAAO8E,EAAO,IAAMX,EAAOQ,EAAQC,EAAM5E,CAC3C,CAEA,IAAM+E,EAAcC,EAAI,GAAGb,CAAI,EAC/B,GAAIY,EAAO,OAAO/E,EAAO,IAAM+E,EAAQJ,EAAQC,EAAM5E,EAErD,GAAUiF,GAAI,GAAGd,CAAI,EAAG,OAAOnE,EAAO,KAAOmE,GAAQ,GAAKQ,EAAQC,EAAM5E,EAExE,GAAImE,IAAS,GAAM,OAAOnE,EAAO,IAAM2E,EAAQC,EAAM5E,EAErD,GAAImE,IAAS,GAAO,OAAOnE,EAAO,IAAM2E,EAAQC,EAAM5E,EAEtD,GAAImE,IAAS,KAAM,OAAOnE,EAAO,IAAM2E,EAAQC,EAAM5E,CAGvD,EAKAC,GAAO,OAAS,CAACkE,EAAce,IAAkF,CAC/G,IAAI1C,EAAI,GACJ2C,EAAI,EACJN,EACAO,EACAC,EAAY,GACZC,EAAU,GACd,GAAInB,EAAK,CAAC,IAAMnE,EAAM,OAEtB,KAAQ6E,EAAUV,EAAK,EAAE3B,CAAC,GACxB,GAAI4C,GAEF,GADIC,IAAc,KAAIA,EAAY7C,GAC9BqC,IAAY7E,GACV,EAAEmF,GAAK,EAAG,CACZG,EAAU9C,EACV,KACF,OAEOqC,IAAY7E,EACrBmF,IAEAC,EAAWP,GAAW,OAI1B,IAAMC,EACJO,IAAc,GAAKlB,EAAK,MAAMkB,EAAWC,IAAY,GAAKA,EAAU9C,CAAC,EAAI,GAEvE0C,IAAKA,EAAI,EAAI1C,EAAI,GAErB,IAAM+C,EAAQT,EAAK,MAAMhF,EAAG,EACtB6B,EAAQ4D,EAAM,CAAC,EACfZ,EAAQY,EAAM,CAAC,EACfX,EAAMW,EAAM,CAAC,EAEnB,GAAKZ,EAaE,CACL,IAAMa,EAAW,WAAWb,CAAK,EACjC,GAAIC,EAAK,CACP,GAAIQ,IAAa,IAAK,MAAO,CAACzD,EAAO6D,EAAUZ,CAAG,EAElD,GAAIQ,IAAa,IAAK,MAAO,CAAOJ,EAAI,IAAIrD,CAAK,EAAG6D,EAAUZ,CAAG,EAEjE,GAAIQ,IAAa,IACf,OAAIzD,EAAM,SAAW,EAAU,CAAC,GAAM6D,EAAUZ,CAAG,EAC5C,CAAC,WAAWjD,CAAK,EAAG6D,EAAUZ,CAAG,EAG1C,GAAIQ,IAAa,IAAK,MAAO,CAAC,GAAOI,EAAUZ,CAAG,EAElD,GAAIQ,IAAa,IAAK,MAAO,CAAC,KAAMI,EAAUZ,CAAG,CACnD,KAAO,CACL,GAAIQ,IAAa,IAAK,MAAO,CAACzD,EAAO6D,CAAQ,EAE7C,GAAIJ,IAAa,IAAK,MAAO,CAAOJ,EAAI,IAAIrD,CAAK,EAAG6D,CAAQ,EAE5D,GAAIJ,IAAa,IACf,OAAIzD,EAAM,SAAW,EAAU,CAAC,GAAM6D,CAAQ,EACvC,CAAC,WAAW7D,CAAK,EAAG6D,CAAQ,EAGrC,GAAIJ,IAAa,IAAK,MAAO,CAAC,GAAOI,CAAQ,EAE7C,GAAIJ,IAAa,IAAK,MAAO,CAAC,KAAMI,CAAQ,CAC9C,CACF,KA1CY,CACV,GAAIJ,IAAa,IAAK,OAAON,EAE7B,GAAIM,IAAa,IAAK,OAAaJ,EAAI,IAAIF,CAAI,EAE/C,GAAIM,IAAa,IACf,OAAIN,EAAK,SAAW,EAAU,GACvB,WAAWA,CAAI,EAGxB,GAAIM,IAAa,IAAK,MAAO,GAE7B,GAAIA,IAAa,IAAK,OAAO,IAC/B,CA+BF,EAEA,IAAOK,GAAQxF,GC5jBf,IAAMyF,GAAS,OAAO,QAAY,KAAe,QAAQ,UAAU,MAAQ,KAGrEC,GAAKD,GACP,KAAM,QAA+B,SAAS,EAC9C,OAGEE,GAAM,IAENC,GAAO,IAEPC,GAAOD,GAAO,KAAOA,GAAO,IAAMA,GAAO,QAAUA,GAKnDE,GAAcC,GAA2C,CAC7D,IAAMC,EAAMD,EAAI,KAEhB,GAAIN,GACF,OAAKC,GAAI,WAAWM,CAAG,GAAGN,GAAI,UAAUM,CAAG,EACtCN,GAAI,WAAWM,EAAM,IAAI,GAAGN,GAAI,cAAcM,EAAM,KAAMH,EAAI,EAE5D,CACL,IAAK,CAACI,EAAMC,IAAO,CACjBR,GAAI,SAASM,EAAM,IAAMC,EAAM,CAACE,EAAmCC,IAAkB,CACnF,GAAID,EAAK,CACP,GAAKA,EAA0B,OAAS,SAAU,CAChDD,EAAG,EACH,MACF,CACA,QAAQ,IAAI,qBAAsBC,CAAG,CACvC,CACA,IAAME,EAAUD,EAAOA,EAAK,SAAS,EAAI,OACzCF,EAAGC,EAAcE,CAAO,CAC1B,CAAC,CACH,EACA,IAAK,CAACJ,EAAMG,EAAMF,IAAO,CACvB,IAAMI,EAAML,EAAO,IAAYM,EAAK,OAAO,CAAC,EAAI,OAChDb,GAAI,UAAUY,EAAKF,EAAiBD,GAAsC,CACxE,GAAIA,EAAK,CACP,QAAQ,IAAI,sBAAuBA,CAAG,EACtCD,EAAGC,CAAY,EACf,MACF,CACAT,GAAI,OAAOY,EAAKN,EAAM,IAAMC,EAAMC,CAAW,CAC/C,CAAC,CACH,EACA,KAAMA,GAAM,CACVR,GAAI,QAAQM,EAAK,CAACG,EAAmCK,IAAqB,CACxE,GAAIL,EAAK,CACP,QAAQ,IAAI,oBAAqBA,CAAG,EACpCD,EAAG,EACH,MACF,CACIM,GAAOA,EAAM,QAAQN,CAAE,EAC3BA,EAAG,CACL,CAAC,CACH,CACF,EAGF,GAAIH,EAAI,UAAW,CACjB,IAAIU,EACEC,EAAU,IAAI,QAAc,CAACC,EAASC,IAAW,CACrD,IAAMC,EAAI,UAAU,KAAKb,EAAK,CAAC,EAC/Ba,EAAE,gBAAkBC,GAAS,CACzBA,EAAM,OAA4B,OAAO,kBAAkBd,CAAG,CAClE,EACAa,EAAE,QAAUC,GAAS,CACnB,QAAQ,IAAIA,CAAK,EACjBF,EAAOE,CAAK,CACd,EACAD,EAAE,UAAY,IAAM,CAElB,GADAJ,EAAKI,EAAE,OACHJ,EAAI,CAEN,IAAMM,EADKN,EAAG,YAAY,CAACT,CAAG,EAAG,UAAU,EAC5B,YAAYA,CAAG,EAAE,OAAO,GAAG,EAC1Ce,EAAI,QAAU,IAAM,CAClB,QAAQ,IAAI,qBAAqBf,CAAG,IAAI,EACxCY,EAAOG,EAAI,KAAK,CAClB,EACAA,EAAI,UAAY,IAAM,CACpB,GAAKA,EAAI,OAWPJ,EAAQ,MAXO,CAEf,IAAMI,EADKN,EAAG,YAAY,CAACT,CAAG,EAAG,WAAW,EAC7B,YAAYA,CAAG,EAAE,IAAIH,GAAM,GAAG,EAC7CkB,EAAI,QAAU,IAAM,CAClB,QAAQ,IAAI,yBAAyBf,CAAG,IAAI,EAC5CY,EAAOG,EAAI,KAAK,CAClB,EACAA,EAAI,UAAY,IAAM,CACpBJ,EAAQ,CACV,CACF,CAGF,CACF,MACE,QAAQ,IAAI,+BAA+B,EAC3CC,EAAO,IAAI,MAAM,yBAAyB,CAAC,CAE/C,CACF,CAAC,EAED,MAAO,CACL,IAAK,CAACX,EAAMC,IAAO,CACjB,IAAMc,EAAO,CAACf,EAAcC,IAAqD,CAE/E,IAAMa,EADKN,EAAG,YAAY,CAACT,CAAG,EAAG,UAAU,EAC5B,YAAYA,CAAG,EAAE,IAAIC,CAAI,EACxCc,EAAI,QAAU,IAAM,CAClB,QAAQ,IAAI,iBAAiBf,CAAG,IAAIC,CAAI,EAAE,EAC1CC,EAAGa,EAAI,KAA0B,CACnC,EACAA,EAAI,UAAY,IAAM,CACpBb,EAAG,KAAMa,EAAI,MAAM,CACrB,CACF,EAEAL,EACG,KAAK,IAAM,CACVM,EAAKf,EAAMC,CAAE,CACf,CAAC,EACA,MAAMC,GAAO,CACZD,EAAGC,CAAa,CAClB,CAAC,CACL,EACA,IAAK,CAACF,EAAMG,EAAMF,IAAO,CACvB,IAAMe,EAAO,CACXhB,EACAG,EACAF,IACG,CAEH,IAAMa,EADKN,EAAG,YAAY,CAACT,CAAG,EAAG,WAAW,EAC7B,YAAYA,CAAG,EAAE,IAAII,EAAMH,CAAI,EAC9Cc,EAAI,QAAU,IAAM,CAClB,QAAQ,IAAI,yBAAyBf,CAAG,IAAIC,CAAI,EAAE,EAClDC,EAAGa,EAAI,KAA0B,CACnC,EACAA,EAAI,UAAY,IAAM,CACpBb,EAAG,IAAI,CACT,CACF,EAEAQ,EACG,KAAK,IAAM,CACVO,EAAKhB,EAAMG,EAAgBF,CAAE,CAC/B,CAAC,EACA,MAAMC,GAAO,CACZD,EAAGC,CAAa,CAClB,CAAC,CACL,EACA,KAAMD,GAAM,CACV,IAAMgB,EAAShB,GAAgC,CAE7C,IAAMa,EADKN,EAAG,YAAY,CAACT,CAAG,EAAG,UAAU,EAC5B,YAAYA,CAAG,EAAE,WAAW,EAC3Ce,EAAI,QAAU,IAAM,CAClB,QAAQ,IAAI,yBAA0Bf,CAAG,EACzCE,EAAG,CACL,EACAa,EAAI,UAAY,IAAM,CAClBA,EAAI,OAAoB,QAAQb,CAAE,EACpCA,EAAG,CACL,CACF,EAEAQ,EACG,KAAK,IAAM,CACVQ,EAAMhB,CAAE,CACV,CAAC,EACA,MAAMC,GAAO,CACZ,QAAQ,IAAI,iCAAkCA,CAAG,EACjDD,EAAG,CACL,CAAC,CACL,CACF,CACF,CAGA,MAAO,CACL,IAAK,CAACiB,EAAOjB,IAAO,CAClBA,EAAG,KAAML,EAAI,CACf,EACA,IAAK,CAACsB,EAAOC,EAAOlB,IAAO,CACzBA,EAAG,IAAI,CACT,EACA,KAAMA,GAAM,CACVA,EAAG,GAAG,EACNA,EAAG,CACL,CACF,CACF,EAcMmB,GAAStB,GAAuC,CACpD,IAAMuB,EAAUvB,GAAO,CAAC,EACxBuB,EAAQ,KAAO,OAAOA,EAAQ,MAAQ,QAAQ,EACzCA,EAAQ,QAAOA,EAAQ,MAAQxB,GAAWwB,CAAO,GACtD,IAAMC,EAASC,GAAOF,CAAgB,EAEtC,MAAO,CACL,IAAK,CAACG,EAAKvB,EAAIwB,IAAS,CACtB,GAAI,CAACD,GAAO,CAAOE,EAAI,GAAGF,CAAG,EAAG,CAC9BvB,EAAG,cAAc,EACjB,MACF,CACA,GAAI,CAACuB,EAAI,GAAG,EAAG,CACbvB,EAAG,sBAAsB,EACzB,MACF,CAEA,IAAM0B,EAAOF,GAAQ,CAAC,EAChBG,EAAOJ,EAAI,GAAG,EACdK,EACJ,CAACF,EAAK,QAAU,OAAOH,EAAI,GAAG,GAAM,SAAWA,EAAI,GAAG,EAAI,GACxDM,EACEC,EAAqC,CAAC,EAEtCC,EAAO,CAACC,EAAqBJ,IAAsB,CAEnDA,IAAcK,GAAiB,CAAOC,GAAMX,EAAI,GAAG,EAAGK,CAAG,IAExDC,IAAMA,EAAO,CAAE,EAAG,CAAE,IAAKF,EAAM,IAAK,CAAC,CAAE,CAAE,GAC9CE,EAAKD,CAAG,EAAII,EAAM,CAAC,EACnBH,EAAK,EAAE,GAAG,EAAED,CAAG,EAAII,EAAM,CAAC,EAEtBA,EAAM,SAAW,GAAKA,EAAM,CAAC,IAC/BF,EAAWE,EAAM,CAAC,EAAE,SAAS,CAAC,EAAIA,EAAM,CAAC,GAE7C,EAEAX,EAAOM,EAAOlC,GAAMmC,EAAK,CAAC3B,EAAK+B,IAAU,CACvC,IAAIG,EACMV,EAAI,GAAGO,CAAK,GACpBI,GAAM,IAAIJ,EAAgBD,CAAI,EACzBF,GAAME,EAAKC,EAAgBJ,CAAG,EACnCO,EAAQ,CAAE,CAACR,CAAI,EAAGE,CAAM,GACfG,IACTD,EAAKC,EAAuBJ,CAAG,EAC/BO,EAAQ,CAAE,CAACR,CAAI,EAAGE,CAAM,GAGtBM,GAASA,EAAMR,CAAI,GAAK,OAAO,KAAKG,CAAU,EAAE,OAAS,IAC3DK,EAAMR,CAAI,EAAE,EAAE,EAAOG,GAEvB9B,EAAGC,EAAKkC,CAAK,CACf,CAAC,CACH,EACA,IAAK,CAACA,EAAOnC,IAAO,CAClB,GAAI,CAACmC,EAAO,CACVnC,EAAG,gBAAgB,EACnB,MACF,CAEA,IAAIqC,EAAQ,EACRC,EAAW,GACTC,EAAOtC,GAA8B,CAEzC,GADAoC,IACI,CAAAC,EAEJ,IAAIrC,EAAK,CACPqC,EAAW,GACXtC,EAAGC,CAAG,EACN,MACF,CAEIoC,IAAU,IACZC,EAAW,GACXtC,EAAG,IAAI,GAEX,EAEA,OAAO,KAAKmC,CAAK,EAAE,QAAQR,GAAQ,CACjC,IAAME,EAAOM,EAAMR,CAAI,EACvB,OAAO,KAAKE,CAAI,EAAE,QAAQD,GAAO,CAC/B,GAAIA,IAAQ,IAAK,OAEjBS,IACA,IAAML,EAAQH,EAAKD,CAAG,EAChBY,EAAQX,EAAK,EAAE,GAAG,EAAED,CAAG,EACvBa,EAAMZ,EAAK,EAAE,GAAQA,EAAK,EAAE,EAAKW,CAAK,EACtCtC,EAAqBuC,EACvB,CAACT,EAAOQ,EAAOC,CAAG,EAClB,CAACT,EAAOQ,CAAK,EACjBnB,EAAOM,EAAOlC,GAAMmC,EAAK1B,EAAMqC,CAAG,CACpC,CAAC,CACH,CAAC,CACH,CACF,CACF,EAEOG,GAAQvB,GCnSf,IAAMwB,GAAS,OAAO,QAAY,KAAe,QAAQ,UAAU,MAAQ,KAGrEC,GAAWD,GAAS,KAAM,QAAO,IAAI,EAAI,OAE3C,OAAO,WAAW,UAAc,KAAeC,KACjD,WAAW,UAAYA,GAAS,WAalC,IAAMC,GAAqBC,GAAuB,CAChD,IAAMC,EAAU,IAAI,IACdC,EAAc,KACdC,EAAW,IACXC,EAAsB,GACxBC,EAAyC,KAgB7C,OAAKL,IACHK,EAAkB,YAfJ,IAAY,CAC1B,IAAMC,EAAM,KAAK,IAAI,EACrB,OAAW,CAACC,EAAWC,CAAI,IAAK,MAAM,KAAKP,EAAQ,QAAQ,CAAC,EACtDK,EAAME,EAAK,YAAcL,IAC3BK,EAAK,SAAW,CAAC,EACjBA,EAAK,YAAcF,GAErBE,EAAK,SAAWA,EAAK,SAAS,OAAOC,GAAQH,EAAMG,EAAON,CAAQ,EAC9DG,EAAME,EAAK,YAAcL,EAAW,KACtCK,EAAK,cAAgB,EAG3B,EAGyCL,EAAW,CAAC,GAG9C,CACL,SAAWO,GAA6B,CACtC,IAAMJ,EAAM,KAAK,IAAI,EACfK,EAASV,EAAQ,IAAIS,CAAQ,GAAK,CACtC,SAAU,CAAC,EACX,YAAaJ,EACb,cAAe,CACjB,EAIA,GAFAK,EAAO,SAAWA,EAAO,SAAS,OAAOF,GAAQH,EAAMG,EAAON,CAAQ,EAElEQ,EAAO,SAAS,QAAUT,EAAa,CACzC,IAAMU,EAAgB,KAAK,IAAI,GAAGD,EAAO,QAAQ,EAC3CE,EAAQV,GAAYG,EAAMM,GAChC,OAAAD,EAAO,eAAiBA,EAAO,eAAiB,GAAK,EACrDV,EAAQ,IAAIS,EAAUC,CAAM,EACrB,KAAK,IAAI,EAAGE,CAAK,CAC1B,CAEA,OAAAF,EAAO,SAAS,KAAKL,CAAG,EACxBL,EAAQ,IAAIS,EAAUC,CAAM,EACrB,CACT,EAEA,qBAAuBD,GAA6B,CAClD,IAAMC,EAASV,EAAQ,IAAIS,CAAQ,EACnC,GAAI,CAACC,EAAQ,OAAOT,EAEpB,IAAMI,EAAM,KAAK,IAAI,EACfQ,EAAgBH,EAAO,SAAS,OAAOF,GAAQH,EAAMG,EAAON,CAAQ,EAC1E,OAAO,KAAK,IAAI,EAAGD,EAAcY,EAAc,MAAM,CACvD,EAEA,iBAAmBJ,GAA6B,CAC9C,IAAMC,EAASV,EAAQ,IAAIS,CAAQ,EACnC,OAAOC,GAASA,EAAO,eAAiB,CAC1C,EAEA,iBAAmBD,GAA8B,CAC/C,IAAMC,EAASV,EAAQ,IAAIS,CAAQ,EACnC,OAAKC,EACEA,EAAO,eAAiBP,EADX,EAEtB,EAEA,QAAS,IAAY,CACfC,IACF,cAAcA,CAAe,EAC7BA,EAAkB,MAEpBJ,EAAQ,MAAM,CAChB,CACF,CACF,EAMMc,GAAgB,CACpBP,EACAQ,EAAU,KAAO,OAC4C,CAC7D,GAAI,CACF,GAAI,OAAOR,GAAS,UAAYA,EAAK,OAASQ,EAC5C,MAAM,IAAI,MAAM,mBAAmB,EAErC,MAAO,CAAE,QAAS,GAAM,KAAM,KAAK,MAAMR,EAAK,SAAS,CAAC,CAAE,CAC5D,OAASS,EAAO,CACd,MAAO,CAAE,QAAS,GAAO,MAAQA,EAAgB,OAAQ,CAC3D,CACF,EAEMC,GAAkB,CACtBV,EACAQ,EAAU,KAAO,OAEb,OAAOR,GAAS,UAAYA,EAAK,OAASQ,EACrC,CAAE,MAAO,GAAO,MAAO,mBAAoB,EAEhD,OAAO,UAAY,OAAO,SAASR,CAAI,GAAKA,EAAK,OAASQ,EACrD,CAAE,MAAO,GAAO,MAAO,mBAAoB,EAE7C,CAAE,MAAO,EAAK,EAOjBG,GAA0B,CAACC,EAAiB,MAAS,CACzD,IAAMC,EAAc,IAAI,IAExB,MAAO,CACL,IAAMC,GAA2B,CAC/B,GAAID,EAAY,MAAQD,EACtB,MAAO,GAETC,EAAY,IAAIC,CAAE,EAElB,IAAMC,EAAgBD,EAAG,MAAM,KAAKA,CAAE,EACtC,OAAAA,EAAG,MAAS,IAAIE,KACdH,EAAY,OAAOC,CAAE,EACdC,EAAc,GAAIC,CAA2B,GAG/C,EACT,EAEA,OAASF,GAAwB,CAC/BD,EAAY,OAAOC,CAAE,CACvB,EAEA,MAAO,IAAcD,EAAY,KAEjC,OAAQ,IAAeA,EAAY,MAAQD,CAC7C,CACF,EAMMK,GAAqB,CAACC,EAAa,IAAM,CAC7C,IAAIC,EAAa,EAEjB,MAAO,CACL,YAAa,IAAeA,EAAaD,EACzC,SAAU,IAAc,KAAK,IAAI,IAAO,KAAK,IAAI,EAAGC,CAAU,EAAG,GAAK,EACtE,UAAW,IAAY,CACrBA,GACF,EACA,MAAO,IAAY,CACjBA,EAAa,CACf,CACF,CACF,EAaMC,GAAQC,GAAiC,CAC7C,IAAMC,EAAUD,GAAO,CAAC,EAClBE,EAAMC,GAAI,EACVC,EAAQC,GAAMJ,CAAgB,EAC9BK,EAAe,CAAC,EAChBC,EAAoD,CAAC,EACrDC,EAAoB,CAAC,EAErBC,EAAoB,IAAI,IACxBC,EAAU,IAAI,IAIdC,EAAe,IAAI,IACnBC,EAAiB,IAEjBC,EAAkB,IAAI,IACtBC,EAAkB,IAAI,IAEtBC,EAAU,MAAOC,GACjBV,EAAMU,CAAI,EAAU,GACjB,IAAI,QAAQC,GAAW,CAC5Bb,EAAM,IAAI,CAAE,IAAKY,CAAK,EAAG,CAACE,EAAKvC,IAAS,CACtCsC,EAAQ,CAACC,GAAO,CAAC,CAACvC,GAAQ,CAAC,CAACA,EAAKqC,CAAI,CAAC,CACxC,CAAC,CACH,CAAC,EAGG7C,EAAY8B,EAAQ,KAAQA,EAAQ,IAA4C,aAAa,OAAS,SACtGkB,EAAcjD,GAAkBC,CAAS,EACzCiD,EAAoB9B,GAAwBW,EAAQ,gBAAkB,GAAI,EAE1EoB,EAAQ,MACZ1C,EACA2C,EACAC,IACqB,CACrB,IAAMC,EAAYC,EAElB,QAAWT,KAAQ,OAAO,KAAKrC,CAAI,EAAG,CACpC,IAAM+C,EAAO/C,EAAKqC,CAAI,EAGtB,GAAIU,EAAKF,CAAG,IAAM,OAAW,SAE7B,IAAMG,EAAM,MAAM,IAAI,QAAqBC,GAAO,CAChDC,EAAgB,CAAE,IAAKb,EAAM,IAAKQ,CAAI,EAAGI,EAAKN,EAAM,CAAC,IAAK,EAAI,CAAC,CACjE,CAAC,EACD,GAAIK,EAAI,IACN,OAAIJ,GAAIA,EAAGI,EAAI,GAAG,EACX,GAOT,GACE,GAACA,EAAI,KACL,CAACA,EAAI,IAAIX,CAAI,GACbW,EAAI,IAAIX,CAAI,EAAGQ,CAAG,IAAME,EAAKF,CAAG,GAKlC,OAAID,GACFA,EAAG,2DAA2DP,CAAI,EAAE,EAE/D,EACT,CAEA,MAAO,EACT,EAEMc,EAAM,CAACH,EAAgCL,IAAsC,CACjF,IAAMS,EAAMC,GAAIL,EAAI,IAAKrB,CAAK,EAC1ByB,EACFT,EACE,KAAK,UAAU,CACb,IAAKpB,EAAI,MAAY+B,EAAK,OAAO,CAAC,CAAC,EACnC,IAAKN,EAAI,GAAG,EACZ,IAAKI,CACP,CAAC,CACH,EAEA3B,EAAM,IACJuB,EAAI,IACJ,CAACT,EAAKa,IAAQ,CACZT,EACE,KAAK,UAAU,CACb,IAAKpB,EAAI,MAAY+B,EAAK,OAAO,CAAC,CAAC,EACnC,IAAKN,EAAI,GAAG,EACZ,IAAKI,EACL,IAAKb,CACP,CAAC,CACH,CACF,EACA,CAAE,OAAQ,EAAK,CACjB,CAEJ,EAEMgB,EAAM,MACVP,EACAL,IACkB,CAClB,IAAMa,EAAS,MAAMC,GAAI,IAAIT,EAAI,IAAKrB,EAAOI,EAAST,EAAQ,QAAU,GAAOO,CAAM,EACrF,GAAI,OAAO,KAAK2B,EAAO,GAAG,EAAE,SAAW,EAAG,CACpC,OAAO,KAAKA,EAAO,KAAK,EAAE,SAAW,GACvC,WAAW,IAAMD,EAAI,CAAE,IAAKC,EAAO,MAAO,IAAKR,EAAI,GAAG,CAAE,EAAGL,CAAI,EAAGa,EAAO,IAAI,EAE/E,MACF,CAEM,MAAMd,EAAMc,EAAO,IAAKb,CAAa,IAE3ClB,EAAM,IAAI+B,EAAO,IAAKjB,GAAO,CACvBA,GAAK,QAAQ,KAAK,YAAaA,CAAG,EACtCI,EACE,KAAK,UAAU,CACb,IAAKpB,EAAI,MAAY+B,EAAK,OAAO,CAAC,CAAC,EACnC,IAAKN,EAAI,GAAG,EACZ,IAAKT,CACP,CAAC,CACH,EACAiB,EAAO,UAAU,QAAQZ,GAAMA,EAAG,CAAC,CACrC,CAAC,EAEG,OAAO,KAAKY,EAAO,KAAK,EAAE,SAAW,GACvC,WAAW,IAAMD,EAAI,CAAE,IAAKC,EAAO,MAAO,IAAKR,EAAI,GAAG,CAAE,EAAGL,CAAI,EAAGa,EAAO,IAAI,EAEjF,EAEMN,EAAkB,CACtBQ,EACAd,EACAD,EACAgB,IACS,CACT,GAAI,CAACf,EAAI,OAET,IAAMgB,EAAOD,GAAQ,CAAC,EAChBE,EAAOD,EAAK,MAAS,CAACF,EAAI,GAAG,GAAK3B,EAAQ,IAAI2B,EAAI,GAAG,CAAC,EACtDN,EAAMC,GAAIK,EAAK/B,EAAOkC,CAAI,EAC1BC,EAAcR,EAAK,OAAO,CAAC,EAC3BS,EAAU,KAAK,UAAU,CAC7B,IAAKxC,EAAI,MAAMuC,CAAK,EACpB,IAAKJ,CACP,CAAC,EAED,GAAIN,EAAK,CACP,GAAI,CAAC/D,GAIH,GAAI,CAACqE,EAAI,GAAG,GAAK,OAAOA,EAAI,GAAG,GAAM,SAAU,CAC7C,IAAMM,EAAWN,EAAI,GAAG,GAAKA,EAAI,GAAG,EAAI,IAAMA,EAAI,GAAG,EAAI,IACnD5D,EAAM,KAAK,IAAI,EACfmE,EAAYjC,EAAa,IAAIgC,CAAQ,EAC3C,GAAI,CAACC,GAAanE,EAAMmE,EAAYhC,EAAgB,CAClDD,EAAa,IAAIgC,EAAUlE,CAAG,EAC9B,IAAMoE,EAAavB,EAAKoB,CAAO,EAC/B,GAAIG,GAAcA,EAAW,IAAK,CAChCtB,EAAG,CAAE,IAAKsB,EAAW,GAAI,CAAC,EAC1B,MACF,CACF,CACF,KAAO,CAEL,IAAMA,EAAavB,EAAKoB,CAAO,EAC/B,GAAIG,GAAcA,EAAW,IAAK,CAChCtB,EAAG,CAAE,IAAKsB,EAAW,GAAI,CAAC,EAC1B,MACF,CACF,CAEFtB,EAAG,CAAE,IAAKQ,CAAI,CAAC,EACf,MACF,CAEA3B,EAAM,IACJiC,EACA,CAACnB,EAAKa,IAAQ,CACZ,GAAIA,EAAK,CAIP,OAAW,CAACf,EAAMU,EAAI,IAAK,OAAO,QAAQK,CAAG,EAC3C,GAAKL,GACL,IAAI,CAACpB,EAAMU,CAAI,EAAG,CAChBV,EAAMU,CAAI,EAAI,CAAC,GAAGU,EAAI,EACtB,QACF,CACA,OAAW,CAACF,GAAKsB,EAAK,IAAK,OAAO,QAAQpB,EAAI,EAAG,CAC/C,GAAIF,KAAQ,IAAK,SACjB,IAAMuB,GAAQzC,EAAMU,CAAI,EACxB,GAAI,OAAO+B,GAAMvB,EAAG,EAAM,IAAa,SACvCuB,GAAMvB,EAAG,EAAIsB,GACb,IAAME,GAAQtB,GAA8B,EAC5C,GAAIsB,KAAO,GAAG,GAAK,OAAOA,GAAK,GAAG,EAAExB,EAAG,EAAM,IAAa,CACxD,IAAMyB,GAAQD,GAAK,GAAG,EAAExB,EAAG,EACrB0B,GAAS5C,EAAMU,CAAI,EAA2B,EACpDkC,GAAM,GAAG,EAAE1B,EAAG,EAAIyB,GACdD,GAAK,IAAOC,EAAK,IACdC,GAAM,IAAMA,GAAM,EAAO,CAAC,GAC/BA,GAAM,EAAMD,EAAK,EAAID,GAAK,EAAKC,EAAK,EAExC,CACF,EAGE,CAACZ,EAAI,GAAG,GAAKN,EAAIM,EAAI,GAAG,CAAC,GAAG3B,EAAQ,IAAI2B,EAAI,GAAG,CAAC,EAEpD,IAAMX,EAAOK,EAAIM,EAAI,GAAG,CAAC,EAMzB,GAJEX,GACA,OAAO,KAAKA,CAAI,EAAE,KAChBF,GAAOA,IAAQ,KAAa2B,GAAMd,EAAI,GAAG,EAAGb,CAAG,CACjD,EACe,CAEf,GAAI,CAACxD,IAAUqE,EAAI,GAAG,IAAYZ,EAChC,GAAI,CAACY,EAAI,GAAG,GAAK,OAAOA,EAAI,GAAG,GAAM,SAAU,CAC7C,IAAMM,EAAWN,EAAI,GAAG,GAAKA,EAAI,GAAG,EAAI,IAAMA,EAAI,GAAG,EAAI,IACnD5D,GAAM,KAAK,IAAI,EACfmE,GAAYjC,EAAa,IAAIgC,CAAQ,EAC3C,GAAI,CAACC,IAAanE,GAAMmE,GAAYhC,EAAgB,CAClDD,EAAa,IAAIgC,EAAUlE,EAAG,EAC9B,IAAMoE,GAAavB,EAAKoB,CAAO,EAC/B,GAAIG,IAAcA,GAAW,IAAK,CAChCtB,EAAG,CAAE,IAAKsB,GAAW,GAAI,CAAC,EAC1B,MACF,CACF,CACF,KAAO,CACL,IAAMA,EAAavB,EAAKoB,CAAO,EAC/B,GAAIG,GAAcA,EAAW,IAAK,CAChCtB,EAAG,CAAE,IAAKsB,EAAW,GAAI,CAAC,EAC1B,MACF,CACF,CAEFtB,EAAGL,EAAM,CAAE,IAAKa,EAAK,IAAKb,CAAI,EAAI,CAAE,IAAKa,CAAI,CAAC,EAC9C,MACF,CACF,CAKA,GAHIb,GAAK,QAAQ,IAAIA,CAAG,EAGpBqB,GAAQA,EAAK,IAAK,CACpB,IAAMa,EAAKf,EAAI,GAAG,EACZN,EAAmD,CAAC,CAACqB,CAAE,EAAG,IAAI,EAChE,OAAOf,EAAI,GAAG,GAAM,WACtBN,EAAIqB,CAAE,EAAI,CAAC,CAACf,EAAI,GAAG,CAAC,EAAG,IAAI,GAE7Bd,EAAG,CAAC,IAAKQ,CAAY,CAAC,EACtB,MACF,CAEAxB,EAAMkC,CAAK,EAAIlB,EAEfV,EAAgB,IAAI4B,EAAOJ,CAAG,EAG9B5B,EAAkB,IAAI4B,EAAI,GAAG,CAAC,EAE9B,IAAMQ,EAAavB,EAAKoB,CAAO,EAC/B,GAAIG,GAAcA,EAAW,IAAK,CAChCtB,EAAG,CAAE,IAAKsB,EAAW,GAAI,CAAC,EAC1B,OAAOtC,EAAMkC,CAAK,EAClB5B,EAAgB,OAAO4B,CAAK,EAC5B,MACF,CACF,EACAF,CACF,CACF,EAEMc,EAAO/B,IACJ,CACL,IAAK,CAACe,EAAKd,EAAIe,IAAS,CAClBD,GAAO,OAAOA,EAAI,GAAG,GAAM,WAC7BA,EAAM,CAAE,GAAGA,EAAK,IAAK,OAAOA,EAAI,GAAG,CAAC,CAAE,GAEpCA,GAAOA,EAAI,GAAG,GAChB5B,EAAkB,IAAI4B,EAAI,GAAG,CAAC,EAEhCR,EAAgBQ,EAAKd,EAAID,EAAMgB,CAAI,CACrC,EACA,IAAK,MAAO3D,EAAM4C,IAAO,CACvB,IAAMY,EAAS,MAAMC,GAAI,IAAIzD,EAAM2B,EAAOI,EAAST,EAAQ,QAAU,GAAOO,CAAM,EAClF,GAAI,OAAO,KAAK2B,EAAO,GAAG,EAAE,SAAW,EAAG,CACpCZ,GAAIA,EAAG,IAAI,EACf,MACF,CAEA,GAAI,CAAE,MAAMF,EAAMc,EAAO,IAAKb,EAAeC,CAAE,EAC7C,OAGF,OAAW,CAAC+B,EAAO5B,CAAI,IAAK,OAAO,QAAQS,EAAO,GAAG,EACnD,GAAIT,GAAQ,OAAOA,GAAS,SAC1B,OAAW,CAAC6B,EAAMT,CAAK,IAAK,OAAO,QAAQpB,CAAI,EAAG,CAChD,IAAM8B,EAAeC,EAAI,GAAGX,CAAmB,EAC3CU,GACF/C,EAAkB,IAAI+C,CAAM,CAEhC,CAIJpD,EAAM,IAAI+B,EAAO,IAAKjB,GAAO,CACvBK,GAAIA,EAAGL,CAAG,EACdiB,EAAO,UAAU,QAAQuB,GAAKA,EAAE,CAAC,CACnC,CAAC,EAED,IAAMb,EAAavB,EACjB,KAAK,UAAU,CACb,IAAKpB,EAAI,MAAY+B,EAAK,OAAO,CAAC,CAAC,EACnC,IAAKtD,CACP,CAAC,CACH,EACA,GAAIkE,GAAcA,EAAW,IAAK,CAC5BtB,GAAIA,EAAGsB,EAAW,GAAG,EACzB,MACF,CACF,EACA,GAAI,CAACR,EAAKd,EAAIoC,EAAMrB,IAAS,CACvBD,GAAO,OAAOA,EAAI,GAAG,GAAM,WAC7BA,EAAM,CAAE,GAAGA,EAAK,IAAK,OAAOA,EAAI,GAAG,CAAC,CAAE,GAExC,IAAMrB,EAAOqB,GAAOA,EAAI,GAAG,EACvB,CAACrB,GAAQ,CAACO,IAEVf,EAAOQ,CAAI,EACbR,EAAOQ,CAAI,EAAG,KAAK,CAAE,IAAKqB,EAAI,GAAG,EAAG,GAAId,CAAY,CAAC,EAErDf,EAAOQ,CAAI,EAAI,CAAC,CAAE,IAAKqB,EAAI,GAAG,EAAG,GAAId,CAAY,CAAC,EAEhDoC,GAAM9B,EAAgBQ,EAAKd,EAAaD,EAAMgB,CAAI,EACxD,EACA,IAAK,CAACD,EAAKd,IAAO,CAChB,IAAMP,EAAOqB,GAAOA,EAAI,GAAG,EAC3B,GAAI,GAACrB,GAAQ,CAACR,EAAOQ,CAAI,GAEzB,GAAIO,EAAI,CACN,IAAMqC,EAAQpD,EAAOQ,CAAI,EAAG,KAAK0C,GAAKA,EAAE,KAAQnC,CAAY,EACxDqC,GACFpD,EAAOQ,CAAI,EAAG,OAAOR,EAAOQ,CAAI,EAAG,QAAQ4C,CAAK,EAAG,CAAC,CAExD,MACE,OAAOpD,EAAOQ,CAAI,CAEtB,CACF,GAGF,GAAIhD,KAAWiC,EAAQ,KAAOA,EAAQ,QAAUA,EAAQ,MAAQ,MAAO,CACrE,IAAI4D,EAAM5D,EAAQ,IACd7B,EAAU,IACXyF,EAAwC,UAAU,GAAK,CAAC,EAC3D,GAAI,CAACA,EAAK,CACR,IAAMC,EAAS7D,EAAQ,OACnB,CAAE,OAAQA,EAAQ,MAAO,EACzB,CAAE,KAAMA,EAAQ,IAAK,EACzB4D,EAAM,IAAI5F,GAAU,gBAAgB6F,CAAM,EAC1C1F,EAAU,IAAM,MAAM,KAAMyF,EAAoC,SAAW,CAAC,CAAC,CAC/E,CAEA,IAAMvC,EAAO,CAAC3C,EAAcoF,IAA6B,CAEvD,IAAMC,EADM,KAAK,MAAMrF,CAAI,EACP,GAAG,EACvB,GAAIqF,GAAWnD,EAAgB,IAAImD,CAAO,EAAG,CAC3C,IAAM3B,EAAMxB,EAAgB,IAAImD,CAAO,EACvCnD,EAAgB,OAAOmD,CAAO,EAE9B,WAAW,IAAM,CACf,IAAMzC,EAAKhB,EAAMyD,CAAO,EACxB,GAAIzC,EAAI,CACN,IAAM6B,EAAKf,EAAI,GAAG,EACZN,EAAa,CAAE,CAACqB,CAAE,EAAG,IAAc,EACrC,OAAOf,EAAI,GAAG,GAAM,WACtBN,EAAIqB,CAAE,EAAI,CAAE,CAACf,EAAI,GAAG,CAAC,EAAG,IAAK,GAE/Bd,EAAG,CAAE,IAAKyC,EAAS,IAAKjC,CAAI,CAAC,EAC7B,OAAOxB,EAAMyD,CAAO,CACtB,CACF,EAAG7F,EAAY,IAAM,GAAK,CAC5B,CAEAC,EAAQ,EAAE,QAAQU,GAAU,CAC1B,IAAMW,EAAKX,EACX,GAAIW,GAAMA,EAAG,aAAe,UAAU,KACpCA,EAAG,KAAKd,EAAM,CAAE,OAAQoF,CAAS,CAAC,UACzBtE,EAAI,CACb,IAAMwE,EAAexE,EAAG,eAAiBG,GAAmB,EAG5D,GAFAH,EAAG,cAAgBwE,EAEfA,EAAa,YAAY,EAAG,CAC9B,IAAMjF,EAAQiF,EAAa,SAAS,EACpCA,EAAa,UAAU,EAEvB,WAAW,IAAM,CACXxE,GAAMA,EAAG,aAAe,UAAU,OACpCwE,EAAa,MAAM,EACnBxE,EAAG,KAAKd,EAAM,CAAE,OAAQoF,CAAS,CAAC,EAEtC,EAAG/E,CAAK,CACV,CACF,CACF,CAAC,CACH,EAEC,OAAC6E,EAAuF,GACvF,aACCpE,GAAyB,CACxB,GAAI,CAAC2B,EAAkB,IAAI3B,CAAE,EAAG,CAC9B,QAAQ,IAAI,gDAAgD,EAC5DA,EAAG,MAAM,KAAM,4CAA4C,EAC3D,MACF,CAEA,IAAMZ,EAAiBoD,EAAK,OAAO,CAAC,EACpC,QAAQ,IAAI,mCAAmCpD,CAAQ,EAAE,EAEzDY,EAAG,KAAK,QAAU,IAAIE,IAAoB,CACxC,IAAMP,EAAQO,EAAK,CAAC,EACpB,QAAQ,IAAI,mBAAoBP,CAAK,EACrCgC,EAAkB,OAAO3B,CAAE,CAC7B,CAAkC,EAElCA,EAAG,KAAK,QAAU,IAAM,CACtB,QAAQ,IAAI,kCAAkCZ,CAAQ,EAAE,EACxDuC,EAAkB,OAAO3B,CAAE,CAC7B,CAAkC,EAElCA,EAAG,KAAK,UAAY,IAAIE,IAAoB,CAC1C,IAAMhB,EAAOgB,EAAK,CAAC,EACboE,EAAWpE,EAAK,CAAC,EACjBuE,EAAa7E,GAAgBV,EAAMsB,EAAQ,cAAc,EAC/D,GAAI,CAACiE,EAAW,MAAO,CACrB,QAAQ,KAAK,oBAAoBA,EAAW,KAAK,EAAE,EACnDzE,EAAG,KAAK,KAAK,UAAU,CAAE,MAAOyE,EAAW,KAAM,CAAC,CAAC,EACnD,MACF,CAEA,IAAMC,EAAcjF,GAAcP,EAAMsB,EAAQ,cAAc,EAC9D,GAAI,CAACkE,EAAY,QAAS,CACxB,QAAQ,KAAK,qBAAqBA,EAAY,KAAK,EAAE,EACrD1E,EAAG,KAAK,KAAK,UAAU,CAAE,MAAO,cAAe,CAAC,CAAC,EACjD,MACF,CAEA,IAAMkC,EAAMwC,EAAY,KAExB,GADI,CAACxC,EAAI,GAAG,GACRzB,EAAI,MAAMyB,EAAI,GAAG,CAAC,EAAG,OAEzB,IAAM3C,EAAQmC,EAAY,SAAStC,CAAQ,EAC3C,GAAIG,EAAQ,EAAG,CACb,IAAMoF,EAAgBjD,EAAY,iBAAiBtC,CAAQ,EAI3D,GAHA,QAAQ,IACN,UAAUA,CAAQ,yCAAyCG,CAAK,yCAAyCoF,CAAa,GACxH,EACIjD,EAAY,iBAAiBtC,CAAQ,EAAG,CAC1C,QAAQ,IACN,UAAUA,CAAQ,yBAAyBuF,CAAa,sBAC1D,EACA3E,EAAG,MAAM,KAAM,uBAAuB,EACtC,MACF,CAEAA,EAAG,KACD,KAAK,UAAU,CACb,IAAKS,EAAI,MAAY+B,EAAK,OAAO,CAAC,CAAC,EACnC,IAAKN,EAAI,GAAG,EACZ,IAAK,iDAAiD,KAAK,KAAK3C,EAAQ,GAAI,CAAC,IAC7E,SAAUA,CACZ,CAAC,CACH,EACA,MACF,CAEA,IAAMqF,EAAiB,SAA2B,CAChDnE,EAAI,MAAMyB,EAAI,GAAG,CAAE,EAEfA,EAAI,KAAKG,EAAIH,EAAcL,CAAI,EAC/BK,EAAI,KAAK,MAAMO,EAAIP,EAAcL,CAAI,EACzCA,EAAK3C,EAAK,SAAS,EAAGoF,CAAQ,EAE9B,IAAMX,EAAKzB,EAAI,GAAG,EACZJ,EAAKhB,EAAM6C,CAAG,EAChB7B,IACF,OAAQI,EAAyB,GAAG,EACpC,OAAQA,EAAyB,GAAG,EACpCJ,EAAGI,CAAG,EACN,OAAOpB,EAAM6C,CAAG,EAEpB,EAEIpE,EAAQ,EACV,WAAWqF,EAAgBrF,CAAK,EAEhCqF,EAAe,CAEnB,CAAkC,CACpC,CACF,EACOhB,EAAI/B,CAAI,CACjB,CAGA,IAAMgD,EAAqB,CAAC,EACxBC,EAAkB,GAClBC,EAAgB,EAChBC,EAAyB,CAAC,EAC1BC,EAAwC,KACtCC,EAAiB1E,EAAQ,gBAAkB,IAE3C2E,EAAuB,CAACZ,EAAiB3B,EAAUrD,EAAQb,EAAY,IAAM,MAC1E,WAAW,IAAM,CACtB2C,EAAgB,OAAOkD,CAAO,EAC9BnD,EAAgB,OAAOmD,CAAO,EAC9B,IAAMzC,EAAKhB,EAAMyD,CAAO,EACxB,GAAIzC,EAAI,CACN,IAAM6B,EAAKf,EAAI,GAAG,EACZN,EAAa,CAAE,CAACqB,CAAE,EAAG,IAAc,EACrC,OAAOf,EAAI,GAAG,GAAM,WACtBN,EAAIqB,CAAE,EAAI,CAAE,CAACf,EAAI,GAAG,CAAC,EAAG,IAAK,GAE/Bd,EAAG,CAAE,IAAKyC,EAAS,IAAKjC,CAAI,CAAC,EAC7B,OAAOxB,EAAMyD,CAAO,CACtB,CACF,EAAGhF,CAAK,EAGJ6F,EAAe,IAAY,CAC/B,GAAIJ,EAAa,SAAW,EAAG,CAC7BC,EAAiB,KACjB,MACF,CAEA,IAAMjG,EAAM,KAAK,IAAI,EACrB,GAAI8F,GAAmB9F,EAAM+F,EAAe,CAC1CE,EAAiB,WAAWG,EAAc,KAAK,IAAI,IAAML,EAAgB/F,CAAG,CAAC,EAC7E,MACF,CAEI8F,GAAmB9F,GAAO+F,IAC5B,QAAQ,IAAI,kDAAkD,EAC9DD,EAAkB,GAClBC,EAAgB,GAGlB,IAAM7F,EAAO8F,EAAa,CAAC,EACrBK,EAAOC,EAAYpG,CAAI,EAEvBgD,EAAM,KAAK,MAAMhD,CAAI,EACrBqF,EAAUrC,EAAI,GAAG,EAIjBqD,EAAsB,CAACF,GAAQ,CAAC,CAACnD,EAAI,KAAO,CAACd,EAAgB,IAAImD,CAAQ,EAM/E,IAJIc,GAAQE,IACVP,EAAa,MAAM,EAGjBT,GAAWnD,EAAgB,IAAImD,CAAO,EAAG,CAC3C,IAAM3B,EAAMxB,EAAgB,IAAImD,CAAO,EACnCc,GACEhE,EAAgB,IAAIkD,CAAO,IAC7B,aAAalD,EAAgB,IAAIkD,CAAO,CAAE,EAC1ClD,EAAgB,OAAOkD,CAAO,GAEhCY,EAAqBZ,EAAS3B,CAAG,GACvBvB,EAAgB,IAAIkD,CAAO,GACrClD,EAAgB,IAAIkD,EAASY,EAAqBZ,EAAS3B,EAAK,CAAC,CAAC,CAEtE,CAEIoC,EAAa,OAAS,EACxBC,EAAiB,WAAWG,EAAc,EAAE,EAE5CH,EAAiB,IAErB,EAEMK,EAAepG,GAA0B,CAC7C,IAAIsG,EAAmB,GACvB,OAAAX,EAAM,QAAQY,GAAQ,CACpB,IAAMzF,EAAKyF,EACX,GAAIzF,GAAMA,EAAG,aAAe,UAAU,KACpCA,EAAG,KAAKd,CAAI,EACZsG,EAAmB,WACVxF,EAAI,CACb,IAAMwE,EAAexE,EAAG,eAAiBG,GAAmB,EAG5D,GAFAH,EAAG,cAAgBwE,EAEfA,EAAa,YAAY,EAAG,CAC9B,IAAMjF,EAAQiF,EAAa,SAAS,EACpCA,EAAa,UAAU,EAEvB,WAAW,IAAM,CACXiB,GAAQA,EAAK,aAAe,UAAU,OACxCjB,EAAa,MAAM,EACnBiB,EAAK,KAAKvG,CAAI,EAElB,EAAGK,CAAK,CACV,CACF,CACF,CAAC,EACMiG,CACT,EAEM3D,EAAQ3C,GAA0C,CACtD,GAAI8F,EAAa,QAAUE,EACzB,MAAO,CACL,IAAK,0CAA0CA,CAAc,6CAC/D,EAGFF,EAAa,KAAK9F,CAAI,EACjB+F,IACHA,EAAiB,WAAWG,EAAc,EAAE,EAEhD,EAEA,OAAI,EAAE5E,EAAQ,iBAAiB,QAAUA,EAAQ,MAAM,SAAW,KAChEA,EAAQ,MAAQ,CAAC,kBAAkBA,EAAQ,MAAQ,IAAI,EAAE,GAG3DA,EAAQ,MAAM,QAASiF,GAAiB,CACtC,IAAMC,EAAQ,IAAY,CACxB,IAAI1F,EAAuB,IAAI,UAAUyF,CAAI,EAC7CZ,EAAM,KAAK7E,CAAE,EACb,IAAMwE,EAAerE,GAAmB,EAExCH,EAAG,QAAU,IAAM,CAMjB,GALIA,GAAM6E,EAAM,QAAQ7E,CAAE,IAAM,IAC9B6E,EAAM,OAAOA,EAAM,QAAQ7E,CAAE,EAAG,CAAC,EAEnCA,EAAK,KAEDwE,EAAa,YAAY,EAAG,CAC9B,IAAMjF,EAAQiF,EAAa,SAAS,EACpCA,EAAa,UAAU,EACvB,WAAWkB,EAAOnG,CAAK,CACzB,CACF,EAEAS,EAAG,OAAS,IAAM,CAChBwE,EAAa,MAAM,CACrB,EAEAxE,EAAG,QAAW2F,GAAa,CACzB,QAAQ,IAAIA,CAAC,CACf,EAEA3F,EAAG,UAAY,MAAO4F,GAAoB,CACxC,IAAM1D,EAAM,KAAK,MAAM0D,EAAE,IAAc,EAEvC,GADI,CAAC1D,EAAI,GAAG,GACRzB,EAAI,MAAMyB,EAAI,GAAG,CAAC,EAAG,OAEzB,GAAIA,EAAI,UAAYA,EAAI,IAAK,CAC3B,QAAQ,IAAI,sBAAsBA,EAAI,GAAG,EAAE,EAC3C4C,EAAkB,GAClBC,EAAgB,KAAK,IAAI,EAAI7C,EAAI,SACjC,MACF,CAIA,GAFAzB,EAAI,MAAMyB,EAAI,GAAG,CAAE,EACfA,EAAI,KAAKG,EAAIH,EAAcL,CAAa,EACxCK,EAAI,IAAK,CAOX,IAAM2D,EAAa,IAAI,IACvB,OAAW,CAACtE,EAAMU,CAAI,IAAK,OAAO,QAAQC,EAAI,GAAG,EAAG,CAClD,IAAM4D,EAAQ,MAAMxE,EAAQC,CAAI,EAEhC,GADAsE,EAAW,IAAItE,EAAMuE,CAAK,EACrB,GAACA,GAAS,CAAC9E,EAAkB,IAAIO,CAAI,GAAM,CAACU,GAAQ,OAAOA,GAAS,UACzE,OAAW,CAAC,CAAEoB,CAAK,IAAK,OAAO,QAAQpB,CAAI,EAAG,CAC5C,IAAM8B,GAAeC,EAAI,GAAGX,CAAmB,EAC3CU,IAAQ/C,EAAkB,IAAI+C,EAAM,CAC1C,CACF,CAIA,IAAMgC,EAAqB,CAAC,EACtBC,EAA4B,CAAC,EACnC,OAAW,CAACzE,EAAMU,CAAI,IAAK,OAAO,QAAQC,EAAI,GAAG,EAAG,CAClD,IAAI+D,EAAcJ,EAAW,IAAItE,CAAI,EACjCP,EAAkB,IAAIO,CAAI,IAC5B0E,EAAc,GAOdD,EAAgB,KAAKzE,CAAI,GAEvB0E,IAAaF,EAAYxE,CAAI,EAAIU,EACvC,CAGA,GAAI,OAAO,KAAK8D,CAAW,EAAE,OAAS,EAAG,CAEvC,IAAMG,EAAc,CAAE,IAAKH,EAAa,IAAK7D,EAAI,GAAG,CAAG,EACvD,MAAMO,EAAIyD,EAAarE,CAAa,CACtC,CAKAmE,EAAgB,QAAQzE,GAAQP,EAAkB,OAAOO,CAAI,CAAC,CAChE,CAEA,IAAMoC,EAAKzB,EAAI,GAAG,EACZJ,EAAKhB,EAAM6C,CAAG,EAChB7B,IACF,OAAQI,EAAyB,GAAG,EACpC,OAAQA,EAAyB,GAAG,EACpCJ,EAAGI,CAAG,EACN,OAAOpB,EAAM6C,CAAG,EAEpB,CACF,EACA+B,EAAM,CACR,CAAC,EAEM9B,EAAI/B,CAAI,CACjB,EAEOsE,GAAQ7F,GCz5Bf,IAAM8F,GAAO,CAACC,EAAiCC,IAAwC,CAChFA,IAAMA,EAAOC,GAAKF,CAAqB,GAC5C,IAAIG,EAAiB,CAAC,EAClBC,EAAW,GACXC,EAAU,GACVC,EAAU,EAERC,EAAO,CACXC,EACAC,EACAC,EACAC,IACS,CACT,IAAMC,EAASJ,GAA2B,CACxCF,IACAC,EAAKC,EAAUC,EAAUC,EAAaC,CAAG,CAC3C,EACME,EAAQC,GAA8B,CAC1CX,EAAO,CAAC,EACRG,EAAU,EACVD,EAAU,GACVM,EAAIG,CAAG,CACT,EACMC,EAAO,IAAY,CACvB,GAAIZ,EAAK,SAAW,EAAG,CACrBU,EAAK,4BAA4B,EACjC,MACF,CAEA,IAAMG,EAAMb,EAAK,MAAM,EACvBF,EAAK,IACH,CAAE,IAAKe,EAAK,IAAK,CAAC,OAAQ,MAAO,MAAM,CAAE,EACzC,MAAMC,GAAO,CACX,GAAIA,EAAI,IAAK,CACXJ,EAAK,iBAAiBG,CAAG,KAAKC,EAAI,GAAG,EAAE,EACvC,MACF,CAEA,IAAMC,EAAOD,EAAI,KAAOA,EAAI,IAAID,CAAG,EACnC,GAAI,CAACE,GAAQ,CAACA,EAAK,KAAM,OAAOH,EAAK,EAErC,IAAMI,EAAW,KAAK,MAAMD,EAAK,IAAc,EAIzCE,EAAO,MAAMC,EAAI,KAAKZ,EAAUU,EAAS,IAAI,EAC7CG,EAAO,MAAMD,EAAI,QAAQF,EAAS,IAAKC,CAAI,EAGjD,GAAI,CAACE,EAAK,OAAOP,EAAK,EAStB,GAPAQ,EAAK,GAAK,CACR,SAAUf,EACV,IAAKU,EAAK,IACV,KAAMA,EAAK,KACX,KAAMI,EAAI,KACV,MAAOA,EAAI,KACb,EACIZ,IAAgB,GAAI,CACtB,IAAMc,EAAaC,EAAK,OAAO,EAAE,EAC3BC,EAAU,MAAML,EAAI,KAAKX,EAAac,CAAI,EAC1CG,EAAM,MAAMN,EAAI,QAAQC,EAAKI,CAAO,EACpCE,EAAS,CACb,KAAM,KAAK,UAAU,CAAE,IAAKD,EAAK,KAAMH,CAAK,CAAC,CAC/C,EACMK,EAAY,KAAK,IAAI,EACrBC,EAAM,MAAMT,EAAI,cAAcQ,EAAWN,EAAK,EAAE,EAChDQ,EAAcA,GAAMf,EAAKY,EAAQE,EAAMZ,EAAK,IAAeW,CAAS,EAC1E5B,EAAK,IAAI8B,EAAOjB,GAAO,CAEnBD,EADEC,EACG,iBAAiB,KAAK,UAAUc,CAAM,CAAC,OAAOZ,CAAG,KAAKF,CAAG,GAEzD,IAF2D,CAIpE,CAAC,EACD,MACF,CAEAD,EAAK,IAAI,CACX,CACF,CACF,EAEA,GAAIP,EAAU,EAAG,CACfO,EAAK,4BAA4B,EACjC,MACF,CAEA,IAAMmB,EAAO,KAAOxB,EACpBP,EAAK,IACH,CAAE,IAAK+B,CAAK,EACZ,MAAMf,GAAO,CACX,GAAIA,EAAI,IAAK,CACXJ,EAAK,iBAAiBmB,CAAI,KAAKf,EAAI,GAAG,EAAE,EACxC,MACF,CAEA,IAAMC,EAAOD,EAAI,KAAOA,EAAI,IAAIe,CAAI,EACpC,GAAI,CAACd,EAAM,OAAON,EAAMJ,CAAQ,EAEhC,OAAQU,EAAyB,EACjCf,EAAO,OAAO,KAAKe,CAAI,EACvBH,EAAK,CACP,CACF,CACF,EAEMQ,EAAsB,CAC1B,GAAI,KACJ,OAAQ,CAACf,EAAUC,EAAUwB,IAAO,CAClC,IAAMtB,EAAOG,GAA8B,CACrCmB,EAAIA,EAAGnB,CAAG,EACLA,GAAK,QAAQ,IAAIA,CAAG,CAC/B,EAEA,GAAIV,EAAU,CACZO,EAAI,+BAA+B,EACnC,MACF,CAEA,GAAIH,IAAa,GAAI,CACnBG,EAAI,2BAA2B,EAC/B,MACF,CAEA,GAAIF,IAAa,GAAI,CACnBE,EAAI,2BAA2B,EAC/B,MACF,CAEAP,EAAW,GAEX,IAAM4B,EAAO,KAAOxB,EACpBP,EAAK,IACH,CAAE,IAAK+B,CAAK,EACZ,MAAMf,GAAO,CACX,GAAIA,EAAI,IAAK,CACXb,EAAW,GACXO,EAAI,iBAAiBqB,CAAI,KAAKf,EAAI,GAAG,EAAE,EACvC,MACF,CAEA,GAAIA,EAAI,KAAOA,EAAI,IAAIe,CAAI,EAAG,CAC5B5B,EAAW,GACXO,EAAI,yBAAyB,EAC7B,MACF,CAEA,IAAMa,EAAaC,EAAK,OAAO,EAAE,EAC3BL,EAAO,MAAMC,EAAI,KAAKZ,EAAUe,CAAI,EACpCU,EAAO,MAAMb,EAAI,KAAK,EACtBc,EAAO,CAAE,KAAMD,EAAK,KAAM,MAAOA,EAAK,KAAM,EAC5CP,EAAM,MAAMN,EAAI,QAAQc,EAAMf,CAAI,EAClCF,EAAO,CACX,SAAUV,EACV,IAAK0B,EAAK,IACV,KAAMA,EAAK,KACX,KAAM,KAAK,UAAU,CAAE,IAAKP,EAAK,KAAMH,CAAK,CAAC,CAC/C,EAEMR,EAAM,IAAMkB,EAAK,IACjBL,EAAY,KAAK,IAAI,EACrBC,EAAM,MAAMT,EAAI,cAAcQ,EAAWK,CAAI,EAC7CH,EAAcA,GAAMf,EAAKE,EAAMY,EAAMI,EAAK,IAAKL,CAAS,EAC9D5B,EAAK,IAAI8B,EAAOjB,GAAO,CAErB,GADAV,EAAW,GACPU,EAAK,CACPH,EAAI,iBAAiB,KAAK,UAAUO,CAAI,CAAC,OAAOF,CAAG,KAAKF,CAAG,EAAE,EAC7D,MACF,CAEA,IAAMsB,EAAM,CAAE,CAACpB,CAAG,EAAG,CAAE,IAAKA,CAAI,CAAE,EAClCf,EAAK,IAAU8B,GAAMC,EAAMI,CAAY,EAAGtB,GAAO,CAC/C,GAAIA,EAAK,CACPH,EAAI,iBAAiB,KAAK,UAAUyB,CAAG,CAAC,OAAOJ,CAAI,KAAKlB,CAAG,EAAE,EAC7D,MACF,CAEImB,GAAIA,EAAG,IAAI,CACjB,CAAC,CACH,CAAC,CACH,CACF,CACF,EACA,KAAM,CAACzB,EAAUC,EAAUwB,IAAO,CAChC,IAAMtB,EAAOG,GAA8B,CACrCmB,EAAIA,EAAGnB,CAAG,EACLA,GAAK,QAAQ,IAAIA,CAAG,CAC/B,EAEA,GAAIT,EAAS,CACXM,EAAI,gCAAgC,EACpC,MACF,CAIA,GAFAY,EAAK,GAAK,KAENf,IAAa,GAAI,CACnBG,EAAI,2BAA2B,EAC/B,MACF,CAEA,GAAIF,IAAa,GAAI,CACnBE,EAAI,2BAA2B,EAC/B,MACF,CAEAN,EAAU,GACVE,EAAKC,EAAUC,EAAU,GAAIE,CAAG,CAClC,EACA,OAAQ,CAACH,EAAUC,EAAUC,EAAauB,IAAO,CAC/C,IAAMtB,EAAOG,GAA8B,CACrCmB,EAAIA,EAAGnB,CAAG,EACLA,GAAK,QAAQ,IAAIA,CAAG,CAC/B,EAEA,GAAIT,EAAS,CACXM,EAAI,gCAAgC,EACpC,MACF,CAIA,GAFAY,EAAK,GAAK,KAENf,IAAa,GAAI,CACnBG,EAAI,2BAA2B,EAC/B,MACF,CAEA,GAAIF,IAAa,GAAI,CACnBE,EAAI,2BAA2B,EAC/B,MACF,CAEA,GAAID,IAAgB,GAAI,CACtBC,EAAI,+BAA+B,EACnC,MACF,CAEAN,EAAU,GACVE,EAAKC,EAAUC,EAAUC,EAAaC,CAAG,CAC3C,EACA,MAAO,CAAC0B,EAAe,KAAU,CAC/B,GAAI,CAACd,EAAK,GAAI,CACZ,QAAQ,IAAI,0CAA0C,EACtD,MACF,CAEA,GAAIc,EAAc,CACZ,OAAO,WAAW,aAAiB,KACrC,WAAW,aAAa,QAAQ,UAAW,KAAK,UAAUd,EAAK,EAAE,CAAC,EAEhE,OAAO,WAAW,eAAmB,KACvC,WAAW,eAAe,WAAW,SAAS,EAEhD,MACF,CAEI,OAAO,WAAW,eAAmB,KACvC,WAAW,eAAe,QAAQ,UAAW,KAAK,UAAUA,EAAK,EAAE,CAAC,EAElE,OAAO,WAAW,aAAiB,KACrC,WAAW,aAAa,WAAW,SAAS,CAEhD,EACA,OAAQ,IAAM,CACZ,GAAI,OAAO,WAAW,aAAiB,IAAa,CAClD,IAAMe,EAAK,WAAW,aAAa,QAAQ,SAAS,EACpD,GAAIA,EAAI,CACNf,EAAK,GAAK,KAAK,MAAMe,CAAE,EACvB,MACF,CACF,CAEA,GAAI,OAAO,WAAW,eAAmB,IAAa,CACpD,IAAMA,EAAK,WAAW,eAAe,QAAQ,SAAS,EAClDA,IACFf,EAAK,GAAK,KAAK,MAAMe,CAAE,EAE3B,CACF,EACA,MAAO,IAAM,CACXf,EAAK,GAAK,KACN,OAAO,WAAW,aAAiB,KACrC,WAAW,aAAa,WAAW,SAAS,EAE1C,OAAO,WAAW,eAAmB,KACvC,WAAW,eAAe,WAAW,SAAS,CAElD,EACA,OAAQ,CAACf,EAAUC,EAAUwB,IAAO,CAClC,IAAMtB,EAAOG,GAA8B,CACrCmB,EAAIA,EAAGnB,CAAG,EACLA,GAAK,QAAQ,IAAIA,CAAG,CAC/B,EAEA,GAAIT,EAAS,CACXM,EAAI,gCAAgC,EACpC,MACF,CAEA,GAAIH,IAAa,GAAI,CACnBG,EAAI,2BAA2B,EAC/B,MACF,CAEA,GAAIF,IAAa,GAAI,CACnBE,EAAI,2BAA2B,EAC/B,MACF,CAEAN,EAAU,GACVE,EAAKC,EAAUC,EAAU,GAAI,MAAMK,GAAO,CACxC,GAAIA,EAAK,CACPH,EAAIG,CAAG,EACP,MACF,CAEA,IAAMI,EAAO,CAAE,SAAU,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,IAAK,EAC3DW,EAAY,KAAK,IAAI,EACrBC,EAAM,MAAMT,EAAI,cAAcQ,EAAWN,EAAK,EAAG,EACjDP,EAAM,IAAMO,EAAK,GAAI,IACrBQ,EAAcA,GAAMf,EAAKE,EAAeY,EAAMP,EAAK,GAAI,IAAKM,CAAS,EAC3E5B,EAAK,IAAI8B,EAAOjB,GAAO,CACrB,GAAIA,EAAK,CACPH,EAAI,yBAAyBK,CAAG,KAAKF,CAAG,EAAE,EAC1C,MACF,CAEAS,EAAK,GAAK,KACNU,GAAIA,EAAG,IAAI,CACjB,CAAC,CACH,CAAC,CACH,CACF,EACA,OAAOV,CACT,EAEOgB,GAAQxC,GC5Tf,IAAMyC,GAAWC,GAAyD,CACxE,IAAIC,EACA,OAAOD,GAAQ,SAAUC,EAAU,CAAE,MAAO,CAACD,CAAG,CAAE,EAC7CA,aAAe,MAAOC,EAAU,CAAE,MAAOD,CAAI,EACtCE,EAAI,GAAGF,CAAG,EACrBC,EAAUD,EADcC,EAAU,CAAC,EAGxC,IAAME,EAAOC,GAAKH,CAAO,EACnBI,EAAOC,GAAKL,EAASE,CAAa,EAClCI,EAAM,IAAI,IACVC,EAAS,IAAI,IAEbC,EAAMC,GAERA,IAAS,MACTA,IAAS,IACTA,IAAS,IACT,OAAOA,GAAS,UAChB,CAAC,CAAOC,EAAI,GAAGD,CAAI,GACbE,GAAI,GAAGF,CAAI,EAIfG,EACJH,GAC6B,CAC7B,GAAID,EAAGC,CAAkB,EAAG,MAAO,GAEnC,GAAUR,EAAI,GAAGQ,CAAI,EAAG,CACtB,IAAMI,EAAiB,CAAC,EACxB,OAAW,CAACC,EAAKC,CAAK,IAAK,OAAO,QAAQN,CAAI,EAAG,CAC/C,GAAIK,IAAQ,IACV,MAAO,qDAET,GAAUb,EAAI,GAAGc,CAAK,GAAKP,EAAGO,CAAmB,EAAG,CAClDF,EAAK,KAAKC,CAAG,EACb,QACF,CACA,OAAI,OAAOC,EAAU,IACZ,mBAAmBD,CAAG,kCAGxB,SADO,KAAK,UAAU,CAAE,CAACA,CAAG,EAAGC,CAAM,CAAC,CACxB,iCACvB,CACA,GAAIF,EAAK,SAAW,EAAG,OAAOA,CAChC,CAEA,MAAO,SADO,KAAK,UAAUJ,CAAI,CACZ,iCACvB,EAEMO,EAAOC,GAAmC,CAC9C,IAAIC,EAAQD,EACNE,EAAM,CACVC,EACAC,EACAC,EACAC,IACS,CACTrB,EAAK,IACGD,EAAI,IAAImB,EAAc,IAAKC,CAAI,EACrC,MAAMG,GAAO,CAEX,GADIA,EAAI,KAAK,QAAQ,IAAIA,EAAI,GAAG,EAC5BA,EAAI,KAAOA,EAAI,IAAIH,CAAI,EAAG,CAC5B,OAAQG,EAAI,IAAIH,CAAI,EAAsB,EAC1C,OAAQG,EAAI,IAAIH,CAAI,EAAoCI,CAAa,EACrE,OAAQD,EAAI,IAAIH,CAAI,EAAoCK,EAAa,EACrE,IAAMC,EAAOH,EAAI,IAAIH,CAAI,EACzB,MAAM,QAAQ,IAAI,OAAO,KAAKM,CAAI,EAAE,IAAI,MAAMb,GAAO,CACnD,IAAMc,EAAWlB,EAAI,GAAGiB,EAAKb,CAAG,CAAe,EAC/C,GAAI,CAACc,EAAI,OACT,IAAMC,EAAc,MAAOC,EAAU,IAAwB,CAC3D,IAAMrB,EAAO,MAAM,IAAI,QAAiBsB,GAAO,CAC7C,IAAMC,EAAeC,EAAK,OAAO,EAC3BC,EAAM3B,EAAO,IAAIW,CAAM,EAC7BX,EAAO,IAAIyB,EAAQ,CACjB,MAAO,CAAC,CAAE,KAAM,KAAM,KAAMJ,CAAG,CAAC,EAChC,KAAMM,EAAMA,EAAI,KAAO,IACzB,CAAC,EACDlB,EAAIgB,CAAM,EAAE,KAAK,KAAeD,EAAcR,CAAI,CACpD,CAAC,EACD,OAAId,IAAS,MAAQqB,GAAW,EACvBrB,GAET,MAAM,IAAI,QAAQ0B,GAAW,WAAWA,EAAS,EAAE,CAAC,EAC7CN,EAAYC,EAAU,CAAC,EAChC,EACAH,EAAKb,CAAG,EAAK,MAAMe,EAAY,CACjC,CAAC,CAAC,EACFP,EAAIE,EAAI,IAAIH,CAAI,CAAC,CACnB,MACEC,EAAI,IAAI,CAEZ,EACAC,CACF,CACF,EAEMa,EAAQ,MACZf,EACAZ,EACA4B,EACAC,IAC0B,CAC1B,GAAID,EAAS,CACX,IAAME,EAAY,KAAK,IAAI,EACrBC,EAAM,MAAMC,EAAI,cAAcF,EAAWF,CAAO,EACtD,OAAaD,GAAMf,EAAMZ,EAAM+B,EAAMH,EAAQ,IAAKE,CAAS,CAC7D,CAEA,OAAIvC,EAAQ,QACLsC,IAAIA,EAAK,QAAQ,KACtBA,EAAG,yBAAyBjB,CAAI,gCAAgC,EACzD,MAGIe,GAAMf,EAAMZ,CAAI,CAC/B,EAEMiC,EAAQxB,GACJT,GAAwB,CAC9B,IAAMyB,EAAM3B,EAAO,IAAIW,CAAK,EACxBgB,GAAO,OAAOA,EAAI,GAAO,IAC3B,WAAW,IAAMA,EAAI,GAAIzB,CAAa,EAAG,CAAC,EACjCA,GACT,QAAQ,IAAI,6BAA8BA,EAAM,MAAOyB,CAAG,EAExDA,GAAO,CAACA,EAAI,IAAI3B,EAAO,OAAOW,CAAK,CACzC,EAGIyB,EAAc,CAClBtB,EACAuB,EACAV,EACAW,EACAC,EACAR,EACAS,EAAK,KACI,CACT,IAAIC,EAA8C,KAC5CC,EAAU,IAAY,CAE1B,GAAI,CAAC1C,EAAO,IAAIW,CAAM,EAAG,CACvBhB,EAAK,IAAI,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EAAGK,CAAO,EACtCD,GAAO,aAAaA,CAAK,EAC7B,MACF,CACA9C,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EACvBpB,GAAO,CACL,IAAMG,EAAOH,EAAI,KAAOA,EAAI,IAAIH,CAAI,EAC9BO,EAAWlB,EAAI,GAAGiB,GAAQA,EAAKiB,CAAI,CAAe,EACxD,GAAI,CAAChB,EAAI,CAGH,CAACmB,GAAMpB,GAAQA,EAAK,GAAK,OAAOA,EAAKiB,CAAI,EAAM,MAC7CI,GAAO,aAAaA,CAAK,EAC7B9C,EAAK,IAAI,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EAAGK,CAAO,EAC1CX,EAAGX,EAAKiB,CAAI,CAAC,GAEf,MACF,CACII,GAAO,aAAaA,CAAK,EAC7B9C,EAAK,IAAI,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EAAGK,CAAO,EAC1Cf,EAAI,MAAMW,CAAC,EAAG,KAAOjB,EACrBrB,EAAO,IAAIW,EAAQ,CAAE,GAAGgB,CAAI,CAAC,EACzBa,EACF/B,EAAIE,CAAK,EAAE,GAAG4B,EAAQ,GAAKR,EAAIQ,EAAQ,KAAMA,EAAQ,IAAI,EAEzD9B,EAAIE,CAAK,EAAE,KAAK,KAAe4B,EAAQ,IAAcR,EAAaQ,EAAQ,IAAI,CAElF,EACA,CAAE,GAAGA,EAAQ,KAAM,QAAS,OAAOZ,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,MAAO,CACvG,CACF,EACAE,EAAK,GAAG,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EAAGK,EAAS,GAAOH,EAAQ,IAAI,EAIzDC,IACHC,EAAQ,WAAW,IAAM,CACvB9C,EAAK,IAAI,CAAE,IAAKmB,EAAM,IAAKuB,CAAK,EAAGK,CAAO,EACtCX,GAAIA,EAAG,IAAI,CACjB,EAAG,IAAK,EAEZ,EAEMH,EAAU,CACdW,EAQAR,IACsB,CACtB,GAAI,CAACQ,EACH,eAAQ,IAAI,0CAA0C,EAC/C,GAGT,IAAM3B,EAAM,OAAO2B,EAAQ,IAAQ,IAC7BI,EAAM,OAAOJ,EAAQ,IAAQ,IAC7BC,EAAK,OAAOD,EAAQ,GAAO,IAC3BK,EAAM,OAAOL,EAAQ,IAAQ,IAE/BM,EAAQ,GACNlB,EAAM3B,EAAO,IAAIW,CAAM,EAC7B,GAAI,CAACgB,EAAK,MAAO,CAAC,KAAM,KAAM,KAAM,IAAI,EACxC,QAASW,EAAI,EAAGA,EAAIX,EAAI,MAAM,OAAQW,IACpC,GAAIX,EAAI,MAAMW,CAAC,EAAG,OAAS,KAC3B,CAAAO,EAAQ,GACR,MAGF,GAAIA,EAAO,CACT,IAAIP,EAAI,EACR,KAAOA,EAAIX,EAAI,MAAM,QAAUA,EAAI,MAAMW,CAAC,EAAG,OAAS,MAAMA,IAC5D,GAAM,CAAE,KAAAD,EAAM,KAAAvB,CAAK,EAAIa,EAAI,MAAMW,EAAI,CAAC,EACtC,OAAA3C,EAAK,IACH,CAAE,IAAKmB,EAAO,IAAKuB,CAAM,EACzB,MAAMpB,GAAO,CACX,GAAIA,EAAI,IAAK,CACX,QAAQ,IAAI,iBAAiBoB,CAAI,OAAOvB,CAAI,KAAKG,EAAI,GAAG,EAAE,EACtDc,GAAIA,EAAG,IAAI,EACf,MACF,CAEA,IAAIX,EAAOH,EAAI,KAAOA,EAAI,IAAIH,CAAK,EACnC,GAAIM,GAAQ,OAAOA,EAAKiB,CAAK,EAAM,IAAa,CAC9C,IAAIhB,EAAWlB,EAAI,GAAGiB,EAAKiB,CAAK,CAAe,EAC/C,GAAIhB,EACFM,EAAI,MAAMW,CAAC,EAAG,KAAOjB,EACrBrB,EAAO,IAAIW,EAAQ,CAAE,GAAGgB,CAAI,CAAC,EACzBf,EACFH,EAAIE,CAAK,EAAE,KAAK,KAAe4B,EAAQ,IAAcR,EAAaQ,EAAQ,IAAI,EACrEI,EACTlC,EAAIE,CAAK,EAAE,IAAI4B,EAAQ,IAAMR,CAAW,EAC/BS,EACT/B,EAAIE,CAAK,EAAE,GAAG4B,EAAQ,GAAKR,EAAKQ,EAAQ,KAAMA,EAAQ,IAAI,EACjDK,GACTnC,EAAIE,CAAK,EAAE,IAAIoB,CAAW,UAEnBnB,EACTmB,EAAIX,EAAKiB,CAAK,CAAC,UACNM,EAAK,CACdtB,EAAWK,EAAK,OAAO,EACvBN,EAAKiB,CAAK,EAAUlC,EAAI,IAAIkB,CAAE,EAC9B,IAAMyB,EAAI,MAAMjB,EAAMf,EAAOM,EAAeO,EAAI,KAAMI,CAAW,EACjE,GAAIe,IAAM,KAAM,OAEhBnD,EAAK,IAAImD,EAAGC,GAAO,CACjB,GAAIA,EAAK,CACNhB,EAA6B,iBAAiBM,CAAI,OAAOvB,CAAI,KAAKiC,CAAG,EAAE,EACxE,MACF,CACI1B,IACFM,EAAI,MAAMW,CAAC,EAAG,KAAOjB,GAEvBZ,EAAIE,CAAK,EAAE,IAAI4B,EAAQ,IAAMR,CAAW,CAC1C,CAAC,CACH,MAAWS,GAGTJ,EAAYtB,EAAOuB,EAAOV,EAAKW,EAAGC,EAASR,CAAG,EAC1CQ,EAAQ,MAAMR,EAAI,IAAI,GACjBa,GACLb,GAAIA,EAAG,IAAI,CAEnB,SAAWY,EAAK,CACd,IAAMtB,EAAWK,EAAK,OAAO,EACxBN,IAAMA,EAAO,CAAC,GACnBA,EAAKiB,CAAK,EAAUlC,EAAI,IAAIkB,CAAE,EAC9B,IAAMyB,EAAI,MAAMjB,EAAMf,EAAOM,EAAeO,EAAI,KAAMI,CAAW,EACjE,GAAIe,IAAM,KAAM,OAEhBnD,EAAK,IAAImD,EAAGC,GAAO,CACjB,GAAIA,EAAK,CACNhB,EAA6B,iBAAiBM,CAAI,OAAOvB,CAAI,KAAKiC,CAAG,EAAE,EACxE,MACF,CACApB,EAAI,MAAMW,CAAC,EAAG,KAAOjB,EACrBZ,EAAIE,CAAK,EAAE,IAAI4B,EAAQ,IAAMR,CAAW,CAC1C,CAAC,CACH,SACMS,EAEFJ,EAAYtB,EAAOuB,EAAOV,EAAKW,EAAGC,EAASR,CAAG,EAC1CQ,EAAQ,MAAMR,EAAI,IAAI,UACjBnB,GAAOQ,EAAM,CACtB,IAAM4B,EAAM5B,EAAwE,IAAI,GAAG,EACvF4B,GAAM,OAAO,KAAKA,CAAE,EAAE,OAAS,GAAK,OAAOA,EAAGX,CAAK,EAAM,IAEvDN,GAAIA,EAAG,IAAI,EAGfK,EAAYtB,EAAOuB,EAAOV,EAAKW,EAAGC,EAASR,EAAK,EAAK,CAEzD,MAEMA,GAAIA,EAAG,IAAI,CAGrB,EACA,CAAE,GAAGQ,EAAQ,KAAM,QAAS,OAAOZ,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,MAAO,CACvG,EACO,EACT,CAEA,OAAImB,GAAOe,EAAI,MAAMA,EAAI,MAAM,OAAS,CAAC,EAAG,OAAS,MACnDA,EAAI,MAAM,KAAK,CAAE,KAAM,KAAM,KAAM,IAAK,CAAC,EACzClB,EAAIE,CAAK,EAAE,KAAK,KAAe4B,EAAQ,IAAcR,EAAaQ,EAAQ,IAAI,EACvE,IAGFZ,EAAI,MAAMA,EAAI,MAAM,OAAS,CAAC,CACvC,EAEA,MAAO,CACL,IAAK,SAEHpB,EACAM,EACAkB,EACAf,EACY,CACZ,IAAIiC,EACAC,EACAC,EAYJ,GAVI,OAAOtC,GAAQ,YACjBsC,EAAOpB,EACPmB,EAAWrC,EACXoC,EAAY,OAEZA,EAAYpC,EACZqC,EAAWnB,EACXoB,EAAOnC,GAGLT,IAAQ,MAAQA,IAAQ,IAAMA,IAAQ,IACxC,eAAQ,IAAI,4BAA4B,EACpC2C,GAAUA,EAAS,IAAI,EACpB,KAGT,GAAID,GAAa,OAAOC,GAAa,WACnC,eAAQ,IAAI,wCAAwC,EAC7C,KAQT,GALAvC,EAAce,EAAK,OAAO,EAC1B1B,EAAO,IAAIW,EAAO,CAChB,MAAO,CAAC,CAAE,KAAM,OAAOJ,CAAG,EAAG,KAAM,MAAO,CAAC,EAC3C,GAAI2C,CACN,CAAC,EACG,CAACA,EAAU,OAAOzC,EAAIE,CAAK,EAE/B,IAAMyC,EAAQjB,EAAKxB,CAAK,EAClB0C,EAASzB,EAAQ,CAAE,IAAKqB,EAAW,KAAME,CAAK,EAAGC,CAAK,EAC5D,OAAIC,GAAQzC,EAAIqC,EAAoBI,EAAO,KAAOD,EAAOD,CAAI,EACtD,IACT,EAEA,KAAM,SAEJ5C,EACAM,EACAkB,EACAf,EACY,CACZ,IAAIiC,EACAC,EACAC,EAEA,OAAOtC,GAAQ,YACjBsC,EAAOpB,EACPmB,EAAWrC,EACXoC,EAAY,OAEZA,EAAYpC,EACZqC,EAAWnB,EACXoB,EAAOnC,GAGT,IAAMD,EAAOJ,GACHT,GAAwB,CAC1BgD,EACFA,EAAShD,CAAI,EAEbiC,EAAKxB,CAAK,EAAET,CAAI,CAEpB,EAGF,GAAI,CAACS,EACH,eAAQ,IAAI,2CAA2C,EACnDuC,GAAUA,EAAS,IAAI,EACpB,KAGT,IAAMI,EAAOvC,EAAIJ,CAAK,EACtB,GAAIJ,IAAQ,IAAMA,IAAQ,IACxB,OAAA+C,EAAK,IAAI,EACF,KAGT,GAAIL,GAAa,OAAOC,GAAa,WACnC,eAAQ,IAAI,wCAAwC,EAC7C,KAGT,IAAMvB,EAAM3B,EAAO,IAAIW,CAAK,EAC5B,GAAI,CAACgB,EAAK,OAAO,KAQjB,GANIuB,GAAY,OAAOvB,EAAI,GAAO,MAChCA,EAAI,GAAKuB,EACTA,EAAW,QAGT3C,IAAQ,MAAMoB,EAAI,MAAM,KAAK,CAAE,KAAM,OAAOpB,CAAG,EAAG,KAAM,IAAK,CAAC,EAC9D,CAACoB,EAAI,GAAI,OAAOlB,EAAIE,CAAK,EAE7B,IAAM0C,EAASzB,EAAQ,CAAE,IAAKqB,EAAW,KAAME,CAAK,EAAGG,CAAI,EAC3D,OAAID,GAAQzC,EAAIqC,EAAoBI,EAAO,KAAOC,EAAMH,CAAI,EACrD,IACT,EAEA,IAAK,SACHjD,EACAqD,EACAxB,EACmB,CACnB,IAAIyB,EAAQ,GACRN,EAEA,OAAOK,GAAQ,YACjBL,EAAWK,EACXC,EAAQ,KAERA,EAAQD,GAAO,GACfL,EAAWnB,GAGb,IAAMhB,EAAOJ,GACHT,GAA+B,CACjCgD,EACFA,EAAShD,CAAI,EAEbiC,EAAKxB,CAAK,EAAET,CAAI,CAEpB,EAGF,GAAI,CAACS,EAAO,CACNuC,GAAUA,EAAS,2CAA2C,EAClE,MACF,CAEA,IAAMvB,EAAM3B,EAAO,IAAIW,CAAM,EAC7B,GAAI,CAACgB,EAAK,OAEN,CAACA,EAAI,IAAMuB,IACbvB,EAAI,GAAKuB,EACTA,EAAW,QAGTM,IAAOtD,EAAO,CAAE,CAAOwB,EAAK,OAAO,CAAC,EAAGxB,CAAK,GAEhD,IAAMoD,EAAOvC,EAAIJ,CAAK,EAChB0C,EAAShD,EAAMH,CAAI,EACzB,GAAI,OAAOmD,GAAW,SAAU,CAC9BC,EAAKD,CAAM,EACX,MACF,CAEA,IAAMI,EAAW7B,EAAQ,CAAE,IAAK1B,EAAM,KAAM,CAAC,IAAK,EAAI,CAAE,EAAGoD,CAAa,EACxE,GAAI,CAACG,EAAU,OAEf,GAAM,CAAE,KAAApB,EAAM,KAAAvB,CAAK,EAAI2C,EACvB,GAAI,CAAC3C,EAAM,OAEX,GAAIuC,IAAW,GAAM,CACnB1D,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EACxB,MAAMpB,GAAO,CACX,GAAIA,EAAI,IAAK,CACXqC,EAAK,iBAAiBxC,CAAI,KAAKG,EAAI,GAAG,EAAE,EACxC,MACF,CAEA,IAAIG,EAAOH,EAAI,KAAOA,EAAI,IAAIH,CAAI,EAC5B4C,EAAUtC,GAAQA,EAAKiB,CAAK,EAC5BhB,EAAWlB,EAAI,GAAGuD,CAAqB,EAC7C,GAAI,CAACrC,EAAI,CACFD,IAAMA,EAAO,CAAC,GACnBA,EAAKiB,CAAK,EAAanC,EACvB,IAAM4C,EAAI,MAAMjB,EAAMf,EAAMM,EAAeO,EAAI,KAAM2B,CAAa,EAClE,GAAIR,IAAM,KAAM,OAEhBnD,EAAK,IAAImD,EAAGQ,CAAa,EACzB,MACF,CAEA3D,EAAK,IAAI,CAAE,IAAK0B,CAAG,EAAG,MAAMJ,GAAO,CACjC,GAAIA,EAAI,IAAK,CACXqC,EAAK,iBAAiBjC,CAAE,KAAKJ,EAAI,GAAG,EAAE,EACtC,MACF,CAEA,GAAI,CAACA,EAAI,KAAO,CAACA,EAAI,IAAII,CAAE,EAAG,CAC5BiC,EAAK,SAASjC,CAAE,YAAY,EAC5B,MACF,CAEA,QAAWd,KAAO,OAAO,KAAKU,EAAI,IAAII,CAAE,CAAE,EAAG,CAC3C,GACEd,IAAQ,KACRA,IAAcW,GACdX,IAAcY,GAEd,SAGF,IAAM4B,EAAM,MAAM,IAAI,QAAmCvB,GAAO,CAC9D,IAAMC,EAAeC,EAAK,OAAO,EAC3BiC,EAAqB,CAAC,CAAE,KAAMpD,EAAK,KAAMc,CAAG,CAAC,EACnDrB,EAAO,IAAIyB,EAAQ,CAAE,MAAOkC,EAAO,KAAMhC,EAAI,IAAK,CAAC,EACnDlB,EAAIgB,CAAM,EAAE,IAAI,KAAOD,CAAY,CACrC,CAAC,EACD,GAAIuB,EAAK,CACPO,EAAKP,CAAG,EACR,MACF,CACF,CACK3B,IAAMA,EAAO,CAAC,GACnBA,EAAKiB,CAAK,EAAInC,EACd,IAAM4C,EAAI,MAAMjB,EAAMf,EAAMM,EAAeO,EAAI,KAAM2B,CAAa,EAC9DR,IAAM,MAEVnD,EAAK,IAAImD,EAAGQ,CAAa,CAC3B,CAAC,CACH,EACA,CAAE,QAAS,OAAO3B,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,OAAQ,IAAK,EAAK,CACjG,EACA,MACF,CAEA,IAAM6B,EAAc,CAACC,EAAU,IAAY,CACzC5B,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EACxB,MAAMpB,GAAO,CACX,GAAIA,EAAI,IAAK,CACXqC,EAAK,iBAAiBxC,CAAI,IAAIuB,CAAI,KAAKpB,EAAI,GAAG,EAAE,EAChD,MACF,CAEA,IAAIG,EAAOH,EAAI,KAAOA,EAAI,IAAIH,CAAI,EAC5B4C,EAAUtC,GAAQA,EAAKiB,CAAK,EAElC,GAAI,CAACqB,GAAWnC,EAAU,EACxB,aAAM,IAAI,QAAQqC,GAAK,WAAWA,EAAG,EAAE,CAAC,EACjCtC,EAAYC,EAAU,CAAC,EAGhC,IAAMF,EAAWlB,EAAI,GAAGuD,CAAqB,EAC7C,GAAI,CAACrC,EAAI,CACFD,IAAMA,EAAO,CAAC,GACnBA,EAAKiB,CAAK,EAAUlC,EAAI,IAAUuB,EAAK,OAAO,CAAC,EAC/C,IAAMoB,EAAI,MAAMjB,EAAMf,EAAMM,EAAeO,EAAI,KAAM2B,CAAa,EAClE,GAAIR,IAAM,KAAM,OAEhBnD,EAAK,IAAImD,EAAGC,GAAO,CACjB,GAAIA,EACFO,EAAK,iBAAiBjB,CAAI,OAAOvB,CAAI,KAAKiC,CAAG,EAAE,MAC1C,CACL,IAAMtB,EAAeC,EAAK,OAAO,EAC3BiC,EAAqB,CAAC,CAAE,KAAMtB,EAAO,KAAMvB,CAAK,CAAC,EACvDd,EAAO,IAAIyB,EAAQ,CACjB,MAAOkC,EACP,KAAMhC,EAAI,KACV,GAAIA,EAAI,EACV,CAAC,EACDlB,EAAIgB,CAAM,EAAE,IAAIvB,CAAI,CACtB,CACF,CAAC,EACD,MACF,CAEA,IAAM2D,EAAmB,CAAC,EAC1B,QAAWtD,KAAO8C,EAAoB,CACpC,IAAMN,EAAM,MAAM,IAAI,QAAmCvB,GAAO,CAC9D,GACQ9B,EAAI,GAAIQ,EAAiCK,CAAG,CAAC,GACnD,CAAOJ,EAAI,GAAID,EAAoCK,CAAG,CAAC,EACvD,CACA,IAAMkB,EAAeC,EAAK,OAAO,EAC3BiC,EAAqB,CAAC,CAAE,KAAMpD,EAAK,KAAMc,CAAG,CAAC,EACnDrB,EAAO,IAAIyB,EAAQ,CAAE,MAAOkC,EAAO,KAAMhC,EAAI,IAAK,CAAC,EACnDlB,EAAIgB,CAAM,EAAE,IAAKvB,EAAoCK,CAAG,EAAIiB,CAAY,CAC1E,MACEqC,EAAO,KAAKtD,CAAG,EACfiB,EAAI,IAAI,CAEZ,CAAC,EACD,GAAIuB,EAAK,CACPO,EAAKP,CAAG,EACR,MACF,CACF,CAEA,GAAIc,EAAO,SAAW,EAAG,CACvBP,EAAK,IAAI,EACT,MACF,CAIA,IAAMQ,EAAyC,CAAC,EAChDD,EAAO,QAAQtD,GAAO,CACpBuD,EAAWvD,CAAG,EAAKL,EAAoCK,CAAG,CAC5D,CAAC,EACD,IAAMuC,EAAI,MAAMjB,EAAMR,EAAIyC,EAAqBnC,EAAI,KAAM2B,CAAa,EAClER,IAAM,MAEVnD,EAAK,IAAImD,EAAGQ,CAAa,CAC3B,EACA,CAAE,QAAS,OAAO3B,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,OAAQ,IAAK,EAAK,CACjG,CACF,EACA6B,EAAY,CACd,EAEA,GAAI,SACFT,EACAkB,EACAgC,EACA/C,EACM,CACN,IAAIiC,EACAC,EACAC,EAaJ,GAXI,OAAOtC,GAAQ,YACjBsC,EAAOY,EACPA,EAAOhC,EACPmB,EAAWrC,EACXoC,EAAY,OAEZA,EAAYpC,EACZqC,EAAY,OAAOnB,GAAO,WAAaA,EAAK,OAC5CoB,EAAOnC,GAGL,OAAOkC,GAAa,WAAY,CAClC,QAAQ,IAAI,yCAAyC,EACrD,MACF,CAEA,GAAI,CAACvC,EAAO,CACV,QAAQ,IAAI,2CAA2C,EACvDuC,EAAS,IAAI,EACb,MACF,CAEA,IAAMO,EAAW7B,EAAQ,CAAE,GAAIqB,EAAW,KAAMc,EAAM,KAAMZ,CAAK,EAAGD,CAAQ,EAC5E,GAAI,CAACO,EAAU,OAEf,GAAM,CAAE,KAAApB,EAAM,KAAAvB,CAAK,EAAI2C,EACvB,GAAI,CAAC3C,EAAM,OAEX,IAAMa,EAAM3B,EAAO,IAAIW,CAAK,EAE5BX,EAAO,IAAIW,EAAO,CAChB,MAAO,CAAC,CAAE,KAAM0B,EAAM,KAAMvB,CAAK,CAAC,EAClC,GAAI,GACJ,KAAMa,EAAMA,EAAI,KAAO,IACzB,CAAC,EAGD,IAAIqC,EAAa,EACXC,EAAa,EACbC,EAAa,IACfC,EAAmD,KAEvDpE,EAAI,IAAImD,EAAU,IAAM,CAKjBlD,EAAO,IAAIW,CAAM,IAGtB,aAAawD,CAAW,EACxBA,EAAa,KACbxE,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EACxBpB,GAAO,CACL,IAAMG,EAAOH,EAAI,KAAOA,EAAI,IAAIH,CAAI,EAC9B4C,EAAUtC,GAAQA,EAAKiB,CAAK,EAC5BhB,EAAWlB,EAAI,GAAGuD,CAAqB,EAC7C,GAAIrC,EAAI,CACN,IAAMC,EAAc,MAAOC,EAAU,IAAqB,CACxD,IAAMrB,EAAO,MAAM,IAAI,QAAiBsB,GAAO,CAC7C,IAAMC,EAAeC,EAAK,OAAO,EACjC1B,EAAO,IAAIyB,EAAQ,CACjB,MAAO,CAAC,CAAE,KAAM,KAAM,KAAMJ,CAAG,CAAC,EAChC,KAAMM,EAAMA,EAAI,KAAO,IACzB,CAAC,EACDlB,EAAIgB,CAAM,EAAE,KAAK,KAAeD,EAAeD,IAAY,EAAU7B,EAAI,IAAIyD,EAAM,OAAQ,EAAI,EAAIA,CAAc,CACnH,CAAC,EACGjD,IAAS,MAAQqB,GAAW,GAC9ByC,EAAa,EACbd,EAAShD,CAAI,IAEb,MAAM,IAAI,QAAQ0B,GAAW,WAAWA,EAAS,EAAE,CAAC,EACpDN,EAAYC,EAAU,CAAC,EAE3B,EACAD,EAAY,CACd,SACqB,CAAC,CAACF,EAEnB4C,EAAa,EACbd,EAASQ,IAAY,OAAYA,EAAU,IAAI,UACtCM,EAAaC,EAAY,CAKlC,IAAMG,EAAY,CAAE,GAAGjB,EAAM,OAAQxB,IAAQ,OAAOA,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,MAAyB,EAClI4E,EAAQ,IAAY,CACxB,IAAMC,EAAQ,KAAK,IAAIJ,EAAa,KAAK,IAAI,EAAGF,CAAU,EAAG,GAAK,EAClEA,IACAG,EAAa,WAAW,IAAM,CAC5BxE,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EACxBkC,GAAY,CACV,IAAMC,EAAYD,EAAS,KAAOA,EAAS,IAAIzD,CAAI,EACnD,GAAI0D,EAAW,CACbR,EAAa,EACbG,EAAa,KACb,IAAMM,EAAaD,EAAUnC,CAAK,EAClCa,EAASuB,IAAe,OAAYA,EAAa,IAAI,CACvD,MAAWT,EAAaC,EACtBI,EAAM,GAENF,EAAa,KACbjB,EAAS,IAAI,EAEjB,EACAkB,CACF,CACF,EAAGE,CAAK,CACV,EACAD,EAAM,CACR,MACEnB,EAAS,IAAI,CAGnB,EACA,CAAE,GAAGC,EAAM,OAAQxB,IAAQ,OAAOA,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,MAAyB,CACxH,EACF,CAAC,EAED,IAAIiF,EAAqDzB,EAC9CvD,EAAI,IAAIuD,EAAoB,IAAKnC,CAAI,EAC5C,CAAE,IAAKA,EAAM,IAAKuB,CAAM,EACxBqC,EAAW,GAAG,GAAK,MAAQ,OAAOA,EAAW,GAAG,GAAM,WACxDA,EAAa,CAAE,GAAGA,EAAY,IAAK,OAAOA,EAAW,GAAG,CAAC,CAAE,GAE7D/E,EAAK,GAAG+E,EAAqB3E,EAAI,IAAImD,CAAQ,EAAI,GAAOC,CAAI,EAE5DxD,EAAK,IACH,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EACxBpB,GAAO,CACL,GAAIA,EAAI,IAAK,CACX,QAAQ,IAAI,iBAAiBH,CAAI,IAAIuB,CAAI,KAAKpB,EAAI,GAAG,EAAE,EACvD,MACF,CAEA,IAAMyC,EAAUzC,EAAI,KAAOA,EAAI,IAAIH,CAAI,GAAKG,EAAI,IAAIH,CAAI,EAAGuB,CAAK,EAC1DhB,EAAWlB,EAAI,GAAGuD,CAAqB,EACzCrC,IACF1B,EAAK,IAAI+E,EAAqB3E,EAAI,IAAImD,CAAQ,CAAE,EAChDvD,EAAK,GAAG,CAAE,IAAK0B,EAAI,IAAK,IAAK,EAAYtB,EAAI,IAAImD,CAAQ,EAAI,GAAOC,CAAI,GACpEY,GAAMhE,EAAI,IAAImD,CAAQ,EAAG,CAKjC,EACA,CAAE,GAAGC,EAAM,OAAQxB,IAAQ,OAAOA,EAAI,MAAS,UAAYA,EAAI,KAAO,CAAC,CAACA,EAAI,OAASlC,EAAQ,MAAyB,CACxH,CACF,EAEA,IAAK,SAAUsC,EAAiD,CAC9D,GAAI,CAACpB,EAAO,CACV,QAAQ,IAAI,2CAA2C,EACnDoB,GAAIA,EAAG,IAAI,EACf,MACF,CAEA,IAAM0B,EAAW7B,EAAQ,CAAE,IAAK,EAAK,EAAGG,CAAE,EAC1C,GAAI,CAAC0B,EAAU,OAEf,GAAM,CAAE,KAAApB,EAAM,KAAAvB,CAAK,EAAI2C,EAClB3C,IAELnB,EAAK,IAAI,CAAE,IAAKmB,CAAK,EAAYf,EAAI,IAAIgC,CAAG,CAAE,EAE9CpC,EAAK,IAAI,CAAE,IAAKmB,EAAM,IAAKuB,CAAM,EAAGpB,GAAO,CACzC,GAAIA,EAAI,IAAK,CACXlB,EAAI,OAAOgC,CAAG,EACd/B,EAAO,OAAOW,CAAM,EACpB,MACF,CAEA,IAAM+C,EAAUzC,EAAI,KAAOA,EAAI,IAAIH,CAAI,GAAKG,EAAI,IAAIH,CAAI,EAAGuB,CAAK,EAC1DhB,EAAWlB,EAAI,GAAGuD,CAAqB,EACzCrC,GAAI1B,EAAK,IAAI,CAAE,IAAK0B,CAAG,EAAYtB,EAAI,IAAIgC,CAAG,CAAE,EACpDhC,EAAI,OAAOgC,CAAG,EACd/B,EAAO,OAAOW,CAAM,CACtB,CAAC,EACH,EAEA,KAAM,KACEd,EAA2B,MAC/B,OAAO,OAAOA,EAAMY,EAAI,CAAC,EACvBZ,EAAoC,IAAM,SAE1CS,EACAO,EACAkB,EACAf,EACY,CACZ,IAAIiC,EACAC,EACAC,EAEA,OAAOtC,GAAQ,YACjBsC,EAAOpB,EACPmB,EAAWrC,EACXoC,EAAY,OAEZA,EAAYpC,EACZqC,EAAWnB,EACXoB,EAAOnC,GAGT,IAAI2D,EAAqB,KACrBpE,EAAqB,KAYzB,GAXIV,EAAK,KAAI8E,EAAM9E,EAAK,GAAG,KACvB,OAAOS,GAAS,SAClBC,EAAMD,EACGA,aAAgB,QACrBA,EAAK,SAAW,GAAKA,EAAK,CAAC,GAAKA,EAAK,CAAC,GACxCqE,EAAMrE,EAAK,CAAC,EACZC,EAAMD,EAAK,CAAC,GACHA,EAAK,SAAW,GAAKA,EAAK,CAAC,IACpCC,EAAMD,EAAK,CAAC,IAGZ,CAACqE,EACH,eAAQ,IAAI,6CAA6C,EACrDzB,GAAUA,EAAS,IAAI,EACpB,KAGT,GAAI3C,IAAQ,MAAQA,IAAQ,IAAMA,IAAQ,IACxC,eAAQ,IAAI,4BAA4B,EACpC2C,GAAUA,EAAS,IAAI,EACpB,KAGT,GAAID,GAAa,CAACC,EAChB,eAAQ,IAAI,wCAAwC,EAC7C,KAGTvC,EAAce,EAAK,OAAO,EAC1B,IAAMiC,EAAqB,CAAC,CAAE,KAAM,OAAOpD,CAAG,EAAG,KAAM,IAAMoE,CAAI,CAAC,EAElE,GADA3E,EAAO,IAAIW,EAAO,CAAE,MAAOgD,EAAO,KAAM9D,EAAK,GAAI,GAAIqD,CAAkB,CAAC,EACpE,CAACA,EAAU,OAAOzC,EAAIE,CAAK,EAE/B,IAAMyC,EAAQjB,EAAKxB,CAAK,EAClB8C,EAAW7B,EAAQ,CAAE,IAAKqB,EAAW,KAAME,CAAK,EAAGC,CAAK,EAC9D,OAAIK,GAAU7C,EAAIqC,EAAoBQ,EAAS,KAAOL,EAAOD,CAAI,EAC1D,IACT,GAEKtD,GAGT,KAAMF,EACN,IAAKuC,CACP,CACF,EACA,OAAOzB,EAAI,CACb,EAEOmE,GAAQrF",
|
|
6
|
+
"names": ["num", "n", "parsed", "obj", "o", "match", "list", "cb", "keys", "i", "key", "result", "value", "target", "map_soul", "soul", "rel", "userSignature", "userPublicKey", "graph", "data", "sig", "pub", "timestamp", "ts", "stateVector", "node", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "len", "Dup", "dup", "id", "now", "dup_default", "Get", "lex", "graph", "fast", "soul", "node", "signatures", "key", "state", "sigs", "userPublicKey", "pkState", "pkSigs", "match", "get_default", "data", "SeaArray", "_SeaArray", "enc", "start", "end", "encoding", "startIdx", "endIdx", "buf", "byte", "_", "i", "charCode", "utf8String", "arrayLike", "arr", "array_default", "SECURITY_LIMITS", "SafeBuffer", "_props", "array_default", "validateStringInput", "input", "_encoding", "validateBufferSize", "size", "operation", "parseHexString", "hexString", "cleanHex", "bytes", "i", "hexByte", "encodeUtf8String", "str", "err", "encodeBinaryString", "charCode", "parseBase64String", "base64String", "cleanBase64", "decodedString", "processArrayLikeInput", "val", "arrayLike", "arr", "args", "encoding", "length", "fill", "fillValue", "buffer", "totalLength", "validatedBuffers", "item", "result", "offset", "obj", "string", "clean", "start", "end", "buffer_default", "isNode", "crypto", "subtle", "stringify", "data", "parse", "text", "random", "length", "array", "filled", "buffer_default", "jwk", "pub", "priv", "x", "y", "sha256", "hash", "aeskey", "key", "salt", "combined", "hashResult", "jwkKey", "keyToJwk", "SEA", "cb", "ecdsa", "subtle", "keys", "pub", "ecdh", "pair", "data", "rand", "random", "ct", "aeskey", "aes", "stringify", "enc", "buffer_default", "dec", "parse", "signed", "key", "jwk", "msg", "k", "userPublicKey", "userSignature", "hash", "sha256", "sig", "alg", "verified", "check", "timestamp", "timestampStr", "signature", "publicKey", "isValid", "err", "salt", "_cb", "_salt", "work", "to", "from", "pubKey", "priv", "derived", "derivedBits", "derivedKey", "sea_default", "MAX_GRAPH_SIZE", "Ham", "state", "currentState", "value", "currentValue", "signed", "valueStr", "currentValueStr", "change", "graph", "hasNode", "secure", "listen", "machine", "now", "defer", "listeners", "validProperties", "validTimestamps", "wait", "soul", "node", "updated", "alias", "verify", "pub", "userPublicKey", "signedTimestamps", "signedProperties", "incomingTimestamps", "key", "sig", "asNumber", "propsForTimestamp", "ts", "prop", "graphState", "sea_default", "rel", "skew", "stateVector", "signatures", "isSigned", "stateVector1", "signatures1", "stateVector2", "signatures2", "l", "match", "souls", "states", "maxState", "a", "b", "ham_default", "group", "record", "isRadixTree", "value", "Radix", "radix", "keys", "tree", "i", "tmp", "key", "max", "noValue", "found", "nextTree", "obj", "hasValue", "hasKey", "j", "matchingKey", "replace", "map", "cb", "opt", "pre", "recordValue", "result", "groupValue", "radix_default", "etx", "enq", "unit", "Radisk", "opt", "cache", "fileListCache", "fileListCacheTime", "FILE_LIST_CACHE_TTL", "pendingReads", "lastMemoryCheck", "MEMORY_CHECK_INTERVAL", "HEAP_WARNING_THRESHOLD", "HEAP_CLEANUP_THRESHOLD", "options", "store", "perfLog", "operation", "startTime", "key", "size", "duration", "checkMemoryUsage", "now", "heapUsed", "maxHeapSize", "heapUsageRatio", "cacheSize", "radisk", "value", "cb", "callback", "batchValue", "thrashValue", "readStart", "timeout", "callbacks", "err", "result", "radix_default", "thrashStart", "batch", "i", "rad", "save", "_tree", "file", "start", "end", "disk", "write", "_key", "k", "pre", "valueStr", "enc", "validBoundary", "fullKey", "endIdx", "writeStart", "soul", "findFile", "files", "lo", "hi", "mid", "f", "read", "parse", "data", "preString", "tmp", "tmpVal", "tmpKey", "a", "o", "input", "state", "sig", "current", "text", "relId", "rel", "num", "obj", "n", "previous", "textStart", "textEnd", "parts", "stateNum", "radisk_default", "isNode", "fs", "enq", "unit", "root", "fileSystem", "opt", "dir", "file", "cb", "err", "data", "dataStr", "tmp", "text", "files", "db", "dbReady", "resolve", "reject", "o", "event", "req", "_get", "_put", "_list", "_file", "_data", "Store", "options", "radisk", "radisk_default", "lex", "_opt", "obj", "opts", "soul", "key", "node", "signatures", "each", "value", "userPublicKey", "match", "graph", "radix_default", "count", "finished", "ack", "state", "sig", "store_default", "isNode", "wsModule", "createRateLimiter", "isTestEnv", "clients", "maxRequests", "windowMs", "disconnectThreshold", "cleanupInterval", "now", "_clientId", "data", "time", "clientId", "client", "oldestRequest", "delay", "validRequests", "safeJSONParse", "maxSize", "error", "validateMessage", "createConnectionManager", "maxConnections", "connections", "ws", "originalClose", "args", "createRetryHandler", "maxRetries", "retryCount", "Wire", "opt", "options", "dup", "dup_default", "store", "store_default", "graph", "queue", "listen", "pendingReferences", "hasNode", "recentChecks", "recentCheckTTL", "pendingTimeouts", "offlineTimeouts", "hasSoul", "soul", "resolve", "err", "rateLimiter", "connectionManager", "check", "send", "cb", "key", "userPublicKey", "node", "msg", "res", "getWithCallback", "get", "ack", "get_default", "text", "put", "update", "ham_default", "lex", "_opt", "opts", "fast", "track", "request", "checkKey", "lastCheck", "sendResult", "value", "gNode", "meta", "state", "gMeta", "match", "id", "api", "_soul", "_key", "soulId", "rel", "l", "_get", "found", "wss", "config", "isBinary", "trackId", "retryHandler", "validation", "parseResult", "throttleCount", "processMessage", "peers", "clientThrottled", "throttleUntil", "messageQueue", "queueProcessor", "maxQueueLength", "startResponseTimeout", "processQueue", "sent", "sendToPeers", "isStaleCheckMessage", "sentToAtLeastOne", "peer", "start", "e", "m", "hasSoulMap", "known", "filteredPut", "pendingToDelete", "shouldStore", "filteredMsg", "wire_default", "User", "opt", "wire", "wire_default", "pubs", "creating", "authing", "retries", "auth", "username", "password", "newPassword", "ack", "retry", "done", "err", "next", "pub", "msg", "data", "authData", "work", "sea_default", "dec", "user", "salt", "text", "newWork", "enc", "update", "timestamp", "sig", "graph", "soul", "cb", "pair", "priv", "rel", "localStorage", "is", "user_default", "Holster", "opt", "options", "obj", "wire", "wire_default", "user", "user_default", "map", "allctx", "ok", "data", "rel", "num", "check", "keys", "key", "value", "api", "initCtxid", "ctxid", "get", "lex", "soul", "ack", "_opt", "msg", "userPublicKey", "userSignature", "node", "id", "attemptRead", "retries", "res", "_ctxid", "text", "ctx", "resolve", "graph", "userctx", "cb", "timestamp", "sig", "sea_default", "done", "watchForRel", "item", "i", "request", "on", "timer", "handler", "put", "off", "found", "g", "err", "sv", "lexFilter", "callback", "opts", "_done", "result", "_ack", "set", "isSet", "resolved", "current", "chain", "r", "update", "updateNode", "_get", "retryCount", "maxRetries", "retryDelay", "retryTimer", "secureOpt", "retry", "delay", "retryMsg", "retryNode", "retryValue", "initialLex", "pub", "holster_default"]
|
|
7
7
|
}
|