@powerhousedao/shared 6.2.3-dev.8 → 6.2.3-dev.9
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/dist/clis/args/common-CcYbXrBx.mjs.map +1 -1
- package/dist/clis/build-config.d.mts.map +1 -1
- package/dist/clis/build-config.mjs +6 -1
- package/dist/clis/build-config.mjs.map +1 -1
- package/dist/clis/constants.d.mts +13 -0
- package/dist/clis/constants.d.mts.map +1 -1
- package/dist/clis/constants.mjs +8 -0
- package/dist/clis/constants.mjs.map +1 -1
- package/dist/clis/index.d.mts +21 -8
- package/dist/clis/index.d.mts.map +1 -1
- package/dist/clis/index.mjs +8 -0
- package/dist/clis/index.mjs.map +1 -1
- package/dist/connect/config-loader.d.ts +1 -1
- package/dist/connect/index.d.ts +1 -1
- package/dist/document-drive/index.d.ts +2 -2
- package/dist/document-model/index.d.ts +2 -2
- package/dist/document-model/index.js +1 -0
- package/dist/document-model/index.js.map +1 -1
- package/dist/{index-DyYIJtVy.d.ts → index-DP3QgHTq.d.ts} +2 -2
- package/dist/{index-DyYIJtVy.d.ts.map → index-DP3QgHTq.d.ts.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/processors/index.d.ts +1 -1
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/manifest-slim.d.ts +1 -1
- package/dist/registry/manifest-slim.d.ts.map +1 -1
- package/dist/registry/manifest-slim.js +2 -1
- package/dist/registry/manifest-slim.js.map +1 -1
- package/dist/{types-CpnWmiFY.d.ts → types-BIoOWpOT.d.ts} +6 -1
- package/dist/types-BIoOWpOT.d.ts.map +1 -0
- package/dist/{types-YqLqb0Zb.d.ts → types-DDpRvBK_.d.ts} +2 -2
- package/dist/{types-YqLqb0Zb.d.ts.map → types-DDpRvBK_.d.ts.map} +1 -1
- package/package.json +1 -1
- package/dist/types-CpnWmiFY.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../document-model/signatures.ts","../../document-model/action-transport.ts","../../document-model/errors.ts","../../document-model/schemas.ts","../../document-model/actions.ts","../../document-model/document-type.ts","../../document-model/auth-v1.ts","../../document-model/constants.ts","../../document-model/state.ts","../../document-model/auth.ts","../../document-model/denied.ts","../../document-model/document-schema.ts","../../document-model/header.ts","../../document-model/documents.ts","../../document-model/operations.ts","../../document-model/reducer.ts","../../document-model/validation.ts","../../document-model/reducers.ts","../../document-model/upgrades.ts","../../document-model/versioned-replay.ts","../../document-model/files.ts"],"sourcesContent":["// Tuple from `buildOperationSignature`:\n// [timestamp, appKey, hash(docId+scope+type+input), previousStateHash, signatureHex].\nexport type Signature = [string, string, string, string, string];\n\n/**\n * A user action signer.\n */\nexport type UserActionSigner = {\n address: string;\n networkId: string; // CAIP-2\n chainId: number; // CAIP-10\n};\n\n/**\n * An app action signer.\n */\nexport type AppActionSigner = {\n name: string; // Connect\n key: string;\n};\n\n/**\n * An action signer.\n */\nexport type ActionSigner = {\n user: UserActionSigner;\n app: AppActionSigner;\n signatures: Signature[];\n};\n\n/**\n * Information to verify the document creator.\n */\nexport type PHDocumentSignatureInfo = {\n /**\n * The public key of the document creator.\n **/\n publicKey: JsonWebKey;\n\n /** The nonce that was appended to the message to create the signature. */\n nonce: string;\n};\n\n/**\n * What separates a signature's params when it travels as one string.\n *\n * GraphQL declares `signatures` as a list of strings, not a list of lists, so a\n * tuple is joined for transport and split on arrival. The separator is here so\n * the two halves cannot disagree about it - they live in different packages, and\n * a mismatch would corrupt every signature that crossed the wire rather than\n * failing outright.\n */\nconst SIGNATURE_PARAM_SEPARATOR = \", \";\n\n/** The number of params a signature carries. */\nconst SIGNATURE_PARAM_COUNT = 5;\n\n/** Joins a signature's params for transport. Already-joined input passes through. */\nexport function serializeSignature(signature: Signature | string): string {\n return Array.isArray(signature)\n ? signature.join(SIGNATURE_PARAM_SEPARATOR)\n : signature;\n}\n\n/**\n * Splits a transported signature back into its params. A tuple passes through.\n *\n * Short input is padded rather than refused: verification reads the params by\n * position and fails on a wrong one, which says more than a length complaint\n * raised here would.\n */\nexport function deserializeSignature(signature: Signature | string): Signature {\n if (Array.isArray(signature)) {\n return signature;\n }\n const parts = signature.split(SIGNATURE_PARAM_SEPARATOR);\n return Array.from(\n { length: SIGNATURE_PARAM_COUNT },\n (_unused, index) => parts[index] ?? \"\",\n ) as Signature;\n}\n\n/**\n * Configuration for hashing document state in operations.\n */\nexport type HashConfig = {\n /** The hashing algorithm to use (e.g., \"sha1\", \"sha256\") */\n algorithm: string;\n\n /** The encoding format for the hash output (e.g., \"base64\", \"hex\") */\n encoding: string;\n\n /** Optional algorithm-specific parameters */\n params?: Record<string, unknown>;\n};\n","import type { Action, ActionContext } from \"./actions.js\";\nimport {\n serializeSignature,\n type AppActionSigner,\n type UserActionSigner,\n} from \"./signatures.js\";\n\n/**\n * An action's signer, as the wire declares it: signatures joined into strings,\n * because GraphQL declares them as a list of strings rather than of lists.\n */\nexport type TransportSigner = {\n user?: { address: string; networkId: string; chainId: number };\n app?: { name: string; key: string };\n signatures: string[];\n};\n\n/** An action's context, as the wire declares it. */\nexport type TransportActionContext = {\n prevOpIndex?: number;\n prevOpHash?: string;\n nonce?: string;\n signer?: TransportSigner;\n};\n\n/** An action projected onto exactly the fields the wire declares. */\nexport type TransportAction = {\n id: string;\n type: string;\n timestampUtcMs: string;\n /**\n * Non-nullable, because the wire declares it so. An action's own type says\n * `unknown`, which admits the absent input an action creator called without\n * one produces - {@link toTransportAction} refuses that rather than passing\n * it on.\n */\n input: NonNullable<unknown>;\n scope: string;\n context?: TransportActionContext;\n};\n\n/**\n * Projects an action onto the fields the GraphQL `ActionInput` declares.\n *\n * A projection rather than a spread, because an input object rejects a field it\n * does not declare, and that refusal takes the whole request with it. An action\n * read back out of storage can carry fields the type no longer has - a legacy\n * `attachments` array, or the operation fields left behind by a signing helper\n * that returns an operation - and any one of them would sink an otherwise valid\n * submission.\n *\n * Only fields the action actually carries are emitted, so an unsigned action\n * sends no context at all rather than a context full of nulls.\n */\nexport function toTransportAction(action: Action): TransportAction {\n if (action.input === undefined || action.input === null) {\n // The wire declares an input, so this would be refused on arrival as a\n // missing required field, naming the field but not the action. Refused here\n // instead, where the action is still in hand.\n throw new Error(\n `Action ${action.id} (${action.type}) has no input, which the wire requires`,\n );\n }\n\n const projected: TransportAction = {\n id: action.id,\n type: action.type,\n timestampUtcMs: action.timestampUtcMs,\n input: action.input,\n scope: action.scope,\n };\n\n const context = toTransportContext(action.context);\n return context ? { ...projected, context } : projected;\n}\n\nfunction toTransportContext(\n context: ActionContext | undefined,\n): TransportActionContext | undefined {\n if (!context) {\n return undefined;\n }\n\n const projected: TransportActionContext = {};\n if (context.prevOpIndex !== undefined) {\n projected.prevOpIndex = context.prevOpIndex;\n }\n if (context.prevOpHash !== undefined) {\n projected.prevOpHash = context.prevOpHash;\n }\n if (context.nonce !== undefined) {\n projected.nonce = context.nonce;\n }\n\n const signer = context.signer;\n if (signer) {\n projected.signer = {\n ...(signer.user ? { user: toTransportSignerUser(signer.user) } : {}),\n ...(signer.app ? { app: toTransportSignerApp(signer.app) } : {}),\n signatures: (signer.signatures ?? []).map(serializeSignature),\n };\n }\n\n return Object.keys(projected).length > 0 ? projected : undefined;\n}\n\n/**\n * The identity, projected for the same reason the context around it is.\n *\n * A signer is handed in by the app, so what reaches here is only as narrow as\n * whoever built it: an identity carrying a session's DID, credential or profile\n * alongside the address is refused by `ReactorSignerUserInput`, and that\n * refusal takes the whole submission with it.\n *\n * The compiler cannot stand in for this. `UserActionSigner` already declares\n * exactly these three fields, but excess-property checks apply to fresh object\n * literals and never to a variable of a wider type, so a wide identity assigned\n * to the narrow type passes untouched.\n */\nfunction toTransportSignerUser(\n user: UserActionSigner,\n): NonNullable<TransportSigner[\"user\"]> {\n return {\n address: user.address,\n networkId: user.networkId,\n chainId: user.chainId,\n };\n}\n\n/** The signing app, projected on the same rule as the identity above. */\nfunction toTransportSignerApp(\n app: AppActionSigner,\n): NonNullable<TransportSigner[\"app\"]> {\n return { name: app.name, key: app.key };\n}\n","import type { ZodIssue } from \"zod\";\nimport type { PHDocument } from \"./documents.js\";\nimport type { Operation } from \"./operations.js\";\n\nexport const FileSystemError = new Error(\"File system not available.\");\n\nexport class InvalidActionInputError extends Error {\n public data: unknown;\n constructor(data: unknown) {\n super();\n this.name = \"InvalidActionInputError\";\n this.data = data;\n this.message =\n this.message || `Invalid action input: ${JSON.stringify(data, null, 2)}`;\n }\n}\n\nexport class InvalidActionInputZodError extends InvalidActionInputError {\n public issues: ZodIssue[];\n\n constructor(issues: ZodIssue[]) {\n super(issues);\n this.issues = issues;\n this.name = \"InvalidActionInputZodError\";\n }\n}\n\n/**\n * Error thrown when attempting to downgrade a document version.\n */\nexport class DowngradeNotSupportedError extends Error {\n public readonly documentType: string;\n public readonly fromVersion: number;\n public readonly toVersion: number;\n\n constructor(documentType: string, fromVersion: number, toVersion: number) {\n super(\n `Downgrade not supported for ${documentType}: cannot upgrade from version ${fromVersion} to ${toVersion}`,\n );\n this.name = \"DowngradeNotSupportedError\";\n this.documentType = documentType;\n this.fromVersion = fromVersion;\n this.toVersion = toVersion;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH is applied to an already-initialized auth scope.\n * The genesis action is valid only at auth revision zero.\n */\nexport class AuthAlreadyInitializedError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `Auth scope already initialized for document ${documentId}: INITIALIZE_AUTH is valid only at auth revision zero`,\n );\n this.name = \"AuthAlreadyInitializedError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH is not signed by the document creator (its signer\n * does not match `header.sig.publicKey`), so it cannot set the auth policy.\n */\nexport class AuthInitializerNotCreatorError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `INITIALIZE_AUTH for document ${documentId} must be signed by the document creator`,\n );\n this.name = \"AuthInitializerNotCreatorError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH carries a version below 1. Version 0 is reserved\n * for the uninitialized auth scope.\n */\nexport class InvalidAuthVersionError extends Error {\n public readonly documentId: string;\n public readonly version: number;\n\n constructor(documentId: string, version: number) {\n super(\n `Invalid auth policy version ${version} for document ${documentId}: INITIALIZE_AUTH requires an integer version >= 1`,\n );\n this.name = \"InvalidAuthVersionError\";\n this.documentId = documentId;\n this.version = version;\n }\n}\n\n/** Thrown when a duplicate would lose the source policy's version or creator binding. */\nexport class AuthPolicyNotPreservedError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `Duplicating document ${documentId} would not preserve its auth policy: the copy loses the policy version or its creator binding`,\n );\n this.name = \"AuthPolicyNotPreservedError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when a grant referenced by REMOVE_GRANT or MOVE_GRANT does not exist.\n */\nexport class GrantNotFoundError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(`Grant not found in auth scope: ${grantId}`);\n this.name = \"GrantNotFoundError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when a disallowed action (UNDO, REDO, PRUNE) targets the auth scope.\n */\nexport class AuthActionNotAllowedError extends Error {\n public readonly actionType: string;\n\n constructor(actionType: string) {\n super(`${actionType} is not permitted on the auth scope`);\n this.name = \"AuthActionNotAllowedError\";\n this.actionType = actionType;\n }\n}\n\nexport class HashMismatchError extends Error {\n protected _scope: string;\n protected _document: PHDocument;\n protected _operation: Operation;\n\n constructor(scope: string, document: PHDocument, operation: Operation) {\n super();\n this.name = \"HashMismatchError\";\n this._document = document;\n this._scope = scope;\n this._operation = operation;\n\n this.message = JSON.stringify(\n {\n error: `Hash mismatch on document ${document.header.id}, scope ${scope}, index ${operation.index}`,\n document,\n operation,\n },\n null,\n 1,\n );\n }\n\n get document() {\n return this._document;\n }\n\n get scope() {\n return this._scope;\n }\n\n get operation() {\n return this._operation;\n }\n}\n\n/**\n * Thrown when replay or import requires a document model version that is not\n * registered. Carries the data the UI needs to explain the mismatch.\n */\nexport class UnsupportedDocumentModelVersionError extends Error {\n public readonly documentType: string;\n public readonly requiredVersion: number;\n public readonly availableVersions: number[];\n\n constructor(\n documentType: string,\n requiredVersion: number,\n availableVersions: number[],\n ) {\n super(\n `No reducer registered for document version ${requiredVersion}. Available versions: ${availableVersions.join(\", \")}`,\n );\n this.name = \"UnsupportedDocumentModelVersionError\";\n this.documentType = documentType;\n this.requiredVersion = requiredVersion;\n this.availableVersions = availableVersions;\n }\n\n static isError(\n error: unknown,\n ): error is UnsupportedDocumentModelVersionError {\n return (\n Error.isError(error) &&\n error.name === \"UnsupportedDocumentModelVersionError\"\n );\n }\n}\n","import { z } from \"zod\";\nimport type { PHConnectPwa } from \"../clis/types.js\";\nimport type {\n AddChangeLogItemInput,\n AddModuleInput,\n AddOperationErrorInput,\n AddOperationExampleInput,\n AddOperationInput,\n AddStateExampleInput,\n Author,\n CodeExample,\n DeleteChangeLogItemInput,\n DeleteModuleInput,\n DeleteOperationErrorInput,\n DeleteOperationExampleInput,\n DeleteOperationInput,\n DeleteStateExampleInput,\n DocumentModelGlobalState,\n DocumentSpecification,\n LoadStateActionInput,\n LoadStateActionStateInput,\n ModuleSpecification,\n MoveOperationInput,\n OperationErrorSpecification,\n OperationSpecification,\n PruneActionInput,\n ReorderChangeLogItemsInput,\n ReorderModuleOperationsInput,\n ReorderModulesInput,\n ReorderOperationErrorsInput,\n ReorderOperationExamplesInput,\n ReorderStateExamplesInput,\n SchemaLoadStateAction,\n SchemaPruneAction,\n SchemaRedoAction,\n SchemaSetNameAction,\n SchemaSetPreferredEditorAction,\n SchemaUndoAction,\n ScopeState,\n SetAuthorNameInput,\n SetAuthorWebsiteInput,\n SetInitialStateInput,\n SetModelDescriptionInput,\n SetModelExtensionInput,\n SetModelIdInput,\n SetModelNameInput,\n SetModuleDescriptionInput,\n SetModuleNameInput,\n SetOperationDescriptionInput,\n SetOperationErrorCodeInput,\n SetOperationErrorDescriptionInput,\n SetOperationErrorNameInput,\n SetOperationErrorTemplateInput,\n SetOperationNameInput,\n SetOperationReducerInput,\n SetOperationSchemaInput,\n SetOperationScopeInput,\n SetOperationTemplateInput,\n SetStateSchemaInput,\n State,\n UpdateChangeLogItemInput,\n UpdateOperationExampleInput,\n UpdateStateExampleInput,\n} from \"./types.js\";\n\ntype definedNonNullAny = {};\n\nexport const isDefinedNonNullAny = (v: any): v is definedNonNullAny =>\n v !== undefined && v !== null;\n\nexport const definedNonNullAnySchema = z\n .any()\n .refine((v) => isDefinedNonNullAny(v));\n\nexport const Load_StateSchema = z.enum([\"LOAD_STATE\"]);\n\nexport const PruneSchema = z.enum([\"PRUNE\"]);\n\nexport const RedoSchema = z.enum([\"REDO\"]);\n\nexport const Set_NameSchema = z.enum([\"SET_NAME\"]);\n\nexport const Set_PreferredEditorSchema = z.enum([\"SET_PREFERRED_EDITOR\"]);\n\nexport const UndoSchema = z.enum([\"UNDO\"]);\n\nexport function OperationScopeSchema(): z.ZodString {\n return z.string();\n}\n\nexport function DocumentActionSchema() {\n return z.union([\n LoadStateActionSchema(),\n PruneActionSchema(),\n RedoActionSchema(),\n SetNameActionSchema(),\n SetPreferredEditorActionSchema(),\n UndoActionSchema(),\n ]);\n}\n\nexport function LoadStateActionSchema(): z.ZodObject<\n Properties<SchemaLoadStateAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string(),\n input: z.lazy(() => LoadStateActionInputSchema()),\n type: Load_StateSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function LoadStateActionInputSchema(): z.ZodObject<\n Properties<LoadStateActionInput>\n> {\n return z.object({\n operations: z.number(),\n state: z.lazy(() => LoadStateActionStateInputSchema()),\n });\n}\n\nexport function LoadStateActionStateInputSchema(): z.ZodObject<\n Properties<LoadStateActionStateInput>\n> {\n return z.object({\n data: z.unknown().nullish(),\n name: z.string(),\n });\n}\n\nexport function PruneActionSchema(): z.ZodObject<\n Properties<SchemaPruneAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string(),\n input: z.lazy(() => PruneActionInputSchema()),\n type: PruneSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function PruneActionInputSchema(): z.ZodObject<\n Properties<PruneActionInput>\n> {\n return z.object({\n end: z.number().nullish(),\n start: z.number().nullish(),\n });\n}\n\nexport function RedoActionInputSchema() {\n return z.object({ count: z.number() });\n}\n\nexport function RedoActionSchema(): z.ZodObject<Properties<SchemaRedoAction>> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: RedoActionInputSchema(),\n type: RedoSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function SetNameActionInputSchema() {\n return z.object({ name: z.string() });\n}\n\nexport function SetNameActionSchema(): z.ZodObject<\n Properties<SchemaSetNameAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: SetNameActionInputSchema(),\n type: Set_NameSchema,\n scope: z.literal(\"global\"),\n });\n}\n\nexport function SetPreferredEditorActionInputSchema() {\n return z.object({ preferredEditor: z.string().nullable() });\n}\n\nexport function SetPreferredEditorActionSchema(): z.ZodObject<\n Properties<SchemaSetPreferredEditorAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: SetPreferredEditorActionInputSchema(),\n type: Set_PreferredEditorSchema,\n scope: z.literal(\"header\"),\n });\n}\n\n// export function SetNameOperationSchema(): z.ZodObject<\n// Properties<SetNameOperation>\n// > {\n// return z.object({\n// __typename: z.literal(\"SetNameOperation\").optional(),\n// hash: z.string(),\n// index: z.number(),\n// input: z.string(),\n// timestampUtcMs: z.string().datetime(),\n// type: z.string(),\n// });\n// }\n\nexport function UndoActionInputSchema() {\n return z.object({ count: z.number() });\n}\n\nexport function UndoActionSchema(): z.ZodObject<Properties<SchemaUndoAction>> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: UndoActionInputSchema(),\n type: UndoSchema,\n scope: OperationScopeSchema(),\n });\n}\n\ntype Properties<T> = Required<{\n [K in keyof T]: z.ZodType<T[K], T[K]>;\n}>;\n\nexport function AddChangeLogItemInputSchema(): z.ZodObject<\n Properties<AddChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"AddChangeLogItemInput\").optional(),\n content: z.string(),\n id: z.string(),\n insertBefore: z.string().nullable(),\n });\n}\n\nexport function AddModuleInputSchema(): z.ZodObject<\n Properties<AddModuleInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n name: z.string(),\n });\n}\n\nexport function AddOperationErrorInputSchema(): z.ZodObject<\n Properties<AddOperationErrorInput>\n> {\n return z.object({\n errorCode: z.string().nullish(),\n errorDescription: z.string().nullish(),\n errorName: z.string().nullish(),\n errorTemplate: z.string().nullish(),\n id: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function AddOperationExampleInputSchema(): z.ZodObject<\n Properties<AddOperationExampleInput>\n> {\n return z.object({\n example: z.string(),\n id: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function AddOperationInputSchema(): z.ZodObject<\n Properties<AddOperationInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n moduleId: z.string(),\n name: z.string(),\n reducer: z.string().nullish(),\n schema: z.string().nullish(),\n template: z.string().nullish(),\n scope: OperationScopeSchema().nullish(),\n });\n}\n\nexport function AddStateExampleInputSchema(): z.ZodObject<\n Properties<AddStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n example: z.string(),\n id: z.string(),\n insertBefore: z.string().nullish(),\n });\n}\n\nexport function AuthorSchema(): z.ZodObject<Properties<Author>> {\n return z.object({\n __typename: z.literal(\"Author\").optional(),\n name: z.string(),\n website: z.string().nullable(),\n });\n}\n\nexport function CodeExampleSchema(): z.ZodObject<Properties<CodeExample>> {\n return z.object({\n __typename: z.literal(\"CodeExample\").optional(),\n id: z.string(),\n value: z.string(),\n });\n}\n\nexport function DeleteChangeLogItemInputSchema(): z.ZodObject<\n Properties<DeleteChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"DeleteChangeLogItemInput\").optional(),\n id: z.string(),\n });\n}\n\nexport function DeleteModuleInputSchema(): z.ZodObject<\n Properties<DeleteModuleInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationErrorInputSchema(): z.ZodObject<\n Properties<DeleteOperationErrorInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationExampleInputSchema(): z.ZodObject<\n Properties<DeleteOperationExampleInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationInputSchema(): z.ZodObject<\n Properties<DeleteOperationInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteStateExampleInputSchema(): z.ZodObject<\n Properties<DeleteStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n id: z.string(),\n });\n}\n\nexport function DocumentModelInputSchema() {\n return z.union([\n AddChangeLogItemInputSchema(),\n AddModuleInputSchema(),\n AddOperationErrorInputSchema(),\n AddOperationExampleInputSchema(),\n AddOperationInputSchema(),\n AddStateExampleInputSchema(),\n DeleteChangeLogItemInputSchema(),\n DeleteModuleInputSchema(),\n DeleteOperationErrorInputSchema(),\n DeleteOperationExampleInputSchema(),\n DeleteOperationInputSchema(),\n DeleteStateExampleInputSchema(),\n MoveOperationInputSchema(),\n ReorderChangeLogItemsInputSchema(),\n ReorderModuleOperationsInputSchema(),\n ReorderModulesInputSchema(),\n ReorderOperationErrorsInputSchema(),\n ReorderOperationExamplesInputSchema(),\n ReorderStateExamplesInputSchema(),\n SetAuthorNameInputSchema(),\n SetAuthorWebsiteInputSchema(),\n SetInitialStateInputSchema(),\n SetModelDescriptionInputSchema(),\n SetModelExtensionInputSchema(),\n SetModelIdInputSchema(),\n SetModelNameInputSchema(),\n SetModuleDescriptionInputSchema(),\n SetModuleNameInputSchema(),\n SetOperationDescriptionInputSchema(),\n SetOperationErrorCodeInputSchema(),\n SetOperationErrorDescriptionInputSchema(),\n SetOperationErrorNameInputSchema(),\n SetOperationErrorTemplateInputSchema(),\n SetOperationNameInputSchema(),\n SetOperationReducerInputSchema(),\n SetOperationSchemaInputSchema(),\n SetOperationTemplateInputSchema(),\n SetStateSchemaInputSchema(),\n UpdateChangeLogItemInputSchema(),\n UpdateOperationExampleInputSchema(),\n UpdateStateExampleInputSchema(),\n ]);\n}\n\nexport function DocumentModelGlobalStateSchema(): z.ZodObject<\n Properties<DocumentModelGlobalState>\n> {\n return z.object({\n __typename: z.literal(\"DocumentModelGlobalState\").optional(),\n id: z.string(),\n name: z.string(),\n author: AuthorSchema(),\n extension: z.string(),\n description: z.string(),\n specifications: z.array(DocumentSpecificationSchema()),\n });\n}\n\nexport function DocumentSpecificationSchema(): z.ZodObject<\n Properties<DocumentSpecification>\n> {\n return z.object({\n __typename: z.literal(\"DocumentSpecification\").optional(),\n state: ScopeStateSchema(),\n modules: z.array(ModuleSchema()),\n version: z.number().int(),\n changeLog: z.array(z.string()),\n });\n}\n\nexport function ModuleSchema(): z.ZodObject<Properties<ModuleSpecification>> {\n return z.object({\n __typename: z.literal(\"ModuleSpecification\").optional(),\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n operations: z.array(OperationSpecificationSchema()),\n });\n}\n\nexport function MoveOperationInputSchema(): z.ZodObject<\n Properties<MoveOperationInput>\n> {\n return z.object({\n newModuleId: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function OperationSpecificationSchema(): z.ZodObject<\n Properties<OperationSpecification>\n> {\n return z.object({\n __typename: z.literal(\"OperationSpecification\").optional(),\n id: z.string(),\n name: z.string().nullable(),\n description: z.string().nullable(),\n schema: z.string().nullable(),\n template: z.string().nullable(),\n reducer: z.string().nullable(),\n errors: z.array(OperationErrorSchema()),\n examples: z.array(CodeExampleSchema()),\n scope: OperationScopeSchema(),\n });\n}\n\nexport function OperationErrorSchema(): z.ZodObject<\n Properties<OperationErrorSpecification>\n> {\n return z.object({\n __typename: z.literal(\"OperationErrorSpecification\").optional(),\n id: z.string(),\n name: z.string().nullable(),\n code: z.string().nullable(),\n description: z.string().nullable(),\n template: z.string().nullable(),\n });\n}\n\nexport function ReorderChangeLogItemsInputSchema(): z.ZodObject<\n Properties<ReorderChangeLogItemsInput>\n> {\n return z.object({\n __typename: z.literal(\"ReorderChangeLogItemsInput\").optional(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderModuleOperationsInputSchema(): z.ZodObject<\n Properties<ReorderModuleOperationsInput>\n> {\n return z.object({\n moduleId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderModulesInputSchema(): z.ZodObject<\n Properties<ReorderModulesInput>\n> {\n return z.object({\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderOperationErrorsInputSchema(): z.ZodObject<\n Properties<ReorderOperationErrorsInput>\n> {\n return z.object({\n operationId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderOperationExamplesInputSchema(): z.ZodObject<\n Properties<ReorderOperationExamplesInput>\n> {\n return z.object({\n operationId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderStateExamplesInputSchema(): z.ZodObject<\n Properties<ReorderStateExamplesInput>\n> {\n return z.object({\n scope: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function SetAuthorNameInputSchema(): z.ZodObject<\n Properties<SetAuthorNameInput>\n> {\n return z.object({\n authorName: z.string(),\n });\n}\n\nexport function SetAuthorWebsiteInputSchema(): z.ZodObject<\n Properties<SetAuthorWebsiteInput>\n> {\n return z.object({\n authorWebsite: z.string(),\n });\n}\n\nexport function SetInitialStateInputSchema(): z.ZodObject<\n Properties<SetInitialStateInput>\n> {\n return z.object({\n scope: z.string(),\n initialValue: z.string(),\n });\n}\n\nexport function SetModelDescriptionInputSchema(): z.ZodObject<\n Properties<SetModelDescriptionInput>\n> {\n return z.object({\n description: z.string(),\n });\n}\n\nexport function SetModelExtensionInputSchema(): z.ZodObject<\n Properties<SetModelExtensionInput>\n> {\n return z.object({\n extension: z.string(),\n });\n}\n\nexport function SetModelIdInputSchema(): z.ZodObject<\n Properties<SetModelIdInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function SetModelNameInputSchema(): z.ZodObject<\n Properties<SetModelNameInput>\n> {\n return z.object({\n name: z.string(),\n });\n}\n\nexport function SetModuleDescriptionInputSchema(): z.ZodObject<\n Properties<SetModuleDescriptionInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetModuleNameInputSchema(): z.ZodObject<\n Properties<SetModuleNameInput>\n> {\n return z.object({\n id: z.string(),\n name: z.string().nullish(),\n });\n}\n\nexport function SetOperationDescriptionInputSchema(): z.ZodObject<\n Properties<SetOperationDescriptionInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorCodeInputSchema(): z.ZodObject<\n Properties<SetOperationErrorCodeInput>\n> {\n return z.object({\n errorCode: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorDescriptionInputSchema(): z.ZodObject<\n Properties<SetOperationErrorDescriptionInput>\n> {\n return z.object({\n errorDescription: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorNameInputSchema(): z.ZodObject<\n Properties<SetOperationErrorNameInput>\n> {\n return z.object({\n errorName: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorTemplateInputSchema(): z.ZodObject<\n Properties<SetOperationErrorTemplateInput>\n> {\n return z.object({\n errorTemplate: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationNameInputSchema(): z.ZodObject<\n Properties<SetOperationNameInput>\n> {\n return z.object({\n id: z.string(),\n name: z.string().nullish(),\n });\n}\n\nexport function SetOperationScopeInputSchema(): z.ZodObject<\n Properties<SetOperationScopeInput>\n> {\n return z.object({\n id: z.string(),\n scope: OperationScopeSchema(),\n });\n}\n\nexport function SetOperationReducerInputSchema(): z.ZodObject<\n Properties<SetOperationReducerInput>\n> {\n return z.object({\n id: z.string(),\n reducer: z.string().nullish(),\n });\n}\n\nexport function SetOperationSchemaInputSchema(): z.ZodObject<\n Properties<SetOperationSchemaInput>\n> {\n return z.object({\n id: z.string(),\n schema: z.string().nullish(),\n });\n}\n\nexport function SetOperationTemplateInputSchema(): z.ZodObject<\n Properties<SetOperationTemplateInput>\n> {\n return z.object({\n id: z.string(),\n template: z.string().nullish(),\n });\n}\n\nexport function SetStateSchemaInputSchema(): z.ZodObject<\n Properties<SetStateSchemaInput>\n> {\n return z.object({\n scope: z.string(),\n schema: z.string(),\n });\n}\n\nexport function StateSchema(): z.ZodObject<Properties<State>> {\n return z.object({\n __typename: z.literal(\"State\").optional(),\n schema: z.string(),\n examples: z.array(CodeExampleSchema()),\n initialValue: z.string(),\n });\n}\n\nexport function ScopeStateSchema(): z.ZodObject<Properties<ScopeState>> {\n return z.object({\n local: StateSchema(),\n global: StateSchema(),\n });\n}\n\nexport function UpdateChangeLogItemInputSchema(): z.ZodObject<\n Properties<UpdateChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"UpdateChangeLogItemInput\").optional(),\n id: z.string(),\n newContent: z.string(),\n });\n}\n\nexport function UpdateOperationExampleInputSchema(): z.ZodObject<\n Properties<UpdateOperationExampleInput>\n> {\n return z.object({\n example: z.string(),\n id: z.string(),\n });\n}\n\nexport function UpdateStateExampleInputSchema(): z.ZodObject<\n Properties<UpdateStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n id: z.string(),\n newExample: z.string(),\n });\n}\n\nexport const PowerhouseModuleSchema = z.object({\n id: z.string(),\n name: z.string(),\n documentTypes: z.array(z.string()).optional(),\n});\n\nexport const PowerhouseModulesSchema = z\n .array(PowerhouseModuleSchema)\n .optional();\n\nexport const PublisherSchema = z.object({\n name: z.string().optional(),\n url: z.string().optional(),\n});\n\nexport const ConfigEntryTypeSchema = z.union([\n z.literal(\"var\"),\n z.literal(\"secret\"),\n]);\n\nexport const ConfigEntrySchema = z.object({\n name: z.string(),\n type: ConfigEntryTypeSchema,\n description: z.string().optional(),\n required: z.boolean().optional(),\n default: z.boolean().optional(),\n});\n\n// PWA / service-worker overrides a package contributes to a Connect build.\n// The `z.ZodType<PHConnectPwa>` annotation pins the schema to the TS type in\n// packages/shared/clis/types.ts, so drift between them is a compile error;\n// the JSON-schema fragment in packages/shared/connect/schema-fragments.ts is\n// the remaining hand-kept mirror. Kept on the manifest (not a separate file)\n// so it ships in dist/powerhouse.manifest.json and the Connect build can read\n// it without executing package code.\n//\n// Every fixed-shape object below is strict (z.strictObject): an unknown key —\n// e.g. a `manifest.nam` typo — fails the build loudly instead of being\n// silently dropped, matching the JSON schema's `additionalProperties: false`.\n// Only the open MIME/header maps (z.record) accept arbitrary keys by design.\nconst PwaUrlPatternSchema = z.union([\n z.string(),\n z\n .strictObject({ source: z.string(), flags: z.string().optional() })\n // The pair is rebuilt into a RegExp at build time; catch a non-compiling\n // pattern here, where validation can still name the contributor.\n .refine(\n (p) => {\n try {\n new RegExp(p.source, p.flags);\n return true;\n } catch {\n return false;\n }\n },\n { message: \"source/flags do not compile to a valid RegExp\" },\n ),\n]);\n\nconst PwaRuntimeCachingSchema = z.strictObject({\n urlPattern: PwaUrlPatternSchema,\n handler: z.enum([\n \"CacheFirst\",\n \"CacheOnly\",\n \"NetworkFirst\",\n \"NetworkOnly\",\n \"StaleWhileRevalidate\",\n ]),\n method: z.enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"HEAD\", \"PATCH\"]).optional(),\n options: z\n .strictObject({\n cacheName: z.string().optional(),\n networkTimeoutSeconds: z.number().optional(),\n expiration: z\n .strictObject({\n maxEntries: z.number().optional(),\n maxAgeSeconds: z.number().optional(),\n })\n .optional(),\n cacheableResponse: z\n .strictObject({\n statuses: z.array(z.number()).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n })\n .optional(),\n});\n\nconst PwaIconSchema = z.strictObject({\n src: z.string(),\n sizes: z.string().optional(),\n type: z.string().optional(),\n purpose: z.string().optional(),\n});\n\n// No `action` field: the route launched files open at is fixed by Connect\n// (the runtime handling lives in Connect's own source), so contributors only\n// declare WHICH file types they accept. `strictObject` rejects a fragment\n// that tries to set its own route. Extensions must carry the leading dot —\n// Chromium silently ignores dotless entries, so fail loudly at build instead.\nconst PwaFileHandlerSchema = z.strictObject({\n accept: z.record(\n z.string(),\n z.array(z.string().regex(/^\\./, \"file extensions must start with '.'\")),\n ),\n icons: z.array(PwaIconSchema).optional(),\n launch_type: z.enum([\"single-client\", \"multiple-clients\"]).optional(),\n});\n\n// `categories` is intentionally NOT here: it is not authored under\n// `connect.pwa` — it is derived from the `category` field of the contributing\n// `powerhouse.manifest.json` files (see collectProjectPwaContribution /\n// toPwaContribution). `strictObject` therefore rejects an authored `categories`\n// (and the removed `shortcuts`/`screenshots`/`share_target`/`display_override`).\nconst PwaManifestOverrideSchema = z.strictObject({\n name: z.string().optional(),\n short_name: z.string().optional(),\n description: z.string().optional(),\n theme_color: z.string().optional(),\n background_color: z.string().optional(),\n display: z\n .enum([\"fullscreen\", \"standalone\", \"minimal-ui\", \"browser\"])\n .optional(),\n start_url: z.string().optional(),\n scope: z.string().optional(),\n icons: z.array(PwaIconSchema).optional(),\n file_handlers: z.array(PwaFileHandlerSchema).optional(),\n launch_handler: z\n .strictObject({\n client_mode: z.enum([\n \"auto\",\n \"focus-existing\",\n \"navigate-existing\",\n \"navigate-new\",\n ]),\n })\n .optional(),\n});\n\nexport const PwaConfigSchema: z.ZodType<PHConnectPwa> = z.strictObject({\n manifest: PwaManifestOverrideSchema.optional(),\n globPatterns: z.array(z.string()).optional(),\n globIgnores: z.array(z.string()).optional(),\n maximumFileSizeToCacheInBytes: z.number().optional(),\n runtimeCaching: z.array(PwaRuntimeCachingSchema).optional(),\n navigateFallbackDenylist: z.array(PwaUrlPatternSchema).optional(),\n});\n\nexport const ManifestSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n category: z.string().optional(),\n image: z.string().optional(),\n publisher: PublisherSchema.optional(),\n documentModels: PowerhouseModulesSchema,\n apps: PowerhouseModulesSchema,\n editors: PowerhouseModulesSchema,\n processors: PowerhouseModulesSchema,\n subgraphs: PowerhouseModulesSchema,\n config: z.array(ConfigEntrySchema).optional(),\n pwa: PwaConfigSchema.optional(),\n});\n","import { ZodError } from \"zod\";\nimport {\n ab2hex,\n buildOperationSignatureMessage,\n buildOperationSignatureParams,\n hex2ab,\n} from \"./crypto.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport {\n InvalidActionInputError,\n InvalidActionInputZodError,\n} from \"./errors.js\";\nimport type { Operation, OperationContext } from \"./operations.js\";\nimport {\n AddChangeLogItemInputSchema,\n AddModuleInputSchema,\n AddOperationErrorInputSchema,\n AddOperationExampleInputSchema,\n AddOperationInputSchema,\n AddStateExampleInputSchema,\n DeleteChangeLogItemInputSchema,\n DeleteModuleInputSchema,\n DeleteOperationErrorInputSchema,\n DeleteOperationExampleInputSchema,\n DeleteOperationInputSchema,\n DeleteStateExampleInputSchema,\n LoadStateActionInputSchema,\n MoveOperationInputSchema,\n PruneActionInputSchema,\n RedoActionInputSchema,\n ReorderChangeLogItemsInputSchema,\n ReorderModuleOperationsInputSchema,\n ReorderModulesInputSchema,\n ReorderOperationErrorsInputSchema,\n ReorderOperationExamplesInputSchema,\n ReorderStateExamplesInputSchema,\n SetAuthorNameInputSchema,\n SetAuthorWebsiteInputSchema,\n SetInitialStateInputSchema,\n SetModelDescriptionInputSchema,\n SetModelExtensionInputSchema,\n SetModelIdInputSchema,\n SetModelNameInputSchema,\n SetModuleDescriptionInputSchema,\n SetModuleNameInputSchema,\n SetNameActionInputSchema,\n SetPreferredEditorActionInputSchema,\n SetOperationDescriptionInputSchema,\n SetOperationErrorCodeInputSchema,\n SetOperationErrorDescriptionInputSchema,\n SetOperationErrorNameInputSchema,\n SetOperationErrorTemplateInputSchema,\n SetOperationNameInputSchema,\n SetOperationReducerInputSchema,\n SetOperationSchemaInputSchema,\n SetOperationScopeInputSchema,\n SetOperationTemplateInputSchema,\n SetStateSchemaInputSchema,\n UndoActionInputSchema,\n UpdateChangeLogItemInputSchema,\n UpdateOperationExampleInputSchema,\n UpdateStateExampleInputSchema,\n} from \"./schemas.js\";\nimport type {\n ActionSigner,\n AppActionSigner,\n Signature,\n UserActionSigner,\n} from \"./signatures.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n ActionSignatureContext,\n ActionSigningHandler,\n ActionVerificationHandler,\n AddChangeLogItemAction,\n AddChangeLogItemInput,\n AddModuleAction,\n AddModuleInput,\n AddOperationAction,\n AddOperationErrorAction,\n AddOperationErrorInput,\n AddOperationExampleAction,\n AddOperationExampleInput,\n AddOperationInput,\n AddStateExampleAction,\n AddStateExampleInput,\n DeleteChangeLogItemAction,\n DeleteChangeLogItemInput,\n DeleteModuleAction,\n DeleteModuleInput,\n DeleteOperationAction,\n DeleteOperationErrorAction,\n DeleteOperationErrorInput,\n DeleteOperationExampleAction,\n DeleteOperationExampleInput,\n DeleteOperationInput,\n DeleteStateExampleAction,\n DeleteStateExampleInput,\n LoadStateAction,\n MoveOperationAction,\n MoveOperationInput,\n NOOPAction,\n RedoAction,\n Reducer,\n ReleaseNewVersionAction,\n ReorderChangeLogItemsAction,\n ReorderChangeLogItemsInput,\n ReorderModuleOperationsAction,\n ReorderModuleOperationsInput,\n ReorderModulesAction,\n ReorderModulesInput,\n ReorderOperationErrorsAction,\n ReorderOperationErrorsInput,\n ReorderOperationExamplesAction,\n ReorderOperationExamplesInput,\n ReorderStateExamplesAction,\n ReorderStateExamplesInput,\n SchemaPruneAction,\n SetAuthorNameAction,\n SetAuthorNameInput,\n SetAuthorWebsiteAction,\n SetAuthorWebsiteInput,\n SetInitialStateAction,\n SetInitialStateInput,\n SetModelDescriptionAction,\n SetModelDescriptionInput,\n SetModelExtensionAction,\n SetModelExtensionInput,\n SetModelIdAction,\n SetModelIdInput,\n SetModelNameAction,\n SetModelNameInput,\n SetModuleDescriptionAction,\n SetModuleDescriptionInput,\n SetModuleNameAction,\n SetModuleNameInput,\n SetNameAction,\n SetPreferredEditorAction,\n SetOperationDescriptionAction,\n SetOperationDescriptionInput,\n SetOperationErrorCodeAction,\n SetOperationErrorCodeInput,\n SetOperationErrorDescriptionAction,\n SetOperationErrorDescriptionInput,\n SetOperationErrorNameAction,\n SetOperationErrorNameInput,\n SetOperationErrorTemplateAction,\n SetOperationErrorTemplateInput,\n SetOperationNameAction,\n SetOperationNameInput,\n SetOperationReducerAction,\n SetOperationReducerInput,\n SetOperationSchemaAction,\n SetOperationSchemaInput,\n SetOperationScopeAction,\n SetOperationScopeInput,\n SetOperationTemplateAction,\n SetOperationTemplateInput,\n SetStateSchemaAction,\n SetStateSchemaInput,\n UndoAction,\n UpdateChangeLogItemAction,\n UpdateChangeLogItemInput,\n UpdateOperationExampleAction,\n UpdateOperationExampleInput,\n UpdateStateExampleAction,\n UpdateStateExampleInput,\n} from \"./types.js\";\nimport { deriveOperationId, generateId } from \"./utils.js\";\n\n/**\n * Cancels the last `count` operations.\n *\n * @param count - Number of operations to cancel\n * @category Actions\n */\nexport const undo = (count = 1, scope = \"global\") =>\n createAction<UndoAction>(\n \"UNDO\",\n { count },\n undefined,\n UndoActionInputSchema,\n scope,\n );\n\n/**\n * Cancels the last `count` {@link undo | UNDO} operations.\n *\n * @param count - Number of UNDO operations to cancel\n * @category Actions\n */\nexport const redo = (count = 1, scope = \"global\") =>\n createAction<RedoAction>(\n \"REDO\",\n { count },\n undefined,\n RedoActionInputSchema,\n scope,\n );\n\n/**\n * Joins multiple operations into a single {@link loadState | LOAD_STATE} operation.\n *\n * @remarks\n * Useful to keep operations history smaller. Operations to prune are selected by index,\n * similar to the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | slice} method in Arrays.\n *\n * @param start - Index of the first operation to prune\n * @param end - Index of the last operation to prune\n * @category Actions\n */\nexport const prune = (start?: number, end?: number, scope = \"global\") =>\n createAction<SchemaPruneAction>(\n \"PRUNE\",\n { start, end },\n undefined,\n PruneActionInputSchema,\n scope,\n );\n\n/**\n * Replaces the state of the document.\n *\n * @remarks\n * This action shouldn't be used directly. It is dispatched by the {@link prune} action.\n *\n * @param state - State to be set in the document.\n * @param operations - Number of operations that were removed from the previous state.\n * @category Actions\n */\nexport const loadState = <TState extends PHBaseState = PHBaseState>(\n state: TState & { name: string },\n operations: number,\n) =>\n createAction<LoadStateAction>(\n \"LOAD_STATE\",\n { state, operations },\n undefined,\n LoadStateActionInputSchema,\n );\n\nexport const noop = (scope = \"global\") =>\n createAction<NOOPAction>(\"NOOP\", {}, undefined, undefined, scope);\n\n// TODO improve base actions type\n\n/**\n * Helper function to be used by action creators.\n *\n * @remarks\n * Creates an action with the given type and input properties. The input\n * properties default to an empty object.\n *\n * @typeParam A - Type of the action to be returned.\n *\n * @param type - The type of the action.\n * @param input - The input properties of the action.\n * @param _attachments - Deprecated and ignored. Retained so action creators\n * generated before the attachment-system removal keep their 5-argument shape.\n * @param validator - The validator to use for the input properties.\n * @param scope - The scope of the action, can either be 'global' or 'local'.\n *\n * @throws Error if the type is empty or not a string.\n *\n * @returns The new action.\n */\nexport function createAction<TAction extends Action>(\n type: TAction[\"type\"],\n input?: TAction[\"input\"],\n // Deprecated, ignored. Retained so action creators generated before the\n // legacy attachment system was removed keep their 5-argument call shape.\n _attachments?: unknown,\n validator?: () => { parse(v: unknown): TAction[\"input\"] },\n scope: Action[\"scope\"] = \"global\",\n): TAction {\n if (!type) throw new Error(\"Empty action type\");\n if (typeof type !== \"string\")\n throw new Error(`Invalid action type: ${JSON.stringify(type)}`);\n\n const action: Action = {\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type,\n input,\n scope,\n };\n\n try {\n validator?.().parse(action.input);\n } catch (error) {\n if (error instanceof ZodError) {\n throw new InvalidActionInputZodError(error.issues);\n }\n throw new InvalidActionInputError(error);\n }\n\n return action as TAction;\n}\n\n/**\n * This function should be used instead of { ...action } to ensure\n * that extra properties are not included in the action.\n */\nexport const actionFromAction = (action: Action): Action => {\n return {\n id: action.id,\n timestampUtcMs: action.timestampUtcMs,\n type: action.type,\n input: action.input,\n scope: action.scope,\n context: action.context,\n };\n};\n\nexport const operationFromAction = (\n action: Action,\n index: number,\n skip: number,\n context: OperationContext,\n): Operation => {\n return {\n ...action,\n action,\n id: deriveOperationId(\n context.documentId,\n context.scope,\n context.branch,\n action.id,\n ),\n timestampUtcMs: action.timestampUtcMs,\n hash: \"\",\n error: undefined,\n\n index,\n skip,\n };\n};\n\nexport const operationFromOperation = (\n operation: Operation,\n index: number,\n skip: number,\n context: OperationContext,\n): Operation => {\n const id = deriveOperationId(\n context.documentId,\n context.scope,\n context.branch,\n operation.action.id,\n );\n\n return {\n ...operation,\n hash: \"\",\n error: undefined,\n index,\n skip,\n id,\n };\n};\n\nexport const operationWithContext = (\n operation: Operation,\n context: ActionContext,\n): Operation => {\n if (!operation.action) {\n throw new Error(\"Operation has no action\");\n }\n\n return {\n ...operation,\n action: {\n ...operation.action,\n context,\n },\n };\n};\n\nexport const actionContext = (): ActionContext => ({});\n\nexport const actionSigner = (\n user: UserActionSigner,\n app: AppActionSigner,\n signatures: Signature[] = [],\n): ActionSigner => ({\n user,\n app,\n signatures,\n});\n\nexport async function buildOperationSignature(\n context: ActionSignatureContext,\n signMethod: ActionSigningHandler,\n): Promise<Signature> {\n const params = buildOperationSignatureParams(context);\n const message = buildOperationSignatureMessage(params);\n const signature = await signMethod(message);\n return [...params, `0x${ab2hex(signature)}`];\n}\n\nexport async function buildSignedAction<\n TState extends PHBaseState = PHBaseState,\n>(\n action: Action,\n reducer: Reducer<TState>,\n document: PHDocument<TState>,\n signer: ActionSigner,\n signHandler: ActionSigningHandler,\n) {\n const result = reducer(document, action, undefined, {\n //reuseHash: true,\n reuseOperationResultingState: true,\n });\n const scopeOperations = result.operations[action.scope];\n if (!scopeOperations) {\n throw new Error(`No operations found for scope: ${action.scope}`);\n }\n const operation = scopeOperations.at(-1);\n if (!operation) {\n throw new Error(\"Action was not applied\");\n }\n\n const previousStateHash = scopeOperations.at(-2)?.hash ?? \"\";\n const signature = await buildOperationSignature(\n {\n documentId: document.header.id,\n signer,\n action,\n previousStateHash,\n },\n signHandler,\n );\n\n const actionContext: ActionContext = {\n signer: actionSigner(signer.user, signer.app, [\n ...signer.signatures,\n signature,\n ]),\n };\n\n return operationWithContext(operation, actionContext);\n}\n\nexport async function verifyOperationSignature(\n signature: Signature,\n signer: Omit<ActionSigner, \"signatures\">,\n verifyHandler: ActionVerificationHandler,\n) {\n const publicKey = signer.app.key;\n const params = signature.slice(0, 4) as [string, string, string, string];\n const signatureBytes = hex2ab(signature[4]);\n const expectedMessage = buildOperationSignatureMessage(params);\n return verifyHandler(publicKey, signatureBytes, expectedMessage);\n}\n\n/**\n * Changes the name of the document.\n *\n * @param name - The name to be set in the document.\n * @category Actions\n */\nexport const setName = (name: string | { name: string }) =>\n createAction<SetNameAction>(\n \"SET_NAME\",\n typeof name === \"string\" ? { name } : name,\n undefined,\n SetNameActionInputSchema,\n // TODO: THIS IS A BUG: This needs to be changed to a HEADER scope action if it's changing the header.\n \"global\",\n );\n\n/**\n * Changes the preferred editor recorded in the document header meta.\n *\n * Passing `null` clears the preferred editor.\n *\n * @category Actions\n */\nexport const setPreferredEditor = (\n input: string | null | { preferredEditor: string | null },\n) =>\n createAction<SetPreferredEditorAction>(\n \"SET_PREFERRED_EDITOR\",\n typeof input === \"object\" && input !== null\n ? input\n : { preferredEditor: input },\n undefined,\n SetPreferredEditorActionInputSchema,\n \"header\",\n );\nexport const setModelName = (input: SetModelNameInput) =>\n createAction<SetModelNameAction>(\n \"SET_MODEL_NAME\",\n { ...input },\n undefined,\n SetModelNameInputSchema,\n \"global\",\n );\n\nexport const setModelId = (input: SetModelIdInput) =>\n createAction<SetModelIdAction>(\n \"SET_MODEL_ID\",\n { ...input },\n undefined,\n SetModelIdInputSchema,\n \"global\",\n );\n\nexport const setModelExtension = (input: SetModelExtensionInput) =>\n createAction<SetModelExtensionAction>(\n \"SET_MODEL_EXTENSION\",\n { ...input },\n undefined,\n SetModelExtensionInputSchema,\n \"global\",\n );\n\nexport const setModelDescription = (input: SetModelDescriptionInput) =>\n createAction<SetModelDescriptionAction>(\n \"SET_MODEL_DESCRIPTION\",\n { ...input },\n undefined,\n SetModelDescriptionInputSchema,\n \"global\",\n );\n\nexport const setAuthorName = (input: SetAuthorNameInput) =>\n createAction<SetAuthorNameAction>(\n \"SET_AUTHOR_NAME\",\n { ...input },\n undefined,\n SetAuthorNameInputSchema,\n \"global\",\n );\n\nexport const setAuthorWebsite = (input: SetAuthorWebsiteInput) =>\n createAction<SetAuthorWebsiteAction>(\n \"SET_AUTHOR_WEBSITE\",\n { ...input },\n undefined,\n SetAuthorWebsiteInputSchema,\n \"global\",\n );\n\nexport const addModule = (input: AddModuleInput) =>\n createAction<AddModuleAction>(\n \"ADD_MODULE\",\n { ...input },\n undefined,\n AddModuleInputSchema,\n \"global\",\n );\n\nexport const setModuleName = (input: SetModuleNameInput) =>\n createAction<SetModuleNameAction>(\n \"SET_MODULE_NAME\",\n { ...input },\n undefined,\n SetModuleNameInputSchema,\n \"global\",\n );\n\nexport const setModuleDescription = (input: SetModuleDescriptionInput) =>\n createAction<SetModuleDescriptionAction>(\n \"SET_MODULE_DESCRIPTION\",\n { ...input },\n undefined,\n SetModuleDescriptionInputSchema,\n \"global\",\n );\n\nexport const deleteModule = (input: DeleteModuleInput) =>\n createAction<DeleteModuleAction>(\n \"DELETE_MODULE\",\n { ...input },\n undefined,\n DeleteModuleInputSchema,\n \"global\",\n );\n\nexport const reorderModules = (input: ReorderModulesInput) =>\n createAction<ReorderModulesAction>(\n \"REORDER_MODULES\",\n { ...input },\n undefined,\n ReorderModulesInputSchema,\n \"global\",\n );\n\nexport const addOperation = (input: AddOperationInput) =>\n createAction<AddOperationAction>(\n \"ADD_OPERATION\",\n { ...input },\n undefined,\n AddOperationInputSchema,\n \"global\",\n );\n\nexport const setOperationName = (input: SetOperationNameInput) =>\n createAction<SetOperationNameAction>(\n \"SET_OPERATION_NAME\",\n { ...input },\n undefined,\n SetOperationNameInputSchema,\n \"global\",\n );\n\nexport const setOperationScope = (input: SetOperationScopeInput) =>\n createAction<SetOperationScopeAction>(\n \"SET_OPERATION_SCOPE\",\n { ...input },\n undefined,\n SetOperationScopeInputSchema,\n \"global\",\n );\n\nexport const setOperationSchema = (input: SetOperationSchemaInput) =>\n createAction<SetOperationSchemaAction>(\n \"SET_OPERATION_SCHEMA\",\n { ...input },\n undefined,\n SetOperationSchemaInputSchema,\n \"global\",\n );\n\nexport const setOperationDescription = (input: SetOperationDescriptionInput) =>\n createAction<SetOperationDescriptionAction>(\n \"SET_OPERATION_DESCRIPTION\",\n { ...input },\n undefined,\n SetOperationDescriptionInputSchema,\n \"global\",\n );\n\nexport const setOperationTemplate = (input: SetOperationTemplateInput) =>\n createAction<SetOperationTemplateAction>(\n \"SET_OPERATION_TEMPLATE\",\n { ...input },\n undefined,\n SetOperationTemplateInputSchema,\n \"global\",\n );\n\nexport const setOperationReducer = (input: SetOperationReducerInput) =>\n createAction<SetOperationReducerAction>(\n \"SET_OPERATION_REDUCER\",\n { ...input },\n undefined,\n SetOperationReducerInputSchema,\n \"global\",\n );\n\nexport const moveOperation = (input: MoveOperationInput) =>\n createAction<MoveOperationAction>(\n \"MOVE_OPERATION\",\n { ...input },\n undefined,\n MoveOperationInputSchema,\n \"global\",\n );\n\nexport const deleteOperation = (input: DeleteOperationInput) =>\n createAction<DeleteOperationAction>(\n \"DELETE_OPERATION\",\n { ...input },\n undefined,\n DeleteOperationInputSchema,\n \"global\",\n );\n\nexport const reorderModuleOperations = (input: ReorderModuleOperationsInput) =>\n createAction<ReorderModuleOperationsAction>(\n \"REORDER_MODULE_OPERATIONS\",\n { ...input },\n undefined,\n ReorderModuleOperationsInputSchema,\n \"global\",\n );\n\nexport const addOperationError = (input: AddOperationErrorInput) =>\n createAction<AddOperationErrorAction>(\n \"ADD_OPERATION_ERROR\",\n { ...input },\n undefined,\n AddOperationErrorInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorCode = (input: SetOperationErrorCodeInput) =>\n createAction<SetOperationErrorCodeAction>(\n \"SET_OPERATION_ERROR_CODE\",\n { ...input },\n undefined,\n SetOperationErrorCodeInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorName = (input: SetOperationErrorNameInput) =>\n createAction<SetOperationErrorNameAction>(\n \"SET_OPERATION_ERROR_NAME\",\n { ...input },\n undefined,\n SetOperationErrorNameInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorDescription = (\n input: SetOperationErrorDescriptionInput,\n) =>\n createAction<SetOperationErrorDescriptionAction>(\n \"SET_OPERATION_ERROR_DESCRIPTION\",\n { ...input },\n undefined,\n SetOperationErrorDescriptionInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorTemplate = (\n input: SetOperationErrorTemplateInput,\n) =>\n createAction<SetOperationErrorTemplateAction>(\n \"SET_OPERATION_ERROR_TEMPLATE\",\n { ...input },\n undefined,\n SetOperationErrorTemplateInputSchema,\n \"global\",\n );\n\nexport const deleteOperationError = (input: DeleteOperationErrorInput) =>\n createAction<DeleteOperationErrorAction>(\n \"DELETE_OPERATION_ERROR\",\n { ...input },\n undefined,\n DeleteOperationErrorInputSchema,\n \"global\",\n );\n\nexport const reorderOperationErrors = (input: ReorderOperationErrorsInput) =>\n createAction<ReorderOperationErrorsAction>(\n \"REORDER_OPERATION_ERRORS\",\n { ...input },\n undefined,\n ReorderOperationErrorsInputSchema,\n \"global\",\n );\n\nexport const addOperationExample = (input: AddOperationExampleInput) =>\n createAction<AddOperationExampleAction>(\n \"ADD_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n AddOperationExampleInputSchema,\n \"global\",\n );\n\nexport const updateOperationExample = (input: UpdateOperationExampleInput) =>\n createAction<UpdateOperationExampleAction>(\n \"UPDATE_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n UpdateOperationExampleInputSchema,\n \"global\",\n );\n\nexport const deleteOperationExample = (input: DeleteOperationExampleInput) =>\n createAction<DeleteOperationExampleAction>(\n \"DELETE_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n DeleteOperationExampleInputSchema,\n \"global\",\n );\n\nexport const reorderOperationExamples = (\n input: ReorderOperationExamplesInput,\n) =>\n createAction<ReorderOperationExamplesAction>(\n \"REORDER_OPERATION_EXAMPLES\",\n { ...input },\n undefined,\n ReorderOperationExamplesInputSchema,\n \"global\",\n );\n\nexport const operationExampleCreators = {\n addOperationExample,\n updateOperationExample,\n deleteOperationExample,\n reorderOperationExamples,\n};\n\nexport const setStateSchema = (input: SetStateSchemaInput) =>\n createAction<SetStateSchemaAction>(\n \"SET_STATE_SCHEMA\",\n { ...input },\n undefined,\n SetStateSchemaInputSchema,\n \"global\",\n );\n\nexport const setInitialState = (input: SetInitialStateInput) =>\n createAction<SetInitialStateAction>(\n \"SET_INITIAL_STATE\",\n { ...input },\n undefined,\n SetInitialStateInputSchema,\n \"global\",\n );\n\nexport const addStateExample = (input: AddStateExampleInput) =>\n createAction<AddStateExampleAction>(\n \"ADD_STATE_EXAMPLE\",\n { ...input },\n undefined,\n AddStateExampleInputSchema,\n \"global\",\n );\n\nexport const updateStateExample = (input: UpdateStateExampleInput) =>\n createAction<UpdateStateExampleAction>(\n \"UPDATE_STATE_EXAMPLE\",\n { ...input },\n undefined,\n UpdateStateExampleInputSchema,\n \"global\",\n );\n\nexport const deleteStateExample = (input: DeleteStateExampleInput) =>\n createAction<DeleteStateExampleAction>(\n \"DELETE_STATE_EXAMPLE\",\n { ...input },\n undefined,\n DeleteStateExampleInputSchema,\n \"global\",\n );\n\nexport const reorderStateExamples = (input: ReorderStateExamplesInput) =>\n createAction<ReorderStateExamplesAction>(\n \"REORDER_STATE_EXAMPLES\",\n { ...input },\n undefined,\n ReorderStateExamplesInputSchema,\n \"global\",\n );\n\nexport const addChangeLogItem = (input: AddChangeLogItemInput) =>\n createAction<AddChangeLogItemAction>(\n \"ADD_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n AddChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const updateChangeLogItem = (input: UpdateChangeLogItemInput) =>\n createAction<UpdateChangeLogItemAction>(\n \"UPDATE_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n UpdateChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const deleteChangeLogItem = (input: DeleteChangeLogItemInput) =>\n createAction<DeleteChangeLogItemAction>(\n \"DELETE_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n DeleteChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const reorderChangeLogItems = (input: ReorderChangeLogItemsInput) =>\n createAction<ReorderChangeLogItemsAction>(\n \"REORDER_CHANGE_LOG_ITEMS\",\n { ...input },\n undefined,\n ReorderChangeLogItemsInputSchema,\n \"global\",\n );\n\nexport const releaseNewVersion = () =>\n createAction<ReleaseNewVersionAction>(\n \"RELEASE_NEW_VERSION\",\n {},\n undefined,\n undefined,\n \"global\",\n );\n\nexport const baseActions = {\n setName,\n setPreferredEditor,\n undo,\n redo,\n prune,\n loadState,\n noop,\n};\n\nexport const documentModelActions = {\n setModelName,\n setModelId,\n setModelExtension,\n setModelDescription,\n setAuthorName,\n setAuthorWebsite,\n addModule,\n setModuleName,\n setModuleDescription,\n deleteModule,\n reorderModules,\n addOperation,\n setOperationName,\n setOperationScope,\n setOperationSchema,\n setOperationDescription,\n setOperationTemplate,\n setOperationReducer,\n moveOperation,\n deleteOperation,\n reorderModuleOperations,\n addOperationError,\n setOperationErrorCode,\n setOperationErrorName,\n setOperationErrorDescription,\n setOperationErrorTemplate,\n deleteOperationError,\n reorderOperationErrors,\n addOperationExample,\n updateOperationExample,\n deleteOperationExample,\n reorderOperationExamples,\n setStateSchema,\n setInitialState,\n addStateExample,\n updateStateExample,\n deleteStateExample,\n reorderStateExamples,\n addChangeLogItem,\n updateChangeLogItem,\n deleteChangeLogItem,\n reorderChangeLogItems,\n releaseNewVersion,\n};\n\nexport const actions = { ...baseActions, ...documentModelActions };\n\n/**\n * The context of an action.\n */\nexport type ActionContext = {\n /** The index of the previous operation, showing intended ordering. */\n prevOpIndex?: number;\n\n /** The hash of the previous operation, showing intended state. */\n prevOpHash?: string;\n\n /** A nonce, to cover specific signing attacks and to prevent replay attacks from no-ops. */\n nonce?: string;\n\n /** The signer of the action. */\n signer?: ActionSigner;\n};\n\n/**\n * Defines the basic structure of an action.\n */\nexport type Action = {\n /** The id of the action. This is distinct from the operation id. */\n id: string;\n\n /** The name of the action. */\n type: string;\n\n /** The timestamp of the action. */\n timestampUtcMs: string;\n\n /** The payload of the action. */\n input: unknown;\n\n /** The scope of the action */\n scope: string;\n\n /** The context of the action. */\n context?: ActionContext;\n};\n","export const documentModelDocumentType = \"powerhouse/document-model\";\nexport const groupDocumentType = \"powerhouse/reactor-group\";\n\n/**\n * The group-model action types that change membership. The groups projection\n * filters its reads to these, so any other group operation is invisible to a\n * decision. Kept here so the reactor never depends on the group package; a\n * reactor-group test guards against drift.\n */\nexport const groupMembershipActionTypes = [\n \"ADD_MEMBER\",\n \"REMOVE_MEMBER\",\n] as const;\n","// Version-1 auth policy rules. These are consensus rules applied identically\n// by every replica; changing any of them requires a new policy version.\n\nimport { z } from \"zod\";\nimport type {\n AuthDecision,\n AuthEvaluation,\n AuthRequest,\n AuthSubject,\n ConditionContext,\n} from \"./auth.js\";\nimport { groupDocumentType } from \"./document-type.js\";\nimport type {\n AuthGroups,\n Capability,\n Condition,\n Grant,\n PHGroupState,\n Principal,\n} from \"./state.js\";\n\n/** Maximum number of grants in a policy. */\nexport const MAX_AUTH_GRANTS = 100;\n/** Maximum nesting depth of a condition tree. */\nexport const MAX_CONDITION_DEPTH = 10;\n/** Maximum node count (conditions plus operands) of a condition tree. */\nexport const MAX_CONDITION_NODES = 100;\n/** Maximum entries in an execute capability's operation list. */\nexport const MAX_CAPABILITY_OPERATIONS = 100;\n\n/**\n * Thrown when a grant violates the v1 validation rules. The message is stored\n * on error operations, so it must be a pure function of the input.\n */\nexport class InvalidGrantError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string, problem: string) {\n super(`Invalid grant \"${grantId}\": ${problem}`);\n this.name = \"InvalidGrantError\";\n this.grantId = grantId;\n }\n}\n\n/** Thrown for a `{ group }` principal on a group document: references never chain. */\nexport class GroupPrincipalNotAllowedError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(\n `Grant \"${grantId}\" uses a group principal on a group document: a group's auth scope cannot reference other groups`,\n );\n this.name = \"GroupPrincipalNotAllowedError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when a change would leave a creator-less policy with no grant\n * permitting execute on the auth scope. Without the creator carve-out no\n * subject could ever administer such a policy again.\n */\nexport class AuthAdministrationLockoutError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(\n `Change to grant \"${grantId}\" would leave no reachable grant permitting execute on the auth scope: a policy with no creator must always retain one`,\n );\n this.name = \"AuthAdministrationLockoutError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH would create a creator-less policy with no grant\n * permitting execute on the auth scope. Such a policy would be born with no\n * subject able to administer it.\n */\nexport class AuthAdministrationMissingError extends Error {\n constructor() {\n super(\n \"Initial grants include no reachable grant permitting execute on the auth scope: a policy with no creator must always include one\",\n );\n this.name = \"AuthAdministrationMissingError\";\n }\n}\n\nconst GRANT_KEYS = new Set([\n \"id\",\n \"description\",\n \"effect\",\n \"principal\",\n \"capability\",\n \"where\",\n]);\nconst PRINCIPAL_KINDS = new Set([\"anyone\", \"address\", \"group\", \"match\"]);\nconst COMPARISON_CONDITION_KINDS = new Set([\n \"eq\",\n \"ne\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n]);\n\nexport function isPlainValue(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction operandProblem(\n value: unknown,\n capabilityScope: string | undefined,\n budget: { nodes: number },\n): string | null {\n budget.nodes -= 1;\n if (budget.nodes < 0) {\n return `condition exceeds ${MAX_CONDITION_NODES} nodes`;\n }\n if (!isPlainValue(value)) {\n return \"operand must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1) {\n return \"operand must have exactly one of attr or lit\";\n }\n if (keys[0] === \"attr\") {\n const attr = value.attr;\n if (typeof attr !== \"string\" || attr.length === 0) {\n return \"attr must be a non-empty string\";\n }\n if (\n capabilityScope !== undefined &&\n capabilityScope !== \"*\" &&\n attr.startsWith(\"doc.\")\n ) {\n const pathScope = attr.split(\".\")[1] ?? \"\";\n if (pathScope !== capabilityScope) {\n return `condition path \"${attr}\" reads scope \"${pathScope}\" but the capability covers only scope \"${capabilityScope}\"`;\n }\n }\n return null;\n }\n if (keys[0] === \"lit\") {\n const lit = value.lit;\n if (\n lit !== null &&\n typeof lit !== \"string\" &&\n typeof lit !== \"number\" &&\n typeof lit !== \"boolean\"\n ) {\n return \"lit must be a string, number, boolean, or null\";\n }\n // NaN, Infinity, and -0 do not survive JSON round-trips identically\n if (typeof lit === \"number\" && !Number.isFinite(lit)) {\n return \"lit must be a finite number\";\n }\n if (typeof lit === \"number\" && Object.is(lit, -0)) {\n return \"lit must not be negative zero\";\n }\n return null;\n }\n return `unknown operand kind \"${keys[0]}\"`;\n}\n\nfunction conditionProblem(\n value: unknown,\n capabilityScope: string | undefined,\n depth: number,\n budget: { nodes: number },\n): string | null {\n if (depth > MAX_CONDITION_DEPTH) {\n return `condition exceeds depth ${MAX_CONDITION_DEPTH}`;\n }\n budget.nodes -= 1;\n if (budget.nodes < 0) {\n return `condition exceeds ${MAX_CONDITION_NODES} nodes`;\n }\n if (!isPlainValue(value)) {\n return \"condition must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1) {\n return \"condition must have exactly one operator\";\n }\n const kind = keys[0];\n const body = value[kind];\n if (COMPARISON_CONDITION_KINDS.has(kind)) {\n if (!Array.isArray(body) || body.length !== 2) {\n return `${kind} requires a pair of operands`;\n }\n for (const operand of body) {\n const problem = operandProblem(operand, capabilityScope, budget);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"in\" || kind === \"notIn\") {\n if (!Array.isArray(body) || body.length !== 2 || !Array.isArray(body[1])) {\n return `${kind} requires an operand and an operand list`;\n }\n const first = operandProblem(body[0], capabilityScope, budget);\n if (first !== null) {\n return first;\n }\n for (const operand of body[1] as unknown[]) {\n const problem = operandProblem(operand, capabilityScope, budget);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"exists\") {\n return operandProblem(body, capabilityScope, budget);\n }\n if (kind === \"and\" || kind === \"or\") {\n if (!Array.isArray(body)) {\n return `${kind} requires a condition list`;\n }\n for (const child of body) {\n const problem = conditionProblem(\n child,\n capabilityScope,\n depth + 1,\n budget,\n );\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"not\") {\n return conditionProblem(body, capabilityScope, depth + 1, budget);\n }\n return `unknown condition operator \"${kind}\"`;\n}\n\nfunction principalProblem(\n value: unknown,\n capabilityScope: string | undefined,\n): string | null {\n if (!isPlainValue(value)) {\n return \"principal must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1 || !PRINCIPAL_KINDS.has(keys[0])) {\n return \"principal must have exactly one of anyone, address, group, or match\";\n }\n const kind = keys[0];\n if (kind === \"anyone\" && value.anyone !== true) {\n return \"anyone must be true\";\n }\n if (kind === \"address\") {\n const address = value.address;\n if (typeof address !== \"string\" || address.length === 0) {\n return \"address must be a non-empty string\";\n }\n }\n if (kind === \"group\") {\n const group = value.group;\n if (typeof group !== \"string\" || group.length === 0) {\n return \"group must be a non-empty string\";\n }\n }\n if (kind === \"match\") {\n return conditionProblem(value.match, capabilityScope, 1, {\n nodes: MAX_CONDITION_NODES,\n });\n }\n return null;\n}\n\nfunction capabilityProblem(value: unknown): string | null {\n if (!isPlainValue(value)) {\n return \"capability must be an object\";\n }\n const can = value.can;\n if (can !== \"read\" && can !== \"execute\") {\n return \"capability.can must be read or execute\";\n }\n const allowedKeys =\n can === \"execute\" ? [\"can\", \"scope\", \"operation\"] : [\"can\", \"scope\"];\n // sorted: jsonb storage does not preserve key order\n const unknownKeys = Object.keys(value)\n .filter((key) => !allowedKeys.includes(key))\n .sort();\n if (unknownKeys.length > 0) {\n return `unknown capability key \"${unknownKeys[0]}\"`;\n }\n if (value.scope !== undefined) {\n if (typeof value.scope !== \"string\" || value.scope.length === 0) {\n return \"capability.scope must be a non-empty string\";\n }\n }\n if (can === \"execute\" && value.operation !== undefined) {\n const operation = value.operation;\n if (!Array.isArray(operation)) {\n return \"capability.operation must be an array\";\n }\n if (operation.length > MAX_CAPABILITY_OPERATIONS) {\n return `capability.operation exceeds ${MAX_CAPABILITY_OPERATIONS} entries`;\n }\n for (const entry of operation) {\n if (typeof entry !== \"string\" || entry.length === 0) {\n return \"capability.operation entries must be non-empty strings\";\n }\n }\n }\n return null;\n}\n\n/** Returns the first v1-rule violation, or null. Pure, total, deterministic. */\nexport function grantProblem(value: unknown): string | null {\n if (!isPlainValue(value)) {\n return \"grant must be an object\";\n }\n // sorted: jsonb storage does not preserve key order\n const unknownKeys = Object.keys(value)\n .filter((key) => !GRANT_KEYS.has(key))\n .sort();\n if (unknownKeys.length > 0) {\n return `unknown grant key \"${unknownKeys[0]}\"`;\n }\n if (typeof value.id !== \"string\" || value.id.length === 0) {\n return \"id must be a non-empty string\";\n }\n if (typeof value.description !== \"string\") {\n return \"description must be a string\";\n }\n if (value.effect !== \"allow\" && value.effect !== \"deny\") {\n return \"effect must be allow or deny\";\n }\n const capabilityValue = value.capability;\n const capability = capabilityProblem(capabilityValue);\n if (capability !== null) {\n return capability;\n }\n const capabilityScope = (capabilityValue as Record<string, unknown>).scope as\n | string\n | undefined;\n const principal = principalProblem(value.principal, capabilityScope);\n if (principal !== null) {\n return principal;\n }\n if (value.where !== undefined) {\n return conditionProblem(value.where, capabilityScope, 1, {\n nodes: MAX_CONDITION_NODES,\n });\n }\n return null;\n}\n\nexport const GrantSchema = () =>\n z.custom<Grant>((value) => grantProblem(value) === null);\n\n/** V1 shape rules plus the group-document group-principal ban. */\nexport function assertValidGrant(grant: unknown, documentType: string): void {\n const grantId =\n isPlainValue(grant) && typeof grant.id === \"string\" ? grant.id : \"\";\n const problem = grantProblem(grant);\n if (problem !== null) {\n throw new InvalidGrantError(grantId, problem);\n }\n if (\n documentType === groupDocumentType &&\n \"group\" in (grant as Grant).principal\n ) {\n throw new GroupPrincipalNotAllowedError(grantId);\n }\n}\n\n/**\n * Validates an initial grant list: the count cap, every grant, and — on a\n * creator-less policy — that some grant keeps the auth scope administrable.\n */\nexport function assertValidInitialGrants(\n grants: Grant[],\n documentType: string,\n creator: string | undefined,\n): void {\n if (grants.length > MAX_AUTH_GRANTS) {\n throw new InvalidGrantError(\"\", `policy exceeds ${MAX_AUTH_GRANTS} grants`);\n }\n for (const grant of grants) {\n assertValidGrant(grant, documentType);\n }\n if (creator === undefined && !administrationReachable(grants)) {\n throw new AuthAdministrationMissingError();\n }\n}\n\n/**\n * Validates a grant upsert: the grant itself, the count cap on append, and\n * administration retention. Retention is checked on an append as well as an\n * in-place replace, because a grant appended after the administration grant can\n * shadow it (evaluation is last-applicable-grant-wins) and so take\n * administration away without removing anything.\n */\nexport function assertValidGrantUpsert(\n grant: Grant,\n existing: Grant[],\n documentType: string,\n creator: string | undefined,\n): void {\n assertValidGrant(grant, documentType);\n const exists = existing.some((g) => g.id === grant.id);\n if (!exists && existing.length >= MAX_AUTH_GRANTS) {\n throw new InvalidGrantError(\n grant.id,\n `policy exceeds ${MAX_AUTH_GRANTS} grants`,\n );\n }\n // Built the same way applySetGrantAction builds it, so the two cannot drift.\n const next = exists\n ? existing.map((g) => (g.id === grant.id ? grant : g))\n : [...existing, grant];\n assertAuthAdministrationRetained(creator, existing, next, grant.id);\n}\n\n/**\n * The request whose coverage keeps a policy administrable: a subject who may\n * SET_GRANT can upsert any grant, so every other repair stays reachable.\n */\nconst AUTH_ADMINISTRATION_REQUEST: AuthRequest = {\n verb: \"execute\",\n scope: \"auth\",\n operation: \"SET_GRANT\",\n};\n\n/**\n * Whether some subject can still administer the auth scope under this grant\n * list.\n *\n * Answers exactly what asking {@link evaluateGrantStack} per candidate grant\n * answered, in one reverse pass instead of one full stack scan per candidate.\n * Evaluation is last-applicable-grant-wins, so scanning from the end meets each\n * subject's deciding grant first: an anyone grant decides every subject not\n * already decided, and an allow reached that way is itself a grant that carries\n * administration. Only anyone and address principals are candidates, because\n * those are the ones v1 can match with no groups and no condition context; a\n * `where` condition or a group or match principal never applies.\n */\nfunction administrationReachable(grants: Grant[]): boolean {\n const shadowedAddresses = new Set<string>();\n for (let index = grants.length - 1; index >= 0; index -= 1) {\n const grant = grants[index];\n if (\n grant.where !== undefined ||\n !grantAnswers(grant, AUTH_ADMINISTRATION_REQUEST)\n ) {\n continue;\n }\n const allows = grant.effect === \"allow\";\n if (\"anyone\" in grant.principal) {\n return allows;\n }\n if (!(\"address\" in grant.principal)) {\n continue;\n }\n const address = grant.principal.address.toLowerCase();\n if (shadowedAddresses.has(address)) {\n continue;\n }\n if (allows) {\n return true;\n }\n shadowedAddresses.add(address);\n }\n return false;\n}\n\n/**\n * A creator-less policy must always retain a grant permitting execute on the\n * auth scope; on a signed document the creator carve-out keeps administration\n * reachable instead. Rejects a change that takes the last such grant away. A\n * policy already without one is left alone: the change is not what locks it.\n */\nexport function assertAuthAdministrationRetained(\n creator: string | undefined,\n previous: Grant[],\n next: Grant[],\n grantId: string,\n): void {\n if (creator !== undefined) {\n return;\n }\n if (administrationReachable(previous) && !administrationReachable(next)) {\n throw new AuthAdministrationLockoutError(grantId);\n }\n}\n\n// --- Condition evaluation (version 1) -------------------------------------\n\n/** A resolved operand value; undefined marks a path that did not resolve. */\ntype ConditionValue = string | number | boolean | null;\n\n/**\n * An operand whose shape validation would have rejected. Distinguished from\n * an unresolved path so a structurally malformed operand poisons its whole\n * condition to false rather than reading as \"absent\", which `not` would\n * otherwise widen to true.\n */\nconst INVALID_OPERAND = Symbol(\"invalid-operand\");\ntype ResolvedOperand = ConditionValue | undefined | typeof INVALID_OPERAND;\n\n/**\n * Narrows to the values conditions compare. An object, array, or non-finite\n * number resolves to undefined, and every comparison involving undefined is\n * false.\n */\nfunction asConditionValue(value: unknown): ConditionValue | undefined {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n return undefined;\n}\n\n/**\n * Resolves one operand. Attr roots: `subject.*`, `doc.<scope>.*` where the\n * scope must be the executing scope (validation already rejects any other,\n * but resolution stays total), and `action.input.*`. Path steps read own\n * properties only, so prototype members can never influence a verdict.\n */\nfunction resolveOperand(\n operand: unknown,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): ResolvedOperand {\n if (!isPlainValue(operand)) {\n return INVALID_OPERAND;\n }\n const keys = Object.keys(operand);\n if (keys.length !== 1) {\n return INVALID_OPERAND;\n }\n\n if (keys[0] === \"lit\") {\n const value = asConditionValue(operand.lit);\n // A lit holds a plain finite value by validation; anything else is shape.\n return value === undefined ? INVALID_OPERAND : value;\n }\n\n if (keys[0] !== \"attr\") {\n return INVALID_OPERAND;\n }\n const attr = operand.attr;\n if (typeof attr !== \"string\" || attr.length === 0) {\n return INVALID_OPERAND;\n }\n const path = attr.split(\".\");\n\n let value: unknown;\n let rest: string[];\n if (path[0] === \"subject\") {\n value = subject;\n rest = path.slice(1);\n } else if (path[0] === \"doc\") {\n if (path[1] !== request.scope) {\n return undefined;\n }\n value = conditions.scopeState;\n rest = path.slice(2);\n } else if (path[0] === \"action\" && path[1] === \"input\") {\n value = conditions.actionInput;\n rest = path.slice(2);\n } else {\n return undefined;\n }\n\n for (const segment of rest) {\n if (!isPlainValue(value) || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = value[segment];\n }\n return asConditionValue(value);\n}\n\n/**\n * Total order within one type: numbers numerically, strings by code point.\n * Everything else, including mixed types, does not order.\n */\nfunction compareValues(\n left: ConditionValue,\n right: ConditionValue,\n): number | undefined {\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left < right ? -1 : left > right ? 1 : 0;\n }\n if (typeof left === \"string\" && typeof right === \"string\") {\n const leftPoints = Array.from(left);\n const rightPoints = Array.from(right);\n const shared = Math.min(leftPoints.length, rightPoints.length);\n for (let i = 0; i < shared; i++) {\n const a = leftPoints[i].codePointAt(0) ?? 0;\n const b = rightPoints[i].codePointAt(0) ?? 0;\n if (a !== b) {\n return a < b ? -1 : 1;\n }\n }\n return leftPoints.length === rightPoints.length\n ? 0\n : leftPoints.length < rightPoints.length\n ? -1\n : 1;\n }\n return undefined;\n}\n\n/**\n * Tri-state evaluation: undefined marks a structurally invalid node, which\n * poisons the whole tree to false at the top — and a structurally malformed\n * operand poisons its condition the same way. Both are distinct from an\n * operand whose path fails to resolve, which is a valid comparison that is\n * false. The distinction keeps `not` from widening over malformed input.\n */\nfunction evaluateNode(\n node: unknown,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): boolean | undefined {\n if (!isPlainValue(node)) {\n return undefined;\n }\n const keys = Object.keys(node);\n if (keys.length !== 1) {\n return undefined;\n }\n const kind = keys[0];\n const body = node[kind];\n\n switch (kind) {\n case \"eq\":\n case \"ne\":\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n if (!Array.isArray(body) || body.length !== 2) {\n return undefined;\n }\n const left = resolveOperand(body[0], subject, request, conditions);\n const right = resolveOperand(body[1], subject, request, conditions);\n if (left === INVALID_OPERAND || right === INVALID_OPERAND) {\n return undefined;\n }\n if (left === undefined || right === undefined) {\n return false;\n }\n if (kind === \"eq\") {\n return left === right;\n }\n if (kind === \"ne\") {\n return left !== right;\n }\n const order = compareValues(left, right);\n if (order === undefined) {\n return false;\n }\n switch (kind) {\n case \"lt\":\n return order < 0;\n case \"lte\":\n return order <= 0;\n case \"gt\":\n return order > 0;\n case \"gte\":\n return order >= 0;\n }\n return undefined;\n }\n case \"in\":\n case \"notIn\": {\n if (\n !Array.isArray(body) ||\n body.length !== 2 ||\n !Array.isArray(body[1])\n ) {\n return undefined;\n }\n const left = resolveOperand(body[0], subject, request, conditions);\n if (left === INVALID_OPERAND) {\n return undefined;\n }\n const elements = body[1].map((element) =>\n resolveOperand(element, subject, request, conditions),\n );\n if (elements.some((value) => value === INVALID_OPERAND)) {\n return undefined;\n }\n if (left === undefined) {\n return false;\n }\n const found = elements.some(\n (value) => value !== undefined && value === left,\n );\n return kind === \"in\" ? found : !found;\n }\n case \"exists\": {\n const value = resolveOperand(body, subject, request, conditions);\n if (value === INVALID_OPERAND) {\n return undefined;\n }\n return value !== undefined;\n }\n case \"and\":\n case \"or\": {\n if (!Array.isArray(body)) {\n return undefined;\n }\n let result = kind === \"and\";\n for (const child of body) {\n const value = evaluateNode(child, subject, request, conditions);\n if (value === undefined) {\n return undefined;\n }\n if (kind === \"and\") {\n result = result && value;\n } else {\n result = result || value;\n }\n }\n return result;\n }\n case \"not\": {\n const value = evaluateNode(body, subject, request, conditions);\n return value === undefined ? undefined : !value;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Evaluates a version-1 condition. Deterministic, total, and pure: any input\n * shape yields a boolean and never throws, and a malformed condition is\n * false. These are consensus semantics, versioned by `PHAuthState.version`;\n * changing them requires a new version.\n */\nexport function evaluateCondition(\n condition: Condition,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): boolean {\n return evaluateNode(condition, subject, request, conditions) === true;\n}\n\n/** Whether a capability's scope reaches the requested one. */\nfunction scopeCovers(scope: string | undefined, requested: string): boolean {\n return scope === undefined || scope === \"*\" || scope === requested;\n}\n\n/**\n * Whether one grant answers this request.\n *\n * A grant allowing execute on a scope also allows reading it: executing an\n * operation means reading the state it applies to, so permitting the write while\n * withholding the read would describe an access nobody could use. The converse\n * does not hold -- a read grant confers no write.\n *\n * Only an allow carries across. A deny on execute withholds the write and says\n * nothing about the read, so a policy locking writes down does not silently\n * revoke a read grant sitting before it. The operation list is not consulted\n * either: it restricts which operations may be executed, not whether the scope\n * is visible, and a read carries no operation to match against.\n *\n * Reads are not consensus -- no replica records a read, and the two read call\n * sites are both inside the read gate -- so this rule is not part of what makes\n * an operation valid, and does not need a policy version of its own.\n */\nfunction grantAnswers(grant: Grant, request: AuthRequest): boolean {\n if (capabilityCovers(grant.capability, request)) {\n return true;\n }\n\n return (\n request.verb === \"read\" &&\n grant.effect === \"allow\" &&\n grant.capability.can === \"execute\" &&\n scopeCovers(grant.capability.scope, request.scope)\n );\n}\n\nfunction capabilityCovers(\n capability: Capability,\n request: AuthRequest,\n): boolean {\n if (capability.can !== request.verb) {\n return false;\n }\n if (!scopeCovers(capability.scope, request.scope)) {\n return false;\n }\n if (capability.can === \"execute\") {\n // An execute capability with no operation list covers every operation in the scope.\n if (capability.operation === undefined) {\n return true;\n }\n return (\n request.operation !== undefined &&\n capability.operation.includes(request.operation)\n );\n }\n return true;\n}\n\nfunction principalMatches(\n principal: Principal,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): boolean {\n if (\"anyone\" in principal) {\n return true;\n }\n if (\"address\" in principal) {\n return (\n subject.address !== undefined &&\n subject.address.toLowerCase() === principal.address.toLowerCase()\n );\n }\n if (\"group\" in principal) {\n // Groups match only when the groups projection is supplied (authGroups\n // on). A group the map does not hold fails closed: access is never\n // widened by a missing group.\n if (groups === undefined || subject.address === undefined) {\n return false;\n }\n // Total over malformed folded state: an index miss or a non-list member\n // field never widens access.\n const group = groups[principal.group] as PHGroupState | undefined;\n if (group === undefined || !Array.isArray(group.members)) {\n return false;\n }\n const address = subject.address.toLowerCase();\n return group.members.some((member) => member.toLowerCase() === address);\n }\n if (\"match\" in principal) {\n // Matches only when a condition context is supplied (authConditions on).\n if (conditions === undefined) {\n return false;\n }\n return evaluateCondition(principal.match, subject, request, conditions);\n }\n return false;\n}\n\n/**\n * The group document ids named by `{ group }` principals in a grant list, in\n * order of first appearance. These are the streams the groups projection reads.\n */\nexport function referencedGroupIds(grants: Grant[]): string[] {\n const ids: string[] = [];\n for (const grant of grants) {\n if (\"group\" in grant.principal && !ids.includes(grant.principal.group)) {\n ids.push(grant.principal.group);\n }\n }\n return ids;\n}\n\n/**\n * Evaluates a v1 grant stack: default deny, last applicable grant wins, and\n * reports which grant decided it. Group principals match only against a\n * supplied groups map, and `where` clauses and { match } principals evaluate\n * only against a supplied condition context; a grant that uses an unsupplied\n * feature never applies.\n */\nexport function evaluateGrantStack(\n grants: Grant[],\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthEvaluation {\n let applicable: Grant | undefined;\n for (const grant of grants) {\n if (grant.where !== undefined) {\n // With no condition context a conditional grant never applies.\n if (conditions === undefined) {\n continue;\n }\n if (!evaluateCondition(grant.where, subject, request, conditions)) {\n continue;\n }\n }\n if (\n grantAnswers(grant, request) &&\n principalMatches(grant.principal, subject, request, groups, conditions)\n ) {\n applicable = grant;\n }\n }\n\n if (applicable === undefined) {\n return { decision: \"deny\", refusal: \"no-applicable-grant\" };\n }\n if (applicable.effect === \"deny\") {\n return {\n decision: \"deny\",\n refusal: \"denied-by-grant\",\n grantId: applicable.id,\n };\n }\n return { decision: \"allow\" };\n}\n\n/**\n * Evaluates a v1 grant stack: default deny, last applicable grant wins. This is\n * {@link evaluateGrantStack} with the reason dropped.\n */\nexport function evaluateGrants(\n grants: Grant[],\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthDecision {\n return evaluateGrantStack(grants, subject, request, groups, conditions)\n .decision;\n}\n","import type {\n DocumentModelGlobalState,\n DocumentModelLocalState,\n} from \"./types.js\";\n\nexport const documentModelFileExtension = \"phdm\" as const;\n\nexport const documentModelInitialLocalState: DocumentModelLocalState = {};\nexport const documentModelInitialGlobalState: DocumentModelGlobalState = {\n id: \"\",\n name: \"\",\n extension: \"\",\n description: \"\",\n author: {\n name: \"\",\n website: \"\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n local: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n },\n modules: [],\n },\n ],\n};\nexport const documentModelGlobalState: DocumentModelGlobalState = {\n id: \"powerhouse/document-model\",\n name: \"DocumentModel\",\n extension: \"phdm\",\n description:\n \"The Powerhouse Document Model describes the state and operations of a document type.\",\n author: {\n name: \"Powerhouse\",\n website: \"https://www.powerhouse.inc/\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema:\n \"type CodeExample {\\n id: ID!\\n value: String!\\n}\\n\\ntype OperationError {\\n id: ID!\\n code: String\\n name: String\\n description: String\\n template: String\\n}\\n\\ntype Operation {\\n id: ID!\\n name: String\\n schema: String\\n description: String\\n template: String\\n errors: [OperationError!]!\\n examples: [CodeExample!]!\\n reducer: String\\n scope: String\\n}\\n\\ntype Module {\\n id: ID!\\n name: String!\\n description: String\\n operations: [Operation!]!\\n}\\n\\ntype State {\\n schema: String!\\n initialValue: String!\\n examples: [CodeExample!]!\\n}\\n\\ntype ScopeState {\\n global: State!\\n local: State!\\n}\\n\\ntype Author {\\n name: String!\\n website: String\\n}\\n\\ntype DocumentSpecification {\\n version: Int!\\n state: ScopeState!\\n modules: [Module!]!\\n changeLog: [String!]!\\n}\\n\\ntype DocumentModelGlobalState {\\n name: String!\\n id: String!\\n extension: String!\\n description: String!\\n author: Author!\\n specifications: [DocumentSpecification!]!\\n}\",\n initialValue:\n '{\\n \"id\": \"\",\\n \"name\": \"\",\\n \"extension\": \"\",\\n \"description\": \"\",\\n \"author\": {\\n \"name\": \"\",\\n \"website\": \"\"\\n },\\n \"specifications\": [\\n {\\n \"version\": 1,\\n \"changeLog\": [],\\n \"state\": {\\n \"global\": {\\n \"schema\": \"\",\\n \"initialValue\": \"\",\\n \"examples\": []\\n },\\n \"local\": {\\n \"schema\": \"\",\\n \"initialValue\": \"\",\\n \"examples\": []\\n }\\n },\\n \"modules\": []\\n }\\n ]\\n}',\n examples: [],\n },\n local: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n },\n modules: [\n {\n name: \"header\",\n operations: [\n {\n name: \"SET_MODEL_NAME\",\n id: \"\",\n description: \"Sets the name of the document model\",\n schema: \"input SetModelNameInput {\\n name: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_ID\",\n id: \"\",\n description: \"Sets the unique identifier for the document model\",\n schema: \"input SetModelIdInput {\\n id: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_EXTENSION\",\n id: \"\",\n description:\n \"Sets the file extension associated with this document model\",\n schema:\n \"input SetModelExtensionInput {\\n extension: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description text for the document model\",\n schema:\n \"input SetModelDescriptionInput {\\n description: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_AUTHOR_NAME\",\n id: \"\",\n description: \"Sets the name of the document model author\",\n schema: \"input SetAuthorNameInput {\\n authorName: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_AUTHOR_WEBSITE\",\n id: \"\",\n description: \"Sets the website URL of the document model author\",\n schema:\n \"input SetAuthorWebsiteInput {\\n authorWebsite: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"versioning\",\n operations: [\n {\n name: \"ADD_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Adds a new item to the document model changelog\",\n schema:\n \"input AddChangeLogItemInput {\\n id: ID!\\n insertBefore: ID\\n content: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Updates an existing changelog item\",\n schema:\n \"input UpdateChangeLogItemInput {\\n id: ID!\\n newContent: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Removes an item from the document model changelog\",\n schema: \"input DeleteChangeLogItemInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_CHANGE_LOG_ITEMS\",\n id: \"\",\n description: \"Changes the order of changelog items\",\n schema:\n \"input ReorderChangeLogItemsInput {\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"RELEASE_NEW_VERSION\",\n schema: null,\n id: \"\",\n description:\n \"Creates a new version of the document model specification\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"module\",\n operations: [\n {\n name: \"ADD_MODULE\",\n id: \"\",\n description:\n \"Adds a new module to the document model specification\",\n schema:\n \"input AddModuleInput {\\n id: ID!\\n name: String!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODULE_NAME\",\n id: \"\",\n description: \"Sets the name of an existing module\",\n schema:\n \"input SetModuleNameInput {\\n id: ID!\\n name: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODULE_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an existing module\",\n schema:\n \"input SetModuleDescriptionInput {\\n id: ID!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_MODULE\",\n id: \"\",\n description:\n \"Removes a module from the document model specification\",\n schema: \"input DeleteModuleInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_MODULES\",\n id: \"\",\n description:\n \"Changes the order of modules in the document model specification\",\n schema: \"input ReorderModulesInput {\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation-error\",\n operations: [\n {\n name: \"ADD_OPERATION_ERROR\",\n id: \"\",\n description: \"Adds a new error definition to an operation\",\n schema:\n \"input AddOperationErrorInput {\\n operationId: ID!\\n id: ID!\\n errorCode: String\\n errorName: String\\n errorDescription: String\\n errorTemplate: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_CODE\",\n id: \"\",\n description: \"Sets the error code for an operation error\",\n schema:\n \"input SetOperationErrorCodeInput {\\n id: ID!\\n errorCode: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_NAME\",\n id: \"\",\n description: \"Sets the name of an operation error\",\n schema:\n \"input SetOperationErrorNameInput {\\n id: ID!\\n errorName: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an operation error\",\n schema:\n \"input SetOperationErrorDescriptionInput {\\n id: ID!\\n errorDescription: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_TEMPLATE\",\n id: \"\",\n description: \"Sets the template for an operation error\",\n schema:\n \"input SetOperationErrorTemplateInput {\\n id: ID!\\n errorTemplate: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION_ERROR\",\n id: \"\",\n description: \"Removes an error definition from an operation\",\n schema: \"input DeleteOperationErrorInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_OPERATION_ERRORS\",\n id: \"\",\n description:\n \"Changes the order of error definitions for an operation\",\n schema:\n \"input ReorderOperationErrorsInput {\\n operationId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation-example\",\n operations: [\n {\n name: \"ADD_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Adds a new code example to an operation\",\n schema:\n \"input AddOperationExampleInput {\\n operationId: ID!\\n id: ID!\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Updates an existing code example for an operation\",\n schema:\n \"input UpdateOperationExampleInput {\\n id: ID!\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Removes a code example from an operation\",\n schema: \"input DeleteOperationExampleInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_OPERATION_EXAMPLES\",\n id: \"\",\n description:\n \"Changes the order of code examples for an operation\",\n schema:\n \"input ReorderOperationExamplesInput {\\n operationId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation\",\n operations: [\n {\n name: \"ADD_OPERATION\",\n id: \"\",\n description: \"Adds a new operation to a module\",\n schema:\n \"input AddOperationInput {\\n moduleId: ID!\\n id: ID!\\n name: String!\\n schema: String\\n description: String\\n template: String\\n reducer: String\\n scope: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_NAME\",\n id: \"\",\n description: \"Sets the name of an operation\",\n schema:\n \"input SetOperationNameInput {\\n id: ID!\\n name: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_SCHEMA\",\n id: \"\",\n description:\n \"Sets the GraphQL schema definition for an operation's input\",\n schema:\n \"input SetOperationSchemaInput {\\n id: ID!\\n schema: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an operation\",\n schema:\n \"input SetOperationDescriptionInput {\\n id: ID!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_TEMPLATE\",\n id: \"\",\n description: \"Sets the template code for an operation\",\n schema:\n \"input SetOperationTemplateInput {\\n id: ID!\\n template: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_REDUCER\",\n id: \"\",\n description: \"Sets the reducer function code for an operation\",\n schema:\n \"input SetOperationReducerInput {\\n id: ID!\\n reducer: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_SCOPE\",\n id: \"\",\n description: \"Sets the scope of an operation (global or local)\",\n schema:\n \"input SetOperationScopeInput {\\n id: ID!\\n scope: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"MOVE_OPERATION\",\n id: \"\",\n description: \"Moves an operation from one module to another\",\n schema:\n \"input MoveOperationInput {\\n operationId: ID!\\n newModuleId: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION\",\n id: \"\",\n description: \"Removes an operation from a module\",\n schema: \"input DeleteOperationInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_MODULE_OPERATIONS\",\n id: \"\",\n description: \"Changes the order of operations within a module\",\n schema:\n \"input ReorderModuleOperationsInput {\\n moduleId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"state\",\n operations: [\n {\n name: \"SET_STATE_SCHEMA\",\n id: \"\",\n description:\n \"Sets the GraphQL schema definition for document state\",\n schema:\n \"input SetStateSchemaInput {\\n scope: String!\\n schema: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_INITIAL_STATE\",\n id: \"\",\n description: \"Sets the initial state value for a document scope\",\n schema:\n \"input SetInitialStateInput {\\n scope: String!\\n initialValue: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"ADD_STATE_EXAMPLE\",\n id: \"\",\n description: \"Adds a new state example to a document scope\",\n schema:\n \"input AddStateExampleInput {\\n scope: String!\\n id: ID!\\n insertBefore: ID\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_STATE_EXAMPLE\",\n id: \"\",\n description:\n \"Updates an existing state example for a document scope\",\n schema:\n \"input UpdateStateExampleInput {\\n scope: String!\\n id: ID!\\n newExample: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_STATE_EXAMPLE\",\n id: \"\",\n description: \"Removes a state example from a document scope\",\n schema:\n \"input DeleteStateExampleInput {\\n scope: String!\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_STATE_EXAMPLES\",\n id: \"\",\n description:\n \"Changes the order of state examples for a document scope\",\n schema:\n \"input ReorderStateExamplesInput {\\n scope: String!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n ],\n },\n ],\n};\n\n// Known hash algorithms (can be extended without breaking changes)\nexport const HASH_ALGORITHM_SHA1 = \"sha1\";\nexport const HASH_ALGORITHM_SHA256 = \"sha256\";\nexport const HASH_ALGORITHM_SHA512 = \"sha512\";\n\n// Known encodings (can be extended without breaking changes)\nexport const HASH_ENCODING_BASE64 = \"base64\";\nexport const HASH_ENCODING_HEX = \"hex\";\n","import { HASH_ALGORITHM_SHA1, HASH_ENCODING_BASE64 } from \"./constants.js\";\nimport type { HashConfig } from \"./signatures.js\";\nimport type {\n DocumentModelGlobalState,\n DocumentModelLocalState,\n DocumentModelPHState,\n} from \"./types.js\";\n\n/**\n * Creates a default PHAuthState\n */\nexport function defaultAuthState(): PHAuthState {\n return {\n version: 0,\n grants: [],\n };\n}\n\n/**\n * Creates a default PHDocumentState\n */\nexport function defaultDocumentState(): PHDocumentState {\n return {\n version: 0,\n hash: {\n algorithm: HASH_ALGORITHM_SHA1,\n encoding: HASH_ENCODING_BASE64,\n },\n };\n}\n/**\n * Creates a default PHBaseState with auth and document properties\n */\nexport function defaultBaseState(): PHBaseState {\n return {\n auth: defaultAuthState(),\n document: defaultDocumentState(),\n };\n}\n\n/**\n * Creates a PHAuthState with the given properties\n */\nexport function createAuthState(auth?: Partial<PHAuthState>): PHAuthState {\n return {\n ...defaultAuthState(),\n ...auth,\n };\n}\n\n/**\n * Creates a PHDocumentState with the given properties\n */\nexport function createDocumentState(\n document?: Partial<PHDocumentState>,\n): PHDocumentState {\n return {\n ...defaultDocumentState(),\n ...document,\n };\n}\n\n/**\n * Creates a PHBaseState with the given auth and document properties\n */\nexport function createBaseState(\n auth?: Partial<PHAuthState>,\n document?: Partial<PHDocumentState>,\n): PHBaseState {\n return {\n auth: createAuthState(auth),\n document: createDocumentState(document),\n };\n}\n\n/**\n * Backfills the auth scope to the default for legacy documents serialized with\n * an empty `auth`. Replaces only `state.auth`. Idempotent.\n */\nexport function backfillAuthState<TState extends PHBaseState>(\n state: TState,\n): TState {\n return {\n ...state,\n auth: createAuthState(state.auth),\n } as TState;\n}\n\n/**\n * The document state of the document.\n */\nexport type PHDocumentState = {\n /**\n * The current document model schema version of the document. This is used\n * with the UPGRADE_DOCUMENT operation to specify the DocumentModelModule\n * version to use for reducer execution.\n */\n version: number;\n\n /** Hash configuration for operation state verification */\n hash: HashConfig;\n\n /** True if and only if the document has been deleted */\n isDeleted?: boolean;\n\n /** The timestamp when the document was deleted, in UTC ISO format */\n deletedAtUtcIso?: string;\n\n /** Optional: who deleted the document */\n deletedBy?: string;\n\n /** Optional: reason for deletion */\n deletionReason?: string;\n};\n\n/**\n * The document's authorization policy: an ordered, stacked list of grants,\n * where the last matching grant wins. `{ version: 0, grants: [] }` is\n * uninitialized and leaves the document open.\n */\nexport type PHAuthState = {\n /**\n * Policy language version. 0 is the uninitialized state; INITIALIZE_AUTH\n * sets an integer >= 1.\n */\n version: number;\n grants: Grant[];\n /**\n * The did:key of the auth-policy creator, captured from the INITIALIZE_AUTH\n * signer. The creator may always administer the auth scope, so a grant policy\n * can never lock administration out of itself. Absent for an unsigned genesis.\n */\n creator?: string;\n};\n\nexport type Grant = {\n /** Stable id. */\n id: string;\n description: string;\n effect: \"allow\" | \"deny\";\n principal: Principal;\n capability: Capability;\n /**\n * The grant applies only when this condition holds. Until conditions are\n * evaluated, a grant carrying one never applies.\n */\n where?: Condition;\n};\n\nexport type Principal =\n | { anyone: true }\n | { address: string }\n | { group: string }\n | { match: Condition };\n\n/**\n * The folded global state of a PHGroup (powerhouse/reactor-group) document,\n * narrowed to what auth evaluation reads. Membership is matched\n * case-insensitively against the subject's address.\n */\nexport type PHGroupState = {\n members: string[];\n};\n\n/**\n * Folded group states keyed by group document id, as the groups projection\n * provides them. A group id a policy names but the map does not hold fails\n * closed: the principal does not match.\n */\nexport type AuthGroups = Record<string, PHGroupState>;\n\nexport type Capability =\n | { can: \"read\"; scope?: string }\n | { can: \"execute\"; scope?: string; operation?: string[] };\n\n/**\n * Boolean condition language for grants: deterministic, total, and\n * JSON-serializable, versioned by `PHAuthState.version`. Defined now but not\n * yet evaluated or enforced.\n */\nexport type Condition =\n | { eq: [Operand, Operand] }\n | { ne: [Operand, Operand] }\n | { in: [Operand, Operand[]] }\n | { notIn: [Operand, Operand[]] }\n | { lt: [Operand, Operand] }\n | { lte: [Operand, Operand] }\n | { gt: [Operand, Operand] }\n | { gte: [Operand, Operand] }\n | { exists: Operand }\n | { and: Condition[] }\n | { or: Condition[] }\n | { not: Condition };\n\n/**\n * A condition operand: `attr` is a dotted path into the decision context\n * (e.g. \"doc.global.status\", \"subject.address\"); `lit` is a constant value.\n */\nexport type Operand =\n | { attr: string }\n | { lit: string | number | boolean | null };\n\n/**\n * The base state of the document.\n */\nexport type PHBaseState = {\n /** Carries authentication information. */\n auth: PHAuthState;\n\n /** Carries information about the document. */\n document: PHDocumentState;\n};\n\nexport function defaultGlobalState(): DocumentModelGlobalState {\n return {\n ...defaultBaseState(),\n author: {\n name: \"\",\n website: \"\",\n },\n description: \"\",\n extension: \"\",\n id: \"\",\n name: \"\",\n specifications: [],\n };\n}\n\nexport function defaultLocalState(): DocumentModelLocalState {\n return {};\n}\n\nexport function defaultPHState(): DocumentModelPHState {\n return {\n ...defaultBaseState(),\n global: defaultGlobalState(),\n local: defaultLocalState(),\n };\n}\n\nexport function createGlobalState(\n state?: Partial<DocumentModelGlobalState>,\n): DocumentModelGlobalState {\n return {\n ...defaultGlobalState(),\n ...(state || {}),\n } as DocumentModelGlobalState;\n}\n\nexport function createLocalState(\n state?: Partial<DocumentModelLocalState>,\n): DocumentModelLocalState {\n return {\n ...defaultLocalState(),\n ...(state || {}),\n } as DocumentModelLocalState;\n}\n\nexport function createState(\n baseState?: Partial<PHBaseState>,\n globalState?: Partial<DocumentModelGlobalState>,\n localState?: Partial<DocumentModelLocalState>,\n): DocumentModelPHState {\n return {\n ...createBaseState(baseState?.auth, baseState?.document),\n global: createGlobalState(globalState),\n local: createLocalState(localState),\n };\n}\n","import { stringify } from \"safe-stable-stringify\";\nimport { z } from \"zod\";\nimport { createAction, type Action } from \"./actions.js\";\nimport {\n assertAuthAdministrationRetained,\n assertValidGrantUpsert,\n assertValidInitialGrants,\n evaluateGrantStack,\n GrantSchema,\n isPlainValue,\n MAX_AUTH_GRANTS,\n} from \"./auth-v1.js\";\nimport { base58Decode, base64UrlToBytes } from \"./crypto.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport {\n AuthActionNotAllowedError,\n AuthAlreadyInitializedError,\n AuthInitializerNotCreatorError,\n AuthPolicyNotPreservedError,\n GrantNotFoundError,\n InvalidActionInputError,\n InvalidAuthVersionError,\n} from \"./errors.js\";\nimport {\n createAuthState,\n type AuthGroups,\n type Grant,\n type PHAuthState,\n type PHBaseState,\n} from \"./state.js\";\n\n// --- Action types --------------------------------------------------------\n\nexport type InitializeAuthActionInput = {\n version: number;\n grants: Grant[];\n};\n\nexport type SetGrantActionInput = {\n grant: Grant;\n};\n\nexport type RemoveGrantActionInput = {\n id: string;\n};\n\nexport type MoveGrantActionInput = {\n id: string;\n /** Target index in the grant list; clamped to the valid range. */\n index: number;\n};\n\nexport type InitializeAuthAction = Action & {\n type: \"INITIALIZE_AUTH\";\n input: InitializeAuthActionInput;\n};\n\nexport type SetGrantAction = Action & {\n type: \"SET_GRANT\";\n input: SetGrantActionInput;\n};\n\nexport type RemoveGrantAction = Action & {\n type: \"REMOVE_GRANT\";\n input: RemoveGrantActionInput;\n};\n\nexport type MoveGrantAction = Action & {\n type: \"MOVE_GRANT\";\n input: MoveGrantActionInput;\n};\n\nexport type AuthAction =\n | InitializeAuthAction\n | SetGrantAction\n | RemoveGrantAction\n | MoveGrantAction;\n\nexport const AUTH_ACTION_TYPES = [\n \"INITIALIZE_AUTH\",\n \"SET_GRANT\",\n \"REMOVE_GRANT\",\n \"MOVE_GRANT\",\n] as const;\n\nexport function isAuthAction(action: Action): action is AuthAction {\n return (AUTH_ACTION_TYPES as readonly string[]).includes(action.type);\n}\n\n// --- Version-1 grant validation ------------------------------------------\n\n/** Highest known policy version; decide() fails closed above it. */\nexport const MAX_SUPPORTED_AUTH_VERSION = 1;\n\n// --- Input schemas -------------------------------------------------------\n\nexport const InitializeAuthActionInputSchema = () =>\n z.object({\n version: z.number().int().min(1),\n grants: z.array(GrantSchema()).max(MAX_AUTH_GRANTS),\n });\n\nexport const SetGrantActionInputSchema = () =>\n z.object({\n grant: GrantSchema(),\n });\n\nexport const RemoveGrantActionInputSchema = () =>\n z.object({\n id: z.string(),\n });\n\nexport const MoveGrantActionInputSchema = () =>\n z.object({\n id: z.string(),\n index: z.number(),\n });\n\n// --- Action creators -----------------------------------------------------\n\nexport const initializeAuth = (input: InitializeAuthActionInput) =>\n createAction<InitializeAuthAction>(\n \"INITIALIZE_AUTH\",\n input,\n undefined,\n InitializeAuthActionInputSchema,\n \"auth\",\n );\n\nexport const setGrant = (input: SetGrantActionInput) =>\n createAction<SetGrantAction>(\n \"SET_GRANT\",\n input,\n undefined,\n SetGrantActionInputSchema,\n \"auth\",\n );\n\nexport const removeGrant = (input: RemoveGrantActionInput) =>\n createAction<RemoveGrantAction>(\n \"REMOVE_GRANT\",\n input,\n undefined,\n RemoveGrantActionInputSchema,\n \"auth\",\n );\n\nexport const moveGrant = (input: MoveGrantActionInput) =>\n createAction<MoveGrantAction>(\n \"MOVE_GRANT\",\n input,\n undefined,\n MoveGrantActionInputSchema,\n \"auth\",\n );\n\n// --- Handlers ------------------------------------------------------------\n\n/**\n * Destructuring a null input (reachable via raw synced operations) would\n * store an engine-specific TypeError message on the error operation.\n */\nfunction assertActionInputShape(input: unknown): void {\n if (!isPlainValue(input)) {\n throw new InvalidActionInputError({ input: \"must be an object\" });\n }\n}\n\nfunction withGrants<TState extends PHBaseState>(\n document: PHDocument<TState>,\n grants: Grant[],\n): PHDocument<TState> {\n return {\n ...document,\n state: {\n ...document.state,\n auth: { ...document.state.auth, grants },\n },\n };\n}\n\nconst P256_PUBKEY_MULTICODEC = [0x80, 0x24] as const;\nconst DID_KEY_PREFIX = \"did:key:z\";\n\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * True when `signerKey` (an ActionSigner app key, a did:key) identifies the same\n * key recorded as the document creator. Returns false\n * when there is no creator (empty JWK) or no signer key.\n */\nexport function isDocumentCreator(\n creatorKey: JsonWebKey | undefined,\n signerKey: string | undefined,\n): boolean {\n if (!creatorKey?.x || !creatorKey.y) {\n return false;\n }\n if (!signerKey || !signerKey.startsWith(DID_KEY_PREFIX)) {\n return false;\n }\n const decoded = base58Decode(signerKey.slice(DID_KEY_PREFIX.length));\n // 2-byte P-256 multicodec + 33-byte compressed point (prefix + 32-byte x).\n if (!decoded || decoded.length !== 35) {\n return false;\n }\n if (\n decoded[0] !== P256_PUBKEY_MULTICODEC[0] ||\n decoded[1] !== P256_PUBKEY_MULTICODEC[1]\n ) {\n return false;\n }\n const parityPrefix = decoded[2];\n if (parityPrefix !== 0x02 && parityPrefix !== 0x03) {\n return false;\n }\n const didX = decoded.subarray(3, 35);\n const jwkX = base64UrlToBytes(creatorKey.x);\n const jwkY = base64UrlToBytes(creatorKey.y);\n if (jwkX.length !== 32 || jwkY.length !== 32) {\n return false;\n }\n if (!bytesEqual(didX, jwkX)) {\n return false;\n }\n const jwkYIsOdd = (jwkY[31] & 1) === 1;\n const didYIsOdd = parityPrefix === 0x03;\n return jwkYIsOdd === didYIsOdd;\n}\n\n/**\n * Sets the initial policy. Valid only while the auth scope is uninitialized\n * (version 0). The input version is the policy language version and must be an\n * integer >= 1; 0 is reserved for the uninitialized state. On a signed-header\n * document it must be signed by the document creator (`header.sig.publicKey`).\n * A creator-less policy must include a grant permitting execute on the auth\n * scope, or it would be born locked out.\n */\nexport function applyInitializeAuthAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: InitializeAuthAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { version, grants } = action.input;\n if (!Number.isInteger(version) || version < 1) {\n throw new InvalidAuthVersionError(document.header.id, version);\n }\n if (document.state.auth.version !== 0) {\n throw new AuthAlreadyInitializedError(document.header.id);\n }\n if (!Array.isArray(grants)) {\n throw new InvalidActionInputError({ grants: \"must be an array\" });\n }\n const creatorKey = document.header.sig.publicKey;\n const signerKey = action.context?.signer?.app.key;\n // Any key material marks a signed header. Unsupported key types then fail\n // closed through isDocumentCreator instead of degrading to an open genesis.\n const hasCreator = Boolean(creatorKey.kty || creatorKey.x || creatorKey.y);\n if (hasCreator && !isDocumentCreator(creatorKey, signerKey)) {\n throw new AuthInitializerNotCreatorError(document.header.id);\n }\n const creator = hasCreator ? signerKey : undefined;\n assertValidInitialGrants(grants, document.header.documentType, creator);\n return {\n ...document,\n state: {\n ...document.state,\n auth: createAuthState(\n creator ? { version, grants, creator } : { version, grants },\n ),\n },\n };\n}\n\n/** Upserts a grant by id: replaces in place if present, otherwise appends. */\nexport function applySetGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: SetGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { grant } = action.input;\n const grants = document.state.auth.grants;\n assertValidGrantUpsert(\n grant,\n grants,\n document.header.documentType,\n document.state.auth.creator,\n );\n const exists = grants.some((g) => g.id === grant.id);\n const next = exists\n ? grants.map((g) => (g.id === grant.id ? grant : g))\n : [...grants, grant];\n return withGrants(document, next);\n}\n\n/**\n * Removes a grant by id; throws if the id is not present or if the removal\n * would leave a creator-less policy with no auth-administration grant.\n */\nexport function applyRemoveGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: RemoveGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { id } = action.input;\n const { grants, creator } = document.state.auth;\n if (!grants.some((g) => g.id === id)) {\n throw new GrantNotFoundError(id);\n }\n const next = grants.filter((g) => g.id !== id);\n assertAuthAdministrationRetained(creator, grants, next, id);\n return withGrants(document, next);\n}\n\n/**\n * Moves a grant by id to a new index. Order is load-bearing (the last\n * applicable grant wins), so the relative order of the other grants is kept.\n * The target index is clamped to the valid range; an unknown id throws.\n *\n * Order alone decides which grant wins, so a move can take administration away\n * without changing the list's contents. It carries the same retention rule as\n * the two mutation paths.\n */\nexport function applyMoveGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: MoveGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { id, index } = action.input;\n const { grants, creator } = document.state.auth;\n const from = grants.findIndex((g) => g.id === id);\n if (from === -1) {\n throw new GrantNotFoundError(id);\n }\n const next = [...grants];\n const [moved] = next.splice(from, 1);\n const to = Math.max(0, Math.min(index, next.length));\n next.splice(to, 0, moved);\n assertAuthAdministrationRetained(creator, grants, next, id);\n return withGrants(document, next);\n}\n\n/**\n * Dispatches an auth-scope action to its handler. This is the auth scope's\n * dedicated reducer: it is applied by the base reducer instead of the model\n * reducer, mirroring the document-scope platform handlers. Unknown types are a\n * no-op, matching the model-reducer default.\n */\nexport function applyAuthAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n): PHDocument<TState> {\n switch (action.type) {\n case \"INITIALIZE_AUTH\":\n return applyInitializeAuthAction(\n document,\n action as InitializeAuthAction,\n );\n case \"SET_GRANT\":\n return applySetGrantAction(document, action as SetGrantAction);\n case \"REMOVE_GRANT\":\n return applyRemoveGrantAction(document, action as RemoveGrantAction);\n case \"MOVE_GRANT\":\n return applyMoveGrantAction(document, action as MoveGrantAction);\n default:\n return document;\n }\n}\n\n/**\n * Because only creators can initialize auth scopes, we must verify that either\n * the document has no auth or the version and creator match.\n */\nexport function assertAuthPreservedOnDuplicate(\n documentId: string,\n source: PHAuthState | undefined,\n duplicated: PHAuthState | undefined,\n): void {\n if (!source || source.version === 0) {\n return;\n }\n if (\n duplicated === undefined ||\n duplicated.version !== source.version ||\n duplicated.creator !== source.creator\n ) {\n throw new AuthPolicyNotPreservedError(documentId);\n }\n}\n\n/**\n * The auth scope a state snapshot may install, given the policy already there.\n *\n * `applyAuthAction` is the validated door onto `state.auth`, but a whole-state\n * snapshot (UPGRADE_DOCUMENT's `initialState`, LOAD_STATE's `data`) replaces the\n * scope wholesale and is authorized as a `document`-scope write. Without this,\n * a subject holding `execute` on `document` and no auth grant at all can install\n * a policy of its choosing, name itself `creator` (which exempts the policy from\n * the retention rule for good), or wipe an existing policy by carrying the\n * default uninitialized one.\n *\n * Three cases:\n *\n * - the snapshot carries no policy, or an uninitialized one: the document\n * keeps the policy it has, so a default-state upgrade cannot reset it;\n * - the document is uninitialized and the snapshot carries a policy: the\n * policy is installed after the same validation genesis applies, so it\n * cannot be born locked out;\n * - both carry a policy: they must agree. A duplicate preserves its source's\n * policy (see {@link assertAuthPreservedOnDuplicate}), and anything else is\n * an attempt to replace one policy with another.\n */\nexport function resolveSnapshotAuth(\n documentId: string,\n documentType: string,\n current: PHAuthState | undefined,\n incoming: PHAuthState | undefined,\n): PHAuthState {\n const currentAuth = current ?? createAuthState({ version: 0, grants: [] });\n\n if (!incoming || !incoming.version) {\n return currentAuth;\n }\n\n if (currentAuth.version !== 0) {\n // The whole policy has to match, grants included: version and creator alone\n // would let one policy be swapped for another with the same version and no\n // creator. Serialized with sorted keys, because jsonb storage does not\n // preserve key order.\n if (stringify(incoming) !== stringify(currentAuth)) {\n throw new AuthPolicyNotPreservedError(documentId);\n }\n return incoming;\n }\n\n if (!Array.isArray(incoming.grants)) {\n throw new InvalidActionInputError({ grants: \"must be an array\" });\n }\n assertValidInitialGrants(incoming.grants, documentType, incoming.creator);\n return incoming;\n}\n\n/** UNDO, REDO and PRUNE are rejected on the auth scope. */\nexport function assertAuthScopeActionAllowed(action: Action): void {\n if (\n action.scope === \"auth\" &&\n [\"UNDO\", \"REDO\", \"PRUNE\"].includes(action.type)\n ) {\n throw new AuthActionNotAllowedError(action.type);\n }\n}\n\n// --- Decision (read-only policy evaluation) ------------------------------\n\nexport type AuthVerb = \"read\" | \"execute\";\n\nexport type AuthRequest = {\n verb: AuthVerb;\n scope: string;\n /** For execute: the operation (action type) being attempted. Omitted for reads. */\n operation?: string;\n};\n\nexport type AuthSubject = {\n /** Verified signer address; undefined for an anonymous subject. */\n address?: string;\n /** The signer's app key (a did:key), used to match the document creator. */\n key?: string;\n};\n\n/**\n * What condition attr paths resolve against, beyond the subject. Supplied\n * only while authConditions enforcement is on: with no context a grant\n * carrying `where` or a { match } principal never applies.\n */\nexport type ConditionContext = {\n /** The executing scope's own state, for `doc.<scope>.*` paths. */\n scopeState: unknown;\n /** The action's input, for `action.input.*` paths. Absent for reads. */\n actionInput?: unknown;\n};\n\nexport type AuthDecision = \"allow\" | \"deny\";\n\n/** Why the policy refused a request. */\nexport type AuthRefusal =\n | \"version-unsupported\"\n | \"no-applicable-grant\"\n | \"denied-by-grant\";\n\n/**\n * A decision together with why it refused. A refusal names which of the\n * policy's rules produced it, so an operation records the reason it was refused\n * rather than one reason standing for every refusal.\n */\nexport type AuthEvaluation =\n | { decision: \"allow\" }\n | { decision: \"deny\"; refusal: AuthRefusal; grantId?: string };\n\n/**\n * Evaluates the auth policy for a single request and reports why it refused.\n * Pure and deterministic.\n *\n * An uninitialized policy (version 0, absent auth state, or a legacy `{}`\n * auth scope serialized before PHAuthState had a version) leaves the document\n * open. Once a policy exists the default is deny, and grants stack in order.\n *\n * Group principals match only against a supplied groups map (the groups\n * projection, present when authGroups is on); with no map they never apply.\n * `where` clauses and { match } principals likewise evaluate only against a\n * supplied condition context (present when authConditions is on).\n */\nexport function evaluate(\n auth: PHAuthState | undefined,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthEvaluation {\n if (!auth || !auth.version) {\n return { decision: \"allow\" };\n }\n\n // creators can always administer the auth scope, checked before the version\n // gate so an unknown policy version cannot brick its own administration\n if (\n request.verb === \"execute\" &&\n request.scope === \"auth\" &&\n subject.key !== undefined &&\n subject.key === auth.creator\n ) {\n return { decision: \"allow\" };\n }\n\n if (auth.version > MAX_SUPPORTED_AUTH_VERSION) {\n return { decision: \"deny\", refusal: \"version-unsupported\" };\n }\n\n return evaluateGrantStack(auth.grants, subject, request, groups, conditions);\n}\n\n/**\n * Evaluates the auth policy for a single request. Pure and deterministic. This\n * is {@link evaluate} with the reason dropped.\n */\nexport function decide(\n auth: PHAuthState | undefined,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthDecision {\n return evaluate(auth, subject, request, groups, conditions).decision;\n}\n\n/**\n * The group document ids a single auth action's input names with `{ group }`\n * principals. INITIALIZE_AUTH contributes the groups named across its grants,\n * SET_GRANT the groups named by its one grant; REMOVE_GRANT and MOVE_GRANT\n * contribute nothing. Total over any input shape, because references are read\n * from the input as it arrived, including inputs later stored as errors.\n */\nexport function mentionedGroupIds(action: Action): string[] {\n const input = action.input as Record<string, unknown> | null | undefined;\n const candidates: unknown[] = [];\n\n if (action.type === \"INITIALIZE_AUTH\" && Array.isArray(input?.grants)) {\n candidates.push(...(input.grants as unknown[]));\n }\n if (action.type === \"SET_GRANT\" && input?.grant !== undefined) {\n candidates.push(input.grant);\n }\n\n const ids: string[] = [];\n for (const candidate of candidates) {\n if (typeof candidate !== \"object\" || candidate === null) {\n continue;\n }\n const principal = (candidate as Record<string, unknown>).principal;\n if (typeof principal !== \"object\" || principal === null) {\n continue;\n }\n const group = (principal as Record<string, unknown>).group;\n if (typeof group === \"string\" && group !== \"\" && !ids.includes(group)) {\n ids.push(group);\n }\n }\n return ids;\n}\n","// Kept out of operations.ts so documents.ts can read the denial verdict without\n// a value import back into operations.ts, which closes a runtime cycle\n// (operations.ts already imports nextSkipNumber/sortOperations from documents.ts).\n// The only import here is type-only, so this module can never join a cycle.\nimport type { Operation } from \"./operations.js\";\n\n/**\n * True iff authorization rejected the action.\n */\nexport function isDenied(operation: Operation): boolean {\n return operation.deniedReason !== undefined;\n}\n\n/**\n * The closed set of strings persisted as `deniedReason`. Re-evaluation compares\n * them, so they are consensus data: exact strings that embed no grant id,\n * subject or timestamp. Changing one is history-visible.\n */\nexport const DOCUMENT_DELETED_REASON = \"document deleted\";\nexport const AUTH_VERSION_UNSUPPORTED_REASON =\n \"auth policy version unsupported\";\nexport const AUTH_NO_GRANT_REASON = \"no grant permits this operation\";\nexport const AUTH_DENIED_BY_GRANT_REASON = \"denied by grant\";\n","import { z } from \"zod\";\nimport { documentModelDocumentType } from \"./document-type.js\";\nimport { DocumentModelGlobalStateSchema } from \"./schemas.js\";\nimport type { DocumentModelDocument, DocumentModelPHState } from \"./types.js\";\n\nexport const BaseDocumentHeaderSchema = z.object({\n id: z.string(),\n name: z.string(),\n createdAtUtcIso: z.string(),\n lastModifiedAtUtcIso: z.string(),\n documentType: z.string(),\n});\n\nexport const BaseDocumentStateSchema = z.object({\n global: z.unknown(),\n});\n\n/** Schema for validating the header object of a DocumentModel document */\nexport const DocumentModelHeaderSchema = BaseDocumentHeaderSchema.extend({\n documentType: z.literal(documentModelDocumentType),\n});\n\n/** Schema for validating the state object of a DocumentModel document */\nexport const DocumentModelPHStateSchema = BaseDocumentStateSchema.extend({\n global: DocumentModelGlobalStateSchema(),\n});\n\nexport const DocumentModelSchema = z.object({\n header: DocumentModelHeaderSchema,\n state: DocumentModelPHStateSchema,\n initialState: DocumentModelPHStateSchema,\n});\n\n/** Simple helper function to check if a state object is a DocumentModel document state object */\nexport function isDocumentModelState(\n state: unknown,\n): state is DocumentModelPHState {\n return DocumentModelPHStateSchema.safeParse(state).success;\n}\n\n/** Simple helper function to assert that a document state object is a DocumentModel document state object */\nexport function assertIsDocumentModelState(\n state: unknown,\n): asserts state is DocumentModelPHState {\n DocumentModelPHStateSchema.parse(state);\n}\n\n/** Simple helper function to check if a document is a DocumentModel document */\nexport function isDocumentModelDocument(\n document: unknown,\n): document is DocumentModelDocument {\n return DocumentModelSchema.safeParse(document).success;\n}\n\n/** Simple helper function to assert that a document is a DocumentModel document */\nexport function assertIsDocumentModelDocument(\n document: unknown,\n): asserts document is DocumentModelDocument {\n DocumentModelSchema.parse(document);\n}\n","import type { Action } from \"./actions.js\";\nimport type { PHDocumentHeader } from \"./documents.js\";\nimport type { Signature } from \"./signatures.js\";\nimport type { ISigner, SigningParameters } from \"./types.js\";\nimport { generateId } from \"./utils.js\";\n\n/**\n * Generates a deterministic payload from signing parameters\n */\nconst generateStablePayload = (parameters: SigningParameters): string =>\n `${parameters.documentType}:${parameters.createdAtUtcIso}:${parameters.nonce}`;\n\n/**\n * Creates a verification-only signer from a public key.\n * This signer can only verify signatures, not sign data.\n *\n * @param pubKey - The public key to use for verification.\n * @returns An ISigner that can only verify signatures.\n */\nexport async function createVerificationSigner(\n pubKey: JsonWebKey,\n): Promise<ISigner> {\n const cryptoKey = await crypto.subtle.importKey(\n \"jwk\",\n pubKey,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"],\n );\n return {\n publicKey: cryptoKey,\n\n async sign(_data: Uint8Array): Promise<Uint8Array> {\n throw new Error(\"verification-only signer cannot sign data\");\n },\n\n async signAction(\n _action: Action,\n _abortSignal?: AbortSignal,\n ): Promise<Signature> {\n throw new Error(\"verification-only signer cannot sign actions\");\n },\n\n async verify(data: Uint8Array, signature: Uint8Array): Promise<void> {\n let isValid: boolean;\n try {\n isValid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n cryptoKey,\n new Uint8Array(signature),\n new Uint8Array(data),\n );\n } catch {\n throw new Error(\"invalid signature\");\n }\n\n if (!isValid) {\n throw new Error(\"invalid signature\");\n }\n },\n };\n}\n\n/**\n * Creates a verification-only signer from a header.\n *\n * @param header - The header to create a signer from.\n * @returns A signer that can verify the header's signature.\n */\nconst createSignerFromHeader = async (\n header: PHDocumentHeader,\n): Promise<ISigner> => {\n return createVerificationSigner(header.sig.publicKey);\n};\n\n/**\n * Signs a header. Generally, this is not called directly, but rather through\n * {@link createSignedHeader}.\n *\n * @param parameters - The parameters used to sign the header.\n * @param signer - The signer of the document.\n *\n * @returns The signature of the header.\n */\nexport const sign = async (\n parameters: SigningParameters,\n signer: ISigner,\n): Promise<string> => {\n // Generate stable payload\n const payload = generateStablePayload(parameters);\n\n // Convert payload to Uint8Array for signing\n const encoder = new TextEncoder();\n const data = encoder.encode(payload);\n\n // Create signature using Web Crypto API with Ed25519\n const signature = await signer.sign(data);\n\n // Convert signature to base64 string for JSON serialization\n const signatureArray = new Uint8Array(signature);\n const signatureBase64 = btoa(String.fromCharCode(...signatureArray));\n return signatureBase64;\n};\n\n/**\n * Verifies a header signature. Generally, this is not called directly, but\n * rather through {@link validateHeader}.\n *\n * @param parameters - The parameters used to sign the header.\n * @param signature - The signature to verify.\n * @param signer - The signer of the document.\n */\nexport const verify = async (\n parameters: SigningParameters,\n signature: string,\n signer: ISigner,\n): Promise<void> => {\n // Generate the same stable payload that was signed\n const payload = generateStablePayload(parameters);\n\n // Convert payload to Uint8Array for verification\n const encoder = new TextEncoder();\n const data = encoder.encode(payload);\n\n // Decode the base64 signature back to binary\n const signatureBytes = Uint8Array.from(atob(signature), (c) =>\n c.charCodeAt(0),\n );\n\n await signer.verify(data, signatureBytes);\n};\n\n/**\n * Validates a header signature.\n */\nexport const validateHeader = async (\n header: PHDocumentHeader,\n): Promise<void> => {\n const signer = await createSignerFromHeader(header);\n\n return verify(\n {\n documentType: header.documentType,\n createdAtUtcIso: header.createdAtUtcIso,\n nonce: header.sig.nonce,\n },\n header.id,\n signer,\n );\n};\n\n/**\n * Creates a header that has yet to be signed. This header is not valid, but\n * can be input into {@link createSignedHeader} to create a signed header.\n *\n * @returns An unsigned header for a document.\n */\nexport const createPresignedHeader = (\n id: string = generateId(),\n documentType = \"\",\n): PHDocumentHeader => {\n return {\n id,\n sig: {\n publicKey: {},\n nonce: \"\",\n },\n documentType,\n createdAtUtcIso: new Date().toISOString(),\n slug: \"\",\n name: \"\",\n branch: \"main\",\n revision: {\n document: 0,\n },\n lastModifiedAtUtcIso: new Date().toISOString(),\n meta: {},\n };\n};\n\n/**\n * Creates a new, signed header for a document. This will replace the id of the\n * document.\n *\n * @param unsignedHeader - The unsigned header to created the signed header from.\n * @param signer - The signer of the document.\n *\n * @returns A new signed header for a document. Some fields are mutable and\n * some are not. See the PHDocumentHeader type for more information.\n */\nexport const createSignedHeader = async (\n unsignedHeader: PHDocumentHeader,\n documentType: string,\n signer: ISigner,\n): Promise<PHDocumentHeader> => {\n const parameters: SigningParameters = {\n documentType,\n createdAtUtcIso: unsignedHeader.createdAtUtcIso,\n nonce: generateId(),\n };\n\n const signature = await sign(parameters, signer);\n\n const jsonPublicKey = await crypto.subtle.exportKey(\"jwk\", signer.publicKey);\n\n return {\n // immutable fields\n id: signature,\n sig: {\n publicKey: jsonPublicKey,\n nonce: parameters.nonce,\n },\n documentType,\n createdAtUtcIso: unsignedHeader.createdAtUtcIso,\n\n // mutable fields\n slug: unsignedHeader.slug,\n name: unsignedHeader.name,\n branch: unsignedHeader.branch,\n revision: unsignedHeader.revision,\n lastModifiedAtUtcIso: unsignedHeader.lastModifiedAtUtcIso,\n meta: unsignedHeader.meta,\n };\n};\n\n/**\n * Creates a signed header for a document. The document header requires a signer\n * as the document id is a cryptographic signature.\n *\n * @param documentType - The type of the document.\n * @param signer - The signer of the document.\n *\n * @returns The signed header for a document. Some fields are mutable and\n * some are not. See the PHDocumentHeader type for more information.\n */\nexport const createSignedHeaderForSigner = async (\n documentType: string,\n signer: ISigner,\n): Promise<PHDocumentHeader> => {\n const unsignedHeader = createPresignedHeader();\n const signedHeader = await createSignedHeader(\n unsignedHeader,\n documentType,\n signer,\n );\n\n return signedHeader;\n};\n","import { stringify } from \"safe-stable-stringify\";\nimport type { Action } from \"./actions.js\";\nimport { hashBrowser } from \"./crypto.js\";\nimport { isDenied } from \"./denied.js\";\nimport { HashMismatchError } from \"./errors.js\";\nimport { createPresignedHeader } from \"./header.js\";\nimport type { DocumentOperations, Operation } from \"./operations.js\";\nimport type { PHDocumentSignatureInfo } from \"./signatures.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n CreateDocumentActionInput,\n CreateState,\n DocumentAction,\n DocumentOperationsIgnoreMap,\n MappedOperation,\n OperationIndex,\n OperationsByScope,\n Reducer,\n ReplayDocumentOptions,\n SignalDispatch,\n SkipHeaderOperationIndex,\n SkipHeaderOperations,\n UndoAction,\n UndoRedoAction,\n UpgradeDocumentActionInput,\n} from \"./types.js\";\nimport { deriveOperationId, generateId } from \"./utils.js\";\n\n/** Meta information about the document. */\nexport type PHDocumentMeta = {\n /** The preferred editor for the document. */\n preferredEditor?: string;\n};\n\n/**\n * The header of a document.\n */\nexport type PHDocumentHeader = {\n /**\n * The id of the document.\n *\n * This is a Ed25519 signature and is immutable.\n **/\n id: string;\n\n /**\n * Information to verify the document creator.\n *\n * This is immutable.\n **/\n sig: PHDocumentSignatureInfo;\n\n /**\n * The type of the document.\n *\n * This is used as part of the signature payload and thus, cannot be changed\n * after the document header has been created.\n **/\n documentType: string;\n\n /**\n * The timestamp of the creation date of the document, in UTC ISO format.\n *\n * This is used as part of the signature payload and thus, cannot be changed\n * after the document header has been created.\n **/\n createdAtUtcIso: string;\n\n /** The slug of the document. */\n slug: string;\n\n /** The name of the document. */\n name: string;\n\n /** The branch of this document. */\n branch: string;\n\n /**\n * The revision of each scope of the document. This object is updated every\n * time any _other_ scope is updated.\n */\n revision: {\n [scope: string]: number;\n };\n\n /**\n * The timestamp of the last change in the document, in UTC ISO format.\n **/\n lastModifiedAtUtcIso: string;\n\n /**\n * This is a map from protocol name to version. A protocol can be any set of\n * rules that are applied to the document.\n *\n * Examples of protocols include:\n *\n * - \"base-reducer\"\n */\n protocolVersions?: { [key: string]: number };\n\n /** Meta information about the document. */\n meta?: PHDocumentMeta;\n};\n\n/**\n * The base type of a document model.\n *\n * @remarks\n * This type is extended by all Document models.\n *\n * @typeParam TState - The type of the document state.\n */\nexport type PHDocument<TState extends PHBaseState = PHBaseState> = {\n /** The header of the document. */\n header: PHDocumentHeader;\n\n /** The document model specific state. */\n state: TState;\n\n /**\n * The initial state of the document, enabling replaying operations.\n *\n * This will be removed in a future release.\n */\n initialState: TState;\n\n /**\n * The operations history of the document.\n *\n * This will be removed in a future release.\n */\n operations: DocumentOperations;\n\n /**\n * A list of undone operations\n *\n * This will be removed in a future release.\n */\n clipboard: Operation[];\n};\n\nexport function isNoopOperation<\n TOp extends {\n type: string;\n skip: number;\n hash: string;\n },\n>(op: Partial<TOp>): boolean {\n return (\n op.type === \"NOOP\" &&\n op.skip !== undefined &&\n op.skip > 0 &&\n op.hash !== undefined\n );\n}\n\nexport function isUndoRedo(action: Action): action is UndoRedoAction {\n return [\"UNDO\", \"REDO\"].includes(action.type);\n}\n\nexport function isUndo(action: Action): action is UndoAction {\n return action.type === \"UNDO\";\n}\n\nexport function isDocumentAction(action: Action): action is DocumentAction {\n return [\n \"SET_NAME\",\n \"SET_PREFERRED_EDITOR\",\n \"UNDO\",\n \"REDO\",\n \"PRUNE\",\n \"LOAD_STATE\",\n ].includes(action.type);\n}\n\n/**\n * The document-scope operations a reactor mints on `create`, so a standalone\n * document carries its initial state when exported outside a reactor.\n */\nfunction createDocumentScopeOperations<TState extends PHBaseState>(\n header: PHDocumentHeader,\n state: TState,\n): Operation[] {\n const createInput: CreateDocumentActionInput = {\n model: header.documentType,\n version: 0,\n documentId: header.id,\n signing: {\n signature: header.id,\n publicKey: header.sig.publicKey,\n nonce: header.sig.nonce,\n createdAtUtcIso: header.createdAtUtcIso,\n documentType: header.documentType,\n },\n slug: header.slug,\n name: header.name,\n branch: header.branch,\n meta: header.meta,\n protocolVersions: header.protocolVersions ?? { \"base-reducer\": 2 },\n };\n const upgradeInput: UpgradeDocumentActionInput = {\n model: header.documentType,\n fromVersion: 0,\n toVersion: state.document.version,\n documentId: header.id,\n initialState: state,\n };\n\n const actions: Action[] = [\n {\n id: generateId(),\n type: \"CREATE_DOCUMENT\",\n scope: \"document\",\n timestampUtcMs: header.createdAtUtcIso,\n input: createInput,\n },\n {\n id: generateId(),\n type: \"UPGRADE_DOCUMENT\",\n scope: \"document\",\n timestampUtcMs: header.createdAtUtcIso,\n input: upgradeInput,\n },\n ];\n\n return actions.map((action, index) => ({\n ...action,\n action,\n id: deriveOperationId(header.id, \"document\", header.branch, action.id),\n hash: \"\",\n error: undefined,\n index,\n skip: 0,\n }));\n}\n\n/**\n * Creates a new document. When `documentType` is given the header is stamped\n * with it and the document-scope operations are seeded.\n */\nexport function baseCreateDocument<TState extends PHBaseState = PHBaseState>(\n createState: CreateState<TState>,\n initialState?: Partial<TState>,\n documentType = \"\",\n): PHDocument<TState> {\n const state = createState(initialState);\n const header = createPresignedHeader(generateId(), documentType);\n\n // The document's own CREATE_DOCUMENT operation records this, so the header\n // has to agree with it. Left off the header factory itself, because that is\n // also how a rebuild starts and a rebuild must take the version from the\n // stored operation rather than assume one.\n header.protocolVersions = { \"base-reducer\": 2 };\n\n const phDocument: PHDocument<TState> = {\n header,\n state,\n initialState: state,\n operations: documentType\n ? {\n global: [],\n local: [],\n document: createDocumentScopeOperations(header, state),\n }\n : { global: [], local: [] },\n clipboard: [],\n };\n\n return phDocument;\n}\n\nexport function hashDocumentStateForScope(\n document: {\n state: {\n [key: string]: unknown;\n };\n },\n scope = \"global\",\n) {\n const stateString = stringify(document.state[scope] || \"\");\n return hashBrowser(stateString);\n}\n\nexport function readOnly<T>(value: T): Readonly<T> {\n return Object.freeze(value);\n}\n\n/**\n * Maps skipped operations in an array of operations.\n * Skipped operations are operations that are ignored during processing.\n * @param operations - The array of operations to map.\n * @param skippedHeadOperations - The number of operations to skip at the head of the array of operations.\n * @returns An array of mapped operations with ignore flag indicating if the operation is skipped.\n * @throws Error if the operation index is invalid and there are missing operations.\n */\nexport function mapSkippedOperations(\n operations: Operation[],\n skippedHeadOperations?: number,\n): MappedOperation[] {\n const ops = [...operations];\n\n let skipped = skippedHeadOperations || 0;\n let latestOpIndex = ops.length > 0 ? ops[ops.length - 1].index : 0;\n\n const scopeOpsWithIgnore: MappedOperation[] = [];\n\n for (const operation of ops.reverse()) {\n if (skipped > 0) {\n const operationsDiff = latestOpIndex - operation.index;\n skipped -= operationsDiff;\n }\n\n if (skipped < 0) {\n throw new Error(\"Invalid operation index, missing operations\");\n }\n\n const mappedOp = {\n ignore: skipped > 0,\n operation,\n };\n\n // here we add 1 to the skip number because we want to get the number of\n // operations that we want to move the pointer back to get the latest valid operation\n // operation.skip = 1 means that we want to move the pointer back 2 operations to get to the latest valid operation\n const operationSkip = operation.skip > 0 ? operation.skip + 1 : 0;\n\n if (operationSkip > 0 && operationSkip > skipped) {\n const skipDiff = operationSkip - skipped;\n skipped = skipped + skipDiff;\n }\n\n latestOpIndex = operation.index;\n scopeOpsWithIgnore.push(mappedOp);\n }\n\n return scopeOpsWithIgnore.reverse();\n}\n\n/**\n * V2 version of mapSkippedOperations for protocol version 2+.\n * In V2, all NOOPs have skip=1 and consecutive NOOPs form chains.\n * N consecutive NOOPs at any point skip N preceding content operations.\n *\n * Algorithm: Process from end to start\n * - When hitting a NOOP: increment chain length, mark as ignored\n * - When hitting a non-NOOP:\n * - If chain > 0: decrement chain, mark as ignored (this op was undone)\n * - If chain == 0: mark as not ignored (apply this op)\n */\nexport function mapSkippedOperationsV2(\n operations: Operation[],\n): MappedOperation[] {\n const ops = [...operations];\n const result: MappedOperation[] = [];\n\n let noopChainLength = 0;\n\n for (let i = ops.length - 1; i >= 0; i--) {\n const operation = ops[i];\n const isNoop = operation.action.type === \"NOOP\";\n\n if (isNoop) {\n noopChainLength++;\n result.unshift({ ignore: true, operation });\n } else if (noopChainLength > 0) {\n noopChainLength--;\n result.unshift({ ignore: true, operation });\n } else {\n result.unshift({ ignore: false, operation });\n }\n }\n\n return result;\n}\n\n/**\n * V2 garbage collect that returns only operations that should be applied for state.\n * Uses the V2 model where consecutive NOOPs form chains.\n * Unlike V1 garbageCollect, this preserves ALL operations but marks which to apply.\n */\n/**\n * The base-reducer protocol version a document is written against. Every\n * document carries one, set from the CREATE_DOCUMENT input. A header without\n * one was built outside that path, and choosing a version on its behalf would\n * replay the document through a reducer it was not written for, so it is an\n * error rather than a default.\n */\nexport function baseReducerVersion(header: PHDocumentHeader): number {\n const version = header.protocolVersions?.[\"base-reducer\"];\n\n if (typeof version !== \"number\") {\n throw new Error(\n `Document ${header.id} carries no base-reducer protocol version`,\n );\n }\n\n return version;\n}\n\nexport function garbageCollectV2<TOpIndex extends OperationIndex>(\n sortedOperations: TOpIndex[],\n): TOpIndex[] {\n const result: TOpIndex[] = [];\n let noopChainLength = 0;\n\n for (let i = sortedOperations.length - 1; i >= 0; i--) {\n const op = sortedOperations[i];\n // Check if this is a NOOP operation\n const isNoop =\n \"action\" in op &&\n (op as unknown as Operation).action.type === \"NOOP\" &&\n op.skip > 0;\n\n if (isNoop) {\n noopChainLength++;\n // Include the NOOP in result (for operation history)\n result.unshift(op);\n } else if (noopChainLength > 0) {\n noopChainLength--;\n // Skip this operation - it was undone\n } else {\n // Include this operation\n result.unshift(op);\n }\n }\n\n return result;\n}\n\n// Flattens the mapped operations (with ignore flag) from all scopes into\n// a single array and sorts them by timestamp\nexport function sortMappedOperations(operations: DocumentOperationsIgnoreMap) {\n return Object.values(operations)\n .flatMap((array) => array)\n .sort(\n (a, b) =>\n new Date(a.operation.timestampUtcMs).getTime() -\n new Date(b.operation.timestampUtcMs).getTime(),\n );\n}\n\n// Default createState function that just returns the state as-is\nconst defaultCreateState = <TState extends PHBaseState = PHBaseState>(\n state?: Partial<TState>,\n) => {\n return state as TState;\n};\n\n/**\n * Records an operation in the history without applying it, which is what a\n * denied operation needs: it occupies its index and contributes no state.\n *\n * The scope defaults to the action's own, and is passed explicitly by a rebuild\n * that is walking one stream and does not want to trust the action's copy.\n */\nexport function appendWithoutApplying<TState extends PHBaseState>(\n document: PHDocument<TState>,\n operation: Operation,\n scope: string = operation.action.scope,\n): PHDocument<TState> {\n return {\n ...document,\n operations: {\n ...document.operations,\n [scope]: [...(document.operations[scope] ?? []), operation],\n },\n };\n}\n\n// Runs the operations on the initial data using the\n// provided document reducer.\n// This rebuilds the document according to the provided actions.\nexport function replayDocument<TState extends PHBaseState = PHBaseState>(\n initialState: TState,\n operations: DocumentOperations,\n reducer: Reducer<TState>,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n skipHeaderOperations: SkipHeaderOperations = {},\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n const {\n checkHashes = true,\n reuseOperationResultingState,\n operationResultingStateParser = parseResultingState,\n skipIndexValidation,\n } = options || {};\n\n const backfilledInitialState = backfillAuthState(initialState);\n let documentState = backfilledInitialState;\n const operationsToReplay: Operation[] = [];\n // Initialize with all scopes found in operations, plus global and local for backward compatibility\n const allScopes = new Set([...Object.keys(operations), \"global\", \"local\"]);\n const initialOperations: DocumentOperations = {};\n for (const scope of allScopes) {\n initialOperations[scope] = [];\n }\n\n // if operation resulting state is to be used then\n // looks for the last operation with state of each\n // scope to use it as the starting point and only\n // replay operations that follow it\n if (reuseOperationResultingState) {\n for (const [scope, scopeOperations] of Object.entries(operations)) {\n if (!scopeOperations) {\n continue;\n }\n const index = scopeOperations.findLastIndex((s) => !!s.resultingState);\n if (index < 0) {\n operationsToReplay.push(...scopeOperations);\n continue;\n }\n const opWithState = scopeOperations[index];\n if (!opWithState || !opWithState.resultingState) continue;\n try {\n const scopeState = operationResultingStateParser(\n opWithState.resultingState,\n );\n documentState = {\n ...documentState,\n [scope]: scopeState,\n };\n const scopeInitialOps =\n initialOperations[scope as keyof typeof initialOperations];\n if (scopeInitialOps) {\n scopeInitialOps.push(...scopeOperations.slice(0, index + 1));\n }\n operationsToReplay.push(...scopeOperations.slice(index + 1));\n } catch {\n /* if parsing fails then keeps replays all scope operations */\n operationsToReplay.push(...scopeOperations);\n }\n }\n } else {\n operationsToReplay.push(\n ...Object.values(operations).flatMap((ops) => ops || []),\n );\n }\n\n // builds a new document using the provided header (no generated header)\n const document: PHDocument<TState> = {\n header,\n state: defaultCreateState<TState>(documentState),\n initialState: backfilledInitialState,\n operations: initialOperations,\n clipboard: [],\n };\n\n let result = document;\n\n // if there are operations left without resulting state\n // then replays them\n if (operationsToReplay.length) {\n result = operationsToReplay.reduce((document, operation) => {\n // A denied operation holds its position without contributing state. The\n // reactor skips it on every rebuild, so a replay that applied it would\n // produce different state from the reactor that served the history. It\n // still occupies its index, so the scope's revision counts it.\n if (isDenied(operation)) {\n return updateHeaderRevision(\n appendWithoutApplying(document, operation),\n operation.action.scope,\n operation.timestampUtcMs,\n ) as PHDocument<TState>;\n }\n\n const doc = reducer(document, operation.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: {\n operation,\n },\n });\n\n return doc;\n }, document);\n }\n // if not then updates the document header according\n // to the latest operation of each scope\n else {\n for (const scopeOperations of Object.values(initialOperations)) {\n if (!scopeOperations) {\n continue;\n }\n const lastOperation = scopeOperations.at(-1);\n if (lastOperation) {\n result = updateHeaderRevision(\n result,\n lastOperation.action.scope,\n lastOperation.timestampUtcMs,\n ) as PHDocument<TState>;\n }\n }\n }\n\n // if hash generation was skipped then checks if the hash\n // of each scope matches the hash of last operation\n if (!checkHashes) {\n for (const scope of Object.keys(result.state)) {\n for (let i = operationsToReplay.length - 1; i >= 0; i--) {\n const operation = operationsToReplay[i];\n\n if (operation.action.scope !== scope) {\n continue;\n }\n if (operation.hash !== hashDocumentStateForScope(result, scope)) {\n throw new HashMismatchError(scope, result, operation);\n } else {\n break;\n }\n }\n }\n }\n\n // reuses operation timestamp if provided\n // Initialize with all scopes from both result.operations and input operations\n const allResultScopes = new Set([\n ...Object.keys(result.operations),\n ...Object.keys(operations),\n \"global\",\n \"local\",\n ]);\n const initialResultOperations: DocumentOperations = {};\n for (const scope of allResultScopes) {\n initialResultOperations[scope] = [];\n }\n\n // Iterate over all scopes (not just result.operations) to preserve empty scopes\n const resultOperations: DocumentOperations = Array.from(\n allResultScopes,\n ).reduce((acc, scope) => {\n const scopeOps = result.operations[scope] || [];\n\n return {\n ...acc,\n [scope]: [\n ...scopeOps.map((operation, index) => {\n return {\n ...operation,\n timestamp:\n operations[scope]?.[index]?.timestampUtcMs ??\n operation.timestampUtcMs,\n };\n }),\n ],\n };\n }, initialResultOperations);\n\n // gets the last modified timestamp from the latest operation\n const lastModified = header\n ? header.lastModifiedAtUtcIso\n : Object.values(resultOperations).reduce((acc, curr) => {\n if (!curr) {\n return acc;\n }\n const operation = curr.at(-1);\n if (operation) {\n if (operation.timestampUtcMs > acc) {\n return operation.timestampUtcMs;\n }\n }\n\n return acc;\n }, document.header.lastModifiedAtUtcIso);\n\n if (header) {\n result.header = {\n ...header,\n revision: result.header.revision,\n lastModifiedAtUtcIso: lastModified,\n };\n }\n\n return {\n ...result,\n operations: resultOperations,\n } as PHDocument<TState>;\n}\n\nexport function parseResultingState<TState>(\n state: string | null | undefined,\n): TState {\n const stateType = typeof state;\n if (stateType === \"string\") {\n return JSON.parse(state!) as TState;\n } else if (stateType === \"object\") {\n return state as TState;\n } else {\n throw new Error(`Providing resulting state is of type: ${stateType}`);\n }\n}\n\nexport enum IntegrityIssueType {\n UNEXPECTED_INDEX = \"UNEXPECTED_INDEX\",\n}\n\nexport enum IntegrityIssueSubType {\n DUPLICATED_INDEX = \"DUPLICATED_INDEX\",\n MISSING_INDEX = \"MISSING_INDEX\",\n}\n\ntype IntegrityIssue = {\n operation: OperationIndex;\n issue: IntegrityIssueType;\n category: IntegrityIssueSubType;\n message: string;\n};\n\ntype Reshuffle = (\n startIndex: OperationIndex,\n opsA: Operation[],\n opsB: Operation[],\n) => Operation[];\n\nexport function checkCleanedOperationsIntegrity(\n sortedOperations: OperationIndex[],\n): IntegrityIssue[] {\n const result: IntegrityIssue[] = [];\n\n // 1:1 1\n // 0:0 0 -> 1:0 1 -> 2:0 -> 3:0 -> 4:0 -> 5:0\n // 0:0 0 -> 2:1 1 -> 3:0 -> 4:0 -> 5:0\n // 0:0 0 -> 3:2 1 -> 4:0 -> 5:0\n // 0:0 0 -> 3:2 1 -> 5:1\n\n // 0:3 (expected 0, got -3)\n // 1:2 (expected 0, got -1)\n // 0:0 -> 1:1\n // 0:0 -> 2:2\n // 0:0 -> 3:2 -> 5:2\n\n let currentIndex = -1;\n for (const nextOperation of sortedOperations) {\n const nextIndex = nextOperation.index - nextOperation.skip;\n\n if (nextIndex !== currentIndex + 1) {\n result.push({\n operation: {\n index: nextOperation.index,\n skip: nextOperation.skip,\n },\n issue: IntegrityIssueType.UNEXPECTED_INDEX,\n category:\n nextIndex > currentIndex + 1\n ? IntegrityIssueSubType.MISSING_INDEX\n : IntegrityIssueSubType.DUPLICATED_INDEX,\n message: `Expected index ${currentIndex + 1} with skip 0 or equivalent, got index ${nextOperation.index} with skip ${nextOperation.skip}`,\n });\n }\n\n currentIndex = nextOperation.index;\n }\n\n return result;\n}\n\n// [] -> []\n// [0:0] -> [0:0]\n\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:1 2:0 => 1:1 2:0, removals 1, no issues\n\n// 0:0 1:1 2:0 3:1 => 1:1 3:1, removals 2, no issues\n// 0:0 1:1 2:0 3:3 => 3:3\n\n// 1:1 2:0 3:0 => 1:1 2:0 3:0, removals 0, no issues\n// 1:0 0:0 2:0 => 2:0, removals 2, issues [UNEXPECTED_INDEX, INDEX_OUT_OF_ORDER]\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n\nexport function garbageCollect<TOpIndex extends OperationIndex>(\n sortedOperations: TOpIndex[],\n) {\n const result: TOpIndex[] = [];\n\n let i = sortedOperations.length - 1;\n\n while (i > -1) {\n result.unshift(sortedOperations[i]);\n const skipUntil =\n (sortedOperations[i]?.index || 0) - (sortedOperations[i]?.skip || 0) - 1;\n\n let j = i - 1;\n while (j > -1 && (sortedOperations[j]?.index || 0) > skipUntil) {\n j--;\n }\n\n i = j;\n }\n\n return result;\n}\nexport function addUndo(sortedOperations: Operation[]) {\n const operationsCopy = [...sortedOperations];\n const latestOperation = operationsCopy[operationsCopy.length - 1];\n\n if (!latestOperation) return operationsCopy;\n\n if (latestOperation.action.type === \"NOOP\") {\n operationsCopy.push({\n ...latestOperation,\n index: latestOperation.index,\n skip: nextSkipNumber(sortedOperations),\n action: {\n ...latestOperation.action,\n\n // TODO: this will break the signature...\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type: \"NOOP\",\n },\n });\n } else {\n operationsCopy.push({\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n index: latestOperation.index + 1,\n skip: 1,\n hash: latestOperation.hash,\n action: {\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type: \"NOOP\",\n input: {},\n scope: latestOperation.action.scope,\n },\n });\n }\n\n return operationsCopy;\n}\n\n// [0:0 2:0 1:0 3:3 3:1] => [0:0 1:0 2:0 3:1 3:3]\n// Sort by index _and_ skip number\nexport function sortOperations<TOpIndex extends OperationIndex>(\n operations: TOpIndex[],\n): TOpIndex[] {\n return operations\n .slice()\n .sort((a, b) => a.skip - b.skip)\n .sort((a, b) => a.index - b.index);\n}\n\n// [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n// GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n// Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n// Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n// merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\nexport function reshuffleByTimestamp<TOp extends OperationIndex>(\n startIndex: OperationIndex,\n opsA: TOp[],\n opsB: TOp[],\n): TOp[] {\n return [...opsA, ...opsB]\n .sort((a, b) => {\n const timestampDiff =\n new Date(a.timestampUtcMs || \"\").getTime() -\n new Date(b.timestampUtcMs || \"\").getTime();\n if (timestampDiff !== 0) {\n return timestampDiff;\n }\n return (a.id || \"\").localeCompare(b.id || \"\");\n })\n .map((op, i) => ({\n ...op,\n index: startIndex.index + i,\n skip: i === 0 ? startIndex.skip : 0,\n }));\n}\n\nexport function reshuffleByTimestampAndIndex<TOp extends OperationIndex>(\n startIndex: OperationIndex,\n opsA: TOp[],\n opsB: TOp[],\n): TOp[] {\n return [...opsA, ...opsB]\n .sort((a, b) => {\n const indexDiff = a.index - b.index;\n if (indexDiff !== 0) {\n return indexDiff;\n }\n const timestampDiff =\n new Date(a.timestampUtcMs || \"\").getTime() -\n new Date(b.timestampUtcMs || \"\").getTime();\n if (timestampDiff !== 0) {\n return timestampDiff;\n }\n return (a.id || \"\").localeCompare(b.id || \"\");\n })\n .map((op, i) => ({\n ...op,\n index: startIndex.index + i,\n skip: i === 0 ? startIndex.skip : 0,\n }));\n}\n\n// TODO: implement better operation equality function\nexport function operationsAreEqual<\n TOp extends {\n index: number;\n skip: number;\n type?: string;\n scope?: string;\n input?: unknown;\n },\n>(op1: TOp, op2: TOp): boolean {\n const a = op1;\n const b = op2;\n\n const aComparable = {\n index: a.index,\n skip: a.skip,\n type: a.type ?? null,\n scope: a.scope ?? null,\n input: a.input ?? null,\n };\n\n const bComparable = {\n index: b.index,\n skip: b.skip,\n type: b.type ?? null,\n scope: b.scope ?? null,\n input: b.input ?? null,\n };\n\n return stringify(aComparable) === stringify(bComparable);\n}\n\n// [T0:0 T1:0 T2:0 T3:0] + [B4:0 B5:0] = [T0:0 T1:0 T2:0 T3:0 B4:0 B5:0]\n// [T0:0 T1:0 T2:0 T3:0] + [B3:0 B4:0] = [T0:0 T1:0 T2:0 B3:0 B4:0]\n// [T0:0 T1:0 T2:0 T3:0] + [B2:0 B3:0] = [T0:0 T1:0 B2:0 B3:0]\n\n// [T0:0 T1:0 T2:0 T3:0] + [B4:0 B4:2] = [T0:0 T1:0 T2:0 T3:0 B4:0 B4:2]\n// [T0:0 T1:0 T2:0 T3:0] + [B3:0 B3:2] = [T0:0 T1:0 T2:0 B3:0 B3:2]\n// [T0:0 T1:0 T2:0 T3:0] + [B2:3 B3:0] = [T0:0 T1:0 B2:3 B3:0]\n\nexport function attachBranch(\n trunk: Operation[],\n newBranch: Operation[],\n): [Operation[], Operation[]] {\n const trunkCopy = garbageCollect(sortOperations(trunk.slice()));\n const newOperations = garbageCollect(sortOperations(newBranch.slice()));\n if (trunkCopy.length < 1) {\n return [newOperations, []];\n }\n\n const result: Operation[] = [];\n let enteredBranch = false;\n\n while (newOperations.length > 0) {\n const newOperationCandidate = newOperations[0];\n\n let nextTrunkOperation = trunkCopy.shift();\n while (\n nextTrunkOperation &&\n precedes(nextTrunkOperation, newOperationCandidate)\n ) {\n result.push(nextTrunkOperation);\n nextTrunkOperation = trunkCopy.shift();\n }\n\n if (!nextTrunkOperation) {\n enteredBranch = true;\n } else if (!enteredBranch) {\n if (operationsAreEqual(nextTrunkOperation, newOperationCandidate)) {\n newOperations.shift();\n result.push(nextTrunkOperation);\n } else {\n trunkCopy.unshift(nextTrunkOperation);\n enteredBranch = true;\n }\n }\n\n if (enteredBranch) {\n let nextAppend = newOperations.shift();\n while (nextAppend) {\n result.push(nextAppend);\n nextAppend = newOperations.shift();\n }\n }\n }\n\n if (!enteredBranch) {\n let nextAppend = trunkCopy.shift();\n while (nextAppend) {\n result.push(nextAppend);\n nextAppend = trunkCopy.shift();\n }\n }\n\n return [garbageCollect(result), trunkCopy];\n}\n\nexport function precedes(op1: OperationIndex, op2: OperationIndex) {\n return (\n op1.index < op2.index ||\n (op1.index === op2.index && op1.id === op2.id && op1.skip < op2.skip)\n );\n}\n\nexport function split(\n sortedTargetOperations: Operation[],\n sortedMergeOperations: Operation[],\n): [Operation[], Operation[], Operation[]] {\n const commonOperations: Operation[] = [];\n const targetDiffOperations: Operation[] = [];\n const mergeDiffOperations: Operation[] = [];\n\n // get bigger array length\n const maxLength = Math.max(\n sortedTargetOperations.length,\n sortedMergeOperations.length,\n );\n\n let splitHappened = false;\n for (let i = 0; i < maxLength; i++) {\n const targetOperation = sortedTargetOperations[i];\n const mergeOperation = sortedMergeOperations[i];\n\n if (targetOperation && mergeOperation) {\n if (\n !splitHappened &&\n operationsAreEqual(targetOperation, mergeOperation)\n ) {\n commonOperations.push(targetOperation);\n } else {\n splitHappened = true;\n targetDiffOperations.push(targetOperation);\n mergeDiffOperations.push(mergeOperation);\n }\n } else if (targetOperation) {\n targetDiffOperations.push(targetOperation);\n } else if (mergeOperation) {\n mergeDiffOperations.push(mergeOperation);\n }\n }\n\n return [commonOperations, targetDiffOperations, mergeDiffOperations];\n}\n\n// [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n// GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n// Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n// Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n// merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\nexport function merge(\n sortedTargetOperations: Operation[],\n sortedMergeOperations: Operation[],\n reshuffle: Reshuffle,\n): Operation[] {\n const [_commonOperations, _targetOperations, _mergeOperations] = split(\n garbageCollect(sortedTargetOperations),\n garbageCollect(sortedMergeOperations),\n );\n\n const maxCommonIndex = getMaxIndex(_commonOperations);\n const nextIndex =\n 1 +\n Math.max(\n maxCommonIndex,\n getMaxIndex(_targetOperations),\n getMaxIndex(_mergeOperations),\n );\n\n const filteredMergeOperations = filterDuplicatedOperations(\n _mergeOperations,\n _targetOperations,\n );\n\n const newOperationHistory = reshuffle(\n {\n index: nextIndex,\n skip: nextIndex - (maxCommonIndex + 1),\n },\n _targetOperations,\n filteredMergeOperations,\n );\n\n return _commonOperations.concat(newOperationHistory);\n}\n\nfunction getMaxIndex(sortedOperations: OperationIndex[]) {\n const lastElement = sortedOperations[sortedOperations.length - 1];\n if (!lastElement) {\n return -1;\n }\n\n return lastElement.index;\n}\n\n// [] => -1\n// [0:0] => -1\n// [0:0 1:0] => 1\n// [0:0 1:1] => -1\n// [1:1] => -1\n// [0:0 1:0 2:0] => 1\n// [0:0 1:0 2:0 2:1] => 2\n// [0:0 1:0 2:0 2:1 2:2] => -1\n// [0:0 1:1 2:0] => 2\n// [0:0 1:1 2:2] => -1\n// [0:0 1:1 2:0 3:0] => 1\n// [0:0 1:1 2:0 3:1] => 3\n// [0:0 1:1 2:0 3:3] => -1\n// [50:50 100:50 150:50 151:0 152:0 153:0 154:3] => 53\n\nexport function nextSkipNumber(sortedOperations: OperationIndex[]) {\n if (sortedOperations.length < 1) {\n return -1;\n }\n\n const cleanedOperations = garbageCollect(sortedOperations);\n\n let nextSkip =\n (cleanedOperations[cleanedOperations.length - 1]?.skip || 0) + 1;\n\n if (cleanedOperations.length > 1) {\n nextSkip += cleanedOperations[cleanedOperations.length - 2]?.skip || 0;\n }\n\n return (cleanedOperations[cleanedOperations.length - 1]?.index || -1) <\n nextSkip\n ? -1\n : nextSkip;\n}\n\nexport function checkOperationsIntegrity(operations: Operation[]) {\n return checkCleanedOperationsIntegrity(\n garbageCollect(sortOperations(operations)),\n );\n}\nexport function groupOperationsByScope(operations: Operation[]) {\n const result = operations.reduce<OperationsByScope>((acc, operation) => {\n if (!acc[operation.action.scope]) {\n acc[operation.action.scope] = [];\n }\n\n acc[operation.action.scope]?.push(operation);\n\n return acc;\n }, {});\n\n return result;\n}\n\ntype PrepareOperationsResult = {\n validOperations: Operation[];\n invalidOperations: Operation[];\n duplicatedOperations: Operation[];\n integrityIssues: IntegrityIssue[];\n};\n\nexport function prepareOperations(\n operationsHistory: Operation[],\n newOperations: Operation[],\n) {\n const result: PrepareOperationsResult = {\n integrityIssues: [],\n validOperations: [],\n invalidOperations: [],\n duplicatedOperations: [],\n };\n\n const sortedOperationsHistory = sortOperations(operationsHistory);\n const sortedOperations = sortOperations(newOperations);\n\n const integrityErrors = checkCleanedOperationsIntegrity([\n ...sortedOperationsHistory,\n ...sortedOperations,\n ]);\n\n const missingIndexErrors = integrityErrors.filter(\n (integrityIssue) =>\n integrityIssue.category === IntegrityIssueSubType.MISSING_INDEX,\n );\n\n // get the integrity error with the lowest index operation\n const firstMissingIndexOperation = [...missingIndexErrors]\n .sort((a, b) => b.operation.index - a.operation.index)\n .pop()?.operation;\n\n for (const newOperation of sortedOperations) {\n // Operation is missing index or it follows an operation that is missing index\n if (\n firstMissingIndexOperation &&\n newOperation.index >= firstMissingIndexOperation.index\n ) {\n result.invalidOperations.push(newOperation);\n continue;\n }\n\n // check if operation is duplicated\n const isDuplicatedOperation = integrityErrors.some((integrityError) => {\n return (\n integrityError.operation.index === newOperation.index &&\n integrityError.operation.skip === newOperation.skip &&\n integrityError.category === IntegrityIssueSubType.DUPLICATED_INDEX\n );\n });\n\n // add to duplicated operations if it is duplicated\n if (isDuplicatedOperation) {\n result.duplicatedOperations.push(newOperation);\n continue;\n }\n\n // otherwise, add to valid operations\n result.validOperations.push(newOperation);\n }\n\n result.integrityIssues.push(...integrityErrors);\n return result;\n}\n\nexport function removeExistingOperations(\n newOperations: Operation[],\n operationsHistory: Operation[],\n) {\n return newOperations.filter((newOperation) => {\n return !operationsHistory.some((historyOperation) => {\n return (\n (newOperation.action.type === \"NOOP\" &&\n newOperation.skip === 0 &&\n newOperation.index === historyOperation.index) ||\n (newOperation.index === historyOperation.index &&\n newOperation.skip === historyOperation.skip &&\n newOperation.action.scope === historyOperation.action.scope &&\n newOperation.hash === historyOperation.hash &&\n newOperation.action.type === historyOperation.action.type)\n );\n });\n });\n}\n\n/**\n * Skips header operations and returns the remaining operations.\n *\n * @param operations - The array of operations.\n * @param skipHeaderOperation - The skip header operation index.\n * @returns The remaining operations after skipping header operations.\n */\nexport function skipHeaderOperations(\n operations: Operation[],\n skipHeaderOperation: SkipHeaderOperationIndex,\n): Operation[] {\n const lastOperation = sortOperations(operations).at(-1);\n const lastIndex = lastOperation?.index ?? -1;\n const nextIndex = lastIndex + 1;\n\n const skipOperationIndex = {\n ...skipHeaderOperation,\n index: skipHeaderOperation.index ?? nextIndex,\n };\n\n if (skipOperationIndex.index < lastIndex) {\n throw new Error(\n `The skip header operation index must be greater than or equal to ${lastIndex}`,\n );\n }\n\n const clearedOperations = garbageCollect(\n sortOperations([...operations, skipOperationIndex]),\n );\n\n return clearedOperations.slice(0, -1) as Operation[]; //clearedOperation ? [clearedOperation as TOpIndex] : [];\n}\n\nexport function garbageCollectDocumentOperations(\n documentOperations: DocumentOperations,\n) {\n const clearedOperations = Object.entries(documentOperations).reduce(\n (acc, entry) => {\n const [scope, ops] = entry;\n if (!ops) {\n return acc;\n }\n\n return {\n ...acc,\n [scope]: garbageCollect(sortOperations(ops)),\n };\n },\n {},\n );\n\n return clearedOperations as DocumentOperations;\n}\n\n/**\n * Filters out duplicated operations from the target operations array based on their IDs.\n * If an operation has an ID, it is considered duplicated if there is another operation in the source operations array with the same ID.\n * If an operation does not have an ID, it is considered unique and will not be filtered out.\n * @param targetOperations - The array of target operations to filter.\n * @param sourceOperations - The array of source operations to compare against.\n * @returns An array of operations with duplicates filtered out.\n */\nexport function filterDuplicatedOperations<T extends { id?: string | number }>(\n targetOperations: T[],\n sourceOperations: T[],\n): T[] {\n return targetOperations.filter((op) => {\n if (op.id) {\n return !sourceOperations.some((targetOp) => targetOp.id === op.id);\n }\n\n return true;\n });\n}\n\nexport function filterDocumentOperationsResultingState(\n documentOperations?: DocumentOperations,\n) {\n if (!documentOperations) {\n return {} as DocumentOperations;\n }\n\n const entries = Object.entries(documentOperations);\n\n return entries.reduce((acc, [scope, operations]) => {\n if (!operations) {\n return acc;\n }\n return {\n ...acc,\n [scope]: operations.map((op) => {\n const { resultingState, ...restProps } = op;\n\n return restProps;\n }),\n };\n }, {} as DocumentOperations);\n}\n\n/**\n * Calculates the difference between two arrays of operations.\n * Returns an array of operations that are present in `clearedOperationsA` but not in `clearedOperationsB`.\n *\n * @template TOp - The type of the operations.\n * @param {TOp[]} clearedOperationsA - The first array of operations.\n * @param {TOp[]} clearedOperationsB - The second array of operations.\n * @returns {TOp[]} - The difference between the two arrays of operations.\n */\nexport function diffOperations<TOp extends OperationIndex>(\n clearedOperationsA: TOp[],\n clearedOperationsB: TOp[],\n): TOp[] {\n return clearedOperationsA.filter(\n (operationA) =>\n !clearedOperationsB.some(\n (operationB) => operationA.index === operationB.index,\n ),\n );\n}\n\n// Returns the timestamp of the latest operation by index (and skip as tiebreaker),\n// falling back to the document header's lastModifiedAtUtcIso\nexport function getDocumentLastModified(document: PHDocument) {\n let latest: Operation | undefined;\n\n for (const ops of Object.values(document.operations)) {\n if (!ops) continue;\n for (const op of ops) {\n if (\n !latest ||\n op.index > latest.index ||\n (op.index === latest.index && op.skip > latest.skip)\n ) {\n latest = op;\n }\n }\n }\n\n return latest?.timestampUtcMs || document.header.lastModifiedAtUtcIso;\n}\n\n/**\n * Gets the next revision number based on the provided scope.\n *\n * @param state The current state of the document.\n * @param scope The scope of the operation.\n * @returns The next revision number.\n */\nfunction getNextRevision(document: PHDocument, scope: string) {\n const scopeOperations = document.operations[scope];\n const maxIndex = scopeOperations?.at(-1)?.index ?? -1;\n return maxIndex + 1;\n}\n\n/**\n * Updates the document header with the latest revision number and\n * date of last modification.\n *\n * @param document The current state of the document.\n * @param scope The scope of the operation.\n * @param lastModifiedTimestamp Optional timestamp to use directly, avoiding a scan of all operations.\n * @returns The updated document state.\n */\nexport function updateHeaderRevision(\n document: PHDocument,\n scope: string,\n lastModifiedTimestamp?: string,\n): PHDocument {\n const newTimestamp =\n lastModifiedTimestamp ?? getDocumentLastModified(document);\n const currentTimestamp = document.header.lastModifiedAtUtcIso;\n\n const header: PHDocumentHeader = {\n ...document.header,\n revision: {\n ...document.header.revision,\n [scope]: getNextRevision(document, scope),\n },\n lastModifiedAtUtcIso:\n !currentTimestamp || newTimestamp > currentTimestamp\n ? newTimestamp\n : currentTimestamp,\n };\n\n return {\n ...document,\n header,\n };\n}\n","import type { Draft } from \"mutative\";\nimport { castDraft, create } from \"mutative\";\nimport { noop, type Action } from \"./actions.js\";\nimport { resolveSnapshotAuth } from \"./auth.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport { nextSkipNumber, sortOperations } from \"./documents.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type { LoadStateActionInput } from \"./types.js\";\n\n// updates the name of the document\nexport function setNameOperation<TDocument extends PHDocument>(\n document: TDocument,\n input: { name: string },\n) {\n return { ...document, header: { ...document.header, name: input.name } };\n}\n\n// updates the preferred editor in the document header meta; clears it when input is null/empty\nexport function setPreferredEditorOperation<TDocument extends PHDocument>(\n document: TDocument,\n input: { preferredEditor: string | null },\n): TDocument {\n const existingMeta = document.header.meta ?? {};\n if (input.preferredEditor) {\n return {\n ...document,\n header: {\n ...document.header,\n meta: { ...existingMeta, preferredEditor: input.preferredEditor },\n },\n };\n }\n const { preferredEditor: _removed, ...rest } = existingMeta;\n return {\n ...document,\n header: { ...document.header, meta: rest },\n };\n}\n\nexport function undoOperation<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n // const scope = action.scope;\n const { scope } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false,\n };\n\n return create(defaultResult, (draft) => {\n const operations = [...document.operations[scope]];\n const sortedOperations = sortOperations(operations);\n\n draft.action = noop(scope) as Draft<Action>;\n\n const lastOperation = sortedOperations.at(-1);\n let nextIndex = lastOperation?.index ?? -1;\n\n const isNewNoop = lastOperation?.action.type !== \"NOOP\";\n\n if (isNewNoop) {\n nextIndex = nextIndex + 1;\n } else {\n draft.reuseLastOperationIndex = true;\n }\n\n const nextOperationHistory = isNewNoop\n ? [...sortedOperations, { index: nextIndex, skip: 0 }]\n : sortedOperations;\n\n draft.skip = nextSkipNumber(nextOperationHistory);\n\n if (lastOperation && draft.skip > lastOperation.skip + 1) {\n // there's an overlap with a previous skip operation\n // (add 1 to the skip value because we are adding a new operation to the history)\n draft.skip = draft.skip + 1;\n }\n\n if (draft.skip < 0) {\n throw new Error(\n `Cannot undo: you can't undo more operations than the ones in the scope history`,\n );\n }\n });\n}\n\n/**\n * V2 of undoOperation for protocol version 2+.\n * Key differences from undoOperation:\n * - Never reuses operation index (always increments)\n * - Always sets skip=1 (consecutive NOOPs are handled during rebuild/GC)\n * - No complex skip calculation - simpler model where each UNDO is independent\n */\nexport function undoOperationV2<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: false;\n} {\n const { scope } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false as const,\n };\n\n return create(defaultResult, (draft) => {\n const operations = document.operations[scope] || [];\n const sortedOperations = sortOperations([...operations]);\n\n // Count non-NOOP operations to determine if there's anything to undo\n const nonNoopOps = sortedOperations.filter(\n (op) => op.action.type !== \"NOOP\",\n );\n\n // Count consecutive NOOPs at the end (these represent pending undos)\n let noopChainLength = 0;\n for (let i = sortedOperations.length - 1; i >= 0; i--) {\n if (sortedOperations[i].action.type === \"NOOP\") {\n noopChainLength++;\n } else {\n break;\n }\n }\n\n // Check if we can undo: need more non-NOOP ops than the current NOOP chain\n if (nonNoopOps.length <= noopChainLength) {\n throw new Error(\n `Cannot undo: no more operations to undo in scope history`,\n );\n }\n\n draft.action = noop(scope) as Draft<Action>;\n draft.skip = 1;\n });\n}\n\nexport function redoOperation<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n const { scope, input } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false,\n };\n\n return create(defaultResult, (draft) => {\n if (draft.skip > 0) {\n throw new Error(\n `Cannot redo: skip value from reducer cannot be used with REDO action`,\n );\n }\n\n // Handle both object format { count: number } and legacy number format\n const count =\n typeof input === \"object\" && input !== null && \"count\" in input\n ? (input as { count: number }).count\n : input;\n\n if (typeof count !== \"number\" || count > 1) {\n throw new Error(`Cannot redo: you can only redo one operation at a time`);\n }\n\n if (typeof count !== \"number\" || count < 1) {\n throw new Error(`Invalid REDO action: invalid redo input value`);\n }\n\n if (draft.document.clipboard.length < 1) {\n throw new Error(`Cannot redo: no operations in the clipboard`);\n }\n\n const operationIndex = draft.document.clipboard.findLastIndex(\n (op) => op.action.scope === scope,\n );\n if (operationIndex < 0) {\n throw new Error(\n `Cannot redo: no operations in clipboard for scope \"${scope}\"`,\n );\n }\n\n const operation = draft.document.clipboard.splice(operationIndex, 1)[0];\n\n draft.action = castDraft({\n type: operation.action.type,\n scope: operation.action.scope,\n input: operation.action.input,\n } as Action);\n });\n}\n\nexport function loadStateOperation<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: LoadStateActionInput,\n): PHDocument<TState> {\n const loaded = backfillAuthState(action.state.data as TState);\n // A loaded snapshot does not get to install or replace a policy; see\n // resolveSnapshotAuth.\n loaded.auth = resolveSnapshotAuth(\n document.header.id,\n document.header.documentType,\n backfillAuthState({ ...document.state }).auth,\n loaded.auth,\n );\n return {\n ...document,\n header: { ...document.header, name: action.state.name },\n state: loaded,\n };\n}\n\n/**\n * An operation that was applied to a {@link BaseDocument}.\n *\n * @remarks\n * Wraps an action with an index, to be added to the operations history of a Document.\n * The `index` field is used to keep all operations in order and enable replaying the\n * document's history from the beginning. Note that indices and skips are relative to\n * a specific reactor. Example below:\n *\n * For (index, skip, ts, action)\n * A - [(0, 0, 1, \"A0\"), (1, 0, 2, \"A1\")]\n * B - [(0, 0, 0, \"B0\"), (1, 0, 3, \"B1\")]\n * ...\n * B gets A's Operations Scenario:\n * B' - [(0, 0, 0, \"B0\"), (1, 0, 3, \"B1\"), (2, 1, 1, \"A0\"), (3, 0, 2, \"A1\"), (4, 0, 3, \"B1\")]\n * Then A needs to end up with:\n * A' - [(0, 0, 1, \"A0\"), (1, 0, 2, \"A1\"), (2, 2, 0, \"B0\"), (3, 0, 1, \"A0\"), (4, 0, 2, \"A1\"), (5, 0, 3, \"B1\")]\n * So that both A and B end up with the stream of actions (action):\n * [(\"B0\"), (\"A0\"), (\"A1\"), (\"B1\")]\n *\n * @typeParam A - The type of the action.\n */\nexport type Operation = {\n /**\n * This is a stable id, derived from various document and action properties\n * in deriveOperationId().\n *\n * It _cannot_ be an arbitrary string.\n *\n * It it also not unique per operation, as reshuffled operations will keep'\n * the same id they had before they were reshuffled. This means that the\n * IOperationStore may have multiple operations with the same operation id.\n **/\n id: string;\n\n /** Position of the operation in the history. This is relative to a specific reactor -- they may not all agree on this value. */\n index: number;\n\n /** The number of operations skipped with this Operation. This is relative to a specific reactor -- they may not all agree on this value. */\n skip: number;\n\n /** Timestamp of when the operation was added */\n timestampUtcMs: string;\n\n /** Hash of the resulting document data after the operation */\n hash: string;\n\n /** Error message for a failed action */\n error?: string;\n\n /**\n * If authorization rejected the action, this records the reason why.\n */\n deniedReason?: string;\n\n /** The resulting state after the operation */\n resultingState?: string;\n\n /**\n * The action that was applied to the document to produce this operation.\n */\n action: Action;\n};\n\n/**\n * The operations history of the document by scope.\n *\n * This will be removed in a future release.\n *\n * TODO: Type should be Partial<Record<string, Operation[]>>,\n * but that is a breaking change for codegen + external doc models.\n */\nexport type DocumentOperations = Record<string, Operation[]>;\n\n/**\n * What happened to an operation. An operation that is not `applied` still\n * occupies its index but contributes nothing to the document's state.\n */\nexport type OperationOutcome =\n | { kind: \"applied\" }\n | { kind: \"reducer-error\"; message: string }\n | { kind: \"denied\"; reason: string };\n\n/**\n * Reads an operation's outcome. A denial takes precedence over a reducer\n * error, since a denied operation never reaches its reducer.\n */\nexport function operationOutcome(operation: Operation): OperationOutcome {\n if (operation.deniedReason !== undefined) {\n return { kind: \"denied\", reason: operation.deniedReason };\n }\n\n if (operation.error !== undefined) {\n return { kind: \"reducer-error\", message: operation.error };\n }\n\n return { kind: \"applied\" };\n}\n\nexport type OperationContext = {\n documentId: string;\n documentType: string;\n scope: string;\n branch: string;\n resultingState?: string;\n\n // This is a _global_ ordinal that is increasing across all documents and scopes.\n ordinal: number;\n};\n\nexport type OperationWithContext = {\n operation: Operation;\n context: OperationContext;\n};\n","import { castDraft, create, unsafe } from \"mutative\";\nimport type { Action } from \"./actions.js\";\nimport {\n actionFromAction,\n loadState,\n operationFromAction,\n operationFromOperation,\n} from \"./actions.js\";\nimport { applyAuthAction, assertAuthScopeActionAllowed } from \"./auth.js\";\nimport {\n baseReducerVersion,\n diffOperations,\n garbageCollect,\n garbageCollectDocumentOperations,\n garbageCollectV2,\n hashDocumentStateForScope,\n isDocumentAction,\n isUndo,\n isUndoRedo,\n parseResultingState,\n replayDocument,\n skipHeaderOperations,\n sortOperations,\n updateHeaderRevision,\n type PHDocument,\n type PHDocumentHeader,\n} from \"./documents.js\";\nimport {\n loadStateOperation,\n redoOperation,\n setNameOperation,\n setPreferredEditorOperation,\n undoOperation,\n undoOperationV2,\n type DocumentOperations,\n type Operation,\n type OperationContext,\n} from \"./operations.js\";\nimport { DocumentActionSchema } from \"./schemas.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n PruneActionInput,\n Reducer,\n ReducerOptions,\n ReplayDocumentOptions,\n SignalDispatch,\n SkipHeaderOperations,\n StateReducer,\n} from \"./types.js\";\n\n// This rebuilds the document according to the provided actions.\nexport function replayOperations<TState extends PHBaseState = PHBaseState>(\n initialState: TState,\n clearedOperations: DocumentOperations,\n stateReducer: StateReducer<TState>,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n documentReducer = baseReducer,\n skipHeaderOperations: SkipHeaderOperations = {},\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n // wraps the provided custom reducer with the\n // base document reducer\n const wrappedReducer = createReducer(stateReducer, documentReducer);\n\n return replayDocument<TState>(\n initialState,\n clearedOperations,\n wrappedReducer,\n header,\n dispatch,\n skipHeaderOperations,\n options,\n );\n}\n\n/**\n * Updates the operations history of the document based on the provided action.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param index The index of the operation to update.\n * @param skip The number of operations to skip before applying the action.\n * @param reuseLastOperationIndex Whether to reuse the last operation index (used when a an UNDO operation is performed after an existing one).\n * @param context The operation context for deterministic ID generation.\n * @returns The updated document state.\n */\nfunction updateOperationsForAction<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n): TDocument {\n // UNDO, REDO and PRUNE are meta operations\n // that alter the operations history themselves\n if ([\"UNDO\", \"REDO\", \"PRUNE\"].includes(action.type)) {\n return document;\n }\n\n const scope = action.scope;\n const existing = document.operations[scope];\n // Relies on ops being sorted ascending by index — see reactor CLAUDE.md invariants.\n const lastOperationIndex = existing?.at(-1)?.index ?? -1;\n\n const index = reuseLastOperationIndex\n ? lastOperationIndex\n : lastOperationIndex + 1;\n\n const newOperation = operationFromAction(action, index, skip, context);\n\n const operations = [...(existing ?? []), newOperation];\n\n return {\n ...document,\n operations: { ...document.operations, [scope]: operations },\n };\n}\n\nfunction updateOperationsForOperation<TDocument extends PHDocument>(\n document: TDocument,\n operation: Operation,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n skipIndexValidation?: boolean,\n): TDocument {\n const scope = operation.action.scope;\n const existing = document.operations[scope];\n // Relies on ops being sorted ascending by index — see reactor CLAUDE.md invariants.\n const lastOperationIndex = existing?.at(-1)?.index ?? -1;\n\n const nextIndex = reuseLastOperationIndex\n ? lastOperationIndex\n : lastOperationIndex + 1;\n\n if (!skipIndexValidation && operation.index - skip > nextIndex) {\n throw new Error(\n `Missing operations: expected ${nextIndex} with skip 0 or equivalent, got index ${operation.index} with skip ${skip}`,\n );\n }\n\n const newOperation = operationFromOperation(\n operation,\n operation.index,\n skip,\n context,\n );\n\n const operations = [...(existing ?? []), newOperation];\n\n return {\n ...document,\n operations: { ...document.operations, [scope]: operations },\n };\n}\n\n/**\n * Updates the document state based on the provided action.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param skip The number of operations to skip before applying the action.\n * @param reuseLastOperationIndex Whether to reuse the last operation index (used when a an UNDO operation is performed after an existing one).\n * @param context The operation context for deterministic ID generation.\n * @returns The updated document state.\n */\nexport function updateDocument<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n operation?: Operation,\n skipIndexValidation?: boolean,\n): TDocument {\n let newDocument: TDocument;\n if (operation) {\n // operation\n newDocument = updateOperationsForOperation(\n document,\n operation,\n reuseLastOperationIndex,\n skip,\n context,\n skipIndexValidation,\n ) as TDocument;\n } else {\n // action\n newDocument = updateOperationsForAction(\n document,\n action,\n reuseLastOperationIndex,\n skip,\n context,\n ) as TDocument;\n }\n\n newDocument = updateHeaderRevision(\n newDocument,\n action.scope,\n action.timestampUtcMs,\n ) as TDocument;\n return newDocument;\n}\n\n/**\n * The base document reducer function that wraps a custom reducer function.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param wrappedReducer The custom reducer function being wrapped by the base reducer.\n * @returns The updated document state.\n */\nfunction _baseReducer<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n wrappedReducer: StateReducer<TState>,\n): PHDocument<TState> {\n // throws if action is not valid base action\n const parsedAction = DocumentActionSchema().parse(action);\n\n switch (parsedAction.type) {\n // TODO: This needs to be changed to a HEADER scope action if it's changing the header.\n case \"SET_NAME\":\n return setNameOperation(document, parsedAction.input);\n case \"SET_PREFERRED_EDITOR\":\n return setPreferredEditorOperation(document, parsedAction.input);\n case \"PRUNE\":\n return pruneOperation(document, parsedAction.input, wrappedReducer);\n case \"LOAD_STATE\":\n return loadStateOperation(document, parsedAction.input);\n default:\n return document;\n }\n}\n\n/**\n * Processes an UNDO or REDO action.\n *\n * @param document The current state of the document.\n * @param action The action being applied to the document.\n * @param skip The number of operations to skip before applying the action.\n * @returns The updated document, calculated skip value and transformed action (if applied).\n */\nexport function processUndoRedo<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n skip: number,\n protocolVersion = 1,\n): {\n document: PHDocument<TState>;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n switch (action.type) {\n case \"UNDO\":\n if (protocolVersion >= 2) {\n return undoOperationV2(document, action, skip);\n }\n return undoOperation(document, action, skip);\n case \"REDO\":\n return redoOperation(document, action, skip);\n default:\n return { document, action, skip, reuseLastOperationIndex: false };\n }\n}\n\nfunction processSkipOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n customReducer: StateReducer<TState>,\n skipValue: number,\n reuseOperationResultingState = false,\n resultingStateParser = parseResultingState,\n): PHDocument<TState> {\n const scope = action.scope;\n\n const scopeOperations = document.operations[scope];\n if (!scopeOperations) {\n return document;\n }\n\n const latestOperation = scopeOperations.at(-1);\n\n if (!latestOperation) return document;\n\n const documentOperations = garbageCollectDocumentOperations({\n ...document.operations,\n [scope]: skipHeaderOperations(scopeOperations, latestOperation),\n });\n\n let scopeState: unknown = undefined;\n const documentScopeOps = documentOperations[scope];\n const lastRemainingOperation = documentScopeOps?.at(-1);\n\n // if the last operation has the resulting state and\n // reuseOperationResultingState is true then reuses it\n // instead of replaying the operations from the beginning\n if (reuseOperationResultingState && lastRemainingOperation?.resultingState) {\n scopeState = resultingStateParser(lastRemainingOperation.resultingState);\n } else {\n const { state } = replayOperations(\n document.initialState,\n documentOperations,\n customReducer,\n document.header,\n undefined,\n undefined,\n undefined,\n {\n reuseOperationResultingState,\n operationResultingStateParser: resultingStateParser,\n skipIndexValidation: true,\n },\n );\n\n scopeState = (state as Record<string, unknown>)[scope];\n }\n\n return {\n ...document,\n state: {\n ...document.state,\n [scope]: scopeState,\n },\n operations: garbageCollectDocumentOperations({\n ...document.operations,\n }),\n };\n}\n\nfunction processUndoOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n scope: string,\n customReducer: StateReducer<TState>,\n reuseOperationResultingState = false,\n resultingStateParser = parseResultingState,\n): PHDocument<TState> {\n const scopeOperations = document.operations[scope];\n if (!scopeOperations) {\n return document;\n }\n const operations = [...scopeOperations];\n const sortedOperations = sortOperations(operations);\n\n sortedOperations.pop();\n\n const documentOperations = garbageCollectDocumentOperations({\n ...document.operations,\n });\n\n const documentScopeOps = documentOperations[scope];\n if (!documentScopeOps) {\n return document;\n }\n const clearedOperations = [...documentScopeOps];\n const diff = diffOperations(\n garbageCollect(sortedOperations),\n clearedOperations,\n );\n\n const doc = replayOperations(\n document.initialState,\n documentOperations,\n customReducer,\n document.header,\n undefined,\n undefined,\n undefined,\n {\n reuseOperationResultingState,\n operationResultingStateParser: resultingStateParser,\n },\n );\n\n const clipboard = sortOperations(\n [...document.clipboard, ...diff].filter((op) => op.action.type !== \"NOOP\"),\n ).reverse();\n\n return { ...doc, clipboard } as PHDocument<TState>;\n}\n\n/**\n * Base document reducer that wraps a custom document reducer and handles\n * document-level actions such as undo, redo, prune, and set name.\n *\n * @template TGlobalState - The type of the state of the custom reducer.\n * @template TAction - The type of the actions of the custom reducer.\n * @param state - The current state of the document.\n * @param action - The action object to apply to the state.\n * @param customReducer - The custom reducer that implements the application logic\n * specific to the document's state.\n * @returns The new state of the document.\n */\nexport function baseReducer<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n customReducer: StateReducer<TState>,\n dispatch?: SignalDispatch,\n options: ReducerOptions = {},\n): PHDocument<TState> {\n const {\n skip,\n ignoreSkipOperations = false,\n reuseOperationResultingState = false,\n operationResultingStateParser,\n pruneOnSkip = true,\n branch = \"main\",\n } = options;\n\n let _action: Action = actionFromAction(action);\n\n // UNDO/REDO/PRUNE are rejected on the auth scope (PRUNE is hardcoded to the\n // global scope, so an auth PRUNE would otherwise corrupt global history).\n assertAuthScopeActionAllowed(_action);\n\n let skipValue = skip ?? options.replayOptions?.operation.skip ?? 0;\n let newDocument = {\n ...document,\n };\n let reuseLastOperationIndex = false;\n\n const shouldProcessSkipOperation = !ignoreSkipOperations && skipValue > 0;\n\n if (isUndoRedo(_action)) {\n const {\n skip: calculatedSkip,\n action: transformedAction,\n document: processedDocument,\n reuseLastOperationIndex: reuseIndex,\n } = processUndoRedo(\n document,\n _action,\n skipValue,\n options.protocolVersion ?? baseReducerVersion(document.header),\n );\n\n _action = transformedAction;\n skipValue = calculatedSkip;\n newDocument = processedDocument;\n reuseLastOperationIndex = reuseIndex;\n } else {\n newDocument = {\n ...newDocument,\n clipboard: [],\n };\n }\n\n // if the action is one the base document actions (SET_NAME, UNDO, REDO, PRUNE)\n // then runs the base reducer first\n if (isDocumentAction(_action)) {\n newDocument = _baseReducer(newDocument, _action, customReducer);\n }\n\n // updates the document revision number, last modified date\n // and operation history\n const operationContext = {\n documentId: document.header.id,\n scope: _action.scope,\n branch,\n } as OperationContext;\n\n newDocument = updateDocument(\n newDocument,\n _action,\n reuseLastOperationIndex,\n skipValue,\n operationContext,\n options.replayOptions?.operation,\n options.skipIndexValidation,\n );\n\n // Only process undo for actual UNDO actions in protocol v1\n // For v2, NOOPs always have skip=1 and indices increment\n // NOOP operations with skip > 0 will have their clipboard populated server-side\n const protocolVersion =\n options.protocolVersion ?? baseReducerVersion(document.header);\n if (isUndo(action) && protocolVersion < 2) {\n const result = processUndoOperation(\n newDocument,\n action.scope,\n customReducer,\n );\n return result;\n }\n\n // V2 UNDO: Rebuild state using garbageCollectV2 which handles consecutive NOOPs as chains\n // Also trigger for NOOP operations loaded from sync (they have skip > 0)\n const isNoopWithSkip = _action.type === \"NOOP\" && skipValue > 0;\n if ((isUndo(action) || isNoopWithSkip) && protocolVersion >= 2) {\n const scope = _action.scope;\n const scopeOperations = newDocument.operations[scope] || [];\n const sortedOps = sortOperations([...scopeOperations]);\n\n // Get operations that should be applied (excludes undone operations)\n const effectiveOps = garbageCollectV2(sortedOps) as Operation[];\n\n // Build operations for replay - only include non-NOOP operations\n const opsToReplay = effectiveOps.filter(\n (op: Operation) => op.action.type !== \"NOOP\",\n );\n\n // Create document operations with only the effective ops for this scope\n const replayOps: DocumentOperations = {\n ...newDocument.operations,\n [scope]: opsToReplay,\n };\n\n // Replay to rebuild state using replayOperations which wraps the reducer\n // Pass skipIndexValidation since garbageCollectV2 creates gapped indices\n const rebuiltDoc = replayOperations(\n newDocument.initialState,\n replayOps,\n customReducer,\n newDocument.header,\n dispatch,\n baseReducer,\n {},\n { skipIndexValidation: true },\n );\n\n // Return document with rebuilt state but original operations (including all NOOPs)\n return {\n ...rebuiltDoc,\n operations: newDocument.operations,\n clipboard: [],\n } as PHDocument<TState>;\n }\n\n if (shouldProcessSkipOperation) {\n const processed = processSkipOperation(\n newDocument,\n _action,\n customReducer,\n skipValue,\n reuseOperationResultingState,\n operationResultingStateParser,\n );\n\n // Preserve operations when pruneOnSkip is false\n if (!pruneOnSkip) {\n newDocument = {\n ...processed,\n operations: newDocument.operations,\n };\n } else {\n newDocument = processed;\n }\n }\n\n // wraps the custom reducer with Mutative to avoid\n // mutation bugs and allow writing reducers with\n // mutating code\n newDocument = create(newDocument, (draft) => {\n // the reducer runs on a immutable version of\n // provided state\n try {\n // auth scope actions have a specialized handler, but we need to catch failures\n // on load (not mutate) to log them\n if (_action.scope === \"auth\") {\n const authState = applyAuthAction(newDocument, _action).state;\n unsafe(() => {\n draft.state = castDraft(authState);\n });\n return;\n }\n const newState = customReducer(draft.state, _action, dispatch);\n\n // const clipboardValue = isUndoRedo(action) ? [...clipboard] : [];\n\n // if the reducer creates a new state object instead\n // of mutating the draft then returns the new state\n if (newState) {\n // Object.assign(draft.state, newState);\n unsafe(() => {\n // casts new state as draft to comply with typescript\n draft.state = castDraft(newState);\n // clipboard: [...clipboardValue],\n });\n } else {\n // unsafe(() => {\n // draft.clipboard = castDraft([...clipboardValue]);\n // });\n }\n } catch (error) {\n // if the reducer throws an error then we should keep the previous state (before replayOperations)\n // and remove skip number from action/operation\n const actionScopeOps = newDocument.operations[_action.scope];\n if (!actionScopeOps) {\n throw new Error(`No operations found for scope: ${_action.scope}`, {\n cause: error,\n });\n }\n const lastOperationIndex = actionScopeOps.length - 1;\n const draftScopeOps = draft.operations[_action.scope];\n if (!draftScopeOps) {\n throw new Error(\n `No operations found in draft for scope: ${_action.scope}`,\n { cause: error },\n );\n }\n draftScopeOps[lastOperationIndex].error = (error as Error).message;\n\n draftScopeOps[lastOperationIndex].skip = 0;\n\n if (shouldProcessSkipOperation) {\n draft.state = castDraft({\n ...document.state,\n });\n const documentScopeOps = document.operations[_action.scope];\n if (!documentScopeOps) {\n throw new Error(`No operations found for scope: ${_action.scope}`, {\n cause: error,\n });\n }\n draft.operations = castDraft({\n ...document.operations,\n [_action.scope]: [\n ...documentScopeOps,\n {\n ...draftScopeOps[lastOperationIndex],\n },\n ],\n });\n }\n }\n });\n // updates the document history\n // meta operations are not added to the operations history\n if ([\"UNDO\", \"REDO\", \"PRUNE\"].includes(_action.type)) {\n return newDocument;\n }\n\n // if the replayed operation carries a hash then it is reused instead of\n // generating one, which also skips hashing the whole scope state\n const scope = _action.scope || \"global\";\n const replayHash = options.replayOptions?.operation.hash;\n const hash = replayHash\n ? replayHash\n : hashDocumentStateForScope(newDocument, scope);\n\n // updates the last operation with the hash of the resulting state\n const scopeOperations = newDocument.operations[scope];\n const lastOperation = scopeOperations?.at(-1);\n if (lastOperation) {\n lastOperation.hash = hash;\n\n if (reuseOperationResultingState) {\n lastOperation.resultingState = JSON.stringify(\n (newDocument.state as Record<string, unknown>)[scope],\n );\n }\n }\n\n return newDocument;\n}\n\n/**\n * Helper function to create a document model reducer.\n *\n * @remarks\n * This function creates a new reducer that wraps the provided `reducer` with\n * `documentReducer`, adding support for document actions:\n * - `SET_NAME`\n * - `UNDO`\n * - `REDO`\n * - `PRUNE`\n *\n * It also updates the document-related attributes on every operation.\n *\n * @param reducer - The custom reducer to wrap.\n * @param documentReducer - The document reducer to use.\n *\n * @returns The new reducer.\n */\nexport function createReducer<TState extends PHBaseState = PHBaseState>(\n stateReducer: StateReducer<TState>,\n documentReducer = baseReducer,\n): Reducer<TState> {\n const reducer: Reducer<TState> = (\n document: PHDocument<TState>,\n action: Action,\n dispatch?: SignalDispatch,\n options?: ReducerOptions,\n ) => {\n return documentReducer(document, action, stateReducer, dispatch, options);\n };\n return reducer;\n}\n\nexport function pruneOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n input: PruneActionInput,\n wrappedReducer: StateReducer<TState>,\n): PHDocument<TState> {\n const operations = document.operations.global;\n if (!operations) {\n throw new Error(\"No global operations found\");\n }\n\n let { start, end } = input;\n start = start || 0;\n end = end || operations.length;\n\n const actionsToPrune = operations.slice(start, end);\n const actionsToKeepStart = operations.slice(0, start);\n const actionsToKeepEnd = operations.slice(end);\n\n // runs all operations from the initial state to\n // the end of prune to get name and data\n const newDocument = replayOperations(\n document.initialState,\n {\n ...document.operations,\n global: actionsToKeepStart.concat(actionsToPrune),\n },\n wrappedReducer,\n document.header,\n );\n\n const newState = newDocument.state;\n const name = newDocument.header.name;\n\n // the new operation has the index of the first pruned operation\n const loadStateIndex = actionsToKeepStart.length;\n\n // if and operation is pruned then reuses the timestamp of the last operation\n // if not then assigns the timestamp of the following unpruned operation\n const loadStateTimestamp = actionsToKeepStart.length\n ? actionsToKeepStart[actionsToKeepStart.length - 1].timestampUtcMs\n : actionsToKeepEnd.length\n ? actionsToKeepEnd[0].timestampUtcMs\n : new Date().toISOString();\n\n const action = loadState({ name, ...newState }, actionsToPrune.length);\n\n // replaces pruned operations with LOAD_STATE\n return replayOperations(\n document.initialState,\n {\n ...document.operations,\n global: [\n ...actionsToKeepStart,\n {\n skip: 0,\n ...action,\n action,\n timestampUtcMs: loadStateTimestamp,\n index: loadStateIndex,\n hash: hashDocumentStateForScope({ state: newState }, \"global\"),\n },\n ...actionsToKeepEnd\n // updates the index for all the following operations\n .map((action, index) => ({\n ...action,\n index: loadStateIndex + index + 1,\n })),\n ],\n },\n wrappedReducer,\n document.header,\n );\n}\n","import { constantCase, pascalCase } from \"change-case\";\nimport type { DocumentOperations } from \"./operations.js\";\nimport type {\n CodeExample,\n DocumentModelGlobalState,\n ModuleSpecification,\n OperationErrorSpecification,\n OperationSpecification,\n ValidationError,\n} from \"./types.js\";\n\n/**\n * Reserved operation names from base reducer (core/actions.ts).\n * These names cannot be used for custom operations.\n */\nexport const RESERVED_OPERATION_NAMES = [\n \"UNDO\",\n \"REDO\",\n \"PRUNE\",\n \"LOAD_STATE\",\n \"SET_NAME\",\n \"SET_PREFERRED_EDITOR\",\n \"NOOP\",\n] as const;\n\nexport type ReservedOperationName = (typeof RESERVED_OPERATION_NAMES)[number];\n\n/**\n * Operation names become the literal action `type` string at runtime and the\n * key for codegen's action union. They must be SCREAMING_SNAKE_CASE so the\n * generated TypeScript is valid.\n */\nexport const OPERATION_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;\n\nexport function isValidOperationNameFormat(name: string): boolean {\n return OPERATION_NAME_PATTERN.test(name);\n}\n\n/**\n * Check if name conflicts with base reducer actions (case-insensitive).\n */\nexport function isReservedOperationName(name: string): boolean {\n return RESERVED_OPERATION_NAMES.includes(\n name.toUpperCase() as ReservedOperationName,\n );\n}\n\n/**\n * Get all operation names from all modules in the latest specification.\n * Returns names in uppercase for case-insensitive comparison.\n */\nexport function getAllOperationNames(\n state: DocumentModelGlobalState,\n excludeOperationId?: string,\n): string[] {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!latestSpec) return [];\n\n const names: string[] = [];\n for (const module of latestSpec.modules) {\n for (const operation of module.operations) {\n if (excludeOperationId && operation.id === excludeOperationId) continue;\n if (operation.name) names.push(operation.name.toUpperCase());\n }\n }\n return names;\n}\n\n/**\n * Validate operation name is not reserved or duplicate. Throws on failure.\n *\n * @param name - The operation name to validate\n * @param state - The document model global state\n * @param excludeOperationId - Optional operation ID to exclude (for rename validation)\n * @throws Error if the name is reserved or a duplicate\n */\nexport function validateOperationName(\n name: string,\n state: DocumentModelGlobalState,\n excludeOperationId?: string,\n): void {\n if (!name) return; // Empty names handled by existing validation\n\n if (!isValidOperationNameFormat(name)) {\n const suggestion = constantCase(name);\n const hint =\n suggestion &&\n suggestion !== name &&\n isValidOperationNameFormat(suggestion)\n ? ` Did you mean \"${suggestion}\"?`\n : \"\";\n throw new Error(\n `Operation name \"${name}\" is invalid. Names must be SCREAMING_SNAKE_CASE (matching ${OPERATION_NAME_PATTERN.source}).${hint}`,\n );\n }\n\n const upperName = name.toUpperCase();\n\n if (isReservedOperationName(name)) {\n throw new Error(\n `Operation name \"${name}\" is reserved. Please use a different name.`,\n );\n }\n\n const existingNames = getAllOperationNames(state, excludeOperationId);\n if (existingNames.includes(upperName)) {\n throw new Error(\n `Operation name \"${name}\" is already used by another operation. Operation names must be unique across all modules.`,\n );\n }\n}\n\nexport function validateInitialState(\n initialState: string,\n allowEmptyState = false,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (allowEmptyState && initialState === \"\") return errors;\n\n try {\n const state = JSON.parse(initialState) as object;\n\n if (!allowEmptyState && !Object.keys(state).length) {\n errors.push({\n message: \"Initial state cannot be empty\",\n details: {\n initialState,\n },\n });\n }\n } catch {\n errors.push({\n message: \"Invalid initial state\",\n details: {\n initialState,\n },\n });\n }\n\n return errors;\n}\n\nexport function validateStateSchemaName(\n schema: string,\n documentName: string,\n scope = \"\",\n allowEmptySchema = true,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!allowEmptySchema && !schema) {\n errors.push({\n message: \"State schema is required\",\n details: {\n schema,\n },\n });\n\n return errors;\n }\n\n if (allowEmptySchema && !schema) return errors;\n\n const expectedTypeName = `${pascalCase(documentName)}${pascalCase(scope)}State`;\n\n // Use regex to match exact type name definition\n // Pattern matches: type TypeName followed by whitespace, {, @, or end of string\n // This ensures we match \"type TodoState\" but NOT \"type TodoState2\"\n const typePattern = new RegExp(\n `\\\\btype\\\\s+${expectedTypeName}(?:\\\\s|\\\\{|@|$)`,\n );\n\n if (!typePattern.test(schema)) {\n errors.push({\n message: `Invalid state schema name. Expected type ${expectedTypeName}`,\n details: {\n schema,\n },\n });\n }\n\n return errors;\n}\n\nexport function validateModules(\n modules: ModuleSpecification[],\n): ValidationError[] {\n const errors: ValidationError[] = [];\n if (!modules.length) {\n errors.push({\n message: \"Modules are required\",\n details: {\n modules,\n },\n });\n }\n\n const modulesError = modules.reduce<ValidationError[]>(\n (acc, mod) => [...acc, ...validateModule(mod)],\n [],\n );\n\n return [...errors, ...modulesError];\n}\n\nexport function validateModule(mod: ModuleSpecification): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!mod.name) {\n errors.push({\n message: \"Module name is required\",\n details: {\n module: mod,\n },\n });\n }\n\n if (!mod.operations.length) {\n errors.push({\n message: \"Module operations are required\",\n details: {\n module: mod,\n },\n });\n }\n\n const operationErrors = mod.operations.reduce<ValidationError[]>(\n (acc, operation) => [...acc, ...validateModuleOperation(operation)],\n [],\n );\n\n return [...errors, ...operationErrors];\n}\n\nexport function validateModuleOperation(\n operation: OperationSpecification,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!operation.name) {\n errors.push({\n message: \"Operation name is required\",\n details: {\n operation,\n },\n });\n }\n\n if (!operation.schema) {\n errors.push({\n message: \"Operation schema is required\",\n details: {\n operation,\n },\n });\n }\n\n return errors;\n}\n\n/**\n * Find a module in the latest specification by id, or throw. Reducers that\n * mutate-by-id should call this up front so an unknown id fails loudly\n * instead of silently no-opping.\n */\nexport function findModuleOrThrow(\n state: DocumentModelGlobalState,\n moduleId: string,\n): ModuleSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const mod = latestSpec?.modules.find((m) => m.id === moduleId);\n if (!mod) {\n throw new Error(\n `Module \"${moduleId}\" not found in the latest specification`,\n );\n }\n return mod;\n}\n\n/**\n * Find an operation in the latest specification by id, or throw. Same\n * rationale as findModuleOrThrow — reducers that target an operation must\n * fail loudly when the operation doesn't exist.\n */\nexport function findOperationOrThrow(\n state: DocumentModelGlobalState,\n operationId: string,\n): OperationSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (latestSpec) {\n for (const mod of latestSpec.modules) {\n const op = mod.operations.find((o) => o.id === operationId);\n if (op) return op;\n }\n }\n throw new Error(\n `Operation \"${operationId}\" not found in the latest specification`,\n );\n}\n\n/**\n * Find an operation error by id across all operations in the latest\n * specification, or throw. Throws on a duplicate id too: setters act on a\n * single error, so an ambiguous id must fail loudly rather than mutate an\n * arbitrary match.\n */\nexport function findOperationErrorOrThrow(\n state: DocumentModelGlobalState,\n errorId: string,\n): OperationErrorSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const matches =\n latestSpec?.modules.flatMap((mod) =>\n mod.operations.flatMap((op) => op.errors.filter((e) => e.id === errorId)),\n ) ?? [];\n if (matches.length === 0) {\n throw new Error(\n `Operation error \"${errorId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation error \"${errorId}\" is duplicated in the latest specification`,\n );\n }\n return matches[0];\n}\n\n/**\n * Find an operation example (code example) by id across all operations in the\n * latest specification, or throw. Throws on a duplicate id for the same reason\n * as findOperationErrorOrThrow.\n */\nexport function findOperationExampleOrThrow(\n state: DocumentModelGlobalState,\n exampleId: string,\n): CodeExample {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const matches =\n latestSpec?.modules.flatMap((mod) =>\n mod.operations.flatMap((op) =>\n op.examples.filter((e) => e.id === exampleId),\n ),\n ) ?? [];\n if (matches.length === 0) {\n throw new Error(\n `Operation example \"${exampleId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation example \"${exampleId}\" is duplicated in the latest specification`,\n );\n }\n return matches[0];\n}\n\n/**\n * Assert no module in the latest specification already uses `id`. Modules are\n * targeted by id by the setter/delete/reorder reducers, so a duplicate id makes\n * those operations ambiguous.\n */\nexport function assertModuleIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (latestSpec?.modules.some((m) => m.id === id)) {\n throw new Error(\n `Module \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation in the latest specification already uses `id`. Operations\n * are targeted by id across all modules, so the id must be unique document-wide.\n */\nexport function assertOperationIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.id === id),\n );\n if (exists) {\n throw new Error(\n `Operation \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation error in the latest specification already uses `id`.\n * Error ids are targeted document-wide by the setter/delete reducers, so the id\n * must be unique to keep those operations unambiguous.\n */\nexport function assertOperationErrorIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.errors.some((e) => e.id === id)),\n );\n if (exists) {\n throw new Error(\n `Operation error \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation example in the latest specification already uses `id`.\n * Example ids are targeted document-wide by the update/delete reducers, so the\n * id must be unique to keep those operations unambiguous.\n */\nexport function assertOperationExampleIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.examples.some((e) => e.id === id)),\n );\n if (exists) {\n throw new Error(\n `Operation example \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\nexport function validateOperations(operations: DocumentOperations) {\n const errors: ValidationError[] = [];\n const scopes = Object.keys(operations);\n\n for (const scope of scopes) {\n const scopeOperations = operations[scope];\n if (!scopeOperations) {\n continue;\n }\n const ops = scopeOperations.sort((a, b) => a.index - b.index);\n\n let opIndex = -1;\n\n for (let i = 0; i < ops.length; i++) {\n opIndex = opIndex + 1 + ops[i].skip;\n if (ops[i].index !== opIndex) {\n errors.push({\n message: `Invalid operation index ${ops[i].index} at position ${i}`,\n details: {\n position: i,\n operation: ops[i],\n scope: ops[i].action.scope,\n },\n });\n }\n }\n }\n\n return errors;\n}\n","import { isDocumentAction } from \"./documents.js\";\nimport { createReducer } from \"./reducer.js\";\nimport {\n AddChangeLogItemInputSchema,\n AddModuleInputSchema,\n AddOperationErrorInputSchema,\n AddOperationExampleInputSchema,\n AddOperationInputSchema,\n AddStateExampleInputSchema,\n DeleteChangeLogItemInputSchema,\n DeleteModuleInputSchema,\n DeleteOperationErrorInputSchema,\n DeleteOperationExampleInputSchema,\n DeleteOperationInputSchema,\n DeleteStateExampleInputSchema,\n MoveOperationInputSchema,\n ReorderChangeLogItemsInputSchema,\n ReorderModuleOperationsInputSchema,\n ReorderModulesInputSchema,\n ReorderOperationErrorsInputSchema,\n ReorderOperationExamplesInputSchema,\n ReorderStateExamplesInputSchema,\n SetAuthorNameInputSchema,\n SetAuthorWebsiteInputSchema,\n SetInitialStateInputSchema,\n SetModelDescriptionInputSchema,\n SetModelExtensionInputSchema,\n SetModelIdInputSchema,\n SetModelNameInputSchema,\n SetModuleDescriptionInputSchema,\n SetModuleNameInputSchema,\n SetOperationDescriptionInputSchema,\n SetOperationErrorCodeInputSchema,\n SetOperationErrorDescriptionInputSchema,\n SetOperationErrorNameInputSchema,\n SetOperationErrorTemplateInputSchema,\n SetOperationNameInputSchema,\n SetOperationReducerInputSchema,\n SetOperationSchemaInputSchema,\n SetOperationScopeInputSchema,\n SetOperationTemplateInputSchema,\n SetStateSchemaInputSchema,\n UpdateChangeLogItemInputSchema,\n UpdateOperationExampleInputSchema,\n UpdateStateExampleInputSchema,\n} from \"./schemas.js\";\nimport type {\n AddChangeLogItemAction,\n AddModuleAction,\n AddOperationAction,\n AddOperationErrorAction,\n AddOperationExampleAction,\n AddStateExampleAction,\n DeleteChangeLogItemAction,\n DeleteModuleAction,\n DeleteOperationAction,\n DeleteOperationErrorAction,\n DeleteOperationExampleAction,\n DeleteStateExampleAction,\n DocumentModelHeaderOperations,\n DocumentModelModuleOperations,\n DocumentModelOperationErrorOperations,\n DocumentModelOperationExampleOperations,\n DocumentModelOperationOperations,\n DocumentModelPHState,\n DocumentModelStateOperations,\n DocumentModelVersioningOperations,\n MoveOperationAction,\n OperationSpecification,\n ReleaseNewVersionAction,\n ReorderChangeLogItemsAction,\n ReorderModuleOperationsAction,\n ReorderModulesAction,\n ReorderOperationErrorsAction,\n ReorderOperationExamplesAction,\n ReorderStateExamplesAction,\n ScopeState,\n SetAuthorNameAction,\n SetAuthorWebsiteAction,\n SetInitialStateAction,\n SetModelDescriptionAction,\n SetModelExtensionAction,\n SetModelIdAction,\n SetModelNameAction,\n SetModuleDescriptionAction,\n SetModuleNameAction,\n SetOperationDescriptionAction,\n SetOperationErrorCodeAction,\n SetOperationErrorDescriptionAction,\n SetOperationErrorNameAction,\n SetOperationErrorTemplateAction,\n SetOperationNameAction,\n SetOperationReducerAction,\n SetOperationSchemaAction,\n SetOperationScopeAction,\n SetOperationTemplateAction,\n SetStateSchemaAction,\n StateReducer,\n UpdateChangeLogItemAction,\n UpdateOperationExampleAction,\n UpdateStateExampleAction,\n} from \"./types.js\";\nimport {\n assertModuleIdUnique,\n assertOperationErrorIdUnique,\n assertOperationExampleIdUnique,\n assertOperationIdUnique,\n findModuleOrThrow,\n findOperationErrorOrThrow,\n findOperationExampleOrThrow,\n findOperationOrThrow,\n validateOperationName,\n} from \"./validation.js\";\n\n/**\n * Reorder `items` by the position of their id in `order`. Ids not listed in\n * `order` keep their relative position after the listed ones. Throws if `order`\n * references an id that isn't present, so a stale or mistyped id fails loudly\n * instead of silently producing an arbitrary order.\n */\nfunction orderBy<TItem extends { id: string }>(\n items: TItem[],\n order: string[],\n): TItem[] {\n const ids = new Set(items.map((item) => item.id));\n for (const id of order) {\n if (!ids.has(id)) {\n throw new Error(`Cannot reorder: unknown id \"${id}\"`);\n }\n }\n const rank = new Map(order.map((id, index) => [id, index]));\n return items\n .map((item, index) => ({ item, index }))\n .sort((a, b) => {\n const ra = rank.get(a.item.id) ?? Number.MAX_SAFE_INTEGER;\n const rb = rank.get(b.item.id) ?? Number.MAX_SAFE_INTEGER;\n return ra - rb || a.index - b.index;\n })\n .map(({ item }) => item);\n}\n\nexport const documentModelHeaderReducer: DocumentModelHeaderOperations = {\n setModelNameOperation(state, action) {\n state.name = action.input.name;\n },\n\n setModelIdOperation(state, action) {\n state.id = action.input.id;\n },\n\n setModelExtensionOperation(state, action) {\n state.extension = action.input.extension;\n },\n\n setModelDescriptionOperation(state, action) {\n state.description = action.input.description;\n },\n\n setAuthorNameOperation(state, action) {\n state.author = state.author || { name: \"\", website: null };\n state.author.name = action.input.authorName;\n },\n\n setAuthorWebsiteOperation(state, action) {\n state.author = state.author || { name: \"\", website: null };\n state.author.website = action.input.authorWebsite;\n },\n};\nexport const documentModelModuleReducer: DocumentModelModuleOperations = {\n addModuleOperation(state, action) {\n assertModuleIdUnique(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || \"\",\n operations: [],\n });\n },\n\n setModuleNameOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.id);\n targetModule.name = action.input.name || \"\";\n },\n\n setModuleDescriptionOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.id);\n targetModule.description = action.input.description || \"\";\n },\n\n deleteModuleOperation(state, action) {\n findModuleOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules = latestSpec.modules.filter(\n (m) => m.id != action.input.id,\n );\n },\n\n reorderModulesOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules = orderBy(latestSpec.modules, action.input.order);\n },\n};\nexport const documentModelOperationErrorReducer: DocumentModelOperationErrorOperations =\n {\n addOperationErrorOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n assertOperationErrorIdUnique(state, action.input.id);\n targetOp.errors.push({\n id: action.input.id,\n name: action.input.errorName || \"\",\n code: action.input.errorCode || \"\",\n description: action.input.errorDescription || \"\",\n template: action.input.errorTemplate || \"\",\n });\n },\n\n setOperationErrorCodeOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.code = action.input.errorCode || \"\";\n },\n\n setOperationErrorNameOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.name = action.input.errorName || \"\";\n },\n\n setOperationErrorDescriptionOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.description = action.input.errorDescription || \"\";\n },\n\n setOperationErrorTemplateOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.template = action.input.errorTemplate || \"\";\n },\n\n deleteOperationErrorOperation(state, action) {\n // Tolerate duplicate ids here: the filter removes every copy, so delete\n // is the recovery path for a document that already holds duplicates.\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec.modules.some((mod) =>\n mod.operations.some((op) =>\n op.errors.some((e) => e.id === action.input.id),\n ),\n );\n if (!exists) {\n throw new Error(\n `Operation error \"${action.input.id}\" not found in the latest specification`,\n );\n }\n for (const mod of latestSpec.modules) {\n for (const op of mod.operations) {\n op.errors = op.errors.filter((e) => e.id != action.input.id);\n }\n }\n },\n\n reorderOperationErrorsOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n targetOp.errors = orderBy(targetOp.errors, action.input.order);\n },\n };\n\nexport const documentModelOperationExampleReducer: DocumentModelOperationExampleOperations =\n {\n addOperationExampleOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n assertOperationExampleIdUnique(state, action.input.id);\n targetOp.examples.push({\n id: action.input.id,\n value: action.input.example,\n });\n },\n\n updateOperationExampleOperation(state, action) {\n const example = findOperationExampleOrThrow(state, action.input.id);\n example.value = action.input.example;\n },\n\n deleteOperationExampleOperation(state, action) {\n // Tolerate duplicate ids here: the filter removes every copy, so delete\n // is the recovery path for a document that already holds duplicates.\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec.modules.some((mod) =>\n mod.operations.some((op) =>\n op.examples.some((e) => e.id === action.input.id),\n ),\n );\n if (!exists) {\n throw new Error(\n `Operation example \"${action.input.id}\" not found in the latest specification`,\n );\n }\n for (const mod of latestSpec.modules) {\n for (const op of mod.operations) {\n op.examples = op.examples.filter((e) => e.id != action.input.id);\n }\n }\n },\n\n reorderOperationExamplesOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n targetOp.examples = orderBy(targetOp.examples, action.input.order);\n },\n };\nexport const documentModelOperationReducer: DocumentModelOperationOperations = {\n addOperationOperation(state, action) {\n validateOperationName(action.input.name, state);\n assertOperationIdUnique(state, action.input.id);\n const targetModule = findModuleOrThrow(state, action.input.moduleId);\n targetModule.operations.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || \"\",\n schema: action.input.schema || \"\",\n template: action.input.template || action.input.description || \"\",\n reducer: action.input.reducer || \"\",\n errors: [],\n examples: [],\n scope: action.input.scope || \"global\",\n });\n },\n\n setOperationNameOperation(state, action) {\n if (action.input.name) {\n validateOperationName(action.input.name, state, action.input.id);\n }\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.name = action.input.name || \"\";\n },\n\n setOperationScopeOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n const allowedScopes = Object.keys(latestSpec.state);\n if (action.input.scope && !allowedScopes.includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n targetOp.scope = action.input.scope || \"global\";\n },\n\n setOperationSchemaOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.schema = action.input.schema || \"\";\n },\n\n setOperationDescriptionOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.description = action.input.description || \"\";\n },\n\n setOperationTemplateOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.template = action.input.template || \"\";\n },\n\n setOperationReducerOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.reducer = action.input.reducer || \"\";\n },\n\n moveOperationOperation(state, action) {\n // Validate fully before mutating: resolve the destination module and the\n // operation to move first, so a missing/ambiguous target aborts the move\n // without having already removed the operation from its source module.\n const targetModule = findModuleOrThrow(state, action.input.newModuleId);\n const latestSpec = state.specifications[state.specifications.length - 1];\n\n const matches = latestSpec.modules.flatMap((mod) =>\n mod.operations.filter((op) => op.id === action.input.operationId),\n );\n if (matches.length === 0) {\n throw new Error(\n `Operation \"${action.input.operationId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation \"${action.input.operationId}\" is duplicated in the latest specification`,\n );\n }\n const moved = matches[0];\n\n for (const mod of latestSpec.modules) {\n mod.operations = mod.operations.filter(\n (op) => op.id !== action.input.operationId,\n );\n }\n targetModule.operations.push(moved);\n },\n\n deleteOperationOperation(state, action) {\n findOperationOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n for (const mod of latestSpec.modules) {\n mod.operations = mod.operations.filter(\n (operation) => operation.id != action.input.id,\n );\n }\n },\n\n reorderModuleOperationsOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.moduleId);\n targetModule.operations = orderBy(\n targetModule.operations,\n action.input.order,\n );\n },\n};\nexport const documentModelStateSchemaReducer: DocumentModelStateOperations = {\n setStateSchemaOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].schema =\n action.input.schema;\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n setInitialStateOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].initialValue =\n action.input.initialValue;\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n addStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].examples.push({\n id: action.input.id,\n value: action.input.example,\n });\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n updateStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const examples =\n latestSpec.state[action.input.scope as keyof ScopeState].examples;\n\n const example = examples.find((e) => e.id == action.input.id);\n if (!example) {\n throw new Error(\n `State example \"${action.input.id}\" not found in scope \"${action.input.scope}\"`,\n );\n }\n example.value = action.input.newExample;\n },\n\n deleteStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const scopeState = latestSpec.state[action.input.scope as keyof ScopeState];\n if (!scopeState.examples.some((e) => e.id == action.input.id)) {\n throw new Error(\n `State example \"${action.input.id}\" not found in scope \"${action.input.scope}\"`,\n );\n }\n scopeState.examples = scopeState.examples.filter(\n (e) => e.id != action.input.id,\n );\n },\n\n reorderStateExamplesOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const scopeState = latestSpec.state[action.input.scope as keyof ScopeState];\n scopeState.examples = orderBy(scopeState.examples, action.input.order);\n },\n};\n\nexport const documentModelVersioningReducer: DocumentModelVersioningOperations =\n {\n addChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"addChangeLogItemOperation\" not yet implemented',\n );\n },\n\n updateChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"updateChangeLogItemOperation\" not yet implemented',\n );\n },\n\n deleteChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"deleteChangeLogItemOperation\" not yet implemented',\n );\n },\n\n reorderChangeLogItemsOperation(state, action) {\n throw new Error(\n 'Reducer \"reorderChangeLogItemsOperation\" not yet implemented',\n );\n },\n\n releaseNewVersionOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n\n const copiedModules = latestSpec.modules.map((module) => ({\n ...module,\n operations: module.operations.map((op) => ({\n ...op,\n errors: op.errors.map((err) => ({ ...err })),\n examples: op.examples.map((ex) => ({ ...ex })),\n })),\n }));\n\n const copiedState = {\n global: {\n ...latestSpec.state.global,\n examples: latestSpec.state.global.examples.map((ex) => ({ ...ex })),\n },\n local: {\n ...latestSpec.state.local,\n examples: latestSpec.state.local.examples.map((ex) => ({ ...ex })),\n },\n };\n\n const newSpec = {\n version: latestSpec.version + 1,\n changeLog: [],\n state: copiedState,\n modules: copiedModules,\n };\n\n state.specifications.push(newSpec);\n },\n };\n\nexport const documentModelStateReducer: StateReducer<DocumentModelPHState> = (\n state,\n action,\n) => {\n if (isDocumentAction(action)) {\n return state;\n }\n\n switch (action.type) {\n case \"SET_MODEL_NAME\":\n SetModelNameInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelNameOperation(\n state.global,\n action as SetModelNameAction,\n );\n break;\n\n case \"SET_MODEL_ID\":\n SetModelIdInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelIdOperation(\n state.global,\n action as SetModelIdAction,\n );\n break;\n\n case \"SET_MODEL_EXTENSION\":\n SetModelExtensionInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelExtensionOperation(\n state.global,\n action as SetModelExtensionAction,\n );\n break;\n\n case \"SET_MODEL_DESCRIPTION\":\n SetModelDescriptionInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelDescriptionOperation(\n state.global,\n action as SetModelDescriptionAction,\n );\n break;\n\n case \"SET_AUTHOR_NAME\":\n SetAuthorNameInputSchema().parse(action.input);\n documentModelHeaderReducer.setAuthorNameOperation(\n state.global,\n action as SetAuthorNameAction,\n );\n break;\n\n case \"SET_AUTHOR_WEBSITE\":\n SetAuthorWebsiteInputSchema().parse(action.input);\n documentModelHeaderReducer.setAuthorWebsiteOperation(\n state.global,\n action as SetAuthorWebsiteAction,\n );\n break;\n\n case \"ADD_CHANGE_LOG_ITEM\":\n AddChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.addChangeLogItemOperation(\n state.global,\n action as AddChangeLogItemAction,\n );\n break;\n\n case \"UPDATE_CHANGE_LOG_ITEM\":\n UpdateChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.updateChangeLogItemOperation(\n state.global,\n action as UpdateChangeLogItemAction,\n );\n break;\n\n case \"DELETE_CHANGE_LOG_ITEM\":\n DeleteChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.deleteChangeLogItemOperation(\n state.global,\n action as DeleteChangeLogItemAction,\n );\n break;\n\n case \"REORDER_CHANGE_LOG_ITEMS\":\n ReorderChangeLogItemsInputSchema().parse(action.input);\n documentModelVersioningReducer.reorderChangeLogItemsOperation(\n state.global,\n action as ReorderChangeLogItemsAction,\n );\n break;\n\n case \"RELEASE_NEW_VERSION\":\n if (Object.keys(action.input as object).length > 0)\n throw new Error(\"Expected empty input for action RELEASE_NEW_VERSION\");\n documentModelVersioningReducer.releaseNewVersionOperation(\n state.global,\n action as ReleaseNewVersionAction,\n );\n break;\n\n case \"ADD_MODULE\":\n AddModuleInputSchema().parse(action.input);\n documentModelModuleReducer.addModuleOperation(\n state.global,\n action as AddModuleAction,\n );\n break;\n\n case \"SET_MODULE_NAME\":\n SetModuleNameInputSchema().parse(action.input);\n documentModelModuleReducer.setModuleNameOperation(\n state.global,\n action as SetModuleNameAction,\n );\n break;\n\n case \"SET_MODULE_DESCRIPTION\":\n SetModuleDescriptionInputSchema().parse(action.input);\n documentModelModuleReducer.setModuleDescriptionOperation(\n state.global,\n action as SetModuleDescriptionAction,\n );\n break;\n\n case \"DELETE_MODULE\":\n DeleteModuleInputSchema().parse(action.input);\n documentModelModuleReducer.deleteModuleOperation(\n state.global,\n action as DeleteModuleAction,\n );\n break;\n\n case \"REORDER_MODULES\":\n ReorderModulesInputSchema().parse(action.input);\n documentModelModuleReducer.reorderModulesOperation(\n state.global,\n action as ReorderModulesAction,\n );\n break;\n\n case \"ADD_OPERATION_ERROR\":\n AddOperationErrorInputSchema().parse(action.input);\n documentModelOperationErrorReducer.addOperationErrorOperation(\n state.global,\n action as AddOperationErrorAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_CODE\":\n SetOperationErrorCodeInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorCodeOperation(\n state.global,\n action as SetOperationErrorCodeAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_NAME\":\n SetOperationErrorNameInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorNameOperation(\n state.global,\n action as SetOperationErrorNameAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_DESCRIPTION\":\n SetOperationErrorDescriptionInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorDescriptionOperation(\n state.global,\n action as SetOperationErrorDescriptionAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_TEMPLATE\":\n SetOperationErrorTemplateInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorTemplateOperation(\n state.global,\n action as SetOperationErrorTemplateAction,\n );\n break;\n\n case \"DELETE_OPERATION_ERROR\":\n DeleteOperationErrorInputSchema().parse(action.input);\n documentModelOperationErrorReducer.deleteOperationErrorOperation(\n state.global,\n action as DeleteOperationErrorAction,\n );\n break;\n\n case \"REORDER_OPERATION_ERRORS\":\n ReorderOperationErrorsInputSchema().parse(action.input);\n documentModelOperationErrorReducer.reorderOperationErrorsOperation(\n state.global,\n action as ReorderOperationErrorsAction,\n );\n break;\n\n case \"ADD_OPERATION_EXAMPLE\":\n AddOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.addOperationExampleOperation(\n state.global,\n action as AddOperationExampleAction,\n );\n break;\n\n case \"UPDATE_OPERATION_EXAMPLE\":\n UpdateOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.updateOperationExampleOperation(\n state.global,\n action as UpdateOperationExampleAction,\n );\n break;\n\n case \"DELETE_OPERATION_EXAMPLE\":\n DeleteOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.deleteOperationExampleOperation(\n state.global,\n action as DeleteOperationExampleAction,\n );\n break;\n\n case \"REORDER_OPERATION_EXAMPLES\":\n ReorderOperationExamplesInputSchema().parse(action.input);\n documentModelOperationExampleReducer.reorderOperationExamplesOperation(\n state.global,\n action as ReorderOperationExamplesAction,\n );\n break;\n\n case \"ADD_OPERATION\":\n AddOperationInputSchema().parse(action.input);\n documentModelOperationReducer.addOperationOperation(\n state.global,\n action as AddOperationAction,\n );\n break;\n\n case \"SET_OPERATION_NAME\":\n SetOperationNameInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationNameOperation(\n state.global,\n action as SetOperationNameAction,\n );\n break;\n\n case \"SET_OPERATION_SCOPE\":\n SetOperationScopeInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationScopeOperation(\n state.global,\n action as SetOperationScopeAction,\n );\n break;\n\n case \"SET_OPERATION_SCHEMA\":\n SetOperationSchemaInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationSchemaOperation(\n state.global,\n action as SetOperationSchemaAction,\n );\n break;\n\n case \"SET_OPERATION_DESCRIPTION\":\n SetOperationDescriptionInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationDescriptionOperation(\n state.global,\n action as SetOperationDescriptionAction,\n );\n break;\n\n case \"SET_OPERATION_TEMPLATE\":\n SetOperationTemplateInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationTemplateOperation(\n state.global,\n action as SetOperationTemplateAction,\n );\n break;\n\n case \"SET_OPERATION_REDUCER\":\n SetOperationReducerInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationReducerOperation(\n state.global,\n action as SetOperationReducerAction,\n );\n break;\n\n case \"MOVE_OPERATION\":\n MoveOperationInputSchema().parse(action.input);\n documentModelOperationReducer.moveOperationOperation(\n state.global,\n action as MoveOperationAction,\n );\n break;\n\n case \"DELETE_OPERATION\":\n DeleteOperationInputSchema().parse(action.input);\n documentModelOperationReducer.deleteOperationOperation(\n state.global,\n action as DeleteOperationAction,\n );\n break;\n\n case \"REORDER_MODULE_OPERATIONS\":\n ReorderModuleOperationsInputSchema().parse(action.input);\n documentModelOperationReducer.reorderModuleOperationsOperation(\n state.global,\n action as ReorderModuleOperationsAction,\n );\n break;\n\n case \"SET_STATE_SCHEMA\":\n SetStateSchemaInputSchema().parse(action.input);\n documentModelStateSchemaReducer.setStateSchemaOperation(\n state.global,\n action as SetStateSchemaAction,\n );\n break;\n\n case \"SET_INITIAL_STATE\":\n SetInitialStateInputSchema().parse(action.input);\n documentModelStateSchemaReducer.setInitialStateOperation(\n state.global,\n action as SetInitialStateAction,\n );\n break;\n\n case \"ADD_STATE_EXAMPLE\":\n AddStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.addStateExampleOperation(\n state.global,\n action as AddStateExampleAction,\n );\n break;\n\n case \"UPDATE_STATE_EXAMPLE\":\n UpdateStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.updateStateExampleOperation(\n state.global,\n action as UpdateStateExampleAction,\n );\n break;\n\n case \"DELETE_STATE_EXAMPLE\":\n DeleteStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.deleteStateExampleOperation(\n state.global,\n action as DeleteStateExampleAction,\n );\n break;\n\n case \"REORDER_STATE_EXAMPLES\":\n ReorderStateExamplesInputSchema().parse(action.input);\n documentModelStateSchemaReducer.reorderStateExamplesOperation(\n state.global,\n action as ReorderStateExamplesAction,\n );\n break;\n\n default:\n return state;\n }\n};\n\nexport const documentModelReducer = createReducer<DocumentModelPHState>(\n documentModelStateReducer,\n);\n","import type { Action } from \"./actions.js\";\nimport { resolveSnapshotAuth } from \"./auth.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport { DowngradeNotSupportedError } from \"./errors.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type { DeleteDocumentAction, UpgradeDocumentAction } from \"./types.js\";\n\n/** Upgrade reducer transforms a document from one version to another */\nexport type UpgradeReducer<\n TFrom extends PHBaseState,\n TTo extends PHBaseState,\n> = (document: PHDocument<TFrom>, action: Action) => PHDocument<TTo>;\ntype ModelVersion = number;\n\n/** Metadata about a version transition */\nexport type UpgradeTransition = {\n toVersion: ModelVersion;\n upgradeReducer: UpgradeReducer<any, any>;\n description?: string;\n};\n\ntype TupleMember<T extends readonly unknown[]> = T[number];\n\n/** Manifest declaring all supported versions and upgrade paths */\nexport type UpgradeManifest<TVersions extends readonly number[]> = {\n documentType: string;\n // union of all versions, e.g. 1 | 2 | 3 for [1, 2, 3]\n latestVersion: TupleMember<TVersions>;\n // the tuple itself, e.g. [1, 2, 3]\n supportedVersions: TVersions;\n // mapped over each version in the tuple\n upgrades: {\n // keys: \"v2\" | \"v3\" | ... (no \"v1\")\n [V in Exclude<TupleMember<TVersions>, 1> as `v${V}`]: UpgradeTransition;\n };\n};\n\n/**\n * Canonical document-model version normalization: documents stamped with 0\n * or nothing at all predate versioning and are treated as version 1, the\n * same version the registry assigns unversioned modules. Every consumer\n * that resolves a module or compares versions must use this rule; resolving\n * 0 to \"latest\" instead re-pins a legacy document's history to whichever\n * module happens to be newest.\n */\nexport function normalizeDocumentModelVersion(\n version: number | undefined | null,\n): number {\n return version && version > 0 ? version : 1;\n}\n\nfunction applyInitialState(\n document: PHDocument,\n action: UpgradeDocumentAction,\n): void {\n const input = action.input as {\n initialState?: PHDocument[\"state\"];\n state?: PHDocument[\"state\"];\n };\n\n const newState = input.initialState || input.state;\n if (newState) {\n // snapshots serialized before PHAuthState had a version carry auth: {}\n const merged = backfillAuthState({ ...document.state, ...newState });\n // The snapshot is authorized as a document-scope write, so it does not get\n // to install or replace a policy on its own terms.\n merged.auth = resolveSnapshotAuth(\n document.header.id,\n document.header.documentType,\n backfillAuthState({ ...document.state }).auth,\n merged.auth,\n );\n document.state = merged;\n document.initialState = document.state;\n }\n}\n\n/**\n * Applies an UPGRADE_DOCUMENT action to a document.\n * Handles all upgrade scenarios including initial upgrades, no-ops, and multi-step upgrades.\n *\n * Behavior based on fromVersion/toVersion:\n * - fromVersion === toVersion (and fromVersion > 0): No-op - return unchanged document\n * - fromVersion > toVersion: Throw DowngradeNotSupportedError\n * - All other cases: Apply upgradePath transitions (if provided), then apply initialState, set version\n */\nexport function applyUpgradeDocumentAction(\n document: PHDocument,\n action: UpgradeDocumentAction,\n upgradePath?: UpgradeTransition[],\n): PHDocument {\n const fromVersion = action.input.fromVersion;\n const toVersion = action.input.toVersion;\n\n if (fromVersion === toVersion && fromVersion > 0) {\n return document;\n }\n\n if (fromVersion > toVersion) {\n throw new DowngradeNotSupportedError(\n document.header.documentType,\n fromVersion,\n toVersion,\n );\n }\n\n if (upgradePath) {\n for (const transition of upgradePath) {\n document = transition.upgradeReducer(document, action);\n }\n }\n\n applyInitialState(document, action);\n\n document.state.document = {\n ...document.state.document,\n version: toVersion,\n };\n return document;\n}\n\n/**\n * Applies a DELETE_DOCUMENT action to a document.\n * Marks the document as deleted in the document scope state.\n */\nexport function applyDeleteDocumentAction(\n document: PHDocument,\n action: DeleteDocumentAction,\n): PHDocument {\n const deletedAt = action.timestampUtcMs || new Date().toISOString();\n\n document.state = {\n ...document.state,\n document: {\n ...document.state.document,\n isDeleted: true,\n deletedAtUtcIso: deletedAt,\n },\n };\n\n return document;\n}\n\n/**\n * Computes the ordered list of upgrade transitions needed to move from\n * fromVersion to toVersion using the provided manifest.\n * Walks keys v(fromVersion+1)..v(toVersion) and throws a descriptive Error\n * if the manifest is absent or any step is missing.\n */\nexport function computeUpgradeTransitions(\n manifest: UpgradeManifest<readonly number[]> | undefined,\n fromVersion: number,\n toVersion: number,\n): UpgradeTransition[] {\n if (!manifest) {\n throw new Error(\n `No upgrade manifest provided for transition from version ${fromVersion} to ${toVersion}`,\n );\n }\n\n const transitions: UpgradeTransition[] = [];\n const upgrades = manifest.upgrades as Record<string, UpgradeTransition>;\n\n for (let v = fromVersion + 1; v <= toVersion; v++) {\n const key = `v${v}`;\n const transition = upgrades[key];\n if (!transition) {\n throw new Error(\n `Upgrade manifest for \"${manifest.documentType}\" is missing step \"${key}\" (from v${fromVersion} to v${toVersion}). Available keys: ${Object.keys(upgrades).join(\", \")}`,\n );\n }\n transitions.push(transition);\n }\n\n return transitions;\n}\n","import { isDenied } from \"./denied.js\";\nimport {\n appendWithoutApplying,\n baseReducerVersion,\n hashDocumentStateForScope,\n replayDocument,\n updateHeaderRevision,\n type PHDocument,\n type PHDocumentHeader,\n} from \"./documents.js\";\nimport {\n HashMismatchError,\n UnsupportedDocumentModelVersionError,\n} from \"./errors.js\";\nimport type { DocumentOperations, Operation } from \"./operations.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n Reducer,\n ReplayDocumentOptions,\n SignalDispatch,\n UpgradeDocumentAction,\n} from \"./types.js\";\nimport {\n applyDeleteDocumentAction,\n applyUpgradeDocumentAction,\n computeUpgradeTransitions,\n type UpgradeManifest,\n} from \"./upgrades.js\";\n\nexport type VersionedReducers = Record<number, Reducer<PHBaseState>>;\n\nexport type VersionedReplayConfig = {\n reducers: VersionedReducers;\n upgradeManifest?: UpgradeManifest<readonly number[]>;\n};\n\nfunction highestReducerVersion(reducers: VersionedReducers): number {\n const keys = Object.keys(reducers).map(Number);\n if (keys.length === 0) {\n throw new Error(\"VersionedReplayConfig.reducers must not be empty\");\n }\n return Math.max(...keys);\n}\n\n/**\n * Version-aware document replay. Replays a versioned document through per-version\n * reducers, applying upgrade transitions at segment boundaries.\n *\n * Algorithm (D5):\n * a. Build spine from operations[\"document\"]. Empty spine or no upgrades → legacy fallback.\n * b. Collect UPGRADE_DOCUMENT ops from the spine.\n * c. Seed state from the creation upgrade (fromVersion===0). Missing seed with validated\n * upgrades throws; otherwise falls back to legacy.\n * d. Identify validated upgrades (fromVersion > 0, version increases). Compute per-scope\n * boundaries using revision snapshot (preferred) or timestamp fallback.\n * e. Loop over version segments, replaying each scope's ops through the matching reducer,\n * then applying the upgrade transition before the next segment.\n * f. Set header.revision[\"document\"], verify per-scope hashes against state at op-time\n * (not post-upgrade state) when checkHashes is false, and map timestamps from input.\n *\n * operations must include ALL scopes (document scope is NOT stripped).\n * reuseOperationResultingState is ignored by this function — zip operations never carry\n * resultingState.\n */\nexport function replayDocumentVersioned<TState extends PHBaseState>(\n initialState: TState,\n operations: DocumentOperations,\n config: VersionedReplayConfig,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n const { checkHashes = true, skipIndexValidation } = options || {};\n\n const protocolVersion = baseReducerVersion(header);\n\n const spine = (operations[\"document\"] ?? [])\n .slice()\n .sort((a, b) => a.index - b.index);\n\n const upgrades = spine.filter((op) => op.action.type === \"UPGRADE_DOCUMENT\");\n\n const legacyFallback = (): PHDocument<TState> => {\n // document-scope ops are applied by dedicated platform handlers; auth ops replay here\n const replayOps = Object.fromEntries(\n Object.entries(operations).filter(([s]) => s !== \"document\"),\n ) as DocumentOperations;\n const latestVersion = highestReducerVersion(config.reducers);\n const reducer = config.reducers[\n latestVersion\n ] as unknown as Reducer<TState>;\n const result = replayDocument(\n initialState,\n replayOps,\n reducer,\n header,\n dispatch,\n {},\n options,\n );\n return { ...result, operations };\n };\n\n if (spine.length === 0 || upgrades.length === 0) {\n return legacyFallback();\n }\n\n const seedOp = upgrades[0];\n if (!seedOp) {\n return legacyFallback();\n }\n const seedAction = seedOp.action as UpgradeDocumentAction;\n if (seedAction.input.fromVersion !== 0) {\n return legacyFallback();\n }\n\n const seedInput = seedAction.input as {\n initialState?: TState;\n state?: TState;\n };\n const seedState = (seedInput.initialState ?? seedInput.state) as\n | TState\n | undefined;\n\n if (!seedState) {\n const validatedUpgradeCount = upgrades.filter((op) => {\n const a = op.action as UpgradeDocumentAction;\n return a.input.fromVersion > 0 && a.input.fromVersion < a.input.toVersion;\n }).length;\n\n if (validatedUpgradeCount > 0) {\n throw new Error(\n `Cannot reconstruct versioned history: the creation UPGRADE_DOCUMENT operation ` +\n `carries no initialState, but the document has ${validatedUpgradeCount} version-changing ` +\n `upgrade(s) recorded after creation. Pre-migration states cannot be reconstructed without the seeded initialState.`,\n );\n }\n return legacyFallback();\n }\n\n const startVersion = seedAction.input.toVersion;\n\n const validatedUpgrades = upgrades.filter((op) => {\n const a = op.action as UpgradeDocumentAction;\n return a.input.fromVersion > 0 && a.input.fromVersion < a.input.toVersion;\n });\n\n // the base reducer applies auth ops identically in every version segment\n const replayScopes = Object.keys(operations).filter((s) => s !== \"document\");\n const scopeOps: Record<string, Operation[]> = {};\n for (const s of replayScopes) {\n scopeOps[s] = (operations[s] ?? [])\n .slice()\n .sort((a, b) => a.index - b.index);\n }\n\n const boundaries: Array<Record<string, number>> = validatedUpgrades.map(\n (upgradeOp) => {\n const upgradeAction = upgradeOp.action as UpgradeDocumentAction;\n const revisionSnapshot = upgradeAction.input.revision;\n const upgradeTimestamp = upgradeOp.timestampUtcMs;\n\n const boundary: Record<string, number> = {};\n for (const s of replayScopes) {\n const ops = scopeOps[s] ?? [];\n if (revisionSnapshot !== undefined) {\n const rev = revisionSnapshot[s] ?? 0;\n let b = 0;\n for (let j = 0; j < ops.length; j++) {\n if ((ops[j]?.index ?? 0) < rev) {\n b = j + 1;\n }\n }\n boundary[s] = b;\n } else {\n let b = ops.length;\n for (let j = 0; j < ops.length; j++) {\n const opTs = ops[j]?.timestampUtcMs ?? \"\";\n if (opTs >= upgradeTimestamp) {\n b = j;\n break;\n }\n }\n boundary[s] = b;\n }\n }\n return boundary;\n },\n );\n\n for (let i = 1; i < boundaries.length; i++) {\n for (const s of replayScopes) {\n const prev = boundaries[i - 1]?.[s] ?? 0;\n const curr = boundaries[i]?.[s] ?? 0;\n if (boundaries[i]) {\n boundaries[i][s] = Math.max(prev, curr);\n }\n }\n }\n\n const allScopes = new Set([...Object.keys(operations), \"global\", \"local\"]);\n const initialOperations: DocumentOperations = {};\n for (const s of allScopes) {\n initialOperations[s] = [];\n }\n\n const backfilledSeed = backfillAuthState(seedState);\n let document: PHDocument<TState> = {\n header,\n state: backfilledSeed,\n initialState: backfilledSeed,\n operations: initialOperations,\n clipboard: [],\n };\n\n let currentVersion = startVersion;\n\n const segmentEndHashPerScope = new Map<string, string>();\n\n for (let k = 0; k <= validatedUpgrades.length; k++) {\n const reducer = config.reducers[currentVersion] as unknown as\n | Reducer<TState>\n | undefined;\n if (!reducer) {\n throw new UnsupportedDocumentModelVersionError(\n header.documentType,\n currentVersion,\n Object.keys(config.reducers)\n .map(Number)\n .sort((a, b) => a - b),\n );\n }\n\n for (const s of replayScopes) {\n const ops = scopeOps[s] ?? [];\n const segStart = k === 0 ? 0 : (boundaries[k - 1]?.[s] ?? 0);\n const segEnd =\n k < validatedUpgrades.length\n ? (boundaries[k]?.[s] ?? ops.length)\n : ops.length;\n const segOps = ops.slice(segStart, segEnd);\n\n for (const op of segOps) {\n // A denied operation holds its position without contributing state, the\n // same way the reactor's own rebuild treats it. It is still recorded, or\n // the operation after it fails index validation and the timestamp remap\n // below shifts onto the wrong rows.\n if (isDenied(op)) {\n document = updateHeaderRevision(\n appendWithoutApplying(document, op, s),\n s,\n op.timestampUtcMs,\n ) as PHDocument<TState>;\n } else {\n document = reducer(document, op.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: { operation: op },\n protocolVersion,\n }) as PHDocument<TState>;\n }\n segmentEndHashPerScope.set(s, hashDocumentStateForScope(document, s));\n }\n }\n\n const prevUpgradeSpineIdx =\n k === 0 ? -1 : spine.indexOf(validatedUpgrades[k - 1]!);\n const nextUpgradeSpineIdx =\n k < validatedUpgrades.length\n ? spine.indexOf(validatedUpgrades[k]!)\n : spine.length;\n\n for (let si = prevUpgradeSpineIdx + 1; si < nextUpgradeSpineIdx; si++) {\n const spineOp = spine[si];\n if (!spineOp) continue;\n const spineActionType = spineOp.action.type;\n if (\n spineActionType === \"CREATE_DOCUMENT\" ||\n spineActionType === \"UPGRADE_DOCUMENT\"\n ) {\n continue;\n }\n // As above: refused, so it occupies its position and changes nothing.\n if (isDenied(spineOp)) {\n continue;\n }\n if (spineActionType === \"DELETE_DOCUMENT\") {\n document = applyDeleteDocumentAction(\n document,\n spineOp.action as Parameters<typeof applyDeleteDocumentAction>[1],\n ) as PHDocument<TState>;\n } else {\n document = reducer(document, spineOp.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: { operation: spineOp },\n protocolVersion,\n }) as PHDocument<TState>;\n }\n }\n\n if (k < validatedUpgrades.length) {\n const upgradeOp = validatedUpgrades[k]!;\n const upgradeAction = upgradeOp.action as UpgradeDocumentAction;\n const fromVer = upgradeAction.input.fromVersion;\n const toVer = upgradeAction.input.toVersion;\n\n const transitions = computeUpgradeTransitions(\n config.upgradeManifest,\n fromVer,\n toVer,\n );\n\n document = applyUpgradeDocumentAction(\n document,\n upgradeAction,\n transitions,\n ) as PHDocument<TState>;\n\n currentVersion = toVer;\n }\n }\n\n const lastSpineOp = spine.at(-1);\n if (lastSpineOp !== undefined && validatedUpgrades.length > 0) {\n document = {\n ...document,\n header: {\n ...document.header,\n revision: {\n ...document.header.revision,\n document: lastSpineOp.index + 1,\n },\n },\n };\n }\n\n if (!checkHashes) {\n const allReplayedOps = replayScopes.flatMap((s) => scopeOps[s] ?? []);\n for (const scope of Object.keys(document.state)) {\n const capturedHash = segmentEndHashPerScope.get(scope);\n const scopeHash =\n capturedHash !== undefined\n ? capturedHash\n : hashDocumentStateForScope(document, scope);\n for (let i = allReplayedOps.length - 1; i >= 0; i--) {\n const operation = allReplayedOps[i];\n if (!operation || operation.action.scope !== scope) {\n continue;\n }\n if (operation.hash !== scopeHash) {\n throw new HashMismatchError(scope, document, operation);\n } else {\n break;\n }\n }\n }\n }\n\n const allResultScopes = new Set([\n ...Object.keys(document.operations),\n ...Object.keys(operations),\n \"global\",\n \"local\",\n ]);\n allResultScopes.delete(\"document\");\n const resultOperations: DocumentOperations = {};\n for (const s of allResultScopes) {\n const scopeResultOps = document.operations[s] ?? [];\n resultOperations[s] = scopeResultOps.map((op, index) => ({\n ...op,\n timestamp: operations[s]?.[index]?.timestampUtcMs ?? op.timestampUtcMs,\n }));\n }\n\n const lastModified = header.lastModifiedAtUtcIso\n ? header.lastModifiedAtUtcIso\n : Object.values(resultOperations).reduce((acc, curr) => {\n if (!curr) return acc;\n const last = curr.at(-1);\n if (last && last.timestampUtcMs > acc) {\n return last.timestampUtcMs;\n }\n return acc;\n }, document.header.lastModifiedAtUtcIso);\n\n return {\n ...document,\n header: {\n ...document.header,\n lastModifiedAtUtcIso: lastModified,\n },\n operations: { ...operations, ...resultOperations },\n } as PHDocument<TState>;\n}\n","import {\n strFromU8,\n strToU8,\n unzip,\n zip,\n type Unzipped,\n type Zippable,\n} from \"fflate\";\nimport type { PHDocument, PHDocumentHeader } from \"./documents.js\";\nimport {\n filterDocumentOperationsResultingState,\n garbageCollectDocumentOperations,\n replayDocument,\n} from \"./documents.js\";\nimport { FileSystemError } from \"./errors.js\";\nimport type { DocumentOperations } from \"./operations.js\";\nimport { documentModelReducer } from \"./reducers.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n DocumentModelPHState,\n FileInput,\n LoadFromInput,\n MinimalBackupData,\n Reducer,\n ReplayDocumentOptions,\n SaveToFileHandle,\n} from \"./types.js\";\nimport { validateOperations } from \"./validation.js\";\nimport {\n replayDocumentVersioned,\n type VersionedReplayConfig,\n} from \"./versioned-replay.js\";\n\nfunction zipAsync(data: Zippable): Promise<Uint8Array> {\n return new Promise((resolve, reject) => {\n zip(data, (err, out) => (err ? reject(err) : resolve(out)));\n });\n}\n\nfunction unzipAsync(data: Uint8Array): Promise<Unzipped> {\n return new Promise((resolve, reject) => {\n unzip(data, (err, out) => (err ? reject(err) : resolve(out)));\n });\n}\n\nconst BASE64_RE = /^[A-Za-z0-9+/]+={0,2}$/;\n\nfunction isLikelyBase64(s: string): boolean {\n // Base64 strings are length % 4 === 0, use only the base64 alphabet,\n // and contain no bytes >= 0x80. A raw binary string (one char per byte)\n // typically has bytes outside that alphabet.\n if (s.length === 0 || s.length % 4 !== 0) return false;\n return BASE64_RE.test(s);\n}\n\nfunction binaryStringToUint8Array(s: string): Uint8Array {\n const arr = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) arr[i] = s.charCodeAt(i) & 0xff;\n return arr;\n}\n\nfunction base64ToUint8Array(s: string): Uint8Array {\n if (typeof atob === \"function\") {\n const bin = atob(s);\n return binaryStringToUint8Array(bin);\n }\n const BufferCtor = (\n globalThis as {\n Buffer?: { from: (s: string, enc: string) => Uint8Array };\n }\n ).Buffer;\n if (!BufferCtor) {\n throw new Error(\n \"Cannot decode base64 string: neither `atob` nor `Buffer` is available in this environment\",\n );\n }\n return BufferCtor.from(s, \"base64\");\n}\n\nasync function toUint8Array(input: FileInput): Promise<Uint8Array> {\n if (input instanceof Uint8Array) return input;\n if (input instanceof ArrayBuffer) return new Uint8Array(input);\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n return new Uint8Array(await input.arrayBuffer());\n }\n if (Array.isArray(input)) return new Uint8Array(input);\n if (typeof input === \"string\") {\n // jszip's loadAsync accepted both raw binary strings and base64 strings\n // with auto-detection. Preserve that so callers passing either keep working.\n return isLikelyBase64(input)\n ? base64ToUint8Array(input)\n : binaryStringToUint8Array(input);\n }\n throw new Error(\"Unsupported FileInput type\");\n}\n\nfunction jsonEntry(value: unknown): Uint8Array {\n return strToU8(JSON.stringify(value, null, 2));\n}\n\nexport async function createZip(document: PHDocument): Promise<Uint8Array> {\n return zipAsync({\n \"header.json\": jsonEntry(document.header),\n \"state.json\": jsonEntry(document.initialState || {}),\n \"current-state.json\": jsonEntry(document.state || {}),\n \"operations.json\": jsonEntry(\n filterDocumentOperationsResultingState(document.operations),\n ),\n });\n}\n\n/**\n * Creates a minimal ZIP backup from strand data.\n * Used when the full document is not available (e.g., in onOperations handler).\n * Creates a ZIP with minimal header and empty operations.\n */\nexport async function createMinimalZip(\n data: MinimalBackupData,\n): Promise<Uint8Array> {\n const now = new Date().toISOString();\n const header: PHDocumentHeader = {\n id: data.documentId,\n sig: { publicKey: {}, nonce: \"\" },\n documentType: data.documentType,\n createdAtUtcIso: now,\n slug: data.name,\n name: data.name,\n branch: data.branch,\n revision: {},\n lastModifiedAtUtcIso: now,\n };\n\n return zipAsync({\n \"header.json\": jsonEntry(header),\n \"state.json\": jsonEntry(data.state),\n \"current-state.json\": jsonEntry(data.state),\n \"operations.json\": jsonEntry({}),\n });\n}\n\nexport async function baseSaveToFileHandle(\n document: PHDocument,\n input: FileSystemFileHandle,\n) {\n const data = await createZip(document);\n const writable = await input.createWritable();\n await writable.write(new Uint8Array(data));\n await writable.close();\n}\n\nfunction readEntry(files: Unzipped, name: string): string {\n const entry = files[name];\n if (!entry) {\n throw new Error(`${name} not found in document zip`);\n }\n return strFromU8(entry);\n}\n\ntype ParsedZip<TState> = {\n initialState: TState;\n header: PHDocumentHeader;\n clearedOperations: DocumentOperations;\n};\n\nasync function parseZipData<TState extends PHBaseState>(\n data: Uint8Array,\n): Promise<ParsedZip<TState>> {\n const files = await unzipAsync(data);\n\n if (!files[\"state.json\"]) {\n throw new Error(\"Initial state not found\");\n }\n const initialState = JSON.parse(readEntry(files, \"state.json\")) as TState;\n\n if (!files[\"header.json\"]) {\n throw new Error(\"Document header not found - file format may be outdated\");\n }\n const header = JSON.parse(\n readEntry(files, \"header.json\"),\n ) as PHDocumentHeader;\n\n if (!files[\"operations.json\"]) {\n throw new Error(\"Operations history not found\");\n }\n const operations = JSON.parse(\n readEntry(files, \"operations.json\"),\n ) as DocumentOperations;\n\n const clearedOperations = garbageCollectDocumentOperations(operations);\n\n const operationsError = validateOperations(clearedOperations);\n if (operationsError.length) {\n const errorMessages = operationsError.map((err) => err.message);\n throw new Error(errorMessages.join(\"\\n\"));\n }\n\n return { initialState, header, clearedOperations };\n}\n\nasync function loadFromZipData<TState extends PHBaseState>(\n data: Uint8Array,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const { initialState, header, clearedOperations } =\n await parseZipData<TState>(data);\n\n // document-scope ops are applied by dedicated platform handlers; auth ops replay here\n const replayOperations = Object.fromEntries(\n Object.entries(clearedOperations).filter(([scope]) => scope !== \"document\"),\n ) as DocumentOperations;\n\n const result = replayDocument(\n initialState,\n replayOperations,\n reducer,\n header,\n undefined,\n {},\n options,\n );\n\n return { ...result, operations: clearedOperations };\n}\n\nasync function loadFromZipDataVersioned<TState extends PHBaseState>(\n data: Uint8Array,\n config: VersionedReplayConfig,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const { initialState, header, clearedOperations } =\n await parseZipData<TState>(data);\n\n const result = replayDocumentVersioned<TState>(\n initialState,\n clearedOperations,\n config,\n header,\n undefined,\n options,\n );\n\n return { ...result, operations: clearedOperations };\n}\n\nexport async function baseLoadFromInput<TState extends PHBaseState>(\n input: FileInput,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const data = await toUint8Array(input);\n return loadFromZipData(data, reducer, options);\n}\n\nexport async function baseLoadFromInputVersioned<TState extends PHBaseState>(\n input: FileInput,\n config: VersionedReplayConfig,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const data = await toUint8Array(input);\n return loadFromZipDataVersioned<TState>(data, config, options);\n}\n\nexport type BulkArchiveEntry = {\n /** \"/\"-separated zip path of a file entry (no trailing slash). */\n path: string;\n data: Uint8Array;\n};\n\n/**\n * Whether this zip is a single Powerhouse document: the document's four JSON\n * entries (header/state/current-state/operations) at the archive root. A\n * bulk archive has a folder tree instead. Returns false for any input that\n * is not a readable zip.\n */\nexport async function isDocumentZip(data: Uint8Array): Promise<boolean> {\n let files: Unzipped;\n try {\n files = await unzipAsync(data);\n } catch {\n return false;\n }\n return (\n Boolean(files[\"header.json\"]) &&\n Boolean(files[\"state.json\"]) &&\n Boolean(files[\"operations.json\"])\n );\n}\n\n/**\n * The file entries of a zip (directory entries excluded). Used for bulk\n * archives; throws when the archive holds no files. Note this does NOT\n * validate that the entries are document zips — pair with isDocumentZip.\n */\nexport async function parseBulkArchive(\n data: Uint8Array,\n): Promise<BulkArchiveEntry[]> {\n const files = await unzipAsync(data);\n const entries = Object.entries(files)\n .filter(([name]) => !name.endsWith(\"/\"))\n .map(([path, value]) => ({ path, data: value }));\n if (entries.length === 0) {\n throw new Error(\"Archive contains no files\");\n }\n return entries;\n}\n\n/**\n * Assemble a zip from raw entries. A key ending in \"/\" with empty data is a\n * directory entry, so an archive's folder structure survives a round-trip.\n */\nexport async function zipEntries(\n entries: Record<string, Uint8Array>,\n): Promise<Uint8Array> {\n return zipAsync(entries);\n}\n\nexport const documentModelLoadFromInput: LoadFromInput<DocumentModelPHState> = (\n input,\n) => {\n return baseLoadFromInput(input, documentModelReducer);\n};\n\nexport const documentModelSaveToFileHandle: SaveToFileHandle = (\n document,\n input,\n) => {\n return baseSaveToFileHandle(document, input);\n};\n\nexport function writeFileBrowser(\n path: string,\n name: string,\n stream: Uint8Array,\n): Promise<string> {\n throw FileSystemError;\n}\n\nexport function readFileBrowser(path: string) {\n throw FileSystemError;\n}\n\nexport function fetchFileBrowser(\n url: string,\n): Promise<{ data: Buffer; mimeType?: string }> {\n throw FileSystemError;\n}\n\nexport const getFileBrowser = (file: string): Promise<void> => {\n return Promise.resolve().then(() => readFileBrowser(file));\n};\n"],"mappings":"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AAE,GAAG,OAAO,EACZ,KAAA,GACA,mCACA,SACD;AAEH,MAAa,4BACX,UAEA,aACE,8BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,qCACA,SACD;AAEH,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACD;AAED,MAAa,kBAAkB,UAC7B,aACE,oBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,2BACA,SACD;AAEH,MAAa,mBAAmB,UAC9B,aACE,qBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,4BACA,SACD;AAEH,MAAa,mBAAmB,UAC9B,aACE,qBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,4BACA,SACD;AAEH,MAAa,sBAAsB,UACjC,aACE,wBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,+BACA,SACD;AAEH,MAAa,sBAAsB,UACjC,aACE,wBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,+BACA,SACD;AAEH,MAAa,wBAAwB,UACnC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,iCACA,SACD;AAEH,MAAa,oBAAoB,UAC/B,aACE,uBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,6BACA,SACD;AAEH,MAAa,uBAAuB,UAClC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,gCACA,SACD;AAEH,MAAa,uBAAuB,UAClC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,gCACA,SACD;AAEH,MAAa,yBAAyB,UACpC,aACE,4BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,kCACA,SACD;AAEH,MAAa,0BACX,aACE,uBACA,EAAE,EACF,KAAA,GACA,KAAA,GACA,SACD;AAEH,MAAa,cAAc;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,UAAU;CAAE,GAAG;CAAa,GAAG;CAAsB;;;ACl7BlE,MAAa,4BAA4B;AACzC,MAAa,oBAAoB;;;;;;;AAQjC,MAAa,6BAA6B,CACxC,cACA,gBACD;;;;ACUD,MAAa,kBAAkB;;AAE/B,MAAa,sBAAsB;;AAEnC,MAAa,sBAAsB;;AAEnC,MAAa,4BAA4B;;;;;AAMzC,IAAa,oBAAb,cAAuC,MAAM;CAC3C;CAEA,YAAY,SAAiB,SAAiB;AAC5C,QAAM,kBAAkB,QAAQ,KAAK,UAAU;AAC/C,OAAK,OAAO;AACZ,OAAK,UAAU;;;;AAKnB,IAAa,gCAAb,cAAmD,MAAM;CACvD;CAEA,YAAY,SAAiB;AAC3B,QACE,UAAU,QAAQ,kGACnB;AACD,OAAK,OAAO;AACZ,OAAK,UAAU;;;;;;;;AASnB,IAAa,iCAAb,cAAoD,MAAM;CACxD;CAEA,YAAY,SAAiB;AAC3B,QACE,oBAAoB,QAAQ,wHAC7B;AACD,OAAK,OAAO;AACZ,OAAK,UAAU;;;;;;;;AASnB,IAAa,iCAAb,cAAoD,MAAM;CACxD,cAAc;AACZ,QACE,mIACD;AACD,OAAK,OAAO;;;AAIhB,MAAM,aAAa,IAAI,IAAI;CACzB;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AACF,MAAM,kBAAkB,IAAI,IAAI;CAAC;CAAU;CAAW;CAAS;CAAQ,CAAC;AACxE,MAAM,6BAA6B,IAAI,IAAI;CACzC;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAgB,aAAa,OAAkD;AAC7E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,eACP,OACA,iBACA,QACe;AACf,QAAO,SAAS;AAChB,KAAI,OAAO,QAAQ,EACjB,QAAO;AAET,KAAI,CAAC,aAAa,MAAM,CACtB,QAAO;CAET,MAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,KAAI,KAAK,WAAW,EAClB,QAAO;AAET,KAAI,KAAK,OAAO,QAAQ;EACtB,MAAM,OAAO,MAAM;AACnB,MAAI,OAAO,SAAS,YAAY,KAAK,WAAW,EAC9C,QAAO;AAET,MACE,oBAAoB,KAAA,KACpB,oBAAoB,OACpB,KAAK,WAAW,OAAO,EACvB;GACA,MAAM,YAAY,KAAK,MAAM,IAAI,CAAC,MAAM;AACxC,OAAI,cAAc,gBAChB,QAAO,mBAAmB,KAAK,iBAAiB,UAAU,0CAA0C,gBAAgB;;AAGxH,SAAO;;AAET,KAAI,KAAK,OAAO,OAAO;EACrB,MAAM,MAAM,MAAM;AAClB,MACE,QAAQ,QACR,OAAO,QAAQ,YACf,OAAO,QAAQ,YACf,OAAO,QAAQ,UAEf,QAAO;AAGT,MAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,IAAI,CAClD,QAAO;AAET,MAAI,OAAO,QAAQ,YAAY,OAAO,GAAG,KAAK,GAAG,CAC/C,QAAO;AAET,SAAO;;AAET,QAAO,yBAAyB,KAAK,GAAG;;AAG1C,SAAS,iBACP,OACA,iBACA,OACA,QACe;AACf,KAAI,QAAA,GACF,QAAO;AAET,QAAO,SAAS;AAChB,KAAI,OAAO,QAAQ,EACjB,QAAO;AAET,KAAI,CAAC,aAAa,MAAM,CACtB,QAAO;CAET,MAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,KAAI,KAAK,WAAW,EAClB,QAAO;CAET,MAAM,OAAO,KAAK;CAClB,MAAM,OAAO,MAAM;AACnB,KAAI,2BAA2B,IAAI,KAAK,EAAE;AACxC,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAC1C,QAAO,GAAG,KAAK;AAEjB,OAAK,MAAM,WAAW,MAAM;GAC1B,MAAM,UAAU,eAAe,SAAS,iBAAiB,OAAO;AAChE,OAAI,YAAY,KACd,QAAO;;AAGX,SAAO;;AAET,KAAI,SAAS,QAAQ,SAAS,SAAS;AACrC,MAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,KAAK,CAAC,MAAM,QAAQ,KAAK,GAAG,CACtE,QAAO,GAAG,KAAK;EAEjB,MAAM,QAAQ,eAAe,KAAK,IAAI,iBAAiB,OAAO;AAC9D,MAAI,UAAU,KACZ,QAAO;AAET,OAAK,MAAM,WAAW,KAAK,IAAiB;GAC1C,MAAM,UAAU,eAAe,SAAS,iBAAiB,OAAO;AAChE,OAAI,YAAY,KACd,QAAO;;AAGX,SAAO;;AAET,KAAI,SAAS,SACX,QAAO,eAAe,MAAM,iBAAiB,OAAO;AAEtD,KAAI,SAAS,SAAS,SAAS,MAAM;AACnC,MAAI,CAAC,MAAM,QAAQ,KAAK,CACtB,QAAO,GAAG,KAAK;AAEjB,OAAK,MAAM,SAAS,MAAM;GACxB,MAAM,UAAU,iBACd,OACA,iBACA,QAAQ,GACR,OACD;AACD,OAAI,YAAY,KACd,QAAO;;AAGX,SAAO;;AAET,KAAI,SAAS,MACX,QAAO,iBAAiB,MAAM,iBAAiB,QAAQ,GAAG,OAAO;AAEnE,QAAO,+BAA+B,KAAK;;AAG7C,SAAS,iBACP,OACA,iBACe;AACf,KAAI,CAAC,aAAa,MAAM,CACtB,QAAO;CAET,MAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,KAAI,KAAK,WAAW,KAAK,CAAC,gBAAgB,IAAI,KAAK,GAAG,CACpD,QAAO;CAET,MAAM,OAAO,KAAK;AAClB,KAAI,SAAS,YAAY,MAAM,WAAW,KACxC,QAAO;AAET,KAAI,SAAS,WAAW;EACtB,MAAM,UAAU,MAAM;AACtB,MAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,EACpD,QAAO;;AAGX,KAAI,SAAS,SAAS;EACpB,MAAM,QAAQ,MAAM;AACpB,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAChD,QAAO;;AAGX,KAAI,SAAS,QACX,QAAO,iBAAiB,MAAM,OAAO,iBAAiB,GAAG,EACvD,OAAA,KACD,CAAC;AAEJ,QAAO;;AAGT,SAAS,kBAAkB,OAA+B;AACxD,KAAI,CAAC,aAAa,MAAM,CACtB,QAAO;CAET,MAAM,MAAM,MAAM;AAClB,KAAI,QAAQ,UAAU,QAAQ,UAC5B,QAAO;CAET,MAAM,cACJ,QAAQ,YAAY;EAAC;EAAO;EAAS;EAAY,GAAG,CAAC,OAAO,QAAQ;CAEtE,MAAM,cAAc,OAAO,KAAK,MAAM,CACnC,QAAQ,QAAQ,CAAC,YAAY,SAAS,IAAI,CAAC,CAC3C,MAAM;AACT,KAAI,YAAY,SAAS,EACvB,QAAO,2BAA2B,YAAY,GAAG;AAEnD,KAAI,MAAM,UAAU,KAAA;MACd,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,WAAW,EAC5D,QAAO;;AAGX,KAAI,QAAQ,aAAa,MAAM,cAAc,KAAA,GAAW;EACtD,MAAM,YAAY,MAAM;AACxB,MAAI,CAAC,MAAM,QAAQ,UAAU,CAC3B,QAAO;AAET,MAAI,UAAU,SAAA,IACZ,QAAO;AAET,OAAK,MAAM,SAAS,UAClB,KAAI,OAAO,UAAU,YAAY,MAAM,WAAW,EAChD,QAAO;;AAIb,QAAO;;;AAIT,SAAgB,aAAa,OAA+B;AAC1D,KAAI,CAAC,aAAa,MAAM,CACtB,QAAO;CAGT,MAAM,cAAc,OAAO,KAAK,MAAM,CACnC,QAAQ,QAAQ,CAAC,WAAW,IAAI,IAAI,CAAC,CACrC,MAAM;AACT,KAAI,YAAY,SAAS,EACvB,QAAO,sBAAsB,YAAY,GAAG;AAE9C,KAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,WAAW,EACtD,QAAO;AAET,KAAI,OAAO,MAAM,gBAAgB,SAC/B,QAAO;AAET,KAAI,MAAM,WAAW,WAAW,MAAM,WAAW,OAC/C,QAAO;CAET,MAAM,kBAAkB,MAAM;CAC9B,MAAM,aAAa,kBAAkB,gBAAgB;AACrD,KAAI,eAAe,KACjB,QAAO;CAET,MAAM,kBAAmB,gBAA4C;CAGrE,MAAM,YAAY,iBAAiB,MAAM,WAAW,gBAAgB;AACpE,KAAI,cAAc,KAChB,QAAO;AAET,KAAI,MAAM,UAAU,KAAA,EAClB,QAAO,iBAAiB,MAAM,OAAO,iBAAiB,GAAG,EACvD,OAAA,KACD,CAAC;AAEJ,QAAO;;AAGT,MAAa,oBACX,EAAE,QAAe,UAAU,aAAa,MAAM,KAAK,KAAK;;AAG1D,SAAgB,iBAAiB,OAAgB,cAA4B;CAC3E,MAAM,UACJ,aAAa,MAAM,IAAI,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;CACnE,MAAM,UAAU,aAAa,MAAM;AACnC,KAAI,YAAY,KACd,OAAM,IAAI,kBAAkB,SAAS,QAAQ;AAE/C,KACE,iBAAA,8BACA,WAAY,MAAgB,UAE5B,OAAM,IAAI,8BAA8B,QAAQ;;;;;;AAQpD,SAAgB,yBACd,QACA,cACA,SACM;AACN,KAAI,OAAO,SAAA,IACT,OAAM,IAAI,kBAAkB,IAAI,4BAA2C;AAE7E,MAAK,MAAM,SAAS,OAClB,kBAAiB,OAAO,aAAa;AAEvC,KAAI,YAAY,KAAA,KAAa,CAAC,wBAAwB,OAAO,CAC3D,OAAM,IAAI,gCAAgC;;;;;;;;;AAW9C,SAAgB,uBACd,OACA,UACA,cACA,SACM;AACN,kBAAiB,OAAO,aAAa;CACrC,MAAM,SAAS,SAAS,MAAM,MAAM,EAAE,OAAO,MAAM,GAAG;AACtD,KAAI,CAAC,UAAU,SAAS,UAAA,IACtB,OAAM,IAAI,kBACR,MAAM,IACN,4BACD;AAMH,kCAAiC,SAAS,UAH7B,SACT,SAAS,KAAK,MAAO,EAAE,OAAO,MAAM,KAAK,QAAQ,EAAG,GACpD,CAAC,GAAG,UAAU,MAAM,EACkC,MAAM,GAAG;;;;;;AAOrE,MAAM,8BAA2C;CAC/C,MAAM;CACN,OAAO;CACP,WAAW;CACZ;;;;;;;;;;;;;;AAeD,SAAS,wBAAwB,QAA0B;CACzD,MAAM,oCAAoB,IAAI,KAAa;AAC3C,MAAK,IAAI,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EAC1D,MAAM,QAAQ,OAAO;AACrB,MACE,MAAM,UAAU,KAAA,KAChB,CAAC,aAAa,OAAO,4BAA4B,CAEjD;EAEF,MAAM,SAAS,MAAM,WAAW;AAChC,MAAI,YAAY,MAAM,UACpB,QAAO;AAET,MAAI,EAAE,aAAa,MAAM,WACvB;EAEF,MAAM,UAAU,MAAM,UAAU,QAAQ,aAAa;AACrD,MAAI,kBAAkB,IAAI,QAAQ,CAChC;AAEF,MAAI,OACF,QAAO;AAET,oBAAkB,IAAI,QAAQ;;AAEhC,QAAO;;;;;;;;AAST,SAAgB,iCACd,SACA,UACA,MACA,SACM;AACN,KAAI,YAAY,KAAA,EACd;AAEF,KAAI,wBAAwB,SAAS,IAAI,CAAC,wBAAwB,KAAK,CACrE,OAAM,IAAI,+BAA+B,QAAQ;;;;;;;;AAerD,MAAM,kBAAkB,OAAO,kBAAkB;;;;;;AAQjD,SAAS,iBAAiB,OAA4C;AACpE,KACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,UAEjB,QAAO;AAET,KAAI,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,CACrD,QAAO;;;;;;;;AAWX,SAAS,eACP,SACA,SACA,SACA,YACiB;AACjB,KAAI,CAAC,aAAa,QAAQ,CACxB,QAAO;CAET,MAAM,OAAO,OAAO,KAAK,QAAQ;AACjC,KAAI,KAAK,WAAW,EAClB,QAAO;AAGT,KAAI,KAAK,OAAO,OAAO;EACrB,MAAM,QAAQ,iBAAiB,QAAQ,IAAI;AAE3C,SAAO,UAAU,KAAA,IAAY,kBAAkB;;AAGjD,KAAI,KAAK,OAAO,OACd,QAAO;CAET,MAAM,OAAO,QAAQ;AACrB,KAAI,OAAO,SAAS,YAAY,KAAK,WAAW,EAC9C,QAAO;CAET,MAAM,OAAO,KAAK,MAAM,IAAI;CAE5B,IAAI;CACJ,IAAI;AACJ,KAAI,KAAK,OAAO,WAAW;AACzB,UAAQ;AACR,SAAO,KAAK,MAAM,EAAE;YACX,KAAK,OAAO,OAAO;AAC5B,MAAI,KAAK,OAAO,QAAQ,MACtB;AAEF,UAAQ,WAAW;AACnB,SAAO,KAAK,MAAM,EAAE;YACX,KAAK,OAAO,YAAY,KAAK,OAAO,SAAS;AACtD,UAAQ,WAAW;AACnB,SAAO,KAAK,MAAM,EAAE;OAEpB;AAGF,MAAK,MAAM,WAAW,MAAM;AAC1B,MAAI,CAAC,aAAa,MAAM,IAAI,CAAC,OAAO,OAAO,OAAO,QAAQ,CACxD;AAEF,UAAQ,MAAM;;AAEhB,QAAO,iBAAiB,MAAM;;;;;;AAOhC,SAAS,cACP,MACA,OACoB;AACpB,KAAI,OAAO,SAAS,YAAY,OAAO,UAAU,SAC/C,QAAO,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;AAEhD,KAAI,OAAO,SAAS,YAAY,OAAO,UAAU,UAAU;EACzD,MAAM,aAAa,MAAM,KAAK,KAAK;EACnC,MAAM,cAAc,MAAM,KAAK,MAAM;EACrC,MAAM,SAAS,KAAK,IAAI,WAAW,QAAQ,YAAY,OAAO;AAC9D,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;GAC/B,MAAM,IAAI,WAAW,GAAG,YAAY,EAAE,IAAI;GAC1C,MAAM,IAAI,YAAY,GAAG,YAAY,EAAE,IAAI;AAC3C,OAAI,MAAM,EACR,QAAO,IAAI,IAAI,KAAK;;AAGxB,SAAO,WAAW,WAAW,YAAY,SACrC,IACA,WAAW,SAAS,YAAY,SAC9B,KACA;;;;;;;;;;AAYV,SAAS,aACP,MACA,SACA,SACA,YACqB;AACrB,KAAI,CAAC,aAAa,KAAK,CACrB;CAEF,MAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,KAAI,KAAK,WAAW,EAClB;CAEF,MAAM,OAAO,KAAK;CAClB,MAAM,OAAO,KAAK;AAElB,SAAQ,MAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,OAAO;AACV,OAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,KAAK,WAAW,EAC1C;GAEF,MAAM,OAAO,eAAe,KAAK,IAAI,SAAS,SAAS,WAAW;GAClE,MAAM,QAAQ,eAAe,KAAK,IAAI,SAAS,SAAS,WAAW;AACnE,OAAI,SAAS,mBAAmB,UAAU,gBACxC;AAEF,OAAI,SAAS,KAAA,KAAa,UAAU,KAAA,EAClC,QAAO;AAET,OAAI,SAAS,KACX,QAAO,SAAS;AAElB,OAAI,SAAS,KACX,QAAO,SAAS;GAElB,MAAM,QAAQ,cAAc,MAAM,MAAM;AACxC,OAAI,UAAU,KAAA,EACZ,QAAO;AAET,WAAQ,MAAR;IACE,KAAK,KACH,QAAO,QAAQ;IACjB,KAAK,MACH,QAAO,SAAS;IAClB,KAAK,KACH,QAAO,QAAQ;IACjB,KAAK,MACH,QAAO,SAAS;;AAEpB;;EAEF,KAAK;EACL,KAAK,SAAS;AACZ,OACE,CAAC,MAAM,QAAQ,KAAK,IACpB,KAAK,WAAW,KAChB,CAAC,MAAM,QAAQ,KAAK,GAAG,CAEvB;GAEF,MAAM,OAAO,eAAe,KAAK,IAAI,SAAS,SAAS,WAAW;AAClE,OAAI,SAAS,gBACX;GAEF,MAAM,WAAW,KAAK,GAAG,KAAK,YAC5B,eAAe,SAAS,SAAS,SAAS,WAAW,CACtD;AACD,OAAI,SAAS,MAAM,UAAU,UAAU,gBAAgB,CACrD;AAEF,OAAI,SAAS,KAAA,EACX,QAAO;GAET,MAAM,QAAQ,SAAS,MACpB,UAAU,UAAU,KAAA,KAAa,UAAU,KAC7C;AACD,UAAO,SAAS,OAAO,QAAQ,CAAC;;EAElC,KAAK,UAAU;GACb,MAAM,QAAQ,eAAe,MAAM,SAAS,SAAS,WAAW;AAChE,OAAI,UAAU,gBACZ;AAEF,UAAO,UAAU,KAAA;;EAEnB,KAAK;EACL,KAAK,MAAM;AACT,OAAI,CAAC,MAAM,QAAQ,KAAK,CACtB;GAEF,IAAI,SAAS,SAAS;AACtB,QAAK,MAAM,SAAS,MAAM;IACxB,MAAM,QAAQ,aAAa,OAAO,SAAS,SAAS,WAAW;AAC/D,QAAI,UAAU,KAAA,EACZ;AAEF,QAAI,SAAS,MACX,UAAS,UAAU;QAEnB,UAAS,UAAU;;AAGvB,UAAO;;EAET,KAAK,OAAO;GACV,MAAM,QAAQ,aAAa,MAAM,SAAS,SAAS,WAAW;AAC9D,UAAO,UAAU,KAAA,IAAY,KAAA,IAAY,CAAC;;EAE5C,QACE;;;;;;;;;AAUN,SAAgB,kBACd,WACA,SACA,SACA,YACS;AACT,QAAO,aAAa,WAAW,SAAS,SAAS,WAAW,KAAK;;;AAInE,SAAS,YAAY,OAA2B,WAA4B;AAC1E,QAAO,UAAU,KAAA,KAAa,UAAU,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;AAqB3D,SAAS,aAAa,OAAc,SAA+B;AACjE,KAAI,iBAAiB,MAAM,YAAY,QAAQ,CAC7C,QAAO;AAGT,QACE,QAAQ,SAAS,UACjB,MAAM,WAAW,WACjB,MAAM,WAAW,QAAQ,aACzB,YAAY,MAAM,WAAW,OAAO,QAAQ,MAAM;;AAItD,SAAS,iBACP,YACA,SACS;AACT,KAAI,WAAW,QAAQ,QAAQ,KAC7B,QAAO;AAET,KAAI,CAAC,YAAY,WAAW,OAAO,QAAQ,MAAM,CAC/C,QAAO;AAET,KAAI,WAAW,QAAQ,WAAW;AAEhC,MAAI,WAAW,cAAc,KAAA,EAC3B,QAAO;AAET,SACE,QAAQ,cAAc,KAAA,KACtB,WAAW,UAAU,SAAS,QAAQ,UAAU;;AAGpD,QAAO;;AAGT,SAAS,iBACP,WACA,SACA,SACA,QACA,YACS;AACT,KAAI,YAAY,UACd,QAAO;AAET,KAAI,aAAa,UACf,QACE,QAAQ,YAAY,KAAA,KACpB,QAAQ,QAAQ,aAAa,KAAK,UAAU,QAAQ,aAAa;AAGrE,KAAI,WAAW,WAAW;AAIxB,MAAI,WAAW,KAAA,KAAa,QAAQ,YAAY,KAAA,EAC9C,QAAO;EAIT,MAAM,QAAQ,OAAO,UAAU;AAC/B,MAAI,UAAU,KAAA,KAAa,CAAC,MAAM,QAAQ,MAAM,QAAQ,CACtD,QAAO;EAET,MAAM,UAAU,QAAQ,QAAQ,aAAa;AAC7C,SAAO,MAAM,QAAQ,MAAM,WAAW,OAAO,aAAa,KAAK,QAAQ;;AAEzE,KAAI,WAAW,WAAW;AAExB,MAAI,eAAe,KAAA,EACjB,QAAO;AAET,SAAO,kBAAkB,UAAU,OAAO,SAAS,SAAS,WAAW;;AAEzE,QAAO;;;;;;AAOT,SAAgB,mBAAmB,QAA2B;CAC5D,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,SAAS,OAClB,KAAI,WAAW,MAAM,aAAa,CAAC,IAAI,SAAS,MAAM,UAAU,MAAM,CACpE,KAAI,KAAK,MAAM,UAAU,MAAM;AAGnC,QAAO;;;;;;;;;AAUT,SAAgB,mBACd,QACA,SACA,SACA,QACA,YACgB;CAChB,IAAI;AACJ,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,MAAM,UAAU,KAAA,GAAW;AAE7B,OAAI,eAAe,KAAA,EACjB;AAEF,OAAI,CAAC,kBAAkB,MAAM,OAAO,SAAS,SAAS,WAAW,CAC/D;;AAGJ,MACE,aAAa,OAAO,QAAQ,IAC5B,iBAAiB,MAAM,WAAW,SAAS,SAAS,QAAQ,WAAW,CAEvE,cAAa;;AAIjB,KAAI,eAAe,KAAA,EACjB,QAAO;EAAE,UAAU;EAAQ,SAAS;EAAuB;AAE7D,KAAI,WAAW,WAAW,OACxB,QAAO;EACL,UAAU;EACV,SAAS;EACT,SAAS,WAAW;EACrB;AAEH,QAAO,EAAE,UAAU,SAAS;;;;;;AAO9B,SAAgB,eACd,QACA,SACA,SACA,QACA,YACc;AACd,QAAO,mBAAmB,QAAQ,SAAS,SAAS,QAAQ,WAAW,CACpE;;;;ACj6BL,MAAa,6BAA6B;AAE1C,MAAa,iCAA0D,EAAE;AACzE,MAAa,kCAA4D;CACvE,IAAI;CACJ,MAAM;CACN,WAAW;CACX,aAAa;CACb,QAAQ;EACN,MAAM;EACN,SAAS;EACV;CACD,gBAAgB,CACd;EACE,SAAS;EACT,WAAW,EAAE;EACb,OAAO;GACL,QAAQ;IACN,QAAQ;IACR,cAAc;IACd,UAAU,EAAE;IACb;GACD,OAAO;IACL,QAAQ;IACR,cAAc;IACd,UAAU,EAAE;IACb;GACF;EACD,SAAS,EAAE;EACZ,CACF;CACF;AACD,MAAa,2BAAqD;CAChE,IAAI;CACJ,MAAM;CACN,WAAW;CACX,aACE;CACF,QAAQ;EACN,MAAM;EACN,SAAS;EACV;CACD,gBAAgB,CACd;EACE,SAAS;EACT,WAAW,EAAE;EACb,OAAO;GACL,QAAQ;IACN,QACE;IACF,cACE;IACF,UAAU,EAAE;IACb;GACD,OAAO;IACL,QAAQ;IACR,cAAc;IACd,UAAU,EAAE;IACb;GACF;EACD,SAAS;GACP;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,QAAQ;MACR,IAAI;MACJ,aACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QAAQ;MACR,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACD;IACE,MAAM;IACN,YAAY;KACV;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aAAa;MACb,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACD;MACE,MAAM;MACN,IAAI;MACJ,aACE;MACF,QACE;MACF,UAAU;MACV,SAAS;MACT,UAAU,EAAE;MACZ,QAAQ,EAAE;MACV,OAAO;MACR;KACF;IACD,IAAI;IACJ,aAAa;IACd;GACF;EACF,CACF;CACF;AAGD,MAAa,sBAAsB;AACnC,MAAa,wBAAwB;AACrC,MAAa,wBAAwB;AAGrC,MAAa,uBAAuB;AACpC,MAAa,oBAAoB;;;;;;ACznBjC,SAAgB,mBAAgC;AAC9C,QAAO;EACL,SAAS;EACT,QAAQ,EAAE;EACX;;;;;AAMH,SAAgB,uBAAwC;AACtD,QAAO;EACL,SAAS;EACT,MAAM;GACJ,WAAW;GACX,UAAU;GACX;EACF;;;;;AAKH,SAAgB,mBAAgC;AAC9C,QAAO;EACL,MAAM,kBAAkB;EACxB,UAAU,sBAAsB;EACjC;;;;;AAMH,SAAgB,gBAAgB,MAA0C;AACxE,QAAO;EACL,GAAG,kBAAkB;EACrB,GAAG;EACJ;;;;;AAMH,SAAgB,oBACd,UACiB;AACjB,QAAO;EACL,GAAG,sBAAsB;EACzB,GAAG;EACJ;;;;;AAMH,SAAgB,gBACd,MACA,UACa;AACb,QAAO;EACL,MAAM,gBAAgB,KAAK;EAC3B,UAAU,oBAAoB,SAAS;EACxC;;;;;;AAOH,SAAgB,kBACd,OACQ;AACR,QAAO;EACL,GAAG;EACH,MAAM,gBAAgB,MAAM,KAAK;EAClC;;AAgIH,SAAgB,qBAA+C;AAC7D,QAAO;EACL,GAAG,kBAAkB;EACrB,QAAQ;GACN,MAAM;GACN,SAAS;GACV;EACD,aAAa;EACb,WAAW;EACX,IAAI;EACJ,MAAM;EACN,gBAAgB,EAAE;EACnB;;AAGH,SAAgB,oBAA6C;AAC3D,QAAO,EAAE;;AAGX,SAAgB,iBAAuC;AACrD,QAAO;EACL,GAAG,kBAAkB;EACrB,QAAQ,oBAAoB;EAC5B,OAAO,mBAAmB;EAC3B;;AAGH,SAAgB,kBACd,OAC0B;AAC1B,QAAO;EACL,GAAG,oBAAoB;EACvB,GAAI,SAAS,EAAE;EAChB;;AAGH,SAAgB,iBACd,OACyB;AACzB,QAAO;EACL,GAAG,mBAAmB;EACtB,GAAI,SAAS,EAAE;EAChB;;AAGH,SAAgB,YACd,WACA,aACA,YACsB;AACtB,QAAO;EACL,GAAG,gBAAgB,WAAW,MAAM,WAAW,SAAS;EACxD,QAAQ,kBAAkB,YAAY;EACtC,OAAO,iBAAiB,WAAW;EACpC;;;;AC7LH,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACD;AAED,SAAgB,aAAa,QAAsC;AACjE,QAAQ,kBAAwC,SAAS,OAAO,KAAK;;;AAMvE,MAAa,6BAA6B;AAI1C,MAAa,wCACX,EAAE,OAAO;CACP,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;CAChC,QAAQ,EAAE,MAAM,aAAa,CAAC,CAAC,IAAA,IAAoB;CACpD,CAAC;AAEJ,MAAa,kCACX,EAAE,OAAO,EACP,OAAO,aAAa,EACrB,CAAC;AAEJ,MAAa,qCACX,EAAE,OAAO,EACP,IAAI,EAAE,QAAQ,EACf,CAAC;AAEJ,MAAa,mCACX,EAAE,OAAO;CACP,IAAI,EAAE,QAAQ;CACd,OAAO,EAAE,QAAQ;CAClB,CAAC;AAIJ,MAAa,kBAAkB,UAC7B,aACE,mBACA,OACA,KAAA,GACA,iCACA,OACD;AAEH,MAAa,YAAY,UACvB,aACE,aACA,OACA,KAAA,GACA,2BACA,OACD;AAEH,MAAa,eAAe,UAC1B,aACE,gBACA,OACA,KAAA,GACA,8BACA,OACD;AAEH,MAAa,aAAa,UACxB,aACE,cACA,OACA,KAAA,GACA,4BACA,OACD;;;;;AAQH,SAAS,uBAAuB,OAAsB;AACpD,KAAI,CAAC,aAAa,MAAM,CACtB,OAAM,IAAI,wBAAwB,EAAE,OAAO,qBAAqB,CAAC;;AAIrE,SAAS,WACP,UACA,QACoB;AACpB,QAAO;EACL,GAAG;EACH,OAAO;GACL,GAAG,SAAS;GACZ,MAAM;IAAE,GAAG,SAAS,MAAM;IAAM;IAAQ;GACzC;EACF;;AAGH,MAAM,yBAAyB,CAAC,KAAM,GAAK;AAC3C,MAAM,iBAAiB;AAEvB,SAAS,WAAW,GAAe,GAAwB;AACzD,KAAI,EAAE,WAAW,EAAE,OACjB,QAAO;AAET,MAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAC5B,KAAI,EAAE,OAAO,EAAE,GACb,QAAO;AAGX,QAAO;;;;;;;AAQT,SAAgB,kBACd,YACA,WACS;AACT,KAAI,CAAC,YAAY,KAAK,CAAC,WAAW,EAChC,QAAO;AAET,KAAI,CAAC,aAAa,CAAC,UAAU,WAAW,eAAe,CACrD,QAAO;CAET,MAAM,UAAU,aAAa,UAAU,MAAM,EAAsB,CAAC;AAEpE,KAAI,CAAC,WAAW,QAAQ,WAAW,GACjC,QAAO;AAET,KACE,QAAQ,OAAO,uBAAuB,MACtC,QAAQ,OAAO,uBAAuB,GAEtC,QAAO;CAET,MAAM,eAAe,QAAQ;AAC7B,KAAI,iBAAiB,KAAQ,iBAAiB,EAC5C,QAAO;CAET,MAAM,OAAO,QAAQ,SAAS,GAAG,GAAG;CACpC,MAAM,OAAO,iBAAiB,WAAW,EAAE;CAC3C,MAAM,OAAO,iBAAiB,WAAW,EAAE;AAC3C,KAAI,KAAK,WAAW,MAAM,KAAK,WAAW,GACxC,QAAO;AAET,KAAI,CAAC,WAAW,MAAM,KAAK,CACzB,QAAO;AAIT,SAFmB,KAAK,MAAM,OAAO,OACnB,iBAAiB;;;;;;;;;;AAYrC,SAAgB,0BACd,UACA,QACoB;AACpB,wBAAuB,OAAO,MAAM;CACpC,MAAM,EAAE,SAAS,WAAW,OAAO;AACnC,KAAI,CAAC,OAAO,UAAU,QAAQ,IAAI,UAAU,EAC1C,OAAM,IAAI,wBAAwB,SAAS,OAAO,IAAI,QAAQ;AAEhE,KAAI,SAAS,MAAM,KAAK,YAAY,EAClC,OAAM,IAAI,4BAA4B,SAAS,OAAO,GAAG;AAE3D,KAAI,CAAC,MAAM,QAAQ,OAAO,CACxB,OAAM,IAAI,wBAAwB,EAAE,QAAQ,oBAAoB,CAAC;CAEnE,MAAM,aAAa,SAAS,OAAO,IAAI;CACvC,MAAM,YAAY,OAAO,SAAS,QAAQ,IAAI;CAG9C,MAAM,aAAa,QAAQ,WAAW,OAAO,WAAW,KAAK,WAAW,EAAE;AAC1E,KAAI,cAAc,CAAC,kBAAkB,YAAY,UAAU,CACzD,OAAM,IAAI,+BAA+B,SAAS,OAAO,GAAG;CAE9D,MAAM,UAAU,aAAa,YAAY,KAAA;AACzC,0BAAyB,QAAQ,SAAS,OAAO,cAAc,QAAQ;AACvE,QAAO;EACL,GAAG;EACH,OAAO;GACL,GAAG,SAAS;GACZ,MAAM,gBACJ,UAAU;IAAE;IAAS;IAAQ;IAAS,GAAG;IAAE;IAAS;IAAQ,CAC7D;GACF;EACF;;;AAIH,SAAgB,oBACd,UACA,QACoB;AACpB,wBAAuB,OAAO,MAAM;CACpC,MAAM,EAAE,UAAU,OAAO;CACzB,MAAM,SAAS,SAAS,MAAM,KAAK;AACnC,wBACE,OACA,QACA,SAAS,OAAO,cAChB,SAAS,MAAM,KAAK,QACrB;AAKD,QAAO,WAAW,UAJH,OAAO,MAAM,MAAM,EAAE,OAAO,MAAM,GAAG,GAEhD,OAAO,KAAK,MAAO,EAAE,OAAO,MAAM,KAAK,QAAQ,EAAG,GAClD,CAAC,GAAG,QAAQ,MAAM,CACW;;;;;;AAOnC,SAAgB,uBACd,UACA,QACoB;AACpB,wBAAuB,OAAO,MAAM;CACpC,MAAM,EAAE,OAAO,OAAO;CACtB,MAAM,EAAE,QAAQ,YAAY,SAAS,MAAM;AAC3C,KAAI,CAAC,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG,CAClC,OAAM,IAAI,mBAAmB,GAAG;CAElC,MAAM,OAAO,OAAO,QAAQ,MAAM,EAAE,OAAO,GAAG;AAC9C,kCAAiC,SAAS,QAAQ,MAAM,GAAG;AAC3D,QAAO,WAAW,UAAU,KAAK;;;;;;;;;;;AAYnC,SAAgB,qBACd,UACA,QACoB;AACpB,wBAAuB,OAAO,MAAM;CACpC,MAAM,EAAE,IAAI,UAAU,OAAO;CAC7B,MAAM,EAAE,QAAQ,YAAY,SAAS,MAAM;CAC3C,MAAM,OAAO,OAAO,WAAW,MAAM,EAAE,OAAO,GAAG;AACjD,KAAI,SAAS,GACX,OAAM,IAAI,mBAAmB,GAAG;CAElC,MAAM,OAAO,CAAC,GAAG,OAAO;CACxB,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,EAAE;CACpC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,OAAO,CAAC;AACpD,MAAK,OAAO,IAAI,GAAG,MAAM;AACzB,kCAAiC,SAAS,QAAQ,MAAM,GAAG;AAC3D,QAAO,WAAW,UAAU,KAAK;;;;;;;;AASnC,SAAgB,gBACd,UACA,QACoB;AACpB,SAAQ,OAAO,MAAf;EACE,KAAK,kBACH,QAAO,0BACL,UACA,OACD;EACH,KAAK,YACH,QAAO,oBAAoB,UAAU,OAAyB;EAChE,KAAK,eACH,QAAO,uBAAuB,UAAU,OAA4B;EACtE,KAAK,aACH,QAAO,qBAAqB,UAAU,OAA0B;EAClE,QACE,QAAO;;;;;;;AAQb,SAAgB,+BACd,YACA,QACA,YACM;AACN,KAAI,CAAC,UAAU,OAAO,YAAY,EAChC;AAEF,KACE,eAAe,KAAA,KACf,WAAW,YAAY,OAAO,WAC9B,WAAW,YAAY,OAAO,QAE9B,OAAM,IAAI,4BAA4B,WAAW;;;;;;;;;;;;;;;;;;;;;;;;AA0BrD,SAAgB,oBACd,YACA,cACA,SACA,UACa;CACb,MAAM,cAAc,WAAW,gBAAgB;EAAE,SAAS;EAAG,QAAQ,EAAE;EAAE,CAAC;AAE1E,KAAI,CAAC,YAAY,CAAC,SAAS,QACzB,QAAO;AAGT,KAAI,YAAY,YAAY,GAAG;AAK7B,MAAI,UAAU,SAAS,KAAK,UAAU,YAAY,CAChD,OAAM,IAAI,4BAA4B,WAAW;AAEnD,SAAO;;AAGT,KAAI,CAAC,MAAM,QAAQ,SAAS,OAAO,CACjC,OAAM,IAAI,wBAAwB,EAAE,QAAQ,oBAAoB,CAAC;AAEnE,0BAAyB,SAAS,QAAQ,cAAc,SAAS,QAAQ;AACzE,QAAO;;;AAIT,SAAgB,6BAA6B,QAAsB;AACjE,KACE,OAAO,UAAU,UACjB;EAAC;EAAQ;EAAQ;EAAQ,CAAC,SAAS,OAAO,KAAK,CAE/C,OAAM,IAAI,0BAA0B,OAAO,KAAK;;;;;;;;;;;;;;;AAgEpD,SAAgB,SACd,MACA,SACA,SACA,QACA,YACgB;AAChB,KAAI,CAAC,QAAQ,CAAC,KAAK,QACjB,QAAO,EAAE,UAAU,SAAS;AAK9B,KACE,QAAQ,SAAS,aACjB,QAAQ,UAAU,UAClB,QAAQ,QAAQ,KAAA,KAChB,QAAQ,QAAQ,KAAK,QAErB,QAAO,EAAE,UAAU,SAAS;AAG9B,KAAI,KAAK,UAAA,EACP,QAAO;EAAE,UAAU;EAAQ,SAAS;EAAuB;AAG7D,QAAO,mBAAmB,KAAK,QAAQ,SAAS,SAAS,QAAQ,WAAW;;;;;;AAO9E,SAAgB,OACd,MACA,SACA,SACA,QACA,YACc;AACd,QAAO,SAAS,MAAM,SAAS,SAAS,QAAQ,WAAW,CAAC;;;;;;;;;AAU9D,SAAgB,kBAAkB,QAA0B;CAC1D,MAAM,QAAQ,OAAO;CACrB,MAAM,aAAwB,EAAE;AAEhC,KAAI,OAAO,SAAS,qBAAqB,MAAM,QAAQ,OAAO,OAAO,CACnE,YAAW,KAAK,GAAI,MAAM,OAAqB;AAEjD,KAAI,OAAO,SAAS,eAAe,OAAO,UAAU,KAAA,EAClD,YAAW,KAAK,MAAM,MAAM;CAG9B,MAAM,MAAgB,EAAE;AACxB,MAAK,MAAM,aAAa,YAAY;AAClC,MAAI,OAAO,cAAc,YAAY,cAAc,KACjD;EAEF,MAAM,YAAa,UAAsC;AACzD,MAAI,OAAO,cAAc,YAAY,cAAc,KACjD;EAEF,MAAM,QAAS,UAAsC;AACrD,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM,CAAC,IAAI,SAAS,MAAM,CACnE,KAAI,KAAK,MAAM;;AAGnB,QAAO;;;;;;;AC5kBT,SAAgB,SAAS,WAA+B;AACtD,QAAO,UAAU,iBAAiB,KAAA;;;;;;;AAQpC,MAAa,0BAA0B;AACvC,MAAa,kCACX;AACF,MAAa,uBAAuB;AACpC,MAAa,8BAA8B;;;ACjB3C,MAAa,2BAA2B,EAAE,OAAO;CAC/C,IAAI,EAAE,QAAQ;CACd,MAAM,EAAE,QAAQ;CAChB,iBAAiB,EAAE,QAAQ;CAC3B,sBAAsB,EAAE,QAAQ;CAChC,cAAc,EAAE,QAAQ;CACzB,CAAC;AAEF,MAAa,0BAA0B,EAAE,OAAO,EAC9C,QAAQ,EAAE,SAAS,EACpB,CAAC;;AAGF,MAAa,4BAA4B,yBAAyB,OAAO,EACvE,cAAc,EAAE,QAAQ,0BAA0B,EACnD,CAAC;;AAGF,MAAa,6BAA6B,wBAAwB,OAAO,EACvE,QAAQ,gCAAgC,EACzC,CAAC;AAEF,MAAa,sBAAsB,EAAE,OAAO;CAC1C,QAAQ;CACR,OAAO;CACP,cAAc;CACf,CAAC;;AAGF,SAAgB,qBACd,OAC+B;AAC/B,QAAO,2BAA2B,UAAU,MAAM,CAAC;;;AAIrD,SAAgB,2BACd,OACuC;AACvC,4BAA2B,MAAM,MAAM;;;AAIzC,SAAgB,wBACd,UACmC;AACnC,QAAO,oBAAoB,UAAU,SAAS,CAAC;;;AAIjD,SAAgB,8BACd,UAC2C;AAC3C,qBAAoB,MAAM,SAAS;;;;;;;ACjDrC,MAAM,yBAAyB,eAC7B,GAAG,WAAW,aAAa,GAAG,WAAW,gBAAgB,GAAG,WAAW;;;;;;;;AASzE,eAAsB,yBACpB,QACkB;CAClB,MAAM,YAAY,MAAM,OAAO,OAAO,UACpC,OACA,QACA;EAAE,MAAM;EAAS,YAAY;EAAS,EACtC,MACA,CAAC,SAAS,CACX;AACD,QAAO;EACL,WAAW;EAEX,MAAM,KAAK,OAAwC;AACjD,SAAM,IAAI,MAAM,4CAA4C;;EAG9D,MAAM,WACJ,SACA,cACoB;AACpB,SAAM,IAAI,MAAM,+CAA+C;;EAGjE,MAAM,OAAO,MAAkB,WAAsC;GACnE,IAAI;AACJ,OAAI;AACF,cAAU,MAAM,OAAO,OAAO,OAC5B;KAAE,MAAM;KAAS,MAAM;KAAW,EAClC,WACA,IAAI,WAAW,UAAU,EACzB,IAAI,WAAW,KAAK,CACrB;WACK;AACN,UAAM,IAAI,MAAM,oBAAoB;;AAGtC,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,oBAAoB;;EAGzC;;;;;;;;AASH,MAAM,yBAAyB,OAC7B,WACqB;AACrB,QAAO,yBAAyB,OAAO,IAAI,UAAU;;;;;;;;;;;AAYvD,MAAa,OAAO,OAClB,YACA,WACoB;CAEpB,MAAM,UAAU,sBAAsB,WAAW;CAIjD,MAAM,OADU,IAAI,aAAa,CACZ,OAAO,QAAQ;CAGpC,MAAM,YAAY,MAAM,OAAO,KAAK,KAAK;CAGzC,MAAM,iBAAiB,IAAI,WAAW,UAAU;AAEhD,QADwB,KAAK,OAAO,aAAa,GAAG,eAAe,CAAC;;;;;;;;;;AAYtE,MAAa,SAAS,OACpB,YACA,WACA,WACkB;CAElB,MAAM,UAAU,sBAAsB,WAAW;CAIjD,MAAM,OADU,IAAI,aAAa,CACZ,OAAO,QAAQ;CAGpC,MAAM,iBAAiB,WAAW,KAAK,KAAK,UAAU,GAAG,MACvD,EAAE,WAAW,EAAE,CAChB;AAED,OAAM,OAAO,OAAO,MAAM,eAAe;;;;;AAM3C,MAAa,iBAAiB,OAC5B,WACkB;CAClB,MAAM,SAAS,MAAM,uBAAuB,OAAO;AAEnD,QAAO,OACL;EACE,cAAc,OAAO;EACrB,iBAAiB,OAAO;EACxB,OAAO,OAAO,IAAI;EACnB,EACD,OAAO,IACP,OACD;;;;;;;;AASH,MAAa,yBACX,KAAa,YAAY,EACzB,eAAe,OACM;AACrB,QAAO;EACL;EACA,KAAK;GACH,WAAW,EAAE;GACb,OAAO;GACR;EACD;EACA,kCAAiB,IAAI,MAAM,EAAC,aAAa;EACzC,MAAM;EACN,MAAM;EACN,QAAQ;EACR,UAAU,EACR,UAAU,GACX;EACD,uCAAsB,IAAI,MAAM,EAAC,aAAa;EAC9C,MAAM,EAAE;EACT;;;;;;;;;;;;AAaH,MAAa,qBAAqB,OAChC,gBACA,cACA,WAC8B;CAC9B,MAAM,aAAgC;EACpC;EACA,iBAAiB,eAAe;EAChC,OAAO,YAAY;EACpB;AAMD,QAAO;EAEL,IANgB,MAAM,KAAK,YAAY,OAAO;EAO9C,KAAK;GACH,WANkB,MAAM,OAAO,OAAO,UAAU,OAAO,OAAO,UAAU;GAOxE,OAAO,WAAW;GACnB;EACD;EACA,iBAAiB,eAAe;EAGhC,MAAM,eAAe;EACrB,MAAM,eAAe;EACrB,QAAQ,eAAe;EACvB,UAAU,eAAe;EACzB,sBAAsB,eAAe;EACrC,MAAM,eAAe;EACtB;;;;;;;;;;;;AAaH,MAAa,8BAA8B,OACzC,cACA,WAC8B;AAQ9B,QANqB,MAAM,mBADJ,uBAAuB,EAG5C,cACA,OACD;;;;ACtGH,SAAgB,gBAMd,IAA2B;AAC3B,QACE,GAAG,SAAS,UACZ,GAAG,SAAS,KAAA,KACZ,GAAG,OAAO,KACV,GAAG,SAAS,KAAA;;AAIhB,SAAgB,WAAW,QAA0C;AACnE,QAAO,CAAC,QAAQ,OAAO,CAAC,SAAS,OAAO,KAAK;;AAG/C,SAAgB,OAAO,QAAsC;AAC3D,QAAO,OAAO,SAAS;;AAGzB,SAAgB,iBAAiB,QAA0C;AACzE,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,SAAS,OAAO,KAAK;;;;;;AAOzB,SAAS,8BACP,QACA,OACa;CACb,MAAM,cAAyC;EAC7C,OAAO,OAAO;EACd,SAAS;EACT,YAAY,OAAO;EACnB,SAAS;GACP,WAAW,OAAO;GAClB,WAAW,OAAO,IAAI;GACtB,OAAO,OAAO,IAAI;GAClB,iBAAiB,OAAO;GACxB,cAAc,OAAO;GACtB;EACD,MAAM,OAAO;EACb,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,MAAM,OAAO;EACb,kBAAkB,OAAO,oBAAoB,EAAE,gBAAgB,GAAG;EACnE;CACD,MAAM,eAA2C;EAC/C,OAAO,OAAO;EACd,aAAa;EACb,WAAW,MAAM,SAAS;EAC1B,YAAY,OAAO;EACnB,cAAc;EACf;AAmBD,QAjB0B,CACxB;EACE,IAAI,YAAY;EAChB,MAAM;EACN,OAAO;EACP,gBAAgB,OAAO;EACvB,OAAO;EACR,EACD;EACE,IAAI,YAAY;EAChB,MAAM;EACN,OAAO;EACP,gBAAgB,OAAO;EACvB,OAAO;EACR,CACF,CAEc,KAAK,QAAQ,WAAW;EACrC,GAAG;EACH;EACA,IAAI,kBAAkB,OAAO,IAAI,YAAY,OAAO,QAAQ,OAAO,GAAG;EACtE,MAAM;EACN,OAAO,KAAA;EACP;EACA,MAAM;EACP,EAAE;;;;;;AAOL,SAAgB,mBACd,aACA,cACA,eAAe,IACK;CACpB,MAAM,QAAQ,YAAY,aAAa;CACvC,MAAM,SAAS,sBAAsB,YAAY,EAAE,aAAa;AAMhE,QAAO,mBAAmB,EAAE,gBAAgB,GAAG;AAgB/C,QAduC;EACrC;EACA;EACA,cAAc;EACd,YAAY,eACR;GACE,QAAQ,EAAE;GACV,OAAO,EAAE;GACT,UAAU,8BAA8B,QAAQ,MAAM;GACvD,GACD;GAAE,QAAQ,EAAE;GAAE,OAAO,EAAE;GAAE;EAC7B,WAAW,EAAE;EACd;;AAKH,SAAgB,0BACd,UAKA,QAAQ,UACR;AAEA,QAAO,YADa,UAAU,SAAS,MAAM,UAAU,GAAG,CAC3B;;AAGjC,SAAgB,SAAY,OAAuB;AACjD,QAAO,OAAO,OAAO,MAAM;;;;;;;;;;AAW7B,SAAgB,qBACd,YACA,uBACmB;CACnB,MAAM,MAAM,CAAC,GAAG,WAAW;CAE3B,IAAI,UAAU,yBAAyB;CACvC,IAAI,gBAAgB,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,GAAG,QAAQ;CAEjE,MAAM,qBAAwC,EAAE;AAEhD,MAAK,MAAM,aAAa,IAAI,SAAS,EAAE;AACrC,MAAI,UAAU,GAAG;GACf,MAAM,iBAAiB,gBAAgB,UAAU;AACjD,cAAW;;AAGb,MAAI,UAAU,EACZ,OAAM,IAAI,MAAM,8CAA8C;EAGhE,MAAM,WAAW;GACf,QAAQ,UAAU;GAClB;GACD;EAKD,MAAM,gBAAgB,UAAU,OAAO,IAAI,UAAU,OAAO,IAAI;AAEhE,MAAI,gBAAgB,KAAK,gBAAgB,SAAS;GAChD,MAAM,WAAW,gBAAgB;AACjC,aAAU,UAAU;;AAGtB,kBAAgB,UAAU;AAC1B,qBAAmB,KAAK,SAAS;;AAGnC,QAAO,mBAAmB,SAAS;;;;;;;;;;;;;AAcrC,SAAgB,uBACd,YACmB;CACnB,MAAM,MAAM,CAAC,GAAG,WAAW;CAC3B,MAAM,SAA4B,EAAE;CAEpC,IAAI,kBAAkB;AAEtB,MAAK,IAAI,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;EACxC,MAAM,YAAY,IAAI;AAGtB,MAFe,UAAU,OAAO,SAAS,QAE7B;AACV;AACA,UAAO,QAAQ;IAAE,QAAQ;IAAM;IAAW,CAAC;aAClC,kBAAkB,GAAG;AAC9B;AACA,UAAO,QAAQ;IAAE,QAAQ;IAAM;IAAW,CAAC;QAE3C,QAAO,QAAQ;GAAE,QAAQ;GAAO;GAAW,CAAC;;AAIhD,QAAO;;;;;;;;;;;;;;AAeT,SAAgB,mBAAmB,QAAkC;CACnE,MAAM,UAAU,OAAO,mBAAmB;AAE1C,KAAI,OAAO,YAAY,SACrB,OAAM,IAAI,MACR,YAAY,OAAO,GAAG,2CACvB;AAGH,QAAO;;AAGT,SAAgB,iBACd,kBACY;CACZ,MAAM,SAAqB,EAAE;CAC7B,IAAI,kBAAkB;AAEtB,MAAK,IAAI,IAAI,iBAAiB,SAAS,GAAG,KAAK,GAAG,KAAK;EACrD,MAAM,KAAK,iBAAiB;AAO5B,MAJE,YAAY,MACX,GAA4B,OAAO,SAAS,UAC7C,GAAG,OAAO,GAEA;AACV;AAEA,UAAO,QAAQ,GAAG;aACT,kBAAkB,EAC3B;MAIA,QAAO,QAAQ,GAAG;;AAItB,QAAO;;AAKT,SAAgB,qBAAqB,YAAyC;AAC5E,QAAO,OAAO,OAAO,WAAW,CAC7B,SAAS,UAAU,MAAM,CACzB,MACE,GAAG,MACF,IAAI,KAAK,EAAE,UAAU,eAAe,CAAC,SAAS,GAC9C,IAAI,KAAK,EAAE,UAAU,eAAe,CAAC,SAAS,CACjD;;AAIL,MAAM,sBACJ,UACG;AACH,QAAO;;;;;;;;;AAUT,SAAgB,sBACd,UACA,WACA,QAAgB,UAAU,OAAO,OACb;AACpB,QAAO;EACL,GAAG;EACH,YAAY;GACV,GAAG,SAAS;IACX,QAAQ,CAAC,GAAI,SAAS,WAAW,UAAU,EAAE,EAAG,UAAU;GAC5D;EACF;;AAMH,SAAgB,eACd,cACA,YACA,SACA,QACA,UACA,uBAA6C,EAAE,EAC/C,SACoB;CACpB,MAAM,EACJ,cAAc,MACd,8BACA,gCAAgC,qBAChC,wBACE,WAAW,EAAE;CAEjB,MAAM,yBAAyB,kBAAkB,aAAa;CAC9D,IAAI,gBAAgB;CACpB,MAAM,qBAAkC,EAAE;CAE1C,MAAM,YAAY,IAAI,IAAI;EAAC,GAAG,OAAO,KAAK,WAAW;EAAE;EAAU;EAAQ,CAAC;CAC1E,MAAM,oBAAwC,EAAE;AAChD,MAAK,MAAM,SAAS,UAClB,mBAAkB,SAAS,EAAE;AAO/B,KAAI,6BACF,MAAK,MAAM,CAAC,OAAO,oBAAoB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,gBACH;EAEF,MAAM,QAAQ,gBAAgB,eAAe,MAAM,CAAC,CAAC,EAAE,eAAe;AACtE,MAAI,QAAQ,GAAG;AACb,sBAAmB,KAAK,GAAG,gBAAgB;AAC3C;;EAEF,MAAM,cAAc,gBAAgB;AACpC,MAAI,CAAC,eAAe,CAAC,YAAY,eAAgB;AACjD,MAAI;GACF,MAAM,aAAa,8BACjB,YAAY,eACb;AACD,mBAAgB;IACd,GAAG;KACF,QAAQ;IACV;GACD,MAAM,kBACJ,kBAAkB;AACpB,OAAI,gBACF,iBAAgB,KAAK,GAAG,gBAAgB,MAAM,GAAG,QAAQ,EAAE,CAAC;AAE9D,sBAAmB,KAAK,GAAG,gBAAgB,MAAM,QAAQ,EAAE,CAAC;UACtD;AAEN,sBAAmB,KAAK,GAAG,gBAAgB;;;KAI/C,oBAAmB,KACjB,GAAG,OAAO,OAAO,WAAW,CAAC,SAAS,QAAQ,OAAO,EAAE,CAAC,CACzD;CAIH,MAAM,WAA+B;EACnC;EACA,OAAO,mBAA2B,cAAc;EAChD,cAAc;EACd,YAAY;EACZ,WAAW,EAAE;EACd;CAED,IAAI,SAAS;AAIb,KAAI,mBAAmB,OACrB,UAAS,mBAAmB,QAAQ,UAAU,cAAc;AAK1D,MAAI,SAAS,UAAU,CACrB,QAAO,qBACL,sBAAsB,UAAU,UAAU,EAC1C,UAAU,OAAO,OACjB,UAAU,eACX;AAYH,SATY,QAAQ,UAAU,UAAU,QAAQ,UAAU;GACxD,sBAAsB;GACtB;GACA;GACA,eAAe,EACb,WACD;GACF,CAAC;IAGD,SAAS;KAKZ,MAAK,MAAM,mBAAmB,OAAO,OAAO,kBAAkB,EAAE;AAC9D,MAAI,CAAC,gBACH;EAEF,MAAM,gBAAgB,gBAAgB,GAAG,GAAG;AAC5C,MAAI,cACF,UAAS,qBACP,QACA,cAAc,OAAO,OACrB,cAAc,eACf;;AAOP,KAAI,CAAC,YACH,MAAK,MAAM,SAAS,OAAO,KAAK,OAAO,MAAM,CAC3C,MAAK,IAAI,IAAI,mBAAmB,SAAS,GAAG,KAAK,GAAG,KAAK;EACvD,MAAM,YAAY,mBAAmB;AAErC,MAAI,UAAU,OAAO,UAAU,MAC7B;AAEF,MAAI,UAAU,SAAS,0BAA0B,QAAQ,MAAM,CAC7D,OAAM,IAAI,kBAAkB,OAAO,QAAQ,UAAU;MAErD;;CAQR,MAAM,kBAAkB,IAAI,IAAI;EAC9B,GAAG,OAAO,KAAK,OAAO,WAAW;EACjC,GAAG,OAAO,KAAK,WAAW;EAC1B;EACA;EACD,CAAC;CACF,MAAM,0BAA8C,EAAE;AACtD,MAAK,MAAM,SAAS,gBAClB,yBAAwB,SAAS,EAAE;CAIrC,MAAM,mBAAuC,MAAM,KACjD,gBACD,CAAC,QAAQ,KAAK,UAAU;EACvB,MAAM,WAAW,OAAO,WAAW,UAAU,EAAE;AAE/C,SAAO;GACL,GAAG;IACF,QAAQ,CACP,GAAG,SAAS,KAAK,WAAW,UAAU;AACpC,WAAO;KACL,GAAG;KACH,WACE,WAAW,SAAS,QAAQ,kBAC5B,UAAU;KACb;KACD,CACH;GACF;IACA,wBAAwB;CAG3B,MAAM,eAAe,SACjB,OAAO,uBACP,OAAO,OAAO,iBAAiB,CAAC,QAAQ,KAAK,SAAS;AACpD,MAAI,CAAC,KACH,QAAO;EAET,MAAM,YAAY,KAAK,GAAG,GAAG;AAC7B,MAAI;OACE,UAAU,iBAAiB,IAC7B,QAAO,UAAU;;AAIrB,SAAO;IACN,SAAS,OAAO,qBAAqB;AAE5C,KAAI,OACF,QAAO,SAAS;EACd,GAAG;EACH,UAAU,OAAO,OAAO;EACxB,sBAAsB;EACvB;AAGH,QAAO;EACL,GAAG;EACH,YAAY;EACb;;AAGH,SAAgB,oBACd,OACQ;CACR,MAAM,YAAY,OAAO;AACzB,KAAI,cAAc,SAChB,QAAO,KAAK,MAAM,MAAO;UAChB,cAAc,SACvB,QAAO;KAEP,OAAM,IAAI,MAAM,yCAAyC,YAAY;;AAIzE,IAAY,qBAAL,yBAAA,oBAAA;AACL,oBAAA,sBAAA;;KACD;AAED,IAAY,wBAAL,yBAAA,uBAAA;AACL,uBAAA,sBAAA;AACA,uBAAA,mBAAA;;KACD;AAeD,SAAgB,gCACd,kBACkB;CAClB,MAAM,SAA2B,EAAE;CAcnC,IAAI,eAAe;AACnB,MAAK,MAAM,iBAAiB,kBAAkB;EAC5C,MAAM,YAAY,cAAc,QAAQ,cAAc;AAEtD,MAAI,cAAc,eAAe,EAC/B,QAAO,KAAK;GACV,WAAW;IACT,OAAO,cAAc;IACrB,MAAM,cAAc;IACrB;GACD,OAAO,mBAAmB;GAC1B,UACE,YAAY,eAAe,IACvB,sBAAsB,gBACtB,sBAAsB;GAC5B,SAAS,kBAAkB,eAAe,EAAE,wCAAwC,cAAc,MAAM,aAAa,cAAc;GACpI,CAAC;AAGJ,iBAAe,cAAc;;AAG/B,QAAO;;AAkBT,SAAgB,eACd,kBACA;CACA,MAAM,SAAqB,EAAE;CAE7B,IAAI,IAAI,iBAAiB,SAAS;AAElC,QAAO,IAAI,IAAI;AACb,SAAO,QAAQ,iBAAiB,GAAG;EACnC,MAAM,aACH,iBAAiB,IAAI,SAAS,MAAM,iBAAiB,IAAI,QAAQ,KAAK;EAEzE,IAAI,IAAI,IAAI;AACZ,SAAO,IAAI,OAAO,iBAAiB,IAAI,SAAS,KAAK,UACnD;AAGF,MAAI;;AAGN,QAAO;;AAET,SAAgB,QAAQ,kBAA+B;CACrD,MAAM,iBAAiB,CAAC,GAAG,iBAAiB;CAC5C,MAAM,kBAAkB,eAAe,eAAe,SAAS;AAE/D,KAAI,CAAC,gBAAiB,QAAO;AAE7B,KAAI,gBAAgB,OAAO,SAAS,OAClC,gBAAe,KAAK;EAClB,GAAG;EACH,OAAO,gBAAgB;EACvB,MAAM,eAAe,iBAAiB;EACtC,QAAQ;GACN,GAAG,gBAAgB;GAGnB,IAAI,YAAY;GAChB,iCAAgB,IAAI,MAAM,EAAC,aAAa;GACxC,MAAM;GACP;EACF,CAAC;KAEF,gBAAe,KAAK;EAClB,IAAI,YAAY;EAChB,iCAAgB,IAAI,MAAM,EAAC,aAAa;EACxC,OAAO,gBAAgB,QAAQ;EAC/B,MAAM;EACN,MAAM,gBAAgB;EACtB,QAAQ;GACN,IAAI,YAAY;GAChB,iCAAgB,IAAI,MAAM,EAAC,aAAa;GACxC,MAAM;GACN,OAAO,EAAE;GACT,OAAO,gBAAgB,OAAO;GAC/B;EACF,CAAC;AAGJ,QAAO;;AAKT,SAAgB,eACd,YACY;AACZ,QAAO,WACJ,OAAO,CACP,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,CAC/B,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;;AAQtC,SAAgB,qBACd,YACA,MACA,MACO;AACP,QAAO,CAAC,GAAG,MAAM,GAAG,KAAK,CACtB,MAAM,GAAG,MAAM;EACd,MAAM,gBACJ,IAAI,KAAK,EAAE,kBAAkB,GAAG,CAAC,SAAS,GAC1C,IAAI,KAAK,EAAE,kBAAkB,GAAG,CAAC,SAAS;AAC5C,MAAI,kBAAkB,EACpB,QAAO;AAET,UAAQ,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,GAAG;GAC7C,CACD,KAAK,IAAI,OAAO;EACf,GAAG;EACH,OAAO,WAAW,QAAQ;EAC1B,MAAM,MAAM,IAAI,WAAW,OAAO;EACnC,EAAE;;AAGP,SAAgB,6BACd,YACA,MACA,MACO;AACP,QAAO,CAAC,GAAG,MAAM,GAAG,KAAK,CACtB,MAAM,GAAG,MAAM;EACd,MAAM,YAAY,EAAE,QAAQ,EAAE;AAC9B,MAAI,cAAc,EAChB,QAAO;EAET,MAAM,gBACJ,IAAI,KAAK,EAAE,kBAAkB,GAAG,CAAC,SAAS,GAC1C,IAAI,KAAK,EAAE,kBAAkB,GAAG,CAAC,SAAS;AAC5C,MAAI,kBAAkB,EACpB,QAAO;AAET,UAAQ,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,GAAG;GAC7C,CACD,KAAK,IAAI,OAAO;EACf,GAAG;EACH,OAAO,WAAW,QAAQ;EAC1B,MAAM,MAAM,IAAI,WAAW,OAAO;EACnC,EAAE;;AAIP,SAAgB,mBAQd,KAAU,KAAmB;CAC7B,MAAM,IAAI;CACV,MAAM,IAAI;CAEV,MAAM,cAAc;EAClB,OAAO,EAAE;EACT,MAAM,EAAE;EACR,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,SAAS;EAClB,OAAO,EAAE,SAAS;EACnB;CAED,MAAM,cAAc;EAClB,OAAO,EAAE;EACT,MAAM,EAAE;EACR,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,SAAS;EAClB,OAAO,EAAE,SAAS;EACnB;AAED,QAAO,UAAU,YAAY,KAAK,UAAU,YAAY;;AAW1D,SAAgB,aACd,OACA,WAC4B;CAC5B,MAAM,YAAY,eAAe,eAAe,MAAM,OAAO,CAAC,CAAC;CAC/D,MAAM,gBAAgB,eAAe,eAAe,UAAU,OAAO,CAAC,CAAC;AACvE,KAAI,UAAU,SAAS,EACrB,QAAO,CAAC,eAAe,EAAE,CAAC;CAG5B,MAAM,SAAsB,EAAE;CAC9B,IAAI,gBAAgB;AAEpB,QAAO,cAAc,SAAS,GAAG;EAC/B,MAAM,wBAAwB,cAAc;EAE5C,IAAI,qBAAqB,UAAU,OAAO;AAC1C,SACE,sBACA,SAAS,oBAAoB,sBAAsB,EACnD;AACA,UAAO,KAAK,mBAAmB;AAC/B,wBAAqB,UAAU,OAAO;;AAGxC,MAAI,CAAC,mBACH,iBAAgB;WACP,CAAC,cACV,KAAI,mBAAmB,oBAAoB,sBAAsB,EAAE;AACjE,iBAAc,OAAO;AACrB,UAAO,KAAK,mBAAmB;SAC1B;AACL,aAAU,QAAQ,mBAAmB;AACrC,mBAAgB;;AAIpB,MAAI,eAAe;GACjB,IAAI,aAAa,cAAc,OAAO;AACtC,UAAO,YAAY;AACjB,WAAO,KAAK,WAAW;AACvB,iBAAa,cAAc,OAAO;;;;AAKxC,KAAI,CAAC,eAAe;EAClB,IAAI,aAAa,UAAU,OAAO;AAClC,SAAO,YAAY;AACjB,UAAO,KAAK,WAAW;AACvB,gBAAa,UAAU,OAAO;;;AAIlC,QAAO,CAAC,eAAe,OAAO,EAAE,UAAU;;AAG5C,SAAgB,SAAS,KAAqB,KAAqB;AACjE,QACE,IAAI,QAAQ,IAAI,SACf,IAAI,UAAU,IAAI,SAAS,IAAI,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI;;AAIpE,SAAgB,MACd,wBACA,uBACyC;CACzC,MAAM,mBAAgC,EAAE;CACxC,MAAM,uBAAoC,EAAE;CAC5C,MAAM,sBAAmC,EAAE;CAG3C,MAAM,YAAY,KAAK,IACrB,uBAAuB,QACvB,sBAAsB,OACvB;CAED,IAAI,gBAAgB;AACpB,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;EAClC,MAAM,kBAAkB,uBAAuB;EAC/C,MAAM,iBAAiB,sBAAsB;AAE7C,MAAI,mBAAmB,eACrB,KACE,CAAC,iBACD,mBAAmB,iBAAiB,eAAe,CAEnD,kBAAiB,KAAK,gBAAgB;OACjC;AACL,mBAAgB;AAChB,wBAAqB,KAAK,gBAAgB;AAC1C,uBAAoB,KAAK,eAAe;;WAEjC,gBACT,sBAAqB,KAAK,gBAAgB;WACjC,eACT,qBAAoB,KAAK,eAAe;;AAI5C,QAAO;EAAC;EAAkB;EAAsB;EAAoB;;AAQtE,SAAgB,MACd,wBACA,uBACA,WACa;CACb,MAAM,CAAC,mBAAmB,mBAAmB,oBAAoB,MAC/D,eAAe,uBAAuB,EACtC,eAAe,sBAAsB,CACtC;CAED,MAAM,iBAAiB,YAAY,kBAAkB;CACrD,MAAM,YACJ,IACA,KAAK,IACH,gBACA,YAAY,kBAAkB,EAC9B,YAAY,iBAAiB,CAC9B;CAEH,MAAM,0BAA0B,2BAC9B,kBACA,kBACD;CAED,MAAM,sBAAsB,UAC1B;EACE,OAAO;EACP,MAAM,aAAa,iBAAiB;EACrC,EACD,mBACA,wBACD;AAED,QAAO,kBAAkB,OAAO,oBAAoB;;AAGtD,SAAS,YAAY,kBAAoC;CACvD,MAAM,cAAc,iBAAiB,iBAAiB,SAAS;AAC/D,KAAI,CAAC,YACH,QAAO;AAGT,QAAO,YAAY;;AAkBrB,SAAgB,eAAe,kBAAoC;AACjE,KAAI,iBAAiB,SAAS,EAC5B,QAAO;CAGT,MAAM,oBAAoB,eAAe,iBAAiB;CAE1D,IAAI,YACD,kBAAkB,kBAAkB,SAAS,IAAI,QAAQ,KAAK;AAEjE,KAAI,kBAAkB,SAAS,EAC7B,aAAY,kBAAkB,kBAAkB,SAAS,IAAI,QAAQ;AAGvE,SAAQ,kBAAkB,kBAAkB,SAAS,IAAI,SAAS,MAChE,WACE,KACA;;AAGN,SAAgB,yBAAyB,YAAyB;AAChE,QAAO,gCACL,eAAe,eAAe,WAAW,CAAC,CAC3C;;AAEH,SAAgB,uBAAuB,YAAyB;AAW9D,QAVe,WAAW,QAA2B,KAAK,cAAc;AACtE,MAAI,CAAC,IAAI,UAAU,OAAO,OACxB,KAAI,UAAU,OAAO,SAAS,EAAE;AAGlC,MAAI,UAAU,OAAO,QAAQ,KAAK,UAAU;AAE5C,SAAO;IACN,EAAE,CAAC;;AAYR,SAAgB,kBACd,mBACA,eACA;CACA,MAAM,SAAkC;EACtC,iBAAiB,EAAE;EACnB,iBAAiB,EAAE;EACnB,mBAAmB,EAAE;EACrB,sBAAsB,EAAE;EACzB;CAED,MAAM,0BAA0B,eAAe,kBAAkB;CACjE,MAAM,mBAAmB,eAAe,cAAc;CAEtD,MAAM,kBAAkB,gCAAgC,CACtD,GAAG,yBACH,GAAG,iBACJ,CAAC;CAQF,MAAM,6BAA6B,CAAC,GANT,gBAAgB,QACxC,mBACC,eAAe,aAAa,sBAAsB,cACrD,CAGyD,CACvD,MAAM,GAAG,MAAM,EAAE,UAAU,QAAQ,EAAE,UAAU,MAAM,CACrD,KAAK,EAAE;AAEV,MAAK,MAAM,gBAAgB,kBAAkB;AAE3C,MACE,8BACA,aAAa,SAAS,2BAA2B,OACjD;AACA,UAAO,kBAAkB,KAAK,aAAa;AAC3C;;AAaF,MAT8B,gBAAgB,MAAM,mBAAmB;AACrE,UACE,eAAe,UAAU,UAAU,aAAa,SAChD,eAAe,UAAU,SAAS,aAAa,QAC/C,eAAe,aAAa,sBAAsB;IAEpD,EAGyB;AACzB,UAAO,qBAAqB,KAAK,aAAa;AAC9C;;AAIF,SAAO,gBAAgB,KAAK,aAAa;;AAG3C,QAAO,gBAAgB,KAAK,GAAG,gBAAgB;AAC/C,QAAO;;AAGT,SAAgB,yBACd,eACA,mBACA;AACA,QAAO,cAAc,QAAQ,iBAAiB;AAC5C,SAAO,CAAC,kBAAkB,MAAM,qBAAqB;AACnD,UACG,aAAa,OAAO,SAAS,UAC5B,aAAa,SAAS,KACtB,aAAa,UAAU,iBAAiB,SACzC,aAAa,UAAU,iBAAiB,SACvC,aAAa,SAAS,iBAAiB,QACvC,aAAa,OAAO,UAAU,iBAAiB,OAAO,SACtD,aAAa,SAAS,iBAAiB,QACvC,aAAa,OAAO,SAAS,iBAAiB,OAAO;IAEzD;GACF;;;;;;;;;AAUJ,SAAgB,qBACd,YACA,qBACa;CAEb,MAAM,YADgB,eAAe,WAAW,CAAC,GAAG,GAAG,EACtB,SAAS;CAC1C,MAAM,YAAY,YAAY;CAE9B,MAAM,qBAAqB;EACzB,GAAG;EACH,OAAO,oBAAoB,SAAS;EACrC;AAED,KAAI,mBAAmB,QAAQ,UAC7B,OAAM,IAAI,MACR,oEAAoE,YACrE;AAOH,QAJ0B,eACxB,eAAe,CAAC,GAAG,YAAY,mBAAmB,CAAC,CACpD,CAEwB,MAAM,GAAG,GAAG;;AAGvC,SAAgB,iCACd,oBACA;AAgBA,QAf0B,OAAO,QAAQ,mBAAmB,CAAC,QAC1D,KAAK,UAAU;EACd,MAAM,CAAC,OAAO,OAAO;AACrB,MAAI,CAAC,IACH,QAAO;AAGT,SAAO;GACL,GAAG;IACF,QAAQ,eAAe,eAAe,IAAI,CAAC;GAC7C;IAEH,EAAE,CACH;;;;;;;;;;AAaH,SAAgB,2BACd,kBACA,kBACK;AACL,QAAO,iBAAiB,QAAQ,OAAO;AACrC,MAAI,GAAG,GACL,QAAO,CAAC,iBAAiB,MAAM,aAAa,SAAS,OAAO,GAAG,GAAG;AAGpE,SAAO;GACP;;AAGJ,SAAgB,uCACd,oBACA;AACA,KAAI,CAAC,mBACH,QAAO,EAAE;AAKX,QAFgB,OAAO,QAAQ,mBAAmB,CAEnC,QAAQ,KAAK,CAAC,OAAO,gBAAgB;AAClD,MAAI,CAAC,WACH,QAAO;AAET,SAAO;GACL,GAAG;IACF,QAAQ,WAAW,KAAK,OAAO;IAC9B,MAAM,EAAE,gBAAgB,GAAG,cAAc;AAEzC,WAAO;KACP;GACH;IACA,EAAE,CAAuB;;;;;;;;;;;AAY9B,SAAgB,eACd,oBACA,oBACO;AACP,QAAO,mBAAmB,QACvB,eACC,CAAC,mBAAmB,MACjB,eAAe,WAAW,UAAU,WAAW,MACjD,CACJ;;AAKH,SAAgB,wBAAwB,UAAsB;CAC5D,IAAI;AAEJ,MAAK,MAAM,OAAO,OAAO,OAAO,SAAS,WAAW,EAAE;AACpD,MAAI,CAAC,IAAK;AACV,OAAK,MAAM,MAAM,IACf,KACE,CAAC,UACD,GAAG,QAAQ,OAAO,SACjB,GAAG,UAAU,OAAO,SAAS,GAAG,OAAO,OAAO,KAE/C,UAAS;;AAKf,QAAO,QAAQ,kBAAkB,SAAS,OAAO;;;;;;;;;AAUnD,SAAS,gBAAgB,UAAsB,OAAe;AAG5D,SAFwB,SAAS,WAAW,QACV,GAAG,GAAG,EAAE,SAAS,MACjC;;;;;;;;;;;AAYpB,SAAgB,qBACd,UACA,OACA,uBACY;CACZ,MAAM,eACJ,yBAAyB,wBAAwB,SAAS;CAC5D,MAAM,mBAAmB,SAAS,OAAO;CAEzC,MAAM,SAA2B;EAC/B,GAAG,SAAS;EACZ,UAAU;GACR,GAAG,SAAS,OAAO;IAClB,QAAQ,gBAAgB,UAAU,MAAM;GAC1C;EACD,sBACE,CAAC,oBAAoB,eAAe,mBAChC,eACA;EACP;AAED,QAAO;EACL,GAAG;EACH;EACD;;;;ACp4CH,SAAgB,iBACd,UACA,OACA;AACA,QAAO;EAAE,GAAG;EAAU,QAAQ;GAAE,GAAG,SAAS;GAAQ,MAAM,MAAM;GAAM;EAAE;;AAI1E,SAAgB,4BACd,UACA,OACW;CACX,MAAM,eAAe,SAAS,OAAO,QAAQ,EAAE;AAC/C,KAAI,MAAM,gBACR,QAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG,SAAS;GACZ,MAAM;IAAE,GAAG;IAAc,iBAAiB,MAAM;IAAiB;GAClE;EACF;CAEH,MAAM,EAAE,iBAAiB,UAAU,GAAG,SAAS;AAC/C,QAAO;EACL,GAAG;EACH,QAAQ;GAAE,GAAG,SAAS;GAAQ,MAAM;GAAM;EAC3C;;AAGH,SAAgB,cACd,UACA,QACA,MAMA;CAEA,MAAM,EAAE,UAAU;AASlB,QAAO,OAPe;EACpB;EACA;EACA;EACA,yBAAyB;EAC1B,GAE6B,UAAU;EAEtC,MAAM,mBAAmB,eADN,CAAC,GAAG,SAAS,WAAW,OAAO,CACC;AAEnD,QAAM,SAAS,KAAK,MAAM;EAE1B,MAAM,gBAAgB,iBAAiB,GAAG,GAAG;EAC7C,IAAI,YAAY,eAAe,SAAS;EAExC,MAAM,YAAY,eAAe,OAAO,SAAS;AAEjD,MAAI,UACF,aAAY,YAAY;MAExB,OAAM,0BAA0B;AAOlC,QAAM,OAAO,eAJgB,YACzB,CAAC,GAAG,kBAAkB;GAAE,OAAO;GAAW,MAAM;GAAG,CAAC,GACpD,iBAE6C;AAEjD,MAAI,iBAAiB,MAAM,OAAO,cAAc,OAAO,EAGrD,OAAM,OAAO,MAAM,OAAO;AAG5B,MAAI,MAAM,OAAO,EACf,OAAM,IAAI,MACR,iFACD;GAEH;;;;;;;;;AAUJ,SAAgB,gBACd,UACA,QACA,MAMA;CACA,MAAM,EAAE,UAAU;AASlB,QAAO,OAPe;EACpB;EACA;EACA;EACA,yBAAyB;EAC1B,GAE6B,UAAU;EAEtC,MAAM,mBAAmB,eAAe,CAAC,GADtB,SAAS,WAAW,UAAU,EAAE,CACI,CAAC;EAGxD,MAAM,aAAa,iBAAiB,QACjC,OAAO,GAAG,OAAO,SAAS,OAC5B;EAGD,IAAI,kBAAkB;AACtB,OAAK,IAAI,IAAI,iBAAiB,SAAS,GAAG,KAAK,GAAG,IAChD,KAAI,iBAAiB,GAAG,OAAO,SAAS,OACtC;MAEA;AAKJ,MAAI,WAAW,UAAU,gBACvB,OAAM,IAAI,MACR,2DACD;AAGH,QAAM,SAAS,KAAK,MAAM;AAC1B,QAAM,OAAO;GACb;;AAGJ,SAAgB,cACd,UACA,QACA,MAMA;CACA,MAAM,EAAE,OAAO,UAAU;AASzB,QAAO,OAPe;EACpB;EACA;EACA;EACA,yBAAyB;EAC1B,GAE6B,UAAU;AACtC,MAAI,MAAM,OAAO,EACf,OAAM,IAAI,MACR,uEACD;EAIH,MAAM,QACJ,OAAO,UAAU,YAAY,UAAU,QAAQ,WAAW,QACrD,MAA4B,QAC7B;AAEN,MAAI,OAAO,UAAU,YAAY,QAAQ,EACvC,OAAM,IAAI,MAAM,yDAAyD;AAG3E,MAAI,OAAO,UAAU,YAAY,QAAQ,EACvC,OAAM,IAAI,MAAM,gDAAgD;AAGlE,MAAI,MAAM,SAAS,UAAU,SAAS,EACpC,OAAM,IAAI,MAAM,8CAA8C;EAGhE,MAAM,iBAAiB,MAAM,SAAS,UAAU,eAC7C,OAAO,GAAG,OAAO,UAAU,MAC7B;AACD,MAAI,iBAAiB,EACnB,OAAM,IAAI,MACR,sDAAsD,MAAM,GAC7D;EAGH,MAAM,YAAY,MAAM,SAAS,UAAU,OAAO,gBAAgB,EAAE,CAAC;AAErE,QAAM,SAAS,UAAU;GACvB,MAAM,UAAU,OAAO;GACvB,OAAO,UAAU,OAAO;GACxB,OAAO,UAAU,OAAO;GACzB,CAAW;GACZ;;AAGJ,SAAgB,mBACd,UACA,QACoB;CACpB,MAAM,SAAS,kBAAkB,OAAO,MAAM,KAAe;AAG7D,QAAO,OAAO,oBACZ,SAAS,OAAO,IAChB,SAAS,OAAO,cAChB,kBAAkB,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC,MACzC,OAAO,KACR;AACD,QAAO;EACL,GAAG;EACH,QAAQ;GAAE,GAAG,SAAS;GAAQ,MAAM,OAAO,MAAM;GAAM;EACvD,OAAO;EACR;;;;;;AA0FH,SAAgB,iBAAiB,WAAwC;AACvE,KAAI,UAAU,iBAAiB,KAAA,EAC7B,QAAO;EAAE,MAAM;EAAU,QAAQ,UAAU;EAAc;AAG3D,KAAI,UAAU,UAAU,KAAA,EACtB,QAAO;EAAE,MAAM;EAAiB,SAAS,UAAU;EAAO;AAG5D,QAAO,EAAE,MAAM,WAAW;;;;AC1R5B,SAAgB,iBACd,cACA,mBACA,cACA,QACA,UACA,kBAAkB,aAClB,uBAA6C,EAAE,EAC/C,SACoB;AAKpB,QAAO,eACL,cACA,mBAJqB,cAAc,cAAc,gBAAgB,EAMjE,QACA,UACA,sBACA,QACD;;;;;;;;;;;;;AAcH,SAAS,0BACP,UACA,QACA,yBACA,MACA,SACW;AAGX,KAAI;EAAC;EAAQ;EAAQ;EAAQ,CAAC,SAAS,OAAO,KAAK,CACjD,QAAO;CAGT,MAAM,QAAQ,OAAO;CACrB,MAAM,WAAW,SAAS,WAAW;CAErC,MAAM,qBAAqB,UAAU,GAAG,GAAG,EAAE,SAAS;CAMtD,MAAM,eAAe,oBAAoB,QAJ3B,0BACV,qBACA,qBAAqB,GAE+B,MAAM,QAAQ;CAEtE,MAAM,aAAa,CAAC,GAAI,YAAY,EAAE,EAAG,aAAa;AAEtD,QAAO;EACL,GAAG;EACH,YAAY;GAAE,GAAG,SAAS;IAAa,QAAQ;GAAY;EAC5D;;AAGH,SAAS,6BACP,UACA,WACA,yBACA,MACA,SACA,qBACW;CACX,MAAM,QAAQ,UAAU,OAAO;CAC/B,MAAM,WAAW,SAAS,WAAW;CAErC,MAAM,qBAAqB,UAAU,GAAG,GAAG,EAAE,SAAS;CAEtD,MAAM,YAAY,0BACd,qBACA,qBAAqB;AAEzB,KAAI,CAAC,uBAAuB,UAAU,QAAQ,OAAO,UACnD,OAAM,IAAI,MACR,gCAAgC,UAAU,wCAAwC,UAAU,MAAM,aAAa,OAChH;CAGH,MAAM,eAAe,uBACnB,WACA,UAAU,OACV,MACA,QACD;CAED,MAAM,aAAa,CAAC,GAAI,YAAY,EAAE,EAAG,aAAa;AAEtD,QAAO;EACL,GAAG;EACH,YAAY;GAAE,GAAG,SAAS;IAAa,QAAQ;GAAY;EAC5D;;;;;;;;;;;;AAaH,SAAgB,eACd,UACA,QACA,yBACA,MACA,SACA,WACA,qBACW;CACX,IAAI;AACJ,KAAI,UAEF,eAAc,6BACZ,UACA,WACA,yBACA,MACA,SACA,oBACD;KAGD,eAAc,0BACZ,UACA,QACA,yBACA,MACA,QACD;AAGH,eAAc,qBACZ,aACA,OAAO,OACP,OAAO,eACR;AACD,QAAO;;;;;;;;;;AAWT,SAAS,aACP,UACA,QACA,gBACoB;CAEpB,MAAM,eAAe,sBAAsB,CAAC,MAAM,OAAO;AAEzD,SAAQ,aAAa,MAArB;EAEE,KAAK,WACH,QAAO,iBAAiB,UAAU,aAAa,MAAM;EACvD,KAAK,uBACH,QAAO,4BAA4B,UAAU,aAAa,MAAM;EAClE,KAAK,QACH,QAAO,eAAe,UAAU,aAAa,OAAO,eAAe;EACrE,KAAK,aACH,QAAO,mBAAmB,UAAU,aAAa,MAAM;EACzD,QACE,QAAO;;;;;;;;;;;AAYb,SAAgB,gBACd,UACA,QACA,MACA,kBAAkB,GAMlB;AACA,SAAQ,OAAO,MAAf;EACE,KAAK;AACH,OAAI,mBAAmB,EACrB,QAAO,gBAAgB,UAAU,QAAQ,KAAK;AAEhD,UAAO,cAAc,UAAU,QAAQ,KAAK;EAC9C,KAAK,OACH,QAAO,cAAc,UAAU,QAAQ,KAAK;EAC9C,QACE,QAAO;GAAE;GAAU;GAAQ;GAAM,yBAAyB;GAAO;;;AAIvE,SAAS,qBACP,UACA,QACA,eACA,WACA,+BAA+B,OAC/B,uBAAuB,qBACH;CACpB,MAAM,QAAQ,OAAO;CAErB,MAAM,kBAAkB,SAAS,WAAW;AAC5C,KAAI,CAAC,gBACH,QAAO;CAGT,MAAM,kBAAkB,gBAAgB,GAAG,GAAG;AAE9C,KAAI,CAAC,gBAAiB,QAAO;CAE7B,MAAM,qBAAqB,iCAAiC;EAC1D,GAAG,SAAS;GACX,QAAQ,qBAAqB,iBAAiB,gBAAgB;EAChE,CAAC;CAEF,IAAI,aAAsB,KAAA;CAE1B,MAAM,yBADmB,mBAAmB,QACK,GAAG,GAAG;AAKvD,KAAI,gCAAgC,wBAAwB,eAC1D,cAAa,qBAAqB,uBAAuB,eAAe;MACnE;EACL,MAAM,EAAE,UAAU,iBAChB,SAAS,cACT,oBACA,eACA,SAAS,QACT,KAAA,GACA,KAAA,GACA,KAAA,GACA;GACE;GACA,+BAA+B;GAC/B,qBAAqB;GACtB,CACF;AAED,eAAc,MAAkC;;AAGlD,QAAO;EACL,GAAG;EACH,OAAO;GACL,GAAG,SAAS;IACX,QAAQ;GACV;EACD,YAAY,iCAAiC,EAC3C,GAAG,SAAS,YACb,CAAC;EACH;;AAGH,SAAS,qBACP,UACA,OACA,eACA,+BAA+B,OAC/B,uBAAuB,qBACH;CACpB,MAAM,kBAAkB,SAAS,WAAW;AAC5C,KAAI,CAAC,gBACH,QAAO;CAGT,MAAM,mBAAmB,eADN,CAAC,GAAG,gBAAgB,CACY;AAEnD,kBAAiB,KAAK;CAEtB,MAAM,qBAAqB,iCAAiC,EAC1D,GAAG,SAAS,YACb,CAAC;CAEF,MAAM,mBAAmB,mBAAmB;AAC5C,KAAI,CAAC,iBACH,QAAO;CAET,MAAM,oBAAoB,CAAC,GAAG,iBAAiB;CAC/C,MAAM,OAAO,eACX,eAAe,iBAAiB,EAChC,kBACD;CAED,MAAM,MAAM,iBACV,SAAS,cACT,oBACA,eACA,SAAS,QACT,KAAA,GACA,KAAA,GACA,KAAA,GACA;EACE;EACA,+BAA+B;EAChC,CACF;CAED,MAAM,YAAY,eAChB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,CAAC,QAAQ,OAAO,GAAG,OAAO,SAAS,OAAO,CAC3E,CAAC,SAAS;AAEX,QAAO;EAAE,GAAG;EAAK;EAAW;;;;;;;;;;;;;;AAe9B,SAAgB,YACd,UACA,QACA,eACA,UACA,UAA0B,EAAE,EACR;CACpB,MAAM,EACJ,MACA,uBAAuB,OACvB,+BAA+B,OAC/B,+BACA,cAAc,MACd,SAAS,WACP;CAEJ,IAAI,UAAkB,iBAAiB,OAAO;AAI9C,8BAA6B,QAAQ;CAErC,IAAI,YAAY,QAAQ,QAAQ,eAAe,UAAU,QAAQ;CACjE,IAAI,cAAc,EAChB,GAAG,UACJ;CACD,IAAI,0BAA0B;CAE9B,MAAM,6BAA6B,CAAC,wBAAwB,YAAY;AAExE,KAAI,WAAW,QAAQ,EAAE;EACvB,MAAM,EACJ,MAAM,gBACN,QAAQ,mBACR,UAAU,mBACV,yBAAyB,eACvB,gBACF,UACA,SACA,WACA,QAAQ,mBAAmB,mBAAmB,SAAS,OAAO,CAC/D;AAED,YAAU;AACV,cAAY;AACZ,gBAAc;AACd,4BAA0B;OAE1B,eAAc;EACZ,GAAG;EACH,WAAW,EAAE;EACd;AAKH,KAAI,iBAAiB,QAAQ,CAC3B,eAAc,aAAa,aAAa,SAAS,cAAc;CAKjE,MAAM,mBAAmB;EACvB,YAAY,SAAS,OAAO;EAC5B,OAAO,QAAQ;EACf;EACD;AAED,eAAc,eACZ,aACA,SACA,yBACA,WACA,kBACA,QAAQ,eAAe,WACvB,QAAQ,oBACT;CAKD,MAAM,kBACJ,QAAQ,mBAAmB,mBAAmB,SAAS,OAAO;AAChE,KAAI,OAAO,OAAO,IAAI,kBAAkB,EAMtC,QALe,qBACb,aACA,OAAO,OACP,cACD;CAMH,MAAM,iBAAiB,QAAQ,SAAS,UAAU,YAAY;AAC9D,MAAK,OAAO,OAAO,IAAI,mBAAmB,mBAAmB,GAAG;EAC9D,MAAM,QAAQ,QAAQ;EAQtB,MAAM,cAHe,iBAHH,eAAe,CAAC,GADV,YAAY,WAAW,UAAU,EAAE,CACN,CAAC,CAGN,CAGf,QAC9B,OAAkB,GAAG,OAAO,SAAS,OACvC;EAGD,MAAM,YAAgC;GACpC,GAAG,YAAY;IACd,QAAQ;GACV;AAgBD,SAAO;GACL,GAbiB,iBACjB,YAAY,cACZ,WACA,eACA,YAAY,QACZ,UACA,aACA,EAAE,EACF,EAAE,qBAAqB,MAAM,CAC9B;GAKC,YAAY,YAAY;GACxB,WAAW,EAAE;GACd;;AAGH,KAAI,4BAA4B;EAC9B,MAAM,YAAY,qBAChB,aACA,SACA,eACA,WACA,8BACA,8BACD;AAGD,MAAI,CAAC,YACH,eAAc;GACZ,GAAG;GACH,YAAY,YAAY;GACzB;MAED,eAAc;;AAOlB,eAAc,OAAO,cAAc,UAAU;AAG3C,MAAI;AAGF,OAAI,QAAQ,UAAU,QAAQ;IAC5B,MAAM,YAAY,gBAAgB,aAAa,QAAQ,CAAC;AACxD,iBAAa;AACX,WAAM,QAAQ,UAAU,UAAU;MAClC;AACF;;GAEF,MAAM,WAAW,cAAc,MAAM,OAAO,SAAS,SAAS;AAM9D,OAAI,SAEF,cAAa;AAEX,UAAM,QAAQ,UAAU,SAAS;KAEjC;WAMG,OAAO;GAGd,MAAM,iBAAiB,YAAY,WAAW,QAAQ;AACtD,OAAI,CAAC,eACH,OAAM,IAAI,MAAM,kCAAkC,QAAQ,SAAS,EACjE,OAAO,OACR,CAAC;GAEJ,MAAM,qBAAqB,eAAe,SAAS;GACnD,MAAM,gBAAgB,MAAM,WAAW,QAAQ;AAC/C,OAAI,CAAC,cACH,OAAM,IAAI,MACR,2CAA2C,QAAQ,SACnD,EAAE,OAAO,OAAO,CACjB;AAEH,iBAAc,oBAAoB,QAAS,MAAgB;AAE3D,iBAAc,oBAAoB,OAAO;AAEzC,OAAI,4BAA4B;AAC9B,UAAM,QAAQ,UAAU,EACtB,GAAG,SAAS,OACb,CAAC;IACF,MAAM,mBAAmB,SAAS,WAAW,QAAQ;AACrD,QAAI,CAAC,iBACH,OAAM,IAAI,MAAM,kCAAkC,QAAQ,SAAS,EACjE,OAAO,OACR,CAAC;AAEJ,UAAM,aAAa,UAAU;KAC3B,GAAG,SAAS;MACX,QAAQ,QAAQ,CACf,GAAG,kBACH,EACE,GAAG,cAAc,qBAClB,CACF;KACF,CAAC;;;GAGN;AAGF,KAAI;EAAC;EAAQ;EAAQ;EAAQ,CAAC,SAAS,QAAQ,KAAK,CAClD,QAAO;CAKT,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,aAAa,QAAQ,eAAe,UAAU;CACpD,MAAM,OAAO,aACT,aACA,0BAA0B,aAAa,MAAM;CAIjD,MAAM,gBADkB,YAAY,WAAW,QACR,GAAG,GAAG;AAC7C,KAAI,eAAe;AACjB,gBAAc,OAAO;AAErB,MAAI,6BACF,eAAc,iBAAiB,KAAK,UACjC,YAAY,MAAkC,OAChD;;AAIL,QAAO;;;;;;;;;;;;;;;;;;;;AAqBT,SAAgB,cACd,cACA,kBAAkB,aACD;CACjB,MAAM,WACJ,UACA,QACA,UACA,YACG;AACH,SAAO,gBAAgB,UAAU,QAAQ,cAAc,UAAU,QAAQ;;AAE3E,QAAO;;AAGT,SAAgB,eACd,UACA,OACA,gBACoB;CACpB,MAAM,aAAa,SAAS,WAAW;AACvC,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,6BAA6B;CAG/C,IAAI,EAAE,OAAO,QAAQ;AACrB,SAAQ,SAAS;AACjB,OAAM,OAAO,WAAW;CAExB,MAAM,iBAAiB,WAAW,MAAM,OAAO,IAAI;CACnD,MAAM,qBAAqB,WAAW,MAAM,GAAG,MAAM;CACrD,MAAM,mBAAmB,WAAW,MAAM,IAAI;CAI9C,MAAM,cAAc,iBAClB,SAAS,cACT;EACE,GAAG,SAAS;EACZ,QAAQ,mBAAmB,OAAO,eAAe;EAClD,EACD,gBACA,SAAS,OACV;CAED,MAAM,WAAW,YAAY;CAC7B,MAAM,OAAO,YAAY,OAAO;CAGhC,MAAM,iBAAiB,mBAAmB;CAI1C,MAAM,qBAAqB,mBAAmB,SAC1C,mBAAmB,mBAAmB,SAAS,GAAG,iBAClD,iBAAiB,SACf,iBAAiB,GAAG,kCACpB,IAAI,MAAM,EAAC,aAAa;CAE9B,MAAM,SAAS,UAAU;EAAE;EAAM,GAAG;EAAU,EAAE,eAAe,OAAO;AAGtE,QAAO,iBACL,SAAS,cACT;EACE,GAAG,SAAS;EACZ,QAAQ;GACN,GAAG;GACH;IACE,MAAM;IACN,GAAG;IACH;IACA,gBAAgB;IAChB,OAAO;IACP,MAAM,0BAA0B,EAAE,OAAO,UAAU,EAAE,SAAS;IAC/D;GACD,GAAG,iBAEA,KAAK,QAAQ,WAAW;IACvB,GAAG;IACH,OAAO,iBAAiB,QAAQ;IACjC,EAAE;GACN;EACF,EACD,gBACA,SAAS,OACV;;;;;;;;AC5uBH,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;AASD,MAAa,yBAAyB;AAEtC,SAAgB,2BAA2B,MAAuB;AAChE,QAAO,uBAAuB,KAAK,KAAK;;;;;AAM1C,SAAgB,wBAAwB,MAAuB;AAC7D,QAAO,yBAAyB,SAC9B,KAAK,aAAa,CACnB;;;;;;AAOH,SAAgB,qBACd,OACA,oBACU;CACV,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,KAAI,CAAC,WAAY,QAAO,EAAE;CAE1B,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,UAAU,WAAW,QAC9B,MAAK,MAAM,aAAa,OAAO,YAAY;AACzC,MAAI,sBAAsB,UAAU,OAAO,mBAAoB;AAC/D,MAAI,UAAU,KAAM,OAAM,KAAK,UAAU,KAAK,aAAa,CAAC;;AAGhE,QAAO;;;;;;;;;;AAWT,SAAgB,sBACd,MACA,OACA,oBACM;AACN,KAAI,CAAC,KAAM;AAEX,KAAI,CAAC,2BAA2B,KAAK,EAAE;EACrC,MAAM,aAAa,aAAa,KAAK;EACrC,MAAM,OACJ,cACA,eAAe,QACf,2BAA2B,WAAW,GAClC,kBAAkB,WAAW,MAC7B;AACN,QAAM,IAAI,MACR,mBAAmB,KAAK,6DAA6D,uBAAuB,OAAO,IAAI,OACxH;;CAGH,MAAM,YAAY,KAAK,aAAa;AAEpC,KAAI,wBAAwB,KAAK,CAC/B,OAAM,IAAI,MACR,mBAAmB,KAAK,6CACzB;AAIH,KADsB,qBAAqB,OAAO,mBAAmB,CACnD,SAAS,UAAU,CACnC,OAAM,IAAI,MACR,mBAAmB,KAAK,4FACzB;;AAIL,SAAgB,qBACd,cACA,kBAAkB,OACC;CACnB,MAAM,SAA4B,EAAE;AAEpC,KAAI,mBAAmB,iBAAiB,GAAI,QAAO;AAEnD,KAAI;EACF,MAAM,QAAQ,KAAK,MAAM,aAAa;AAEtC,MAAI,CAAC,mBAAmB,CAAC,OAAO,KAAK,MAAM,CAAC,OAC1C,QAAO,KAAK;GACV,SAAS;GACT,SAAS,EACP,cACD;GACF,CAAC;SAEE;AACN,SAAO,KAAK;GACV,SAAS;GACT,SAAS,EACP,cACD;GACF,CAAC;;AAGJ,QAAO;;AAGT,SAAgB,wBACd,QACA,cACA,QAAQ,IACR,mBAAmB,MACA;CACnB,MAAM,SAA4B,EAAE;AAEpC,KAAI,CAAC,oBAAoB,CAAC,QAAQ;AAChC,SAAO,KAAK;GACV,SAAS;GACT,SAAS,EACP,QACD;GACF,CAAC;AAEF,SAAO;;AAGT,KAAI,oBAAoB,CAAC,OAAQ,QAAO;CAExC,MAAM,mBAAmB,GAAG,WAAW,aAAa,GAAG,WAAW,MAAM,CAAC;AASzE,KAAI,CAJgB,IAAI,OACtB,cAAc,iBAAiB,iBAChC,CAEgB,KAAK,OAAO,CAC3B,QAAO,KAAK;EACV,SAAS,4CAA4C;EACrD,SAAS,EACP,QACD;EACF,CAAC;AAGJ,QAAO;;AAGT,SAAgB,gBACd,SACmB;CACnB,MAAM,SAA4B,EAAE;AACpC,KAAI,CAAC,QAAQ,OACX,QAAO,KAAK;EACV,SAAS;EACT,SAAS,EACP,SACD;EACF,CAAC;CAGJ,MAAM,eAAe,QAAQ,QAC1B,KAAK,QAAQ,CAAC,GAAG,KAAK,GAAG,eAAe,IAAI,CAAC,EAC9C,EAAE,CACH;AAED,QAAO,CAAC,GAAG,QAAQ,GAAG,aAAa;;AAGrC,SAAgB,eAAe,KAA6C;CAC1E,MAAM,SAA4B,EAAE;AAEpC,KAAI,CAAC,IAAI,KACP,QAAO,KAAK;EACV,SAAS;EACT,SAAS,EACP,QAAQ,KACT;EACF,CAAC;AAGJ,KAAI,CAAC,IAAI,WAAW,OAClB,QAAO,KAAK;EACV,SAAS;EACT,SAAS,EACP,QAAQ,KACT;EACF,CAAC;CAGJ,MAAM,kBAAkB,IAAI,WAAW,QACpC,KAAK,cAAc,CAAC,GAAG,KAAK,GAAG,wBAAwB,UAAU,CAAC,EACnE,EAAE,CACH;AAED,QAAO,CAAC,GAAG,QAAQ,GAAG,gBAAgB;;AAGxC,SAAgB,wBACd,WACmB;CACnB,MAAM,SAA4B,EAAE;AAEpC,KAAI,CAAC,UAAU,KACb,QAAO,KAAK;EACV,SAAS;EACT,SAAS,EACP,WACD;EACF,CAAC;AAGJ,KAAI,CAAC,UAAU,OACb,QAAO,KAAK;EACV,SAAS;EACT,SAAS,EACP,WACD;EACF,CAAC;AAGJ,QAAO;;;;;;;AAQT,SAAgB,kBACd,OACA,UACqB;CAErB,MAAM,MADa,MAAM,eAAe,MAAM,eAAe,SAAS,IAC9C,QAAQ,MAAM,MAAM,EAAE,OAAO,SAAS;AAC9D,KAAI,CAAC,IACH,OAAM,IAAI,MACR,WAAW,SAAS,yCACrB;AAEH,QAAO;;;;;;;AAQT,SAAgB,qBACd,OACA,aACwB;CACxB,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,KAAI,WACF,MAAK,MAAM,OAAO,WAAW,SAAS;EACpC,MAAM,KAAK,IAAI,WAAW,MAAM,MAAM,EAAE,OAAO,YAAY;AAC3D,MAAI,GAAI,QAAO;;AAGnB,OAAM,IAAI,MACR,cAAc,YAAY,yCAC3B;;;;;;;;AASH,SAAgB,0BACd,OACA,SAC6B;CAE7B,MAAM,UADa,MAAM,eAAe,MAAM,eAAe,SAAS,IAExD,QAAQ,SAAS,QAC3B,IAAI,WAAW,SAAS,OAAO,GAAG,OAAO,QAAQ,MAAM,EAAE,OAAO,QAAQ,CAAC,CAC1E,IAAI,EAAE;AACT,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MACR,oBAAoB,QAAQ,yCAC7B;AAEH,KAAI,QAAQ,SAAS,EACnB,OAAM,IAAI,MACR,oBAAoB,QAAQ,6CAC7B;AAEH,QAAO,QAAQ;;;;;;;AAQjB,SAAgB,4BACd,OACA,WACa;CAEb,MAAM,UADa,MAAM,eAAe,MAAM,eAAe,SAAS,IAExD,QAAQ,SAAS,QAC3B,IAAI,WAAW,SAAS,OACtB,GAAG,SAAS,QAAQ,MAAM,EAAE,OAAO,UAAU,CAC9C,CACF,IAAI,EAAE;AACT,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MACR,sBAAsB,UAAU,yCACjC;AAEH,KAAI,QAAQ,SAAS,EACnB,OAAM,IAAI,MACR,sBAAsB,UAAU,6CACjC;AAEH,QAAO,QAAQ;;;;;;;AAQjB,SAAgB,qBACd,OACA,IACM;AAEN,KADmB,MAAM,eAAe,MAAM,eAAe,SAAS,IACtD,QAAQ,MAAM,MAAM,EAAE,OAAO,GAAG,CAC9C,OAAM,IAAI,MACR,WAAW,GAAG,8CACf;;;;;;AAQL,SAAgB,wBACd,OACA,IACM;AAKN,KAJmB,MAAM,eAAe,MAAM,eAAe,SAAS,IAC3C,QAAQ,MAAM,MACvC,EAAE,WAAW,MAAM,MAAM,EAAE,OAAO,GAAG,CACtC,CAEC,OAAM,IAAI,MACR,cAAc,GAAG,8CAClB;;;;;;;AASL,SAAgB,6BACd,OACA,IACM;AAKN,KAJmB,MAAM,eAAe,MAAM,eAAe,SAAS,IAC3C,QAAQ,MAAM,MACvC,EAAE,WAAW,MAAM,MAAM,EAAE,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG,CAAC,CAC5D,CAEC,OAAM,IAAI,MACR,oBAAoB,GAAG,8CACxB;;;;;;;AASL,SAAgB,+BACd,OACA,IACM;AAKN,KAJmB,MAAM,eAAe,MAAM,eAAe,SAAS,IAC3C,QAAQ,MAAM,MACvC,EAAE,WAAW,MAAM,MAAM,EAAE,SAAS,MAAM,MAAM,EAAE,OAAO,GAAG,CAAC,CAC9D,CAEC,OAAM,IAAI,MACR,sBAAsB,GAAG,8CAC1B;;AAIL,SAAgB,mBAAmB,YAAgC;CACjE,MAAM,SAA4B,EAAE;CACpC,MAAM,SAAS,OAAO,KAAK,WAAW;AAEtC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,kBAAkB,WAAW;AACnC,MAAI,CAAC,gBACH;EAEF,MAAM,MAAM,gBAAgB,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;EAE7D,IAAI,UAAU;AAEd,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,aAAU,UAAU,IAAI,IAAI,GAAG;AAC/B,OAAI,IAAI,GAAG,UAAU,QACnB,QAAO,KAAK;IACV,SAAS,2BAA2B,IAAI,GAAG,MAAM,eAAe;IAChE,SAAS;KACP,UAAU;KACV,WAAW,IAAI;KACf,OAAO,IAAI,GAAG,OAAO;KACtB;IACF,CAAC;;;AAKR,QAAO;;;;;;;;;;ACtVT,SAAS,QACP,OACA,OACS;CACT,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AACjD,MAAK,MAAM,MAAM,MACf,KAAI,CAAC,IAAI,IAAI,GAAG,CACd,OAAM,IAAI,MAAM,+BAA+B,GAAG,GAAG;CAGzD,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK,IAAI,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC;AAC3D,QAAO,MACJ,KAAK,MAAM,WAAW;EAAE;EAAM;EAAO,EAAE,CACvC,MAAM,GAAG,MAAM;AAGd,UAFW,KAAK,IAAI,EAAE,KAAK,GAAG,IAAI,OAAO,qBAC9B,KAAK,IAAI,EAAE,KAAK,GAAG,IAAI,OAAO,qBACvB,EAAE,QAAQ,EAAE;GAC9B,CACD,KAAK,EAAE,WAAW,KAAK;;AAG5B,MAAa,6BAA4D;CACvE,sBAAsB,OAAO,QAAQ;AACnC,QAAM,OAAO,OAAO,MAAM;;CAG5B,oBAAoB,OAAO,QAAQ;AACjC,QAAM,KAAK,OAAO,MAAM;;CAG1B,2BAA2B,OAAO,QAAQ;AACxC,QAAM,YAAY,OAAO,MAAM;;CAGjC,6BAA6B,OAAO,QAAQ;AAC1C,QAAM,cAAc,OAAO,MAAM;;CAGnC,uBAAuB,OAAO,QAAQ;AACpC,QAAM,SAAS,MAAM,UAAU;GAAE,MAAM;GAAI,SAAS;GAAM;AAC1D,QAAM,OAAO,OAAO,OAAO,MAAM;;CAGnC,0BAA0B,OAAO,QAAQ;AACvC,QAAM,SAAS,MAAM,UAAU;GAAE,MAAM;GAAI,SAAS;GAAM;AAC1D,QAAM,OAAO,UAAU,OAAO,MAAM;;CAEvC;AACD,MAAa,6BAA4D;CACvE,mBAAmB,OAAO,QAAQ;AAChC,uBAAqB,OAAO,OAAO,MAAM,GAAG;AACzB,QAAM,eAAe,MAAM,eAAe,SAAS,GAC3D,QAAQ,KAAK;GACtB,IAAI,OAAO,MAAM;GACjB,MAAM,OAAO,MAAM;GACnB,aAAa,OAAO,MAAM,eAAe;GACzC,YAAY,EAAE;GACf,CAAC;;CAGJ,uBAAuB,OAAO,QAAQ;EACpC,MAAM,eAAe,kBAAkB,OAAO,OAAO,MAAM,GAAG;AAC9D,eAAa,OAAO,OAAO,MAAM,QAAQ;;CAG3C,8BAA8B,OAAO,QAAQ;EAC3C,MAAM,eAAe,kBAAkB,OAAO,OAAO,MAAM,GAAG;AAC9D,eAAa,cAAc,OAAO,MAAM,eAAe;;CAGzD,sBAAsB,OAAO,QAAQ;AACnC,oBAAkB,OAAO,OAAO,MAAM,GAAG;EACzC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,aAAW,UAAU,WAAW,QAAQ,QACrC,MAAM,EAAE,MAAM,OAAO,MAAM,GAC7B;;CAGH,wBAAwB,OAAO,QAAQ;EACrC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,aAAW,UAAU,QAAQ,WAAW,SAAS,OAAO,MAAM,MAAM;;CAEvE;AACD,MAAa,qCACX;CACE,2BAA2B,OAAO,QAAQ;EACxC,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,YAAY;AACtE,+BAA6B,OAAO,OAAO,MAAM,GAAG;AACpD,WAAS,OAAO,KAAK;GACnB,IAAI,OAAO,MAAM;GACjB,MAAM,OAAO,MAAM,aAAa;GAChC,MAAM,OAAO,MAAM,aAAa;GAChC,aAAa,OAAO,MAAM,oBAAoB;GAC9C,UAAU,OAAO,MAAM,iBAAiB;GACzC,CAAC;;CAGJ,+BAA+B,OAAO,QAAQ;EAC5C,MAAM,QAAQ,0BAA0B,OAAO,OAAO,MAAM,GAAG;AAC/D,QAAM,OAAO,OAAO,MAAM,aAAa;;CAGzC,+BAA+B,OAAO,QAAQ;EAC5C,MAAM,QAAQ,0BAA0B,OAAO,OAAO,MAAM,GAAG;AAC/D,QAAM,OAAO,OAAO,MAAM,aAAa;;CAGzC,sCAAsC,OAAO,QAAQ;EACnD,MAAM,QAAQ,0BAA0B,OAAO,OAAO,MAAM,GAAG;AAC/D,QAAM,cAAc,OAAO,MAAM,oBAAoB;;CAGvD,mCAAmC,OAAO,QAAQ;EAChD,MAAM,QAAQ,0BAA0B,OAAO,OAAO,MAAM,GAAG;AAC/D,QAAM,WAAW,OAAO,MAAM,iBAAiB;;CAGjD,8BAA8B,OAAO,QAAQ;EAG3C,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AAMtE,MAAI,CALW,WAAW,QAAQ,MAAM,QACtC,IAAI,WAAW,MAAM,OACnB,GAAG,OAAO,MAAM,MAAM,EAAE,OAAO,OAAO,MAAM,GAAG,CAChD,CACF,CAEC,OAAM,IAAI,MACR,oBAAoB,OAAO,MAAM,GAAG,yCACrC;AAEH,OAAK,MAAM,OAAO,WAAW,QAC3B,MAAK,MAAM,MAAM,IAAI,WACnB,IAAG,SAAS,GAAG,OAAO,QAAQ,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG;;CAKlE,gCAAgC,OAAO,QAAQ;EAC7C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,YAAY;AACtE,WAAS,SAAS,QAAQ,SAAS,QAAQ,OAAO,MAAM,MAAM;;CAEjE;AAEH,MAAa,uCACX;CACE,6BAA6B,OAAO,QAAQ;EAC1C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,YAAY;AACtE,iCAA+B,OAAO,OAAO,MAAM,GAAG;AACtD,WAAS,SAAS,KAAK;GACrB,IAAI,OAAO,MAAM;GACjB,OAAO,OAAO,MAAM;GACrB,CAAC;;CAGJ,gCAAgC,OAAO,QAAQ;EAC7C,MAAM,UAAU,4BAA4B,OAAO,OAAO,MAAM,GAAG;AACnE,UAAQ,QAAQ,OAAO,MAAM;;CAG/B,gCAAgC,OAAO,QAAQ;EAG7C,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AAMtE,MAAI,CALW,WAAW,QAAQ,MAAM,QACtC,IAAI,WAAW,MAAM,OACnB,GAAG,SAAS,MAAM,MAAM,EAAE,OAAO,OAAO,MAAM,GAAG,CAClD,CACF,CAEC,OAAM,IAAI,MACR,sBAAsB,OAAO,MAAM,GAAG,yCACvC;AAEH,OAAK,MAAM,OAAO,WAAW,QAC3B,MAAK,MAAM,MAAM,IAAI,WACnB,IAAG,WAAW,GAAG,SAAS,QAAQ,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG;;CAKtE,kCAAkC,OAAO,QAAQ;EAC/C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,YAAY;AACtE,WAAS,WAAW,QAAQ,SAAS,UAAU,OAAO,MAAM,MAAM;;CAErE;AACH,MAAa,gCAAkE;CAC7E,sBAAsB,OAAO,QAAQ;AACnC,wBAAsB,OAAO,MAAM,MAAM,MAAM;AAC/C,0BAAwB,OAAO,OAAO,MAAM,GAAG;AAC1B,oBAAkB,OAAO,OAAO,MAAM,SAAS,CACvD,WAAW,KAAK;GAC3B,IAAI,OAAO,MAAM;GACjB,MAAM,OAAO,MAAM;GACnB,aAAa,OAAO,MAAM,eAAe;GACzC,QAAQ,OAAO,MAAM,UAAU;GAC/B,UAAU,OAAO,MAAM,YAAY,OAAO,MAAM,eAAe;GAC/D,SAAS,OAAO,MAAM,WAAW;GACjC,QAAQ,EAAE;GACV,UAAU,EAAE;GACZ,OAAO,OAAO,MAAM,SAAS;GAC9B,CAAC;;CAGJ,0BAA0B,OAAO,QAAQ;AACvC,MAAI,OAAO,MAAM,KACf,uBAAsB,OAAO,MAAM,MAAM,OAAO,OAAO,MAAM,GAAG;EAElE,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;AAC7D,WAAS,OAAO,OAAO,MAAM,QAAQ;;CAGvC,2BAA2B,OAAO,QAAQ;EACxC,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;EAC7D,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;EACtE,MAAM,gBAAgB,OAAO,KAAK,WAAW,MAAM;AACnD,MAAI,OAAO,MAAM,SAAS,CAAC,cAAc,SAAS,OAAO,MAAM,MAAM,CACnE,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;AAEzD,WAAS,QAAQ,OAAO,MAAM,SAAS;;CAGzC,4BAA4B,OAAO,QAAQ;EACzC,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;AAC7D,WAAS,SAAS,OAAO,MAAM,UAAU;;CAG3C,iCAAiC,OAAO,QAAQ;EAC9C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;AAC7D,WAAS,cAAc,OAAO,MAAM,eAAe;;CAGrD,8BAA8B,OAAO,QAAQ;EAC3C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;AAC7D,WAAS,WAAW,OAAO,MAAM,YAAY;;CAG/C,6BAA6B,OAAO,QAAQ;EAC1C,MAAM,WAAW,qBAAqB,OAAO,OAAO,MAAM,GAAG;AAC7D,WAAS,UAAU,OAAO,MAAM,WAAW;;CAG7C,uBAAuB,OAAO,QAAQ;EAIpC,MAAM,eAAe,kBAAkB,OAAO,OAAO,MAAM,YAAY;EACvE,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;EAEtE,MAAM,UAAU,WAAW,QAAQ,SAAS,QAC1C,IAAI,WAAW,QAAQ,OAAO,GAAG,OAAO,OAAO,MAAM,YAAY,CAClE;AACD,MAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MACR,cAAc,OAAO,MAAM,YAAY,yCACxC;AAEH,MAAI,QAAQ,SAAS,EACnB,OAAM,IAAI,MACR,cAAc,OAAO,MAAM,YAAY,6CACxC;EAEH,MAAM,QAAQ,QAAQ;AAEtB,OAAK,MAAM,OAAO,WAAW,QAC3B,KAAI,aAAa,IAAI,WAAW,QAC7B,OAAO,GAAG,OAAO,OAAO,MAAM,YAChC;AAEH,eAAa,WAAW,KAAK,MAAM;;CAGrC,yBAAyB,OAAO,QAAQ;AACtC,uBAAqB,OAAO,OAAO,MAAM,GAAG;EAC5C,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,OAAK,MAAM,OAAO,WAAW,QAC3B,KAAI,aAAa,IAAI,WAAW,QAC7B,cAAc,UAAU,MAAM,OAAO,MAAM,GAC7C;;CAIL,iCAAiC,OAAO,QAAQ;EAC9C,MAAM,eAAe,kBAAkB,OAAO,OAAO,MAAM,SAAS;AACpE,eAAa,aAAa,QACxB,aAAa,YACb,OAAO,MAAM,MACd;;CAEJ;AACD,MAAa,kCAAgE;CAC3E,wBAAwB,OAAO,QAAQ;EACrC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC5D,YAAW,MAAM,OAAO,MAAM,OAA2B,SACvD,OAAO,MAAM;MAEf,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;;CAI3D,yBAAyB,OAAO,QAAQ;EACtC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC5D,YAAW,MAAM,OAAO,MAAM,OAA2B,eACvD,OAAO,MAAM;MAEf,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;;CAI3D,yBAAyB,OAAO,QAAQ;EACtC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC5D,YAAW,MAAM,OAAO,MAAM,OAA2B,SAAS,KAAK;GACrE,IAAI,OAAO,MAAM;GACjB,OAAO,OAAO,MAAM;GACrB,CAAC;MAEF,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;;CAI3D,4BAA4B,OAAO,QAAQ;EACzC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,CAAC,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC7D,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;EAKzD,MAAM,UAFJ,WAAW,MAAM,OAAO,MAAM,OAA2B,SAElC,MAAM,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG;AAC7D,MAAI,CAAC,QACH,OAAM,IAAI,MACR,kBAAkB,OAAO,MAAM,GAAG,wBAAwB,OAAO,MAAM,MAAM,GAC9E;AAEH,UAAQ,QAAQ,OAAO,MAAM;;CAG/B,4BAA4B,OAAO,QAAQ;EACzC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,CAAC,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC7D,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;EAEzD,MAAM,aAAa,WAAW,MAAM,OAAO,MAAM;AACjD,MAAI,CAAC,WAAW,SAAS,MAAM,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG,CAC3D,OAAM,IAAI,MACR,kBAAkB,OAAO,MAAM,GAAG,wBAAwB,OAAO,MAAM,MAAM,GAC9E;AAEH,aAAW,WAAW,WAAW,SAAS,QACvC,MAAM,EAAE,MAAM,OAAO,MAAM,GAC7B;;CAGH,8BAA8B,OAAO,QAAQ;EAC3C,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;AACtE,MAAI,CAAC,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,CAC7D,OAAM,IAAI,MAAM,kBAAkB,OAAO,MAAM,QAAQ;EAEzD,MAAM,aAAa,WAAW,MAAM,OAAO,MAAM;AACjD,aAAW,WAAW,QAAQ,WAAW,UAAU,OAAO,MAAM,MAAM;;CAEzE;AAED,MAAa,iCACX;CACE,0BAA0B,OAAO,QAAQ;AACvC,QAAM,IAAI,MACR,4DACD;;CAGH,6BAA6B,OAAO,QAAQ;AAC1C,QAAM,IAAI,MACR,+DACD;;CAGH,6BAA6B,OAAO,QAAQ;AAC1C,QAAM,IAAI,MACR,+DACD;;CAGH,+BAA+B,OAAO,QAAQ;AAC5C,QAAM,IAAI,MACR,iEACD;;CAGH,2BAA2B,OAAO,QAAQ;EACxC,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,SAAS;EAEtE,MAAM,gBAAgB,WAAW,QAAQ,KAAK,YAAY;GACxD,GAAG;GACH,YAAY,OAAO,WAAW,KAAK,QAAQ;IACzC,GAAG;IACH,QAAQ,GAAG,OAAO,KAAK,SAAS,EAAE,GAAG,KAAK,EAAE;IAC5C,UAAU,GAAG,SAAS,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;IAC/C,EAAE;GACJ,EAAE;EAEH,MAAM,cAAc;GAClB,QAAQ;IACN,GAAG,WAAW,MAAM;IACpB,UAAU,WAAW,MAAM,OAAO,SAAS,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;IACpE;GACD,OAAO;IACL,GAAG,WAAW,MAAM;IACpB,UAAU,WAAW,MAAM,MAAM,SAAS,KAAK,QAAQ,EAAE,GAAG,IAAI,EAAE;IACnE;GACF;EAED,MAAM,UAAU;GACd,SAAS,WAAW,UAAU;GAC9B,WAAW,EAAE;GACb,OAAO;GACP,SAAS;GACV;AAED,QAAM,eAAe,KAAK,QAAQ;;CAErC;AAEH,MAAa,6BACX,OACA,WACG;AACH,KAAI,iBAAiB,OAAO,CAC1B,QAAO;AAGT,SAAQ,OAAO,MAAf;EACE,KAAK;AACH,4BAAyB,CAAC,MAAM,OAAO,MAAM;AAC7C,8BAA2B,sBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,0BAAuB,CAAC,MAAM,OAAO,MAAM;AAC3C,8BAA2B,oBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,iCAA8B,CAAC,MAAM,OAAO,MAAM;AAClD,8BAA2B,2BACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,mCAAgC,CAAC,MAAM,OAAO,MAAM;AACpD,8BAA2B,6BACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,6BAA0B,CAAC,MAAM,OAAO,MAAM;AAC9C,8BAA2B,uBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,gCAA6B,CAAC,MAAM,OAAO,MAAM;AACjD,8BAA2B,0BACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,gCAA6B,CAAC,MAAM,OAAO,MAAM;AACjD,kCAA+B,0BAC7B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,mCAAgC,CAAC,MAAM,OAAO,MAAM;AACpD,kCAA+B,6BAC7B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,mCAAgC,CAAC,MAAM,OAAO,MAAM;AACpD,kCAA+B,6BAC7B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,qCAAkC,CAAC,MAAM,OAAO,MAAM;AACtD,kCAA+B,+BAC7B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,OAAI,OAAO,KAAK,OAAO,MAAgB,CAAC,SAAS,EAC/C,OAAM,IAAI,MAAM,sDAAsD;AACxE,kCAA+B,2BAC7B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,yBAAsB,CAAC,MAAM,OAAO,MAAM;AAC1C,8BAA2B,mBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,6BAA0B,CAAC,MAAM,OAAO,MAAM;AAC9C,8BAA2B,uBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,oCAAiC,CAAC,MAAM,OAAO,MAAM;AACrD,8BAA2B,8BACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,4BAAyB,CAAC,MAAM,OAAO,MAAM;AAC7C,8BAA2B,sBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,8BAA2B,CAAC,MAAM,OAAO,MAAM;AAC/C,8BAA2B,wBACzB,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,iCAA8B,CAAC,MAAM,OAAO,MAAM;AAClD,sCAAmC,2BACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,qCAAkC,CAAC,MAAM,OAAO,MAAM;AACtD,sCAAmC,+BACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,qCAAkC,CAAC,MAAM,OAAO,MAAM;AACtD,sCAAmC,+BACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,4CAAyC,CAAC,MAAM,OAAO,MAAM;AAC7D,sCAAmC,sCACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,yCAAsC,CAAC,MAAM,OAAO,MAAM;AAC1D,sCAAmC,mCACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,oCAAiC,CAAC,MAAM,OAAO,MAAM;AACrD,sCAAmC,8BACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,sCAAmC,CAAC,MAAM,OAAO,MAAM;AACvD,sCAAmC,gCACjC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,mCAAgC,CAAC,MAAM,OAAO,MAAM;AACpD,wCAAqC,6BACnC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,sCAAmC,CAAC,MAAM,OAAO,MAAM;AACvD,wCAAqC,gCACnC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,sCAAmC,CAAC,MAAM,OAAO,MAAM;AACvD,wCAAqC,gCACnC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,wCAAqC,CAAC,MAAM,OAAO,MAAM;AACzD,wCAAqC,kCACnC,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,4BAAyB,CAAC,MAAM,OAAO,MAAM;AAC7C,iCAA8B,sBAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,gCAA6B,CAAC,MAAM,OAAO,MAAM;AACjD,iCAA8B,0BAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,iCAA8B,CAAC,MAAM,OAAO,MAAM;AAClD,iCAA8B,2BAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,kCAA+B,CAAC,MAAM,OAAO,MAAM;AACnD,iCAA8B,4BAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,uCAAoC,CAAC,MAAM,OAAO,MAAM;AACxD,iCAA8B,iCAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,oCAAiC,CAAC,MAAM,OAAO,MAAM;AACrD,iCAA8B,8BAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,mCAAgC,CAAC,MAAM,OAAO,MAAM;AACpD,iCAA8B,6BAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,6BAA0B,CAAC,MAAM,OAAO,MAAM;AAC9C,iCAA8B,uBAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,+BAA4B,CAAC,MAAM,OAAO,MAAM;AAChD,iCAA8B,yBAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,uCAAoC,CAAC,MAAM,OAAO,MAAM;AACxD,iCAA8B,iCAC5B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,8BAA2B,CAAC,MAAM,OAAO,MAAM;AAC/C,mCAAgC,wBAC9B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,+BAA4B,CAAC,MAAM,OAAO,MAAM;AAChD,mCAAgC,yBAC9B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,+BAA4B,CAAC,MAAM,OAAO,MAAM;AAChD,mCAAgC,yBAC9B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,kCAA+B,CAAC,MAAM,OAAO,MAAM;AACnD,mCAAgC,4BAC9B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,kCAA+B,CAAC,MAAM,OAAO,MAAM;AACnD,mCAAgC,4BAC9B,MAAM,QACN,OACD;AACD;EAEF,KAAK;AACH,oCAAiC,CAAC,MAAM,OAAO,MAAM;AACrD,mCAAgC,8BAC9B,MAAM,QACN,OACD;AACD;EAEF,QACE,QAAO;;;AAIb,MAAa,uBAAuB,cAClC,0BACD;;;;;;;;;;;AC71BD,SAAgB,8BACd,SACQ;AACR,QAAO,WAAW,UAAU,IAAI,UAAU;;AAG5C,SAAS,kBACP,UACA,QACM;CACN,MAAM,QAAQ,OAAO;CAKrB,MAAM,WAAW,MAAM,gBAAgB,MAAM;AAC7C,KAAI,UAAU;EAEZ,MAAM,SAAS,kBAAkB;GAAE,GAAG,SAAS;GAAO,GAAG;GAAU,CAAC;AAGpE,SAAO,OAAO,oBACZ,SAAS,OAAO,IAChB,SAAS,OAAO,cAChB,kBAAkB,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC,MACzC,OAAO,KACR;AACD,WAAS,QAAQ;AACjB,WAAS,eAAe,SAAS;;;;;;;;;;;;AAarC,SAAgB,2BACd,UACA,QACA,aACY;CACZ,MAAM,cAAc,OAAO,MAAM;CACjC,MAAM,YAAY,OAAO,MAAM;AAE/B,KAAI,gBAAgB,aAAa,cAAc,EAC7C,QAAO;AAGT,KAAI,cAAc,UAChB,OAAM,IAAI,2BACR,SAAS,OAAO,cAChB,aACA,UACD;AAGH,KAAI,YACF,MAAK,MAAM,cAAc,YACvB,YAAW,WAAW,eAAe,UAAU,OAAO;AAI1D,mBAAkB,UAAU,OAAO;AAEnC,UAAS,MAAM,WAAW;EACxB,GAAG,SAAS,MAAM;EAClB,SAAS;EACV;AACD,QAAO;;;;;;AAOT,SAAgB,0BACd,UACA,QACY;CACZ,MAAM,YAAY,OAAO,mCAAkB,IAAI,MAAM,EAAC,aAAa;AAEnE,UAAS,QAAQ;EACf,GAAG,SAAS;EACZ,UAAU;GACR,GAAG,SAAS,MAAM;GAClB,WAAW;GACX,iBAAiB;GAClB;EACF;AAED,QAAO;;;;;;;;AAST,SAAgB,0BACd,UACA,aACA,WACqB;AACrB,KAAI,CAAC,SACH,OAAM,IAAI,MACR,4DAA4D,YAAY,MAAM,YAC/E;CAGH,MAAM,cAAmC,EAAE;CAC3C,MAAM,WAAW,SAAS;AAE1B,MAAK,IAAI,IAAI,cAAc,GAAG,KAAK,WAAW,KAAK;EACjD,MAAM,MAAM,IAAI;EAChB,MAAM,aAAa,SAAS;AAC5B,MAAI,CAAC,WACH,OAAM,IAAI,MACR,yBAAyB,SAAS,aAAa,qBAAqB,IAAI,WAAW,YAAY,OAAO,UAAU,qBAAqB,OAAO,KAAK,SAAS,CAAC,KAAK,KAAK,GACtK;AAEH,cAAY,KAAK,WAAW;;AAG9B,QAAO;;;;AC1IT,SAAS,sBAAsB,UAAqC;CAClE,MAAM,OAAO,OAAO,KAAK,SAAS,CAAC,IAAI,OAAO;AAC9C,KAAI,KAAK,WAAW,EAClB,OAAM,IAAI,MAAM,mDAAmD;AAErE,QAAO,KAAK,IAAI,GAAG,KAAK;;;;;;;;;;;;;;;;;;;;;;AAuB1B,SAAgB,wBACd,cACA,YACA,QACA,QACA,UACA,SACoB;CACpB,MAAM,EAAE,cAAc,MAAM,wBAAwB,WAAW,EAAE;CAEjE,MAAM,kBAAkB,mBAAmB,OAAO;CAElD,MAAM,SAAS,WAAW,eAAe,EAAE,EACxC,OAAO,CACP,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;CAEpC,MAAM,WAAW,MAAM,QAAQ,OAAO,GAAG,OAAO,SAAS,mBAAmB;CAE5E,MAAM,uBAA2C;EAE/C,MAAM,YAAY,OAAO,YACvB,OAAO,QAAQ,WAAW,CAAC,QAAQ,CAAC,OAAO,MAAM,WAAW,CAC7D;EACD,MAAM,gBAAgB,sBAAsB,OAAO,SAAS;EAC5D,MAAM,UAAU,OAAO,SACrB;AAWF,SAAO;GAAE,GATM,eACb,cACA,WACA,SACA,QACA,UACA,EAAE,EACF,QACD;GACmB;GAAY;;AAGlC,KAAI,MAAM,WAAW,KAAK,SAAS,WAAW,EAC5C,QAAO,gBAAgB;CAGzB,MAAM,SAAS,SAAS;AACxB,KAAI,CAAC,OACH,QAAO,gBAAgB;CAEzB,MAAM,aAAa,OAAO;AAC1B,KAAI,WAAW,MAAM,gBAAgB,EACnC,QAAO,gBAAgB;CAGzB,MAAM,YAAY,WAAW;CAI7B,MAAM,YAAa,UAAU,gBAAgB,UAAU;AAIvD,KAAI,CAAC,WAAW;EACd,MAAM,wBAAwB,SAAS,QAAQ,OAAO;GACpD,MAAM,IAAI,GAAG;AACb,UAAO,EAAE,MAAM,cAAc,KAAK,EAAE,MAAM,cAAc,EAAE,MAAM;IAChE,CAAC;AAEH,MAAI,wBAAwB,EAC1B,OAAM,IAAI,MACR,+HACmD,sBAAsB,qIAE1E;AAEH,SAAO,gBAAgB;;CAGzB,MAAM,eAAe,WAAW,MAAM;CAEtC,MAAM,oBAAoB,SAAS,QAAQ,OAAO;EAChD,MAAM,IAAI,GAAG;AACb,SAAO,EAAE,MAAM,cAAc,KAAK,EAAE,MAAM,cAAc,EAAE,MAAM;GAChE;CAGF,MAAM,eAAe,OAAO,KAAK,WAAW,CAAC,QAAQ,MAAM,MAAM,WAAW;CAC5E,MAAM,WAAwC,EAAE;AAChD,MAAK,MAAM,KAAK,aACd,UAAS,MAAM,WAAW,MAAM,EAAE,EAC/B,OAAO,CACP,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;CAGtC,MAAM,aAA4C,kBAAkB,KACjE,cAAc;EAEb,MAAM,mBADgB,UAAU,OACO,MAAM;EAC7C,MAAM,mBAAmB,UAAU;EAEnC,MAAM,WAAmC,EAAE;AAC3C,OAAK,MAAM,KAAK,cAAc;GAC5B,MAAM,MAAM,SAAS,MAAM,EAAE;AAC7B,OAAI,qBAAqB,KAAA,GAAW;IAClC,MAAM,MAAM,iBAAiB,MAAM;IACnC,IAAI,IAAI;AACR,SAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAC9B,MAAK,IAAI,IAAI,SAAS,KAAK,IACzB,KAAI,IAAI;AAGZ,aAAS,KAAK;UACT;IACL,IAAI,IAAI,IAAI;AACZ,SAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,IAE9B,MADa,IAAI,IAAI,kBAAkB,OAC3B,kBAAkB;AAC5B,SAAI;AACJ;;AAGJ,aAAS,KAAK;;;AAGlB,SAAO;GAEV;AAED,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,IACrC,MAAK,MAAM,KAAK,cAAc;EAC5B,MAAM,OAAO,WAAW,IAAI,KAAK,MAAM;EACvC,MAAM,OAAO,WAAW,KAAK,MAAM;AACnC,MAAI,WAAW,GACb,YAAW,GAAG,KAAK,KAAK,IAAI,MAAM,KAAK;;CAK7C,MAAM,YAAY,IAAI,IAAI;EAAC,GAAG,OAAO,KAAK,WAAW;EAAE;EAAU;EAAQ,CAAC;CAC1E,MAAM,oBAAwC,EAAE;AAChD,MAAK,MAAM,KAAK,UACd,mBAAkB,KAAK,EAAE;CAG3B,MAAM,iBAAiB,kBAAkB,UAAU;CACnD,IAAI,WAA+B;EACjC;EACA,OAAO;EACP,cAAc;EACd,YAAY;EACZ,WAAW,EAAE;EACd;CAED,IAAI,iBAAiB;CAErB,MAAM,yCAAyB,IAAI,KAAqB;AAExD,MAAK,IAAI,IAAI,GAAG,KAAK,kBAAkB,QAAQ,KAAK;EAClD,MAAM,UAAU,OAAO,SAAS;AAGhC,MAAI,CAAC,QACH,OAAM,IAAI,qCACR,OAAO,cACP,gBACA,OAAO,KAAK,OAAO,SAAS,CACzB,IAAI,OAAO,CACX,MAAM,GAAG,MAAM,IAAI,EAAE,CACzB;AAGH,OAAK,MAAM,KAAK,cAAc;GAC5B,MAAM,MAAM,SAAS,MAAM,EAAE;GAC7B,MAAM,WAAW,MAAM,IAAI,IAAK,WAAW,IAAI,KAAK,MAAM;GAC1D,MAAM,SACJ,IAAI,kBAAkB,SACjB,WAAW,KAAK,MAAM,IAAI,SAC3B,IAAI;GACV,MAAM,SAAS,IAAI,MAAM,UAAU,OAAO;AAE1C,QAAK,MAAM,MAAM,QAAQ;AAKvB,QAAI,SAAS,GAAG,CACd,YAAW,qBACT,sBAAsB,UAAU,IAAI,EAAE,EACtC,GACA,GAAG,eACJ;QAED,YAAW,QAAQ,UAAU,GAAG,QAAQ,UAAU;KAChD,sBAAsB;KACtB;KACA;KACA,eAAe,EAAE,WAAW,IAAI;KAChC;KACD,CAAC;AAEJ,2BAAuB,IAAI,GAAG,0BAA0B,UAAU,EAAE,CAAC;;;EAIzE,MAAM,sBACJ,MAAM,IAAI,KAAK,MAAM,QAAQ,kBAAkB,IAAI,GAAI;EACzD,MAAM,sBACJ,IAAI,kBAAkB,SAClB,MAAM,QAAQ,kBAAkB,GAAI,GACpC,MAAM;AAEZ,OAAK,IAAI,KAAK,sBAAsB,GAAG,KAAK,qBAAqB,MAAM;GACrE,MAAM,UAAU,MAAM;AACtB,OAAI,CAAC,QAAS;GACd,MAAM,kBAAkB,QAAQ,OAAO;AACvC,OACE,oBAAoB,qBACpB,oBAAoB,mBAEpB;AAGF,OAAI,SAAS,QAAQ,CACnB;AAEF,OAAI,oBAAoB,kBACtB,YAAW,0BACT,UACA,QAAQ,OACT;OAED,YAAW,QAAQ,UAAU,QAAQ,QAAQ,UAAU;IACrD,sBAAsB;IACtB;IACA;IACA,eAAe,EAAE,WAAW,SAAS;IACrC;IACD,CAAC;;AAIN,MAAI,IAAI,kBAAkB,QAAQ;GAEhC,MAAM,gBADY,kBAAkB,GACJ;GAChC,MAAM,UAAU,cAAc,MAAM;GACpC,MAAM,QAAQ,cAAc,MAAM;GAElC,MAAM,cAAc,0BAClB,OAAO,iBACP,SACA,MACD;AAED,cAAW,2BACT,UACA,eACA,YACD;AAED,oBAAiB;;;CAIrB,MAAM,cAAc,MAAM,GAAG,GAAG;AAChC,KAAI,gBAAgB,KAAA,KAAa,kBAAkB,SAAS,EAC1D,YAAW;EACT,GAAG;EACH,QAAQ;GACN,GAAG,SAAS;GACZ,UAAU;IACR,GAAG,SAAS,OAAO;IACnB,UAAU,YAAY,QAAQ;IAC/B;GACF;EACF;AAGH,KAAI,CAAC,aAAa;EAChB,MAAM,iBAAiB,aAAa,SAAS,MAAM,SAAS,MAAM,EAAE,CAAC;AACrE,OAAK,MAAM,SAAS,OAAO,KAAK,SAAS,MAAM,EAAE;GAC/C,MAAM,eAAe,uBAAuB,IAAI,MAAM;GACtD,MAAM,YACJ,iBAAiB,KAAA,IACb,eACA,0BAA0B,UAAU,MAAM;AAChD,QAAK,IAAI,IAAI,eAAe,SAAS,GAAG,KAAK,GAAG,KAAK;IACnD,MAAM,YAAY,eAAe;AACjC,QAAI,CAAC,aAAa,UAAU,OAAO,UAAU,MAC3C;AAEF,QAAI,UAAU,SAAS,UACrB,OAAM,IAAI,kBAAkB,OAAO,UAAU,UAAU;QAEvD;;;;CAMR,MAAM,kBAAkB,IAAI,IAAI;EAC9B,GAAG,OAAO,KAAK,SAAS,WAAW;EACnC,GAAG,OAAO,KAAK,WAAW;EAC1B;EACA;EACD,CAAC;AACF,iBAAgB,OAAO,WAAW;CAClC,MAAM,mBAAuC,EAAE;AAC/C,MAAK,MAAM,KAAK,gBAEd,kBAAiB,MADM,SAAS,WAAW,MAAM,EAAE,EACd,KAAK,IAAI,WAAW;EACvD,GAAG;EACH,WAAW,WAAW,KAAK,QAAQ,kBAAkB,GAAG;EACzD,EAAE;CAGL,MAAM,eAAe,OAAO,uBACxB,OAAO,uBACP,OAAO,OAAO,iBAAiB,CAAC,QAAQ,KAAK,SAAS;AACpD,MAAI,CAAC,KAAM,QAAO;EAClB,MAAM,OAAO,KAAK,GAAG,GAAG;AACxB,MAAI,QAAQ,KAAK,iBAAiB,IAChC,QAAO,KAAK;AAEd,SAAO;IACN,SAAS,OAAO,qBAAqB;AAE5C,QAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG,SAAS;GACZ,sBAAsB;GACvB;EACD,YAAY;GAAE,GAAG;GAAY,GAAG;GAAkB;EACnD;;;;AC3WH,SAAS,SAAS,MAAqC;AACrD,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,MAAI,OAAO,KAAK,QAAS,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,CAAE;GAC3D;;AAGJ,SAAS,WAAW,MAAqC;AACvD,QAAO,IAAI,SAAS,SAAS,WAAW;AACtC,QAAM,OAAO,KAAK,QAAS,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,CAAE;GAC7D;;AAGJ,MAAM,YAAY;AAElB,SAAS,eAAe,GAAoB;AAI1C,KAAI,EAAE,WAAW,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACjD,QAAO,UAAU,KAAK,EAAE;;AAG1B,SAAS,yBAAyB,GAAuB;CACvD,MAAM,MAAM,IAAI,WAAW,EAAE,OAAO;AACpC,MAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,KAAI,KAAK,EAAE,WAAW,EAAE,GAAG;AAC9D,QAAO;;AAGT,SAAS,mBAAmB,GAAuB;AACjD,KAAI,OAAO,SAAS,WAElB,QAAO,yBADK,KAAK,EAAE,CACiB;CAEtC,MAAM,aACJ,WAGA;AACF,KAAI,CAAC,WACH,OAAM,IAAI,MACR,4FACD;AAEH,QAAO,WAAW,KAAK,GAAG,SAAS;;AAGrC,eAAe,aAAa,OAAuC;AACjE,KAAI,iBAAiB,WAAY,QAAO;AACxC,KAAI,iBAAiB,YAAa,QAAO,IAAI,WAAW,MAAM;AAC9D,KAAI,OAAO,SAAS,eAAe,iBAAiB,KAClD,QAAO,IAAI,WAAW,MAAM,MAAM,aAAa,CAAC;AAElD,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,IAAI,WAAW,MAAM;AACtD,KAAI,OAAO,UAAU,SAGnB,QAAO,eAAe,MAAM,GACxB,mBAAmB,MAAM,GACzB,yBAAyB,MAAM;AAErC,OAAM,IAAI,MAAM,6BAA6B;;AAG/C,SAAS,UAAU,OAA4B;AAC7C,QAAO,QAAQ,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;;AAGhD,eAAsB,UAAU,UAA2C;AACzE,QAAO,SAAS;EACd,eAAe,UAAU,SAAS,OAAO;EACzC,cAAc,UAAU,SAAS,gBAAgB,EAAE,CAAC;EACpD,sBAAsB,UAAU,SAAS,SAAS,EAAE,CAAC;EACrD,mBAAmB,UACjB,uCAAuC,SAAS,WAAW,CAC5D;EACF,CAAC;;;;;;;AAQJ,eAAsB,iBACpB,MACqB;CACrB,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;CACpC,MAAM,SAA2B;EAC/B,IAAI,KAAK;EACT,KAAK;GAAE,WAAW,EAAE;GAAE,OAAO;GAAI;EACjC,cAAc,KAAK;EACnB,iBAAiB;EACjB,MAAM,KAAK;EACX,MAAM,KAAK;EACX,QAAQ,KAAK;EACb,UAAU,EAAE;EACZ,sBAAsB;EACvB;AAED,QAAO,SAAS;EACd,eAAe,UAAU,OAAO;EAChC,cAAc,UAAU,KAAK,MAAM;EACnC,sBAAsB,UAAU,KAAK,MAAM;EAC3C,mBAAmB,UAAU,EAAE,CAAC;EACjC,CAAC;;AAGJ,eAAsB,qBACpB,UACA,OACA;CACA,MAAM,OAAO,MAAM,UAAU,SAAS;CACtC,MAAM,WAAW,MAAM,MAAM,gBAAgB;AAC7C,OAAM,SAAS,MAAM,IAAI,WAAW,KAAK,CAAC;AAC1C,OAAM,SAAS,OAAO;;AAGxB,SAAS,UAAU,OAAiB,MAAsB;CACxD,MAAM,QAAQ,MAAM;AACpB,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,GAAG,KAAK,4BAA4B;AAEtD,QAAO,UAAU,MAAM;;AASzB,eAAe,aACb,MAC4B;CAC5B,MAAM,QAAQ,MAAM,WAAW,KAAK;AAEpC,KAAI,CAAC,MAAM,cACT,OAAM,IAAI,MAAM,0BAA0B;CAE5C,MAAM,eAAe,KAAK,MAAM,UAAU,OAAO,aAAa,CAAC;AAE/D,KAAI,CAAC,MAAM,eACT,OAAM,IAAI,MAAM,0DAA0D;CAE5E,MAAM,SAAS,KAAK,MAClB,UAAU,OAAO,cAAc,CAChC;AAED,KAAI,CAAC,MAAM,mBACT,OAAM,IAAI,MAAM,+BAA+B;CAMjD,MAAM,oBAAoB,iCAJP,KAAK,MACtB,UAAU,OAAO,kBAAkB,CACpC,CAEqE;CAEtE,MAAM,kBAAkB,mBAAmB,kBAAkB;AAC7D,KAAI,gBAAgB,QAAQ;EAC1B,MAAM,gBAAgB,gBAAgB,KAAK,QAAQ,IAAI,QAAQ;AAC/D,QAAM,IAAI,MAAM,cAAc,KAAK,KAAK,CAAC;;AAG3C,QAAO;EAAE;EAAc;EAAQ;EAAmB;;AAGpD,eAAe,gBACb,MACA,SACA,SAC6B;CAC7B,MAAM,EAAE,cAAc,QAAQ,sBAC5B,MAAM,aAAqB,KAAK;AAiBlC,QAAO;EAAE,GAVM,eACb,cALuB,OAAO,YAC9B,OAAO,QAAQ,kBAAkB,CAAC,QAAQ,CAAC,WAAW,UAAU,WAAW,CAC5E,EAKC,SACA,QACA,KAAA,GACA,EAAE,EACF,QACD;EAEmB,YAAY;EAAmB;;AAGrD,eAAe,yBACb,MACA,QACA,SAC6B;CAC7B,MAAM,EAAE,cAAc,QAAQ,sBAC5B,MAAM,aAAqB,KAAK;AAWlC,QAAO;EAAE,GATM,wBACb,cACA,mBACA,QACA,QACA,KAAA,GACA,QACD;EAEmB,YAAY;EAAmB;;AAGrD,eAAsB,kBACpB,OACA,SACA,SAC6B;AAE7B,QAAO,gBADM,MAAM,aAAa,MAAM,EACT,SAAS,QAAQ;;AAGhD,eAAsB,2BACpB,OACA,QACA,SAC6B;AAE7B,QAAO,yBADM,MAAM,aAAa,MAAM,EACQ,QAAQ,QAAQ;;;;;;;;AAehE,eAAsB,cAAc,MAAoC;CACtE,IAAI;AACJ,KAAI;AACF,UAAQ,MAAM,WAAW,KAAK;SACxB;AACN,SAAO;;AAET,QACE,QAAQ,MAAM,eAAe,IAC7B,QAAQ,MAAM,cAAc,IAC5B,QAAQ,MAAM,mBAAmB;;;;;;;AASrC,eAAsB,iBACpB,MAC6B;CAC7B,MAAM,QAAQ,MAAM,WAAW,KAAK;CACpC,MAAM,UAAU,OAAO,QAAQ,MAAM,CAClC,QAAQ,CAAC,UAAU,CAAC,KAAK,SAAS,IAAI,CAAC,CACvC,KAAK,CAAC,MAAM,YAAY;EAAE;EAAM,MAAM;EAAO,EAAE;AAClD,KAAI,QAAQ,WAAW,EACrB,OAAM,IAAI,MAAM,4BAA4B;AAE9C,QAAO;;;;;;AAOT,eAAsB,WACpB,SACqB;AACrB,QAAO,SAAS,QAAQ;;AAG1B,MAAa,8BACX,UACG;AACH,QAAO,kBAAkB,OAAO,qBAAqB;;AAGvD,MAAa,iCACX,UACA,UACG;AACH,QAAO,qBAAqB,UAAU,MAAM;;AAG9C,SAAgB,iBACd,MACA,MACA,QACiB;AACjB,OAAM;;AAGR,SAAgB,gBAAgB,MAAc;AAC5C,OAAM;;AAGR,SAAgB,iBACd,KAC8C;AAC9C,OAAM;;AAGR,MAAa,kBAAkB,SAAgC;AAC7D,QAAO,QAAQ,SAAS,CAAC,WAAW,gBAAgB,KAAK,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../document-model/signatures.ts","../../document-model/action-transport.ts","../../document-model/errors.ts","../../document-model/schemas.ts","../../document-model/actions.ts","../../document-model/document-type.ts","../../document-model/auth-v1.ts","../../document-model/constants.ts","../../document-model/state.ts","../../document-model/auth.ts","../../document-model/denied.ts","../../document-model/document-schema.ts","../../document-model/header.ts","../../document-model/documents.ts","../../document-model/operations.ts","../../document-model/reducer.ts","../../document-model/validation.ts","../../document-model/reducers.ts","../../document-model/upgrades.ts","../../document-model/versioned-replay.ts","../../document-model/files.ts"],"sourcesContent":["// Tuple from `buildOperationSignature`:\n// [timestamp, appKey, hash(docId+scope+type+input), previousStateHash, signatureHex].\nexport type Signature = [string, string, string, string, string];\n\n/**\n * A user action signer.\n */\nexport type UserActionSigner = {\n address: string;\n networkId: string; // CAIP-2\n chainId: number; // CAIP-10\n};\n\n/**\n * An app action signer.\n */\nexport type AppActionSigner = {\n name: string; // Connect\n key: string;\n};\n\n/**\n * An action signer.\n */\nexport type ActionSigner = {\n user: UserActionSigner;\n app: AppActionSigner;\n signatures: Signature[];\n};\n\n/**\n * Information to verify the document creator.\n */\nexport type PHDocumentSignatureInfo = {\n /**\n * The public key of the document creator.\n **/\n publicKey: JsonWebKey;\n\n /** The nonce that was appended to the message to create the signature. */\n nonce: string;\n};\n\n/**\n * What separates a signature's params when it travels as one string.\n *\n * GraphQL declares `signatures` as a list of strings, not a list of lists, so a\n * tuple is joined for transport and split on arrival. The separator is here so\n * the two halves cannot disagree about it - they live in different packages, and\n * a mismatch would corrupt every signature that crossed the wire rather than\n * failing outright.\n */\nconst SIGNATURE_PARAM_SEPARATOR = \", \";\n\n/** The number of params a signature carries. */\nconst SIGNATURE_PARAM_COUNT = 5;\n\n/** Joins a signature's params for transport. Already-joined input passes through. */\nexport function serializeSignature(signature: Signature | string): string {\n return Array.isArray(signature)\n ? signature.join(SIGNATURE_PARAM_SEPARATOR)\n : signature;\n}\n\n/**\n * Splits a transported signature back into its params. A tuple passes through.\n *\n * Short input is padded rather than refused: verification reads the params by\n * position and fails on a wrong one, which says more than a length complaint\n * raised here would.\n */\nexport function deserializeSignature(signature: Signature | string): Signature {\n if (Array.isArray(signature)) {\n return signature;\n }\n const parts = signature.split(SIGNATURE_PARAM_SEPARATOR);\n return Array.from(\n { length: SIGNATURE_PARAM_COUNT },\n (_unused, index) => parts[index] ?? \"\",\n ) as Signature;\n}\n\n/**\n * Configuration for hashing document state in operations.\n */\nexport type HashConfig = {\n /** The hashing algorithm to use (e.g., \"sha1\", \"sha256\") */\n algorithm: string;\n\n /** The encoding format for the hash output (e.g., \"base64\", \"hex\") */\n encoding: string;\n\n /** Optional algorithm-specific parameters */\n params?: Record<string, unknown>;\n};\n","import type { Action, ActionContext } from \"./actions.js\";\nimport {\n serializeSignature,\n type AppActionSigner,\n type UserActionSigner,\n} from \"./signatures.js\";\n\n/**\n * An action's signer, as the wire declares it: signatures joined into strings,\n * because GraphQL declares them as a list of strings rather than of lists.\n */\nexport type TransportSigner = {\n user?: { address: string; networkId: string; chainId: number };\n app?: { name: string; key: string };\n signatures: string[];\n};\n\n/** An action's context, as the wire declares it. */\nexport type TransportActionContext = {\n prevOpIndex?: number;\n prevOpHash?: string;\n nonce?: string;\n signer?: TransportSigner;\n};\n\n/** An action projected onto exactly the fields the wire declares. */\nexport type TransportAction = {\n id: string;\n type: string;\n timestampUtcMs: string;\n /**\n * Non-nullable, because the wire declares it so. An action's own type says\n * `unknown`, which admits the absent input an action creator called without\n * one produces - {@link toTransportAction} refuses that rather than passing\n * it on.\n */\n input: NonNullable<unknown>;\n scope: string;\n context?: TransportActionContext;\n};\n\n/**\n * Projects an action onto the fields the GraphQL `ActionInput` declares.\n *\n * A projection rather than a spread, because an input object rejects a field it\n * does not declare, and that refusal takes the whole request with it. An action\n * read back out of storage can carry fields the type no longer has - a legacy\n * `attachments` array, or the operation fields left behind by a signing helper\n * that returns an operation - and any one of them would sink an otherwise valid\n * submission.\n *\n * Only fields the action actually carries are emitted, so an unsigned action\n * sends no context at all rather than a context full of nulls.\n */\nexport function toTransportAction(action: Action): TransportAction {\n if (action.input === undefined || action.input === null) {\n // The wire declares an input, so this would be refused on arrival as a\n // missing required field, naming the field but not the action. Refused here\n // instead, where the action is still in hand.\n throw new Error(\n `Action ${action.id} (${action.type}) has no input, which the wire requires`,\n );\n }\n\n const projected: TransportAction = {\n id: action.id,\n type: action.type,\n timestampUtcMs: action.timestampUtcMs,\n input: action.input,\n scope: action.scope,\n };\n\n const context = toTransportContext(action.context);\n return context ? { ...projected, context } : projected;\n}\n\nfunction toTransportContext(\n context: ActionContext | undefined,\n): TransportActionContext | undefined {\n if (!context) {\n return undefined;\n }\n\n const projected: TransportActionContext = {};\n if (context.prevOpIndex !== undefined) {\n projected.prevOpIndex = context.prevOpIndex;\n }\n if (context.prevOpHash !== undefined) {\n projected.prevOpHash = context.prevOpHash;\n }\n if (context.nonce !== undefined) {\n projected.nonce = context.nonce;\n }\n\n const signer = context.signer;\n if (signer) {\n projected.signer = {\n ...(signer.user ? { user: toTransportSignerUser(signer.user) } : {}),\n ...(signer.app ? { app: toTransportSignerApp(signer.app) } : {}),\n signatures: (signer.signatures ?? []).map(serializeSignature),\n };\n }\n\n return Object.keys(projected).length > 0 ? projected : undefined;\n}\n\n/**\n * The identity, projected for the same reason the context around it is.\n *\n * A signer is handed in by the app, so what reaches here is only as narrow as\n * whoever built it: an identity carrying a session's DID, credential or profile\n * alongside the address is refused by `ReactorSignerUserInput`, and that\n * refusal takes the whole submission with it.\n *\n * The compiler cannot stand in for this. `UserActionSigner` already declares\n * exactly these three fields, but excess-property checks apply to fresh object\n * literals and never to a variable of a wider type, so a wide identity assigned\n * to the narrow type passes untouched.\n */\nfunction toTransportSignerUser(\n user: UserActionSigner,\n): NonNullable<TransportSigner[\"user\"]> {\n return {\n address: user.address,\n networkId: user.networkId,\n chainId: user.chainId,\n };\n}\n\n/** The signing app, projected on the same rule as the identity above. */\nfunction toTransportSignerApp(\n app: AppActionSigner,\n): NonNullable<TransportSigner[\"app\"]> {\n return { name: app.name, key: app.key };\n}\n","import type { ZodIssue } from \"zod\";\nimport type { PHDocument } from \"./documents.js\";\nimport type { Operation } from \"./operations.js\";\n\nexport const FileSystemError = new Error(\"File system not available.\");\n\nexport class InvalidActionInputError extends Error {\n public data: unknown;\n constructor(data: unknown) {\n super();\n this.name = \"InvalidActionInputError\";\n this.data = data;\n this.message =\n this.message || `Invalid action input: ${JSON.stringify(data, null, 2)}`;\n }\n}\n\nexport class InvalidActionInputZodError extends InvalidActionInputError {\n public issues: ZodIssue[];\n\n constructor(issues: ZodIssue[]) {\n super(issues);\n this.issues = issues;\n this.name = \"InvalidActionInputZodError\";\n }\n}\n\n/**\n * Error thrown when attempting to downgrade a document version.\n */\nexport class DowngradeNotSupportedError extends Error {\n public readonly documentType: string;\n public readonly fromVersion: number;\n public readonly toVersion: number;\n\n constructor(documentType: string, fromVersion: number, toVersion: number) {\n super(\n `Downgrade not supported for ${documentType}: cannot upgrade from version ${fromVersion} to ${toVersion}`,\n );\n this.name = \"DowngradeNotSupportedError\";\n this.documentType = documentType;\n this.fromVersion = fromVersion;\n this.toVersion = toVersion;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH is applied to an already-initialized auth scope.\n * The genesis action is valid only at auth revision zero.\n */\nexport class AuthAlreadyInitializedError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `Auth scope already initialized for document ${documentId}: INITIALIZE_AUTH is valid only at auth revision zero`,\n );\n this.name = \"AuthAlreadyInitializedError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH is not signed by the document creator (its signer\n * does not match `header.sig.publicKey`), so it cannot set the auth policy.\n */\nexport class AuthInitializerNotCreatorError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `INITIALIZE_AUTH for document ${documentId} must be signed by the document creator`,\n );\n this.name = \"AuthInitializerNotCreatorError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH carries a version below 1. Version 0 is reserved\n * for the uninitialized auth scope.\n */\nexport class InvalidAuthVersionError extends Error {\n public readonly documentId: string;\n public readonly version: number;\n\n constructor(documentId: string, version: number) {\n super(\n `Invalid auth policy version ${version} for document ${documentId}: INITIALIZE_AUTH requires an integer version >= 1`,\n );\n this.name = \"InvalidAuthVersionError\";\n this.documentId = documentId;\n this.version = version;\n }\n}\n\n/** Thrown when a duplicate would lose the source policy's version or creator binding. */\nexport class AuthPolicyNotPreservedError extends Error {\n public readonly documentId: string;\n\n constructor(documentId: string) {\n super(\n `Duplicating document ${documentId} would not preserve its auth policy: the copy loses the policy version or its creator binding`,\n );\n this.name = \"AuthPolicyNotPreservedError\";\n this.documentId = documentId;\n }\n}\n\n/**\n * Thrown when a grant referenced by REMOVE_GRANT or MOVE_GRANT does not exist.\n */\nexport class GrantNotFoundError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(`Grant not found in auth scope: ${grantId}`);\n this.name = \"GrantNotFoundError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when a disallowed action (UNDO, REDO, PRUNE) targets the auth scope.\n */\nexport class AuthActionNotAllowedError extends Error {\n public readonly actionType: string;\n\n constructor(actionType: string) {\n super(`${actionType} is not permitted on the auth scope`);\n this.name = \"AuthActionNotAllowedError\";\n this.actionType = actionType;\n }\n}\n\nexport class HashMismatchError extends Error {\n protected _scope: string;\n protected _document: PHDocument;\n protected _operation: Operation;\n\n constructor(scope: string, document: PHDocument, operation: Operation) {\n super();\n this.name = \"HashMismatchError\";\n this._document = document;\n this._scope = scope;\n this._operation = operation;\n\n this.message = JSON.stringify(\n {\n error: `Hash mismatch on document ${document.header.id}, scope ${scope}, index ${operation.index}`,\n document,\n operation,\n },\n null,\n 1,\n );\n }\n\n get document() {\n return this._document;\n }\n\n get scope() {\n return this._scope;\n }\n\n get operation() {\n return this._operation;\n }\n}\n\n/**\n * Thrown when replay or import requires a document model version that is not\n * registered. Carries the data the UI needs to explain the mismatch.\n */\nexport class UnsupportedDocumentModelVersionError extends Error {\n public readonly documentType: string;\n public readonly requiredVersion: number;\n public readonly availableVersions: number[];\n\n constructor(\n documentType: string,\n requiredVersion: number,\n availableVersions: number[],\n ) {\n super(\n `No reducer registered for document version ${requiredVersion}. Available versions: ${availableVersions.join(\", \")}`,\n );\n this.name = \"UnsupportedDocumentModelVersionError\";\n this.documentType = documentType;\n this.requiredVersion = requiredVersion;\n this.availableVersions = availableVersions;\n }\n\n static isError(\n error: unknown,\n ): error is UnsupportedDocumentModelVersionError {\n return (\n Error.isError(error) &&\n error.name === \"UnsupportedDocumentModelVersionError\"\n );\n }\n}\n","import { z } from \"zod\";\nimport type { PHConnectPwa } from \"../clis/types.js\";\nimport type {\n AddChangeLogItemInput,\n AddModuleInput,\n AddOperationErrorInput,\n AddOperationExampleInput,\n AddOperationInput,\n AddStateExampleInput,\n Author,\n CodeExample,\n DeleteChangeLogItemInput,\n DeleteModuleInput,\n DeleteOperationErrorInput,\n DeleteOperationExampleInput,\n DeleteOperationInput,\n DeleteStateExampleInput,\n DocumentModelGlobalState,\n DocumentSpecification,\n LoadStateActionInput,\n LoadStateActionStateInput,\n ModuleSpecification,\n MoveOperationInput,\n OperationErrorSpecification,\n OperationSpecification,\n PruneActionInput,\n ReorderChangeLogItemsInput,\n ReorderModuleOperationsInput,\n ReorderModulesInput,\n ReorderOperationErrorsInput,\n ReorderOperationExamplesInput,\n ReorderStateExamplesInput,\n SchemaLoadStateAction,\n SchemaPruneAction,\n SchemaRedoAction,\n SchemaSetNameAction,\n SchemaSetPreferredEditorAction,\n SchemaUndoAction,\n ScopeState,\n SetAuthorNameInput,\n SetAuthorWebsiteInput,\n SetInitialStateInput,\n SetModelDescriptionInput,\n SetModelExtensionInput,\n SetModelIdInput,\n SetModelNameInput,\n SetModuleDescriptionInput,\n SetModuleNameInput,\n SetOperationDescriptionInput,\n SetOperationErrorCodeInput,\n SetOperationErrorDescriptionInput,\n SetOperationErrorNameInput,\n SetOperationErrorTemplateInput,\n SetOperationNameInput,\n SetOperationReducerInput,\n SetOperationSchemaInput,\n SetOperationScopeInput,\n SetOperationTemplateInput,\n SetStateSchemaInput,\n State,\n UpdateChangeLogItemInput,\n UpdateOperationExampleInput,\n UpdateStateExampleInput,\n} from \"./types.js\";\n\ntype definedNonNullAny = {};\n\nexport const isDefinedNonNullAny = (v: any): v is definedNonNullAny =>\n v !== undefined && v !== null;\n\nexport const definedNonNullAnySchema = z\n .any()\n .refine((v) => isDefinedNonNullAny(v));\n\nexport const Load_StateSchema = z.enum([\"LOAD_STATE\"]);\n\nexport const PruneSchema = z.enum([\"PRUNE\"]);\n\nexport const RedoSchema = z.enum([\"REDO\"]);\n\nexport const Set_NameSchema = z.enum([\"SET_NAME\"]);\n\nexport const Set_PreferredEditorSchema = z.enum([\"SET_PREFERRED_EDITOR\"]);\n\nexport const UndoSchema = z.enum([\"UNDO\"]);\n\nexport function OperationScopeSchema(): z.ZodString {\n return z.string();\n}\n\nexport function DocumentActionSchema() {\n return z.union([\n LoadStateActionSchema(),\n PruneActionSchema(),\n RedoActionSchema(),\n SetNameActionSchema(),\n SetPreferredEditorActionSchema(),\n UndoActionSchema(),\n ]);\n}\n\nexport function LoadStateActionSchema(): z.ZodObject<\n Properties<SchemaLoadStateAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string(),\n input: z.lazy(() => LoadStateActionInputSchema()),\n type: Load_StateSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function LoadStateActionInputSchema(): z.ZodObject<\n Properties<LoadStateActionInput>\n> {\n return z.object({\n operations: z.number(),\n state: z.lazy(() => LoadStateActionStateInputSchema()),\n });\n}\n\nexport function LoadStateActionStateInputSchema(): z.ZodObject<\n Properties<LoadStateActionStateInput>\n> {\n return z.object({\n data: z.unknown().nullish(),\n name: z.string(),\n });\n}\n\nexport function PruneActionSchema(): z.ZodObject<\n Properties<SchemaPruneAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string(),\n input: z.lazy(() => PruneActionInputSchema()),\n type: PruneSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function PruneActionInputSchema(): z.ZodObject<\n Properties<PruneActionInput>\n> {\n return z.object({\n end: z.number().nullish(),\n start: z.number().nullish(),\n });\n}\n\nexport function RedoActionInputSchema() {\n return z.object({ count: z.number() });\n}\n\nexport function RedoActionSchema(): z.ZodObject<Properties<SchemaRedoAction>> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: RedoActionInputSchema(),\n type: RedoSchema,\n scope: OperationScopeSchema(),\n });\n}\n\nexport function SetNameActionInputSchema() {\n return z.object({ name: z.string() });\n}\n\nexport function SetNameActionSchema(): z.ZodObject<\n Properties<SchemaSetNameAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: SetNameActionInputSchema(),\n type: Set_NameSchema,\n scope: z.literal(\"global\"),\n });\n}\n\nexport function SetPreferredEditorActionInputSchema() {\n return z.object({ preferredEditor: z.string().nullable() });\n}\n\nexport function SetPreferredEditorActionSchema(): z.ZodObject<\n Properties<SchemaSetPreferredEditorAction>\n> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: SetPreferredEditorActionInputSchema(),\n type: Set_PreferredEditorSchema,\n scope: z.literal(\"header\"),\n });\n}\n\n// export function SetNameOperationSchema(): z.ZodObject<\n// Properties<SetNameOperation>\n// > {\n// return z.object({\n// __typename: z.literal(\"SetNameOperation\").optional(),\n// hash: z.string(),\n// index: z.number(),\n// input: z.string(),\n// timestampUtcMs: z.string().datetime(),\n// type: z.string(),\n// });\n// }\n\nexport function UndoActionInputSchema() {\n return z.object({ count: z.number() });\n}\n\nexport function UndoActionSchema(): z.ZodObject<Properties<SchemaUndoAction>> {\n return z.object({\n id: z.string(),\n timestampUtcMs: z.string().datetime(),\n input: UndoActionInputSchema(),\n type: UndoSchema,\n scope: OperationScopeSchema(),\n });\n}\n\ntype Properties<T> = Required<{\n [K in keyof T]: z.ZodType<T[K], T[K]>;\n}>;\n\nexport function AddChangeLogItemInputSchema(): z.ZodObject<\n Properties<AddChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"AddChangeLogItemInput\").optional(),\n content: z.string(),\n id: z.string(),\n insertBefore: z.string().nullable(),\n });\n}\n\nexport function AddModuleInputSchema(): z.ZodObject<\n Properties<AddModuleInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n name: z.string(),\n });\n}\n\nexport function AddOperationErrorInputSchema(): z.ZodObject<\n Properties<AddOperationErrorInput>\n> {\n return z.object({\n errorCode: z.string().nullish(),\n errorDescription: z.string().nullish(),\n errorName: z.string().nullish(),\n errorTemplate: z.string().nullish(),\n id: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function AddOperationExampleInputSchema(): z.ZodObject<\n Properties<AddOperationExampleInput>\n> {\n return z.object({\n example: z.string(),\n id: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function AddOperationInputSchema(): z.ZodObject<\n Properties<AddOperationInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n moduleId: z.string(),\n name: z.string(),\n reducer: z.string().nullish(),\n schema: z.string().nullish(),\n template: z.string().nullish(),\n scope: OperationScopeSchema().nullish(),\n });\n}\n\nexport function AddStateExampleInputSchema(): z.ZodObject<\n Properties<AddStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n example: z.string(),\n id: z.string(),\n insertBefore: z.string().nullish(),\n });\n}\n\nexport function AuthorSchema(): z.ZodObject<Properties<Author>> {\n return z.object({\n __typename: z.literal(\"Author\").optional(),\n name: z.string(),\n website: z.string().nullable(),\n });\n}\n\nexport function CodeExampleSchema(): z.ZodObject<Properties<CodeExample>> {\n return z.object({\n __typename: z.literal(\"CodeExample\").optional(),\n id: z.string(),\n value: z.string(),\n });\n}\n\nexport function DeleteChangeLogItemInputSchema(): z.ZodObject<\n Properties<DeleteChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"DeleteChangeLogItemInput\").optional(),\n id: z.string(),\n });\n}\n\nexport function DeleteModuleInputSchema(): z.ZodObject<\n Properties<DeleteModuleInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationErrorInputSchema(): z.ZodObject<\n Properties<DeleteOperationErrorInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationExampleInputSchema(): z.ZodObject<\n Properties<DeleteOperationExampleInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteOperationInputSchema(): z.ZodObject<\n Properties<DeleteOperationInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function DeleteStateExampleInputSchema(): z.ZodObject<\n Properties<DeleteStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n id: z.string(),\n });\n}\n\nexport function DocumentModelInputSchema() {\n return z.union([\n AddChangeLogItemInputSchema(),\n AddModuleInputSchema(),\n AddOperationErrorInputSchema(),\n AddOperationExampleInputSchema(),\n AddOperationInputSchema(),\n AddStateExampleInputSchema(),\n DeleteChangeLogItemInputSchema(),\n DeleteModuleInputSchema(),\n DeleteOperationErrorInputSchema(),\n DeleteOperationExampleInputSchema(),\n DeleteOperationInputSchema(),\n DeleteStateExampleInputSchema(),\n MoveOperationInputSchema(),\n ReorderChangeLogItemsInputSchema(),\n ReorderModuleOperationsInputSchema(),\n ReorderModulesInputSchema(),\n ReorderOperationErrorsInputSchema(),\n ReorderOperationExamplesInputSchema(),\n ReorderStateExamplesInputSchema(),\n SetAuthorNameInputSchema(),\n SetAuthorWebsiteInputSchema(),\n SetInitialStateInputSchema(),\n SetModelDescriptionInputSchema(),\n SetModelExtensionInputSchema(),\n SetModelIdInputSchema(),\n SetModelNameInputSchema(),\n SetModuleDescriptionInputSchema(),\n SetModuleNameInputSchema(),\n SetOperationDescriptionInputSchema(),\n SetOperationErrorCodeInputSchema(),\n SetOperationErrorDescriptionInputSchema(),\n SetOperationErrorNameInputSchema(),\n SetOperationErrorTemplateInputSchema(),\n SetOperationNameInputSchema(),\n SetOperationReducerInputSchema(),\n SetOperationSchemaInputSchema(),\n SetOperationTemplateInputSchema(),\n SetStateSchemaInputSchema(),\n UpdateChangeLogItemInputSchema(),\n UpdateOperationExampleInputSchema(),\n UpdateStateExampleInputSchema(),\n ]);\n}\n\nexport function DocumentModelGlobalStateSchema(): z.ZodObject<\n Properties<DocumentModelGlobalState>\n> {\n return z.object({\n __typename: z.literal(\"DocumentModelGlobalState\").optional(),\n id: z.string(),\n name: z.string(),\n author: AuthorSchema(),\n extension: z.string(),\n description: z.string(),\n specifications: z.array(DocumentSpecificationSchema()),\n });\n}\n\nexport function DocumentSpecificationSchema(): z.ZodObject<\n Properties<DocumentSpecification>\n> {\n return z.object({\n __typename: z.literal(\"DocumentSpecification\").optional(),\n state: ScopeStateSchema(),\n modules: z.array(ModuleSchema()),\n version: z.number().int(),\n changeLog: z.array(z.string()),\n });\n}\n\nexport function ModuleSchema(): z.ZodObject<Properties<ModuleSpecification>> {\n return z.object({\n __typename: z.literal(\"ModuleSpecification\").optional(),\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n operations: z.array(OperationSpecificationSchema()),\n });\n}\n\nexport function MoveOperationInputSchema(): z.ZodObject<\n Properties<MoveOperationInput>\n> {\n return z.object({\n newModuleId: z.string(),\n operationId: z.string(),\n });\n}\n\nexport function OperationSpecificationSchema(): z.ZodObject<\n Properties<OperationSpecification>\n> {\n return z.object({\n __typename: z.literal(\"OperationSpecification\").optional(),\n id: z.string(),\n name: z.string().nullable(),\n description: z.string().nullable(),\n schema: z.string().nullable(),\n template: z.string().nullable(),\n reducer: z.string().nullable(),\n errors: z.array(OperationErrorSchema()),\n examples: z.array(CodeExampleSchema()),\n scope: OperationScopeSchema(),\n });\n}\n\nexport function OperationErrorSchema(): z.ZodObject<\n Properties<OperationErrorSpecification>\n> {\n return z.object({\n __typename: z.literal(\"OperationErrorSpecification\").optional(),\n id: z.string(),\n name: z.string().nullable(),\n code: z.string().nullable(),\n description: z.string().nullable(),\n template: z.string().nullable(),\n });\n}\n\nexport function ReorderChangeLogItemsInputSchema(): z.ZodObject<\n Properties<ReorderChangeLogItemsInput>\n> {\n return z.object({\n __typename: z.literal(\"ReorderChangeLogItemsInput\").optional(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderModuleOperationsInputSchema(): z.ZodObject<\n Properties<ReorderModuleOperationsInput>\n> {\n return z.object({\n moduleId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderModulesInputSchema(): z.ZodObject<\n Properties<ReorderModulesInput>\n> {\n return z.object({\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderOperationErrorsInputSchema(): z.ZodObject<\n Properties<ReorderOperationErrorsInput>\n> {\n return z.object({\n operationId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderOperationExamplesInputSchema(): z.ZodObject<\n Properties<ReorderOperationExamplesInput>\n> {\n return z.object({\n operationId: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function ReorderStateExamplesInputSchema(): z.ZodObject<\n Properties<ReorderStateExamplesInput>\n> {\n return z.object({\n scope: z.string(),\n order: z.array(z.string()),\n });\n}\n\nexport function SetAuthorNameInputSchema(): z.ZodObject<\n Properties<SetAuthorNameInput>\n> {\n return z.object({\n authorName: z.string(),\n });\n}\n\nexport function SetAuthorWebsiteInputSchema(): z.ZodObject<\n Properties<SetAuthorWebsiteInput>\n> {\n return z.object({\n authorWebsite: z.string(),\n });\n}\n\nexport function SetInitialStateInputSchema(): z.ZodObject<\n Properties<SetInitialStateInput>\n> {\n return z.object({\n scope: z.string(),\n initialValue: z.string(),\n });\n}\n\nexport function SetModelDescriptionInputSchema(): z.ZodObject<\n Properties<SetModelDescriptionInput>\n> {\n return z.object({\n description: z.string(),\n });\n}\n\nexport function SetModelExtensionInputSchema(): z.ZodObject<\n Properties<SetModelExtensionInput>\n> {\n return z.object({\n extension: z.string(),\n });\n}\n\nexport function SetModelIdInputSchema(): z.ZodObject<\n Properties<SetModelIdInput>\n> {\n return z.object({\n id: z.string(),\n });\n}\n\nexport function SetModelNameInputSchema(): z.ZodObject<\n Properties<SetModelNameInput>\n> {\n return z.object({\n name: z.string(),\n });\n}\n\nexport function SetModuleDescriptionInputSchema(): z.ZodObject<\n Properties<SetModuleDescriptionInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetModuleNameInputSchema(): z.ZodObject<\n Properties<SetModuleNameInput>\n> {\n return z.object({\n id: z.string(),\n name: z.string().nullish(),\n });\n}\n\nexport function SetOperationDescriptionInputSchema(): z.ZodObject<\n Properties<SetOperationDescriptionInput>\n> {\n return z.object({\n description: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorCodeInputSchema(): z.ZodObject<\n Properties<SetOperationErrorCodeInput>\n> {\n return z.object({\n errorCode: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorDescriptionInputSchema(): z.ZodObject<\n Properties<SetOperationErrorDescriptionInput>\n> {\n return z.object({\n errorDescription: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorNameInputSchema(): z.ZodObject<\n Properties<SetOperationErrorNameInput>\n> {\n return z.object({\n errorName: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationErrorTemplateInputSchema(): z.ZodObject<\n Properties<SetOperationErrorTemplateInput>\n> {\n return z.object({\n errorTemplate: z.string().nullish(),\n id: z.string(),\n });\n}\n\nexport function SetOperationNameInputSchema(): z.ZodObject<\n Properties<SetOperationNameInput>\n> {\n return z.object({\n id: z.string(),\n name: z.string().nullish(),\n });\n}\n\nexport function SetOperationScopeInputSchema(): z.ZodObject<\n Properties<SetOperationScopeInput>\n> {\n return z.object({\n id: z.string(),\n scope: OperationScopeSchema(),\n });\n}\n\nexport function SetOperationReducerInputSchema(): z.ZodObject<\n Properties<SetOperationReducerInput>\n> {\n return z.object({\n id: z.string(),\n reducer: z.string().nullish(),\n });\n}\n\nexport function SetOperationSchemaInputSchema(): z.ZodObject<\n Properties<SetOperationSchemaInput>\n> {\n return z.object({\n id: z.string(),\n schema: z.string().nullish(),\n });\n}\n\nexport function SetOperationTemplateInputSchema(): z.ZodObject<\n Properties<SetOperationTemplateInput>\n> {\n return z.object({\n id: z.string(),\n template: z.string().nullish(),\n });\n}\n\nexport function SetStateSchemaInputSchema(): z.ZodObject<\n Properties<SetStateSchemaInput>\n> {\n return z.object({\n scope: z.string(),\n schema: z.string(),\n });\n}\n\nexport function StateSchema(): z.ZodObject<Properties<State>> {\n return z.object({\n __typename: z.literal(\"State\").optional(),\n schema: z.string(),\n examples: z.array(CodeExampleSchema()),\n initialValue: z.string(),\n });\n}\n\nexport function ScopeStateSchema(): z.ZodObject<Properties<ScopeState>> {\n return z.object({\n local: StateSchema(),\n global: StateSchema(),\n });\n}\n\nexport function UpdateChangeLogItemInputSchema(): z.ZodObject<\n Properties<UpdateChangeLogItemInput>\n> {\n return z.object({\n __typename: z.literal(\"UpdateChangeLogItemInput\").optional(),\n id: z.string(),\n newContent: z.string(),\n });\n}\n\nexport function UpdateOperationExampleInputSchema(): z.ZodObject<\n Properties<UpdateOperationExampleInput>\n> {\n return z.object({\n example: z.string(),\n id: z.string(),\n });\n}\n\nexport function UpdateStateExampleInputSchema(): z.ZodObject<\n Properties<UpdateStateExampleInput>\n> {\n return z.object({\n scope: z.string(),\n id: z.string(),\n newExample: z.string(),\n });\n}\n\nexport const PowerhouseModuleSchema = z.object({\n id: z.string(),\n name: z.string(),\n documentTypes: z.array(z.string()).optional(),\n});\n\nexport const PowerhouseModulesSchema = z\n .array(PowerhouseModuleSchema)\n .optional();\n\nexport const PublisherSchema = z.object({\n name: z.string().optional(),\n url: z.string().optional(),\n});\n\nexport const ConfigEntryTypeSchema = z.union([\n z.literal(\"var\"),\n z.literal(\"secret\"),\n]);\n\nexport const ConfigEntrySchema = z.object({\n name: z.string(),\n type: ConfigEntryTypeSchema,\n description: z.string().optional(),\n required: z.boolean().optional(),\n default: z.boolean().optional(),\n});\n\n// PWA / service-worker overrides a package contributes to a Connect build.\n// The `z.ZodType<PHConnectPwa>` annotation pins the schema to the TS type in\n// packages/shared/clis/types.ts, so drift between them is a compile error;\n// the JSON-schema fragment in packages/shared/connect/schema-fragments.ts is\n// the remaining hand-kept mirror. Kept on the manifest (not a separate file)\n// so it ships in dist/powerhouse.manifest.json and the Connect build can read\n// it without executing package code.\n//\n// Every fixed-shape object below is strict (z.strictObject): an unknown key —\n// e.g. a `manifest.nam` typo — fails the build loudly instead of being\n// silently dropped, matching the JSON schema's `additionalProperties: false`.\n// Only the open MIME/header maps (z.record) accept arbitrary keys by design.\nconst PwaUrlPatternSchema = z.union([\n z.string(),\n z\n .strictObject({ source: z.string(), flags: z.string().optional() })\n // The pair is rebuilt into a RegExp at build time; catch a non-compiling\n // pattern here, where validation can still name the contributor.\n .refine(\n (p) => {\n try {\n new RegExp(p.source, p.flags);\n return true;\n } catch {\n return false;\n }\n },\n { message: \"source/flags do not compile to a valid RegExp\" },\n ),\n]);\n\nconst PwaRuntimeCachingSchema = z.strictObject({\n urlPattern: PwaUrlPatternSchema,\n handler: z.enum([\n \"CacheFirst\",\n \"CacheOnly\",\n \"NetworkFirst\",\n \"NetworkOnly\",\n \"StaleWhileRevalidate\",\n ]),\n method: z.enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"HEAD\", \"PATCH\"]).optional(),\n options: z\n .strictObject({\n cacheName: z.string().optional(),\n networkTimeoutSeconds: z.number().optional(),\n expiration: z\n .strictObject({\n maxEntries: z.number().optional(),\n maxAgeSeconds: z.number().optional(),\n })\n .optional(),\n cacheableResponse: z\n .strictObject({\n statuses: z.array(z.number()).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n })\n .optional(),\n});\n\nconst PwaIconSchema = z.strictObject({\n src: z.string(),\n sizes: z.string().optional(),\n type: z.string().optional(),\n purpose: z.string().optional(),\n});\n\n// No `action` field: the route launched files open at is fixed by Connect\n// (the runtime handling lives in Connect's own source), so contributors only\n// declare WHICH file types they accept. `strictObject` rejects a fragment\n// that tries to set its own route. Extensions must carry the leading dot —\n// Chromium silently ignores dotless entries, so fail loudly at build instead.\nconst PwaFileHandlerSchema = z.strictObject({\n accept: z.record(\n z.string(),\n z.array(z.string().regex(/^\\./, \"file extensions must start with '.'\")),\n ),\n icons: z.array(PwaIconSchema).optional(),\n launch_type: z.enum([\"single-client\", \"multiple-clients\"]).optional(),\n});\n\n// `categories` is intentionally NOT here: it is not authored under\n// `connect.pwa` — it is derived from the `category` field of the contributing\n// `powerhouse.manifest.json` files (see collectProjectPwaContribution /\n// toPwaContribution). `strictObject` therefore rejects an authored `categories`\n// (and the removed `shortcuts`/`screenshots`/`share_target`/`display_override`).\nconst PwaManifestOverrideSchema = z.strictObject({\n name: z.string().optional(),\n short_name: z.string().optional(),\n description: z.string().optional(),\n theme_color: z.string().optional(),\n background_color: z.string().optional(),\n display: z\n .enum([\"fullscreen\", \"standalone\", \"minimal-ui\", \"browser\"])\n .optional(),\n start_url: z.string().optional(),\n scope: z.string().optional(),\n icons: z.array(PwaIconSchema).optional(),\n file_handlers: z.array(PwaFileHandlerSchema).optional(),\n launch_handler: z\n .strictObject({\n client_mode: z.enum([\n \"auto\",\n \"focus-existing\",\n \"navigate-existing\",\n \"navigate-new\",\n ]),\n })\n .optional(),\n});\n\nexport const PwaConfigSchema: z.ZodType<PHConnectPwa> = z.strictObject({\n manifest: PwaManifestOverrideSchema.optional(),\n globPatterns: z.array(z.string()).optional(),\n globIgnores: z.array(z.string()).optional(),\n maximumFileSizeToCacheInBytes: z.number().optional(),\n runtimeCaching: z.array(PwaRuntimeCachingSchema).optional(),\n navigateFallbackDenylist: z.array(PwaUrlPatternSchema).optional(),\n});\n\nexport const ManifestSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n category: z.string().optional(),\n image: z.string().optional(),\n publisher: PublisherSchema.optional(),\n documentModels: PowerhouseModulesSchema,\n apps: PowerhouseModulesSchema,\n editors: PowerhouseModulesSchema,\n processors: PowerhouseModulesSchema,\n subgraphs: PowerhouseModulesSchema,\n // Connector pieces the package ships, built under pieces/ and loaded by a\n // host that runs them. Optional like every other module list, so a package\n // that ships none says nothing.\n pieces: PowerhouseModulesSchema,\n config: z.array(ConfigEntrySchema).optional(),\n pwa: PwaConfigSchema.optional(),\n});\n","import { ZodError } from \"zod\";\nimport {\n ab2hex,\n buildOperationSignatureMessage,\n buildOperationSignatureParams,\n hex2ab,\n} from \"./crypto.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport {\n InvalidActionInputError,\n InvalidActionInputZodError,\n} from \"./errors.js\";\nimport type { Operation, OperationContext } from \"./operations.js\";\nimport {\n AddChangeLogItemInputSchema,\n AddModuleInputSchema,\n AddOperationErrorInputSchema,\n AddOperationExampleInputSchema,\n AddOperationInputSchema,\n AddStateExampleInputSchema,\n DeleteChangeLogItemInputSchema,\n DeleteModuleInputSchema,\n DeleteOperationErrorInputSchema,\n DeleteOperationExampleInputSchema,\n DeleteOperationInputSchema,\n DeleteStateExampleInputSchema,\n LoadStateActionInputSchema,\n MoveOperationInputSchema,\n PruneActionInputSchema,\n RedoActionInputSchema,\n ReorderChangeLogItemsInputSchema,\n ReorderModuleOperationsInputSchema,\n ReorderModulesInputSchema,\n ReorderOperationErrorsInputSchema,\n ReorderOperationExamplesInputSchema,\n ReorderStateExamplesInputSchema,\n SetAuthorNameInputSchema,\n SetAuthorWebsiteInputSchema,\n SetInitialStateInputSchema,\n SetModelDescriptionInputSchema,\n SetModelExtensionInputSchema,\n SetModelIdInputSchema,\n SetModelNameInputSchema,\n SetModuleDescriptionInputSchema,\n SetModuleNameInputSchema,\n SetNameActionInputSchema,\n SetPreferredEditorActionInputSchema,\n SetOperationDescriptionInputSchema,\n SetOperationErrorCodeInputSchema,\n SetOperationErrorDescriptionInputSchema,\n SetOperationErrorNameInputSchema,\n SetOperationErrorTemplateInputSchema,\n SetOperationNameInputSchema,\n SetOperationReducerInputSchema,\n SetOperationSchemaInputSchema,\n SetOperationScopeInputSchema,\n SetOperationTemplateInputSchema,\n SetStateSchemaInputSchema,\n UndoActionInputSchema,\n UpdateChangeLogItemInputSchema,\n UpdateOperationExampleInputSchema,\n UpdateStateExampleInputSchema,\n} from \"./schemas.js\";\nimport type {\n ActionSigner,\n AppActionSigner,\n Signature,\n UserActionSigner,\n} from \"./signatures.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n ActionSignatureContext,\n ActionSigningHandler,\n ActionVerificationHandler,\n AddChangeLogItemAction,\n AddChangeLogItemInput,\n AddModuleAction,\n AddModuleInput,\n AddOperationAction,\n AddOperationErrorAction,\n AddOperationErrorInput,\n AddOperationExampleAction,\n AddOperationExampleInput,\n AddOperationInput,\n AddStateExampleAction,\n AddStateExampleInput,\n DeleteChangeLogItemAction,\n DeleteChangeLogItemInput,\n DeleteModuleAction,\n DeleteModuleInput,\n DeleteOperationAction,\n DeleteOperationErrorAction,\n DeleteOperationErrorInput,\n DeleteOperationExampleAction,\n DeleteOperationExampleInput,\n DeleteOperationInput,\n DeleteStateExampleAction,\n DeleteStateExampleInput,\n LoadStateAction,\n MoveOperationAction,\n MoveOperationInput,\n NOOPAction,\n RedoAction,\n Reducer,\n ReleaseNewVersionAction,\n ReorderChangeLogItemsAction,\n ReorderChangeLogItemsInput,\n ReorderModuleOperationsAction,\n ReorderModuleOperationsInput,\n ReorderModulesAction,\n ReorderModulesInput,\n ReorderOperationErrorsAction,\n ReorderOperationErrorsInput,\n ReorderOperationExamplesAction,\n ReorderOperationExamplesInput,\n ReorderStateExamplesAction,\n ReorderStateExamplesInput,\n SchemaPruneAction,\n SetAuthorNameAction,\n SetAuthorNameInput,\n SetAuthorWebsiteAction,\n SetAuthorWebsiteInput,\n SetInitialStateAction,\n SetInitialStateInput,\n SetModelDescriptionAction,\n SetModelDescriptionInput,\n SetModelExtensionAction,\n SetModelExtensionInput,\n SetModelIdAction,\n SetModelIdInput,\n SetModelNameAction,\n SetModelNameInput,\n SetModuleDescriptionAction,\n SetModuleDescriptionInput,\n SetModuleNameAction,\n SetModuleNameInput,\n SetNameAction,\n SetPreferredEditorAction,\n SetOperationDescriptionAction,\n SetOperationDescriptionInput,\n SetOperationErrorCodeAction,\n SetOperationErrorCodeInput,\n SetOperationErrorDescriptionAction,\n SetOperationErrorDescriptionInput,\n SetOperationErrorNameAction,\n SetOperationErrorNameInput,\n SetOperationErrorTemplateAction,\n SetOperationErrorTemplateInput,\n SetOperationNameAction,\n SetOperationNameInput,\n SetOperationReducerAction,\n SetOperationReducerInput,\n SetOperationSchemaAction,\n SetOperationSchemaInput,\n SetOperationScopeAction,\n SetOperationScopeInput,\n SetOperationTemplateAction,\n SetOperationTemplateInput,\n SetStateSchemaAction,\n SetStateSchemaInput,\n UndoAction,\n UpdateChangeLogItemAction,\n UpdateChangeLogItemInput,\n UpdateOperationExampleAction,\n UpdateOperationExampleInput,\n UpdateStateExampleAction,\n UpdateStateExampleInput,\n} from \"./types.js\";\nimport { deriveOperationId, generateId } from \"./utils.js\";\n\n/**\n * Cancels the last `count` operations.\n *\n * @param count - Number of operations to cancel\n * @category Actions\n */\nexport const undo = (count = 1, scope = \"global\") =>\n createAction<UndoAction>(\n \"UNDO\",\n { count },\n undefined,\n UndoActionInputSchema,\n scope,\n );\n\n/**\n * Cancels the last `count` {@link undo | UNDO} operations.\n *\n * @param count - Number of UNDO operations to cancel\n * @category Actions\n */\nexport const redo = (count = 1, scope = \"global\") =>\n createAction<RedoAction>(\n \"REDO\",\n { count },\n undefined,\n RedoActionInputSchema,\n scope,\n );\n\n/**\n * Joins multiple operations into a single {@link loadState | LOAD_STATE} operation.\n *\n * @remarks\n * Useful to keep operations history smaller. Operations to prune are selected by index,\n * similar to the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | slice} method in Arrays.\n *\n * @param start - Index of the first operation to prune\n * @param end - Index of the last operation to prune\n * @category Actions\n */\nexport const prune = (start?: number, end?: number, scope = \"global\") =>\n createAction<SchemaPruneAction>(\n \"PRUNE\",\n { start, end },\n undefined,\n PruneActionInputSchema,\n scope,\n );\n\n/**\n * Replaces the state of the document.\n *\n * @remarks\n * This action shouldn't be used directly. It is dispatched by the {@link prune} action.\n *\n * @param state - State to be set in the document.\n * @param operations - Number of operations that were removed from the previous state.\n * @category Actions\n */\nexport const loadState = <TState extends PHBaseState = PHBaseState>(\n state: TState & { name: string },\n operations: number,\n) =>\n createAction<LoadStateAction>(\n \"LOAD_STATE\",\n { state, operations },\n undefined,\n LoadStateActionInputSchema,\n );\n\nexport const noop = (scope = \"global\") =>\n createAction<NOOPAction>(\"NOOP\", {}, undefined, undefined, scope);\n\n// TODO improve base actions type\n\n/**\n * Helper function to be used by action creators.\n *\n * @remarks\n * Creates an action with the given type and input properties. The input\n * properties default to an empty object.\n *\n * @typeParam A - Type of the action to be returned.\n *\n * @param type - The type of the action.\n * @param input - The input properties of the action.\n * @param _attachments - Deprecated and ignored. Retained so action creators\n * generated before the attachment-system removal keep their 5-argument shape.\n * @param validator - The validator to use for the input properties.\n * @param scope - The scope of the action, can either be 'global' or 'local'.\n *\n * @throws Error if the type is empty or not a string.\n *\n * @returns The new action.\n */\nexport function createAction<TAction extends Action>(\n type: TAction[\"type\"],\n input?: TAction[\"input\"],\n // Deprecated, ignored. Retained so action creators generated before the\n // legacy attachment system was removed keep their 5-argument call shape.\n _attachments?: unknown,\n validator?: () => { parse(v: unknown): TAction[\"input\"] },\n scope: Action[\"scope\"] = \"global\",\n): TAction {\n if (!type) throw new Error(\"Empty action type\");\n if (typeof type !== \"string\")\n throw new Error(`Invalid action type: ${JSON.stringify(type)}`);\n\n const action: Action = {\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type,\n input,\n scope,\n };\n\n try {\n validator?.().parse(action.input);\n } catch (error) {\n if (error instanceof ZodError) {\n throw new InvalidActionInputZodError(error.issues);\n }\n throw new InvalidActionInputError(error);\n }\n\n return action as TAction;\n}\n\n/**\n * This function should be used instead of { ...action } to ensure\n * that extra properties are not included in the action.\n */\nexport const actionFromAction = (action: Action): Action => {\n return {\n id: action.id,\n timestampUtcMs: action.timestampUtcMs,\n type: action.type,\n input: action.input,\n scope: action.scope,\n context: action.context,\n };\n};\n\nexport const operationFromAction = (\n action: Action,\n index: number,\n skip: number,\n context: OperationContext,\n): Operation => {\n return {\n ...action,\n action,\n id: deriveOperationId(\n context.documentId,\n context.scope,\n context.branch,\n action.id,\n ),\n timestampUtcMs: action.timestampUtcMs,\n hash: \"\",\n error: undefined,\n\n index,\n skip,\n };\n};\n\nexport const operationFromOperation = (\n operation: Operation,\n index: number,\n skip: number,\n context: OperationContext,\n): Operation => {\n const id = deriveOperationId(\n context.documentId,\n context.scope,\n context.branch,\n operation.action.id,\n );\n\n return {\n ...operation,\n hash: \"\",\n error: undefined,\n index,\n skip,\n id,\n };\n};\n\nexport const operationWithContext = (\n operation: Operation,\n context: ActionContext,\n): Operation => {\n if (!operation.action) {\n throw new Error(\"Operation has no action\");\n }\n\n return {\n ...operation,\n action: {\n ...operation.action,\n context,\n },\n };\n};\n\nexport const actionContext = (): ActionContext => ({});\n\nexport const actionSigner = (\n user: UserActionSigner,\n app: AppActionSigner,\n signatures: Signature[] = [],\n): ActionSigner => ({\n user,\n app,\n signatures,\n});\n\nexport async function buildOperationSignature(\n context: ActionSignatureContext,\n signMethod: ActionSigningHandler,\n): Promise<Signature> {\n const params = buildOperationSignatureParams(context);\n const message = buildOperationSignatureMessage(params);\n const signature = await signMethod(message);\n return [...params, `0x${ab2hex(signature)}`];\n}\n\nexport async function buildSignedAction<\n TState extends PHBaseState = PHBaseState,\n>(\n action: Action,\n reducer: Reducer<TState>,\n document: PHDocument<TState>,\n signer: ActionSigner,\n signHandler: ActionSigningHandler,\n) {\n const result = reducer(document, action, undefined, {\n //reuseHash: true,\n reuseOperationResultingState: true,\n });\n const scopeOperations = result.operations[action.scope];\n if (!scopeOperations) {\n throw new Error(`No operations found for scope: ${action.scope}`);\n }\n const operation = scopeOperations.at(-1);\n if (!operation) {\n throw new Error(\"Action was not applied\");\n }\n\n const previousStateHash = scopeOperations.at(-2)?.hash ?? \"\";\n const signature = await buildOperationSignature(\n {\n documentId: document.header.id,\n signer,\n action,\n previousStateHash,\n },\n signHandler,\n );\n\n const actionContext: ActionContext = {\n signer: actionSigner(signer.user, signer.app, [\n ...signer.signatures,\n signature,\n ]),\n };\n\n return operationWithContext(operation, actionContext);\n}\n\nexport async function verifyOperationSignature(\n signature: Signature,\n signer: Omit<ActionSigner, \"signatures\">,\n verifyHandler: ActionVerificationHandler,\n) {\n const publicKey = signer.app.key;\n const params = signature.slice(0, 4) as [string, string, string, string];\n const signatureBytes = hex2ab(signature[4]);\n const expectedMessage = buildOperationSignatureMessage(params);\n return verifyHandler(publicKey, signatureBytes, expectedMessage);\n}\n\n/**\n * Changes the name of the document.\n *\n * @param name - The name to be set in the document.\n * @category Actions\n */\nexport const setName = (name: string | { name: string }) =>\n createAction<SetNameAction>(\n \"SET_NAME\",\n typeof name === \"string\" ? { name } : name,\n undefined,\n SetNameActionInputSchema,\n // TODO: THIS IS A BUG: This needs to be changed to a HEADER scope action if it's changing the header.\n \"global\",\n );\n\n/**\n * Changes the preferred editor recorded in the document header meta.\n *\n * Passing `null` clears the preferred editor.\n *\n * @category Actions\n */\nexport const setPreferredEditor = (\n input: string | null | { preferredEditor: string | null },\n) =>\n createAction<SetPreferredEditorAction>(\n \"SET_PREFERRED_EDITOR\",\n typeof input === \"object\" && input !== null\n ? input\n : { preferredEditor: input },\n undefined,\n SetPreferredEditorActionInputSchema,\n \"header\",\n );\nexport const setModelName = (input: SetModelNameInput) =>\n createAction<SetModelNameAction>(\n \"SET_MODEL_NAME\",\n { ...input },\n undefined,\n SetModelNameInputSchema,\n \"global\",\n );\n\nexport const setModelId = (input: SetModelIdInput) =>\n createAction<SetModelIdAction>(\n \"SET_MODEL_ID\",\n { ...input },\n undefined,\n SetModelIdInputSchema,\n \"global\",\n );\n\nexport const setModelExtension = (input: SetModelExtensionInput) =>\n createAction<SetModelExtensionAction>(\n \"SET_MODEL_EXTENSION\",\n { ...input },\n undefined,\n SetModelExtensionInputSchema,\n \"global\",\n );\n\nexport const setModelDescription = (input: SetModelDescriptionInput) =>\n createAction<SetModelDescriptionAction>(\n \"SET_MODEL_DESCRIPTION\",\n { ...input },\n undefined,\n SetModelDescriptionInputSchema,\n \"global\",\n );\n\nexport const setAuthorName = (input: SetAuthorNameInput) =>\n createAction<SetAuthorNameAction>(\n \"SET_AUTHOR_NAME\",\n { ...input },\n undefined,\n SetAuthorNameInputSchema,\n \"global\",\n );\n\nexport const setAuthorWebsite = (input: SetAuthorWebsiteInput) =>\n createAction<SetAuthorWebsiteAction>(\n \"SET_AUTHOR_WEBSITE\",\n { ...input },\n undefined,\n SetAuthorWebsiteInputSchema,\n \"global\",\n );\n\nexport const addModule = (input: AddModuleInput) =>\n createAction<AddModuleAction>(\n \"ADD_MODULE\",\n { ...input },\n undefined,\n AddModuleInputSchema,\n \"global\",\n );\n\nexport const setModuleName = (input: SetModuleNameInput) =>\n createAction<SetModuleNameAction>(\n \"SET_MODULE_NAME\",\n { ...input },\n undefined,\n SetModuleNameInputSchema,\n \"global\",\n );\n\nexport const setModuleDescription = (input: SetModuleDescriptionInput) =>\n createAction<SetModuleDescriptionAction>(\n \"SET_MODULE_DESCRIPTION\",\n { ...input },\n undefined,\n SetModuleDescriptionInputSchema,\n \"global\",\n );\n\nexport const deleteModule = (input: DeleteModuleInput) =>\n createAction<DeleteModuleAction>(\n \"DELETE_MODULE\",\n { ...input },\n undefined,\n DeleteModuleInputSchema,\n \"global\",\n );\n\nexport const reorderModules = (input: ReorderModulesInput) =>\n createAction<ReorderModulesAction>(\n \"REORDER_MODULES\",\n { ...input },\n undefined,\n ReorderModulesInputSchema,\n \"global\",\n );\n\nexport const addOperation = (input: AddOperationInput) =>\n createAction<AddOperationAction>(\n \"ADD_OPERATION\",\n { ...input },\n undefined,\n AddOperationInputSchema,\n \"global\",\n );\n\nexport const setOperationName = (input: SetOperationNameInput) =>\n createAction<SetOperationNameAction>(\n \"SET_OPERATION_NAME\",\n { ...input },\n undefined,\n SetOperationNameInputSchema,\n \"global\",\n );\n\nexport const setOperationScope = (input: SetOperationScopeInput) =>\n createAction<SetOperationScopeAction>(\n \"SET_OPERATION_SCOPE\",\n { ...input },\n undefined,\n SetOperationScopeInputSchema,\n \"global\",\n );\n\nexport const setOperationSchema = (input: SetOperationSchemaInput) =>\n createAction<SetOperationSchemaAction>(\n \"SET_OPERATION_SCHEMA\",\n { ...input },\n undefined,\n SetOperationSchemaInputSchema,\n \"global\",\n );\n\nexport const setOperationDescription = (input: SetOperationDescriptionInput) =>\n createAction<SetOperationDescriptionAction>(\n \"SET_OPERATION_DESCRIPTION\",\n { ...input },\n undefined,\n SetOperationDescriptionInputSchema,\n \"global\",\n );\n\nexport const setOperationTemplate = (input: SetOperationTemplateInput) =>\n createAction<SetOperationTemplateAction>(\n \"SET_OPERATION_TEMPLATE\",\n { ...input },\n undefined,\n SetOperationTemplateInputSchema,\n \"global\",\n );\n\nexport const setOperationReducer = (input: SetOperationReducerInput) =>\n createAction<SetOperationReducerAction>(\n \"SET_OPERATION_REDUCER\",\n { ...input },\n undefined,\n SetOperationReducerInputSchema,\n \"global\",\n );\n\nexport const moveOperation = (input: MoveOperationInput) =>\n createAction<MoveOperationAction>(\n \"MOVE_OPERATION\",\n { ...input },\n undefined,\n MoveOperationInputSchema,\n \"global\",\n );\n\nexport const deleteOperation = (input: DeleteOperationInput) =>\n createAction<DeleteOperationAction>(\n \"DELETE_OPERATION\",\n { ...input },\n undefined,\n DeleteOperationInputSchema,\n \"global\",\n );\n\nexport const reorderModuleOperations = (input: ReorderModuleOperationsInput) =>\n createAction<ReorderModuleOperationsAction>(\n \"REORDER_MODULE_OPERATIONS\",\n { ...input },\n undefined,\n ReorderModuleOperationsInputSchema,\n \"global\",\n );\n\nexport const addOperationError = (input: AddOperationErrorInput) =>\n createAction<AddOperationErrorAction>(\n \"ADD_OPERATION_ERROR\",\n { ...input },\n undefined,\n AddOperationErrorInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorCode = (input: SetOperationErrorCodeInput) =>\n createAction<SetOperationErrorCodeAction>(\n \"SET_OPERATION_ERROR_CODE\",\n { ...input },\n undefined,\n SetOperationErrorCodeInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorName = (input: SetOperationErrorNameInput) =>\n createAction<SetOperationErrorNameAction>(\n \"SET_OPERATION_ERROR_NAME\",\n { ...input },\n undefined,\n SetOperationErrorNameInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorDescription = (\n input: SetOperationErrorDescriptionInput,\n) =>\n createAction<SetOperationErrorDescriptionAction>(\n \"SET_OPERATION_ERROR_DESCRIPTION\",\n { ...input },\n undefined,\n SetOperationErrorDescriptionInputSchema,\n \"global\",\n );\n\nexport const setOperationErrorTemplate = (\n input: SetOperationErrorTemplateInput,\n) =>\n createAction<SetOperationErrorTemplateAction>(\n \"SET_OPERATION_ERROR_TEMPLATE\",\n { ...input },\n undefined,\n SetOperationErrorTemplateInputSchema,\n \"global\",\n );\n\nexport const deleteOperationError = (input: DeleteOperationErrorInput) =>\n createAction<DeleteOperationErrorAction>(\n \"DELETE_OPERATION_ERROR\",\n { ...input },\n undefined,\n DeleteOperationErrorInputSchema,\n \"global\",\n );\n\nexport const reorderOperationErrors = (input: ReorderOperationErrorsInput) =>\n createAction<ReorderOperationErrorsAction>(\n \"REORDER_OPERATION_ERRORS\",\n { ...input },\n undefined,\n ReorderOperationErrorsInputSchema,\n \"global\",\n );\n\nexport const addOperationExample = (input: AddOperationExampleInput) =>\n createAction<AddOperationExampleAction>(\n \"ADD_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n AddOperationExampleInputSchema,\n \"global\",\n );\n\nexport const updateOperationExample = (input: UpdateOperationExampleInput) =>\n createAction<UpdateOperationExampleAction>(\n \"UPDATE_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n UpdateOperationExampleInputSchema,\n \"global\",\n );\n\nexport const deleteOperationExample = (input: DeleteOperationExampleInput) =>\n createAction<DeleteOperationExampleAction>(\n \"DELETE_OPERATION_EXAMPLE\",\n { ...input },\n undefined,\n DeleteOperationExampleInputSchema,\n \"global\",\n );\n\nexport const reorderOperationExamples = (\n input: ReorderOperationExamplesInput,\n) =>\n createAction<ReorderOperationExamplesAction>(\n \"REORDER_OPERATION_EXAMPLES\",\n { ...input },\n undefined,\n ReorderOperationExamplesInputSchema,\n \"global\",\n );\n\nexport const operationExampleCreators = {\n addOperationExample,\n updateOperationExample,\n deleteOperationExample,\n reorderOperationExamples,\n};\n\nexport const setStateSchema = (input: SetStateSchemaInput) =>\n createAction<SetStateSchemaAction>(\n \"SET_STATE_SCHEMA\",\n { ...input },\n undefined,\n SetStateSchemaInputSchema,\n \"global\",\n );\n\nexport const setInitialState = (input: SetInitialStateInput) =>\n createAction<SetInitialStateAction>(\n \"SET_INITIAL_STATE\",\n { ...input },\n undefined,\n SetInitialStateInputSchema,\n \"global\",\n );\n\nexport const addStateExample = (input: AddStateExampleInput) =>\n createAction<AddStateExampleAction>(\n \"ADD_STATE_EXAMPLE\",\n { ...input },\n undefined,\n AddStateExampleInputSchema,\n \"global\",\n );\n\nexport const updateStateExample = (input: UpdateStateExampleInput) =>\n createAction<UpdateStateExampleAction>(\n \"UPDATE_STATE_EXAMPLE\",\n { ...input },\n undefined,\n UpdateStateExampleInputSchema,\n \"global\",\n );\n\nexport const deleteStateExample = (input: DeleteStateExampleInput) =>\n createAction<DeleteStateExampleAction>(\n \"DELETE_STATE_EXAMPLE\",\n { ...input },\n undefined,\n DeleteStateExampleInputSchema,\n \"global\",\n );\n\nexport const reorderStateExamples = (input: ReorderStateExamplesInput) =>\n createAction<ReorderStateExamplesAction>(\n \"REORDER_STATE_EXAMPLES\",\n { ...input },\n undefined,\n ReorderStateExamplesInputSchema,\n \"global\",\n );\n\nexport const addChangeLogItem = (input: AddChangeLogItemInput) =>\n createAction<AddChangeLogItemAction>(\n \"ADD_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n AddChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const updateChangeLogItem = (input: UpdateChangeLogItemInput) =>\n createAction<UpdateChangeLogItemAction>(\n \"UPDATE_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n UpdateChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const deleteChangeLogItem = (input: DeleteChangeLogItemInput) =>\n createAction<DeleteChangeLogItemAction>(\n \"DELETE_CHANGE_LOG_ITEM\",\n { ...input },\n undefined,\n DeleteChangeLogItemInputSchema,\n \"global\",\n );\n\nexport const reorderChangeLogItems = (input: ReorderChangeLogItemsInput) =>\n createAction<ReorderChangeLogItemsAction>(\n \"REORDER_CHANGE_LOG_ITEMS\",\n { ...input },\n undefined,\n ReorderChangeLogItemsInputSchema,\n \"global\",\n );\n\nexport const releaseNewVersion = () =>\n createAction<ReleaseNewVersionAction>(\n \"RELEASE_NEW_VERSION\",\n {},\n undefined,\n undefined,\n \"global\",\n );\n\nexport const baseActions = {\n setName,\n setPreferredEditor,\n undo,\n redo,\n prune,\n loadState,\n noop,\n};\n\nexport const documentModelActions = {\n setModelName,\n setModelId,\n setModelExtension,\n setModelDescription,\n setAuthorName,\n setAuthorWebsite,\n addModule,\n setModuleName,\n setModuleDescription,\n deleteModule,\n reorderModules,\n addOperation,\n setOperationName,\n setOperationScope,\n setOperationSchema,\n setOperationDescription,\n setOperationTemplate,\n setOperationReducer,\n moveOperation,\n deleteOperation,\n reorderModuleOperations,\n addOperationError,\n setOperationErrorCode,\n setOperationErrorName,\n setOperationErrorDescription,\n setOperationErrorTemplate,\n deleteOperationError,\n reorderOperationErrors,\n addOperationExample,\n updateOperationExample,\n deleteOperationExample,\n reorderOperationExamples,\n setStateSchema,\n setInitialState,\n addStateExample,\n updateStateExample,\n deleteStateExample,\n reorderStateExamples,\n addChangeLogItem,\n updateChangeLogItem,\n deleteChangeLogItem,\n reorderChangeLogItems,\n releaseNewVersion,\n};\n\nexport const actions = { ...baseActions, ...documentModelActions };\n\n/**\n * The context of an action.\n */\nexport type ActionContext = {\n /** The index of the previous operation, showing intended ordering. */\n prevOpIndex?: number;\n\n /** The hash of the previous operation, showing intended state. */\n prevOpHash?: string;\n\n /** A nonce, to cover specific signing attacks and to prevent replay attacks from no-ops. */\n nonce?: string;\n\n /** The signer of the action. */\n signer?: ActionSigner;\n};\n\n/**\n * Defines the basic structure of an action.\n */\nexport type Action = {\n /** The id of the action. This is distinct from the operation id. */\n id: string;\n\n /** The name of the action. */\n type: string;\n\n /** The timestamp of the action. */\n timestampUtcMs: string;\n\n /** The payload of the action. */\n input: unknown;\n\n /** The scope of the action */\n scope: string;\n\n /** The context of the action. */\n context?: ActionContext;\n};\n","export const documentModelDocumentType = \"powerhouse/document-model\";\nexport const groupDocumentType = \"powerhouse/reactor-group\";\n\n/**\n * The group-model action types that change membership. The groups projection\n * filters its reads to these, so any other group operation is invisible to a\n * decision. Kept here so the reactor never depends on the group package; a\n * reactor-group test guards against drift.\n */\nexport const groupMembershipActionTypes = [\n \"ADD_MEMBER\",\n \"REMOVE_MEMBER\",\n] as const;\n","// Version-1 auth policy rules. These are consensus rules applied identically\n// by every replica; changing any of them requires a new policy version.\n\nimport { z } from \"zod\";\nimport type {\n AuthDecision,\n AuthEvaluation,\n AuthRequest,\n AuthSubject,\n ConditionContext,\n} from \"./auth.js\";\nimport { groupDocumentType } from \"./document-type.js\";\nimport type {\n AuthGroups,\n Capability,\n Condition,\n Grant,\n PHGroupState,\n Principal,\n} from \"./state.js\";\n\n/** Maximum number of grants in a policy. */\nexport const MAX_AUTH_GRANTS = 100;\n/** Maximum nesting depth of a condition tree. */\nexport const MAX_CONDITION_DEPTH = 10;\n/** Maximum node count (conditions plus operands) of a condition tree. */\nexport const MAX_CONDITION_NODES = 100;\n/** Maximum entries in an execute capability's operation list. */\nexport const MAX_CAPABILITY_OPERATIONS = 100;\n\n/**\n * Thrown when a grant violates the v1 validation rules. The message is stored\n * on error operations, so it must be a pure function of the input.\n */\nexport class InvalidGrantError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string, problem: string) {\n super(`Invalid grant \"${grantId}\": ${problem}`);\n this.name = \"InvalidGrantError\";\n this.grantId = grantId;\n }\n}\n\n/** Thrown for a `{ group }` principal on a group document: references never chain. */\nexport class GroupPrincipalNotAllowedError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(\n `Grant \"${grantId}\" uses a group principal on a group document: a group's auth scope cannot reference other groups`,\n );\n this.name = \"GroupPrincipalNotAllowedError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when a change would leave a creator-less policy with no grant\n * permitting execute on the auth scope. Without the creator carve-out no\n * subject could ever administer such a policy again.\n */\nexport class AuthAdministrationLockoutError extends Error {\n public readonly grantId: string;\n\n constructor(grantId: string) {\n super(\n `Change to grant \"${grantId}\" would leave no reachable grant permitting execute on the auth scope: a policy with no creator must always retain one`,\n );\n this.name = \"AuthAdministrationLockoutError\";\n this.grantId = grantId;\n }\n}\n\n/**\n * Thrown when INITIALIZE_AUTH would create a creator-less policy with no grant\n * permitting execute on the auth scope. Such a policy would be born with no\n * subject able to administer it.\n */\nexport class AuthAdministrationMissingError extends Error {\n constructor() {\n super(\n \"Initial grants include no reachable grant permitting execute on the auth scope: a policy with no creator must always include one\",\n );\n this.name = \"AuthAdministrationMissingError\";\n }\n}\n\nconst GRANT_KEYS = new Set([\n \"id\",\n \"description\",\n \"effect\",\n \"principal\",\n \"capability\",\n \"where\",\n]);\nconst PRINCIPAL_KINDS = new Set([\"anyone\", \"address\", \"group\", \"match\"]);\nconst COMPARISON_CONDITION_KINDS = new Set([\n \"eq\",\n \"ne\",\n \"lt\",\n \"lte\",\n \"gt\",\n \"gte\",\n]);\n\nexport function isPlainValue(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction operandProblem(\n value: unknown,\n capabilityScope: string | undefined,\n budget: { nodes: number },\n): string | null {\n budget.nodes -= 1;\n if (budget.nodes < 0) {\n return `condition exceeds ${MAX_CONDITION_NODES} nodes`;\n }\n if (!isPlainValue(value)) {\n return \"operand must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1) {\n return \"operand must have exactly one of attr or lit\";\n }\n if (keys[0] === \"attr\") {\n const attr = value.attr;\n if (typeof attr !== \"string\" || attr.length === 0) {\n return \"attr must be a non-empty string\";\n }\n if (\n capabilityScope !== undefined &&\n capabilityScope !== \"*\" &&\n attr.startsWith(\"doc.\")\n ) {\n const pathScope = attr.split(\".\")[1] ?? \"\";\n if (pathScope !== capabilityScope) {\n return `condition path \"${attr}\" reads scope \"${pathScope}\" but the capability covers only scope \"${capabilityScope}\"`;\n }\n }\n return null;\n }\n if (keys[0] === \"lit\") {\n const lit = value.lit;\n if (\n lit !== null &&\n typeof lit !== \"string\" &&\n typeof lit !== \"number\" &&\n typeof lit !== \"boolean\"\n ) {\n return \"lit must be a string, number, boolean, or null\";\n }\n // NaN, Infinity, and -0 do not survive JSON round-trips identically\n if (typeof lit === \"number\" && !Number.isFinite(lit)) {\n return \"lit must be a finite number\";\n }\n if (typeof lit === \"number\" && Object.is(lit, -0)) {\n return \"lit must not be negative zero\";\n }\n return null;\n }\n return `unknown operand kind \"${keys[0]}\"`;\n}\n\nfunction conditionProblem(\n value: unknown,\n capabilityScope: string | undefined,\n depth: number,\n budget: { nodes: number },\n): string | null {\n if (depth > MAX_CONDITION_DEPTH) {\n return `condition exceeds depth ${MAX_CONDITION_DEPTH}`;\n }\n budget.nodes -= 1;\n if (budget.nodes < 0) {\n return `condition exceeds ${MAX_CONDITION_NODES} nodes`;\n }\n if (!isPlainValue(value)) {\n return \"condition must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1) {\n return \"condition must have exactly one operator\";\n }\n const kind = keys[0];\n const body = value[kind];\n if (COMPARISON_CONDITION_KINDS.has(kind)) {\n if (!Array.isArray(body) || body.length !== 2) {\n return `${kind} requires a pair of operands`;\n }\n for (const operand of body) {\n const problem = operandProblem(operand, capabilityScope, budget);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"in\" || kind === \"notIn\") {\n if (!Array.isArray(body) || body.length !== 2 || !Array.isArray(body[1])) {\n return `${kind} requires an operand and an operand list`;\n }\n const first = operandProblem(body[0], capabilityScope, budget);\n if (first !== null) {\n return first;\n }\n for (const operand of body[1] as unknown[]) {\n const problem = operandProblem(operand, capabilityScope, budget);\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"exists\") {\n return operandProblem(body, capabilityScope, budget);\n }\n if (kind === \"and\" || kind === \"or\") {\n if (!Array.isArray(body)) {\n return `${kind} requires a condition list`;\n }\n for (const child of body) {\n const problem = conditionProblem(\n child,\n capabilityScope,\n depth + 1,\n budget,\n );\n if (problem !== null) {\n return problem;\n }\n }\n return null;\n }\n if (kind === \"not\") {\n return conditionProblem(body, capabilityScope, depth + 1, budget);\n }\n return `unknown condition operator \"${kind}\"`;\n}\n\nfunction principalProblem(\n value: unknown,\n capabilityScope: string | undefined,\n): string | null {\n if (!isPlainValue(value)) {\n return \"principal must be an object\";\n }\n const keys = Object.keys(value);\n if (keys.length !== 1 || !PRINCIPAL_KINDS.has(keys[0])) {\n return \"principal must have exactly one of anyone, address, group, or match\";\n }\n const kind = keys[0];\n if (kind === \"anyone\" && value.anyone !== true) {\n return \"anyone must be true\";\n }\n if (kind === \"address\") {\n const address = value.address;\n if (typeof address !== \"string\" || address.length === 0) {\n return \"address must be a non-empty string\";\n }\n }\n if (kind === \"group\") {\n const group = value.group;\n if (typeof group !== \"string\" || group.length === 0) {\n return \"group must be a non-empty string\";\n }\n }\n if (kind === \"match\") {\n return conditionProblem(value.match, capabilityScope, 1, {\n nodes: MAX_CONDITION_NODES,\n });\n }\n return null;\n}\n\nfunction capabilityProblem(value: unknown): string | null {\n if (!isPlainValue(value)) {\n return \"capability must be an object\";\n }\n const can = value.can;\n if (can !== \"read\" && can !== \"execute\") {\n return \"capability.can must be read or execute\";\n }\n const allowedKeys =\n can === \"execute\" ? [\"can\", \"scope\", \"operation\"] : [\"can\", \"scope\"];\n // sorted: jsonb storage does not preserve key order\n const unknownKeys = Object.keys(value)\n .filter((key) => !allowedKeys.includes(key))\n .sort();\n if (unknownKeys.length > 0) {\n return `unknown capability key \"${unknownKeys[0]}\"`;\n }\n if (value.scope !== undefined) {\n if (typeof value.scope !== \"string\" || value.scope.length === 0) {\n return \"capability.scope must be a non-empty string\";\n }\n }\n if (can === \"execute\" && value.operation !== undefined) {\n const operation = value.operation;\n if (!Array.isArray(operation)) {\n return \"capability.operation must be an array\";\n }\n if (operation.length > MAX_CAPABILITY_OPERATIONS) {\n return `capability.operation exceeds ${MAX_CAPABILITY_OPERATIONS} entries`;\n }\n for (const entry of operation) {\n if (typeof entry !== \"string\" || entry.length === 0) {\n return \"capability.operation entries must be non-empty strings\";\n }\n }\n }\n return null;\n}\n\n/** Returns the first v1-rule violation, or null. Pure, total, deterministic. */\nexport function grantProblem(value: unknown): string | null {\n if (!isPlainValue(value)) {\n return \"grant must be an object\";\n }\n // sorted: jsonb storage does not preserve key order\n const unknownKeys = Object.keys(value)\n .filter((key) => !GRANT_KEYS.has(key))\n .sort();\n if (unknownKeys.length > 0) {\n return `unknown grant key \"${unknownKeys[0]}\"`;\n }\n if (typeof value.id !== \"string\" || value.id.length === 0) {\n return \"id must be a non-empty string\";\n }\n if (typeof value.description !== \"string\") {\n return \"description must be a string\";\n }\n if (value.effect !== \"allow\" && value.effect !== \"deny\") {\n return \"effect must be allow or deny\";\n }\n const capabilityValue = value.capability;\n const capability = capabilityProblem(capabilityValue);\n if (capability !== null) {\n return capability;\n }\n const capabilityScope = (capabilityValue as Record<string, unknown>).scope as\n | string\n | undefined;\n const principal = principalProblem(value.principal, capabilityScope);\n if (principal !== null) {\n return principal;\n }\n if (value.where !== undefined) {\n return conditionProblem(value.where, capabilityScope, 1, {\n nodes: MAX_CONDITION_NODES,\n });\n }\n return null;\n}\n\nexport const GrantSchema = () =>\n z.custom<Grant>((value) => grantProblem(value) === null);\n\n/** V1 shape rules plus the group-document group-principal ban. */\nexport function assertValidGrant(grant: unknown, documentType: string): void {\n const grantId =\n isPlainValue(grant) && typeof grant.id === \"string\" ? grant.id : \"\";\n const problem = grantProblem(grant);\n if (problem !== null) {\n throw new InvalidGrantError(grantId, problem);\n }\n if (\n documentType === groupDocumentType &&\n \"group\" in (grant as Grant).principal\n ) {\n throw new GroupPrincipalNotAllowedError(grantId);\n }\n}\n\n/**\n * Validates an initial grant list: the count cap, every grant, and — on a\n * creator-less policy — that some grant keeps the auth scope administrable.\n */\nexport function assertValidInitialGrants(\n grants: Grant[],\n documentType: string,\n creator: string | undefined,\n): void {\n if (grants.length > MAX_AUTH_GRANTS) {\n throw new InvalidGrantError(\"\", `policy exceeds ${MAX_AUTH_GRANTS} grants`);\n }\n for (const grant of grants) {\n assertValidGrant(grant, documentType);\n }\n if (creator === undefined && !administrationReachable(grants)) {\n throw new AuthAdministrationMissingError();\n }\n}\n\n/**\n * Validates a grant upsert: the grant itself, the count cap on append, and\n * administration retention. Retention is checked on an append as well as an\n * in-place replace, because a grant appended after the administration grant can\n * shadow it (evaluation is last-applicable-grant-wins) and so take\n * administration away without removing anything.\n */\nexport function assertValidGrantUpsert(\n grant: Grant,\n existing: Grant[],\n documentType: string,\n creator: string | undefined,\n): void {\n assertValidGrant(grant, documentType);\n const exists = existing.some((g) => g.id === grant.id);\n if (!exists && existing.length >= MAX_AUTH_GRANTS) {\n throw new InvalidGrantError(\n grant.id,\n `policy exceeds ${MAX_AUTH_GRANTS} grants`,\n );\n }\n // Built the same way applySetGrantAction builds it, so the two cannot drift.\n const next = exists\n ? existing.map((g) => (g.id === grant.id ? grant : g))\n : [...existing, grant];\n assertAuthAdministrationRetained(creator, existing, next, grant.id);\n}\n\n/**\n * The request whose coverage keeps a policy administrable: a subject who may\n * SET_GRANT can upsert any grant, so every other repair stays reachable.\n */\nconst AUTH_ADMINISTRATION_REQUEST: AuthRequest = {\n verb: \"execute\",\n scope: \"auth\",\n operation: \"SET_GRANT\",\n};\n\n/**\n * Whether some subject can still administer the auth scope under this grant\n * list.\n *\n * Answers exactly what asking {@link evaluateGrantStack} per candidate grant\n * answered, in one reverse pass instead of one full stack scan per candidate.\n * Evaluation is last-applicable-grant-wins, so scanning from the end meets each\n * subject's deciding grant first: an anyone grant decides every subject not\n * already decided, and an allow reached that way is itself a grant that carries\n * administration. Only anyone and address principals are candidates, because\n * those are the ones v1 can match with no groups and no condition context; a\n * `where` condition or a group or match principal never applies.\n */\nfunction administrationReachable(grants: Grant[]): boolean {\n const shadowedAddresses = new Set<string>();\n for (let index = grants.length - 1; index >= 0; index -= 1) {\n const grant = grants[index];\n if (\n grant.where !== undefined ||\n !grantAnswers(grant, AUTH_ADMINISTRATION_REQUEST)\n ) {\n continue;\n }\n const allows = grant.effect === \"allow\";\n if (\"anyone\" in grant.principal) {\n return allows;\n }\n if (!(\"address\" in grant.principal)) {\n continue;\n }\n const address = grant.principal.address.toLowerCase();\n if (shadowedAddresses.has(address)) {\n continue;\n }\n if (allows) {\n return true;\n }\n shadowedAddresses.add(address);\n }\n return false;\n}\n\n/**\n * A creator-less policy must always retain a grant permitting execute on the\n * auth scope; on a signed document the creator carve-out keeps administration\n * reachable instead. Rejects a change that takes the last such grant away. A\n * policy already without one is left alone: the change is not what locks it.\n */\nexport function assertAuthAdministrationRetained(\n creator: string | undefined,\n previous: Grant[],\n next: Grant[],\n grantId: string,\n): void {\n if (creator !== undefined) {\n return;\n }\n if (administrationReachable(previous) && !administrationReachable(next)) {\n throw new AuthAdministrationLockoutError(grantId);\n }\n}\n\n// --- Condition evaluation (version 1) -------------------------------------\n\n/** A resolved operand value; undefined marks a path that did not resolve. */\ntype ConditionValue = string | number | boolean | null;\n\n/**\n * An operand whose shape validation would have rejected. Distinguished from\n * an unresolved path so a structurally malformed operand poisons its whole\n * condition to false rather than reading as \"absent\", which `not` would\n * otherwise widen to true.\n */\nconst INVALID_OPERAND = Symbol(\"invalid-operand\");\ntype ResolvedOperand = ConditionValue | undefined | typeof INVALID_OPERAND;\n\n/**\n * Narrows to the values conditions compare. An object, array, or non-finite\n * number resolves to undefined, and every comparison involving undefined is\n * false.\n */\nfunction asConditionValue(value: unknown): ConditionValue | undefined {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n return undefined;\n}\n\n/**\n * Resolves one operand. Attr roots: `subject.*`, `doc.<scope>.*` where the\n * scope must be the executing scope (validation already rejects any other,\n * but resolution stays total), and `action.input.*`. Path steps read own\n * properties only, so prototype members can never influence a verdict.\n */\nfunction resolveOperand(\n operand: unknown,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): ResolvedOperand {\n if (!isPlainValue(operand)) {\n return INVALID_OPERAND;\n }\n const keys = Object.keys(operand);\n if (keys.length !== 1) {\n return INVALID_OPERAND;\n }\n\n if (keys[0] === \"lit\") {\n const value = asConditionValue(operand.lit);\n // A lit holds a plain finite value by validation; anything else is shape.\n return value === undefined ? INVALID_OPERAND : value;\n }\n\n if (keys[0] !== \"attr\") {\n return INVALID_OPERAND;\n }\n const attr = operand.attr;\n if (typeof attr !== \"string\" || attr.length === 0) {\n return INVALID_OPERAND;\n }\n const path = attr.split(\".\");\n\n let value: unknown;\n let rest: string[];\n if (path[0] === \"subject\") {\n value = subject;\n rest = path.slice(1);\n } else if (path[0] === \"doc\") {\n if (path[1] !== request.scope) {\n return undefined;\n }\n value = conditions.scopeState;\n rest = path.slice(2);\n } else if (path[0] === \"action\" && path[1] === \"input\") {\n value = conditions.actionInput;\n rest = path.slice(2);\n } else {\n return undefined;\n }\n\n for (const segment of rest) {\n if (!isPlainValue(value) || !Object.hasOwn(value, segment)) {\n return undefined;\n }\n value = value[segment];\n }\n return asConditionValue(value);\n}\n\n/**\n * Total order within one type: numbers numerically, strings by code point.\n * Everything else, including mixed types, does not order.\n */\nfunction compareValues(\n left: ConditionValue,\n right: ConditionValue,\n): number | undefined {\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left < right ? -1 : left > right ? 1 : 0;\n }\n if (typeof left === \"string\" && typeof right === \"string\") {\n const leftPoints = Array.from(left);\n const rightPoints = Array.from(right);\n const shared = Math.min(leftPoints.length, rightPoints.length);\n for (let i = 0; i < shared; i++) {\n const a = leftPoints[i].codePointAt(0) ?? 0;\n const b = rightPoints[i].codePointAt(0) ?? 0;\n if (a !== b) {\n return a < b ? -1 : 1;\n }\n }\n return leftPoints.length === rightPoints.length\n ? 0\n : leftPoints.length < rightPoints.length\n ? -1\n : 1;\n }\n return undefined;\n}\n\n/**\n * Tri-state evaluation: undefined marks a structurally invalid node, which\n * poisons the whole tree to false at the top — and a structurally malformed\n * operand poisons its condition the same way. Both are distinct from an\n * operand whose path fails to resolve, which is a valid comparison that is\n * false. The distinction keeps `not` from widening over malformed input.\n */\nfunction evaluateNode(\n node: unknown,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): boolean | undefined {\n if (!isPlainValue(node)) {\n return undefined;\n }\n const keys = Object.keys(node);\n if (keys.length !== 1) {\n return undefined;\n }\n const kind = keys[0];\n const body = node[kind];\n\n switch (kind) {\n case \"eq\":\n case \"ne\":\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n if (!Array.isArray(body) || body.length !== 2) {\n return undefined;\n }\n const left = resolveOperand(body[0], subject, request, conditions);\n const right = resolveOperand(body[1], subject, request, conditions);\n if (left === INVALID_OPERAND || right === INVALID_OPERAND) {\n return undefined;\n }\n if (left === undefined || right === undefined) {\n return false;\n }\n if (kind === \"eq\") {\n return left === right;\n }\n if (kind === \"ne\") {\n return left !== right;\n }\n const order = compareValues(left, right);\n if (order === undefined) {\n return false;\n }\n switch (kind) {\n case \"lt\":\n return order < 0;\n case \"lte\":\n return order <= 0;\n case \"gt\":\n return order > 0;\n case \"gte\":\n return order >= 0;\n }\n return undefined;\n }\n case \"in\":\n case \"notIn\": {\n if (\n !Array.isArray(body) ||\n body.length !== 2 ||\n !Array.isArray(body[1])\n ) {\n return undefined;\n }\n const left = resolveOperand(body[0], subject, request, conditions);\n if (left === INVALID_OPERAND) {\n return undefined;\n }\n const elements = body[1].map((element) =>\n resolveOperand(element, subject, request, conditions),\n );\n if (elements.some((value) => value === INVALID_OPERAND)) {\n return undefined;\n }\n if (left === undefined) {\n return false;\n }\n const found = elements.some(\n (value) => value !== undefined && value === left,\n );\n return kind === \"in\" ? found : !found;\n }\n case \"exists\": {\n const value = resolveOperand(body, subject, request, conditions);\n if (value === INVALID_OPERAND) {\n return undefined;\n }\n return value !== undefined;\n }\n case \"and\":\n case \"or\": {\n if (!Array.isArray(body)) {\n return undefined;\n }\n let result = kind === \"and\";\n for (const child of body) {\n const value = evaluateNode(child, subject, request, conditions);\n if (value === undefined) {\n return undefined;\n }\n if (kind === \"and\") {\n result = result && value;\n } else {\n result = result || value;\n }\n }\n return result;\n }\n case \"not\": {\n const value = evaluateNode(body, subject, request, conditions);\n return value === undefined ? undefined : !value;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Evaluates a version-1 condition. Deterministic, total, and pure: any input\n * shape yields a boolean and never throws, and a malformed condition is\n * false. These are consensus semantics, versioned by `PHAuthState.version`;\n * changing them requires a new version.\n */\nexport function evaluateCondition(\n condition: Condition,\n subject: AuthSubject,\n request: AuthRequest,\n conditions: ConditionContext,\n): boolean {\n return evaluateNode(condition, subject, request, conditions) === true;\n}\n\n/** Whether a capability's scope reaches the requested one. */\nfunction scopeCovers(scope: string | undefined, requested: string): boolean {\n return scope === undefined || scope === \"*\" || scope === requested;\n}\n\n/**\n * Whether one grant answers this request.\n *\n * A grant allowing execute on a scope also allows reading it: executing an\n * operation means reading the state it applies to, so permitting the write while\n * withholding the read would describe an access nobody could use. The converse\n * does not hold -- a read grant confers no write.\n *\n * Only an allow carries across. A deny on execute withholds the write and says\n * nothing about the read, so a policy locking writes down does not silently\n * revoke a read grant sitting before it. The operation list is not consulted\n * either: it restricts which operations may be executed, not whether the scope\n * is visible, and a read carries no operation to match against.\n *\n * Reads are not consensus -- no replica records a read, and the two read call\n * sites are both inside the read gate -- so this rule is not part of what makes\n * an operation valid, and does not need a policy version of its own.\n */\nfunction grantAnswers(grant: Grant, request: AuthRequest): boolean {\n if (capabilityCovers(grant.capability, request)) {\n return true;\n }\n\n return (\n request.verb === \"read\" &&\n grant.effect === \"allow\" &&\n grant.capability.can === \"execute\" &&\n scopeCovers(grant.capability.scope, request.scope)\n );\n}\n\nfunction capabilityCovers(\n capability: Capability,\n request: AuthRequest,\n): boolean {\n if (capability.can !== request.verb) {\n return false;\n }\n if (!scopeCovers(capability.scope, request.scope)) {\n return false;\n }\n if (capability.can === \"execute\") {\n // An execute capability with no operation list covers every operation in the scope.\n if (capability.operation === undefined) {\n return true;\n }\n return (\n request.operation !== undefined &&\n capability.operation.includes(request.operation)\n );\n }\n return true;\n}\n\nfunction principalMatches(\n principal: Principal,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): boolean {\n if (\"anyone\" in principal) {\n return true;\n }\n if (\"address\" in principal) {\n return (\n subject.address !== undefined &&\n subject.address.toLowerCase() === principal.address.toLowerCase()\n );\n }\n if (\"group\" in principal) {\n // Groups match only when the groups projection is supplied (authGroups\n // on). A group the map does not hold fails closed: access is never\n // widened by a missing group.\n if (groups === undefined || subject.address === undefined) {\n return false;\n }\n // Total over malformed folded state: an index miss or a non-list member\n // field never widens access.\n const group = groups[principal.group] as PHGroupState | undefined;\n if (group === undefined || !Array.isArray(group.members)) {\n return false;\n }\n const address = subject.address.toLowerCase();\n return group.members.some((member) => member.toLowerCase() === address);\n }\n if (\"match\" in principal) {\n // Matches only when a condition context is supplied (authConditions on).\n if (conditions === undefined) {\n return false;\n }\n return evaluateCondition(principal.match, subject, request, conditions);\n }\n return false;\n}\n\n/**\n * The group document ids named by `{ group }` principals in a grant list, in\n * order of first appearance. These are the streams the groups projection reads.\n */\nexport function referencedGroupIds(grants: Grant[]): string[] {\n const ids: string[] = [];\n for (const grant of grants) {\n if (\"group\" in grant.principal && !ids.includes(grant.principal.group)) {\n ids.push(grant.principal.group);\n }\n }\n return ids;\n}\n\n/**\n * Evaluates a v1 grant stack: default deny, last applicable grant wins, and\n * reports which grant decided it. Group principals match only against a\n * supplied groups map, and `where` clauses and { match } principals evaluate\n * only against a supplied condition context; a grant that uses an unsupplied\n * feature never applies.\n */\nexport function evaluateGrantStack(\n grants: Grant[],\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthEvaluation {\n let applicable: Grant | undefined;\n for (const grant of grants) {\n if (grant.where !== undefined) {\n // With no condition context a conditional grant never applies.\n if (conditions === undefined) {\n continue;\n }\n if (!evaluateCondition(grant.where, subject, request, conditions)) {\n continue;\n }\n }\n if (\n grantAnswers(grant, request) &&\n principalMatches(grant.principal, subject, request, groups, conditions)\n ) {\n applicable = grant;\n }\n }\n\n if (applicable === undefined) {\n return { decision: \"deny\", refusal: \"no-applicable-grant\" };\n }\n if (applicable.effect === \"deny\") {\n return {\n decision: \"deny\",\n refusal: \"denied-by-grant\",\n grantId: applicable.id,\n };\n }\n return { decision: \"allow\" };\n}\n\n/**\n * Evaluates a v1 grant stack: default deny, last applicable grant wins. This is\n * {@link evaluateGrantStack} with the reason dropped.\n */\nexport function evaluateGrants(\n grants: Grant[],\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthDecision {\n return evaluateGrantStack(grants, subject, request, groups, conditions)\n .decision;\n}\n","import type {\n DocumentModelGlobalState,\n DocumentModelLocalState,\n} from \"./types.js\";\n\nexport const documentModelFileExtension = \"phdm\" as const;\n\nexport const documentModelInitialLocalState: DocumentModelLocalState = {};\nexport const documentModelInitialGlobalState: DocumentModelGlobalState = {\n id: \"\",\n name: \"\",\n extension: \"\",\n description: \"\",\n author: {\n name: \"\",\n website: \"\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n local: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n },\n modules: [],\n },\n ],\n};\nexport const documentModelGlobalState: DocumentModelGlobalState = {\n id: \"powerhouse/document-model\",\n name: \"DocumentModel\",\n extension: \"phdm\",\n description:\n \"The Powerhouse Document Model describes the state and operations of a document type.\",\n author: {\n name: \"Powerhouse\",\n website: \"https://www.powerhouse.inc/\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema:\n \"type CodeExample {\\n id: ID!\\n value: String!\\n}\\n\\ntype OperationError {\\n id: ID!\\n code: String\\n name: String\\n description: String\\n template: String\\n}\\n\\ntype Operation {\\n id: ID!\\n name: String\\n schema: String\\n description: String\\n template: String\\n errors: [OperationError!]!\\n examples: [CodeExample!]!\\n reducer: String\\n scope: String\\n}\\n\\ntype Module {\\n id: ID!\\n name: String!\\n description: String\\n operations: [Operation!]!\\n}\\n\\ntype State {\\n schema: String!\\n initialValue: String!\\n examples: [CodeExample!]!\\n}\\n\\ntype ScopeState {\\n global: State!\\n local: State!\\n}\\n\\ntype Author {\\n name: String!\\n website: String\\n}\\n\\ntype DocumentSpecification {\\n version: Int!\\n state: ScopeState!\\n modules: [Module!]!\\n changeLog: [String!]!\\n}\\n\\ntype DocumentModelGlobalState {\\n name: String!\\n id: String!\\n extension: String!\\n description: String!\\n author: Author!\\n specifications: [DocumentSpecification!]!\\n}\",\n initialValue:\n '{\\n \"id\": \"\",\\n \"name\": \"\",\\n \"extension\": \"\",\\n \"description\": \"\",\\n \"author\": {\\n \"name\": \"\",\\n \"website\": \"\"\\n },\\n \"specifications\": [\\n {\\n \"version\": 1,\\n \"changeLog\": [],\\n \"state\": {\\n \"global\": {\\n \"schema\": \"\",\\n \"initialValue\": \"\",\\n \"examples\": []\\n },\\n \"local\": {\\n \"schema\": \"\",\\n \"initialValue\": \"\",\\n \"examples\": []\\n }\\n },\\n \"modules\": []\\n }\\n ]\\n}',\n examples: [],\n },\n local: {\n schema: \"\",\n initialValue: \"\",\n examples: [],\n },\n },\n modules: [\n {\n name: \"header\",\n operations: [\n {\n name: \"SET_MODEL_NAME\",\n id: \"\",\n description: \"Sets the name of the document model\",\n schema: \"input SetModelNameInput {\\n name: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_ID\",\n id: \"\",\n description: \"Sets the unique identifier for the document model\",\n schema: \"input SetModelIdInput {\\n id: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_EXTENSION\",\n id: \"\",\n description:\n \"Sets the file extension associated with this document model\",\n schema:\n \"input SetModelExtensionInput {\\n extension: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODEL_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description text for the document model\",\n schema:\n \"input SetModelDescriptionInput {\\n description: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_AUTHOR_NAME\",\n id: \"\",\n description: \"Sets the name of the document model author\",\n schema: \"input SetAuthorNameInput {\\n authorName: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_AUTHOR_WEBSITE\",\n id: \"\",\n description: \"Sets the website URL of the document model author\",\n schema:\n \"input SetAuthorWebsiteInput {\\n authorWebsite: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"versioning\",\n operations: [\n {\n name: \"ADD_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Adds a new item to the document model changelog\",\n schema:\n \"input AddChangeLogItemInput {\\n id: ID!\\n insertBefore: ID\\n content: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Updates an existing changelog item\",\n schema:\n \"input UpdateChangeLogItemInput {\\n id: ID!\\n newContent: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_CHANGE_LOG_ITEM\",\n id: \"\",\n description: \"Removes an item from the document model changelog\",\n schema: \"input DeleteChangeLogItemInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_CHANGE_LOG_ITEMS\",\n id: \"\",\n description: \"Changes the order of changelog items\",\n schema:\n \"input ReorderChangeLogItemsInput {\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"RELEASE_NEW_VERSION\",\n schema: null,\n id: \"\",\n description:\n \"Creates a new version of the document model specification\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"module\",\n operations: [\n {\n name: \"ADD_MODULE\",\n id: \"\",\n description:\n \"Adds a new module to the document model specification\",\n schema:\n \"input AddModuleInput {\\n id: ID!\\n name: String!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODULE_NAME\",\n id: \"\",\n description: \"Sets the name of an existing module\",\n schema:\n \"input SetModuleNameInput {\\n id: ID!\\n name: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_MODULE_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an existing module\",\n schema:\n \"input SetModuleDescriptionInput {\\n id: ID!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_MODULE\",\n id: \"\",\n description:\n \"Removes a module from the document model specification\",\n schema: \"input DeleteModuleInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_MODULES\",\n id: \"\",\n description:\n \"Changes the order of modules in the document model specification\",\n schema: \"input ReorderModulesInput {\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation-error\",\n operations: [\n {\n name: \"ADD_OPERATION_ERROR\",\n id: \"\",\n description: \"Adds a new error definition to an operation\",\n schema:\n \"input AddOperationErrorInput {\\n operationId: ID!\\n id: ID!\\n errorCode: String\\n errorName: String\\n errorDescription: String\\n errorTemplate: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_CODE\",\n id: \"\",\n description: \"Sets the error code for an operation error\",\n schema:\n \"input SetOperationErrorCodeInput {\\n id: ID!\\n errorCode: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_NAME\",\n id: \"\",\n description: \"Sets the name of an operation error\",\n schema:\n \"input SetOperationErrorNameInput {\\n id: ID!\\n errorName: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an operation error\",\n schema:\n \"input SetOperationErrorDescriptionInput {\\n id: ID!\\n errorDescription: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_ERROR_TEMPLATE\",\n id: \"\",\n description: \"Sets the template for an operation error\",\n schema:\n \"input SetOperationErrorTemplateInput {\\n id: ID!\\n errorTemplate: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION_ERROR\",\n id: \"\",\n description: \"Removes an error definition from an operation\",\n schema: \"input DeleteOperationErrorInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_OPERATION_ERRORS\",\n id: \"\",\n description:\n \"Changes the order of error definitions for an operation\",\n schema:\n \"input ReorderOperationErrorsInput {\\n operationId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation-example\",\n operations: [\n {\n name: \"ADD_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Adds a new code example to an operation\",\n schema:\n \"input AddOperationExampleInput {\\n operationId: ID!\\n id: ID!\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Updates an existing code example for an operation\",\n schema:\n \"input UpdateOperationExampleInput {\\n id: ID!\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION_EXAMPLE\",\n id: \"\",\n description: \"Removes a code example from an operation\",\n schema: \"input DeleteOperationExampleInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_OPERATION_EXAMPLES\",\n id: \"\",\n description:\n \"Changes the order of code examples for an operation\",\n schema:\n \"input ReorderOperationExamplesInput {\\n operationId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"operation\",\n operations: [\n {\n name: \"ADD_OPERATION\",\n id: \"\",\n description: \"Adds a new operation to a module\",\n schema:\n \"input AddOperationInput {\\n moduleId: ID!\\n id: ID!\\n name: String!\\n schema: String\\n description: String\\n template: String\\n reducer: String\\n scope: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_NAME\",\n id: \"\",\n description: \"Sets the name of an operation\",\n schema:\n \"input SetOperationNameInput {\\n id: ID!\\n name: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_SCHEMA\",\n id: \"\",\n description:\n \"Sets the GraphQL schema definition for an operation's input\",\n schema:\n \"input SetOperationSchemaInput {\\n id: ID!\\n schema: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_DESCRIPTION\",\n id: \"\",\n description: \"Sets the description of an operation\",\n schema:\n \"input SetOperationDescriptionInput {\\n id: ID!\\n description: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_TEMPLATE\",\n id: \"\",\n description: \"Sets the template code for an operation\",\n schema:\n \"input SetOperationTemplateInput {\\n id: ID!\\n template: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_REDUCER\",\n id: \"\",\n description: \"Sets the reducer function code for an operation\",\n schema:\n \"input SetOperationReducerInput {\\n id: ID!\\n reducer: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_OPERATION_SCOPE\",\n id: \"\",\n description: \"Sets the scope of an operation (global or local)\",\n schema:\n \"input SetOperationScopeInput {\\n id: ID!\\n scope: String\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"MOVE_OPERATION\",\n id: \"\",\n description: \"Moves an operation from one module to another\",\n schema:\n \"input MoveOperationInput {\\n operationId: ID!\\n newModuleId: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_OPERATION\",\n id: \"\",\n description: \"Removes an operation from a module\",\n schema: \"input DeleteOperationInput {\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_MODULE_OPERATIONS\",\n id: \"\",\n description: \"Changes the order of operations within a module\",\n schema:\n \"input ReorderModuleOperationsInput {\\n moduleId: ID!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n {\n name: \"state\",\n operations: [\n {\n name: \"SET_STATE_SCHEMA\",\n id: \"\",\n description:\n \"Sets the GraphQL schema definition for document state\",\n schema:\n \"input SetStateSchemaInput {\\n scope: String!\\n schema: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"SET_INITIAL_STATE\",\n id: \"\",\n description: \"Sets the initial state value for a document scope\",\n schema:\n \"input SetInitialStateInput {\\n scope: String!\\n initialValue: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"ADD_STATE_EXAMPLE\",\n id: \"\",\n description: \"Adds a new state example to a document scope\",\n schema:\n \"input AddStateExampleInput {\\n scope: String!\\n id: ID!\\n insertBefore: ID\\n example: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"UPDATE_STATE_EXAMPLE\",\n id: \"\",\n description:\n \"Updates an existing state example for a document scope\",\n schema:\n \"input UpdateStateExampleInput {\\n scope: String!\\n id: ID!\\n newExample: String!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"DELETE_STATE_EXAMPLE\",\n id: \"\",\n description: \"Removes a state example from a document scope\",\n schema:\n \"input DeleteStateExampleInput {\\n scope: String!\\n id: ID!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n {\n name: \"REORDER_STATE_EXAMPLES\",\n id: \"\",\n description:\n \"Changes the order of state examples for a document scope\",\n schema:\n \"input ReorderStateExamplesInput {\\n scope: String!\\n order: [ID!]!\\n}\",\n template: \"\",\n reducer: \"\",\n examples: [],\n errors: [],\n scope: \"global\",\n },\n ],\n id: \"\",\n description: \"\",\n },\n ],\n },\n ],\n};\n\n// Known hash algorithms (can be extended without breaking changes)\nexport const HASH_ALGORITHM_SHA1 = \"sha1\";\nexport const HASH_ALGORITHM_SHA256 = \"sha256\";\nexport const HASH_ALGORITHM_SHA512 = \"sha512\";\n\n// Known encodings (can be extended without breaking changes)\nexport const HASH_ENCODING_BASE64 = \"base64\";\nexport const HASH_ENCODING_HEX = \"hex\";\n","import { HASH_ALGORITHM_SHA1, HASH_ENCODING_BASE64 } from \"./constants.js\";\nimport type { HashConfig } from \"./signatures.js\";\nimport type {\n DocumentModelGlobalState,\n DocumentModelLocalState,\n DocumentModelPHState,\n} from \"./types.js\";\n\n/**\n * Creates a default PHAuthState\n */\nexport function defaultAuthState(): PHAuthState {\n return {\n version: 0,\n grants: [],\n };\n}\n\n/**\n * Creates a default PHDocumentState\n */\nexport function defaultDocumentState(): PHDocumentState {\n return {\n version: 0,\n hash: {\n algorithm: HASH_ALGORITHM_SHA1,\n encoding: HASH_ENCODING_BASE64,\n },\n };\n}\n/**\n * Creates a default PHBaseState with auth and document properties\n */\nexport function defaultBaseState(): PHBaseState {\n return {\n auth: defaultAuthState(),\n document: defaultDocumentState(),\n };\n}\n\n/**\n * Creates a PHAuthState with the given properties\n */\nexport function createAuthState(auth?: Partial<PHAuthState>): PHAuthState {\n return {\n ...defaultAuthState(),\n ...auth,\n };\n}\n\n/**\n * Creates a PHDocumentState with the given properties\n */\nexport function createDocumentState(\n document?: Partial<PHDocumentState>,\n): PHDocumentState {\n return {\n ...defaultDocumentState(),\n ...document,\n };\n}\n\n/**\n * Creates a PHBaseState with the given auth and document properties\n */\nexport function createBaseState(\n auth?: Partial<PHAuthState>,\n document?: Partial<PHDocumentState>,\n): PHBaseState {\n return {\n auth: createAuthState(auth),\n document: createDocumentState(document),\n };\n}\n\n/**\n * Backfills the auth scope to the default for legacy documents serialized with\n * an empty `auth`. Replaces only `state.auth`. Idempotent.\n */\nexport function backfillAuthState<TState extends PHBaseState>(\n state: TState,\n): TState {\n return {\n ...state,\n auth: createAuthState(state.auth),\n } as TState;\n}\n\n/**\n * The document state of the document.\n */\nexport type PHDocumentState = {\n /**\n * The current document model schema version of the document. This is used\n * with the UPGRADE_DOCUMENT operation to specify the DocumentModelModule\n * version to use for reducer execution.\n */\n version: number;\n\n /** Hash configuration for operation state verification */\n hash: HashConfig;\n\n /** True if and only if the document has been deleted */\n isDeleted?: boolean;\n\n /** The timestamp when the document was deleted, in UTC ISO format */\n deletedAtUtcIso?: string;\n\n /** Optional: who deleted the document */\n deletedBy?: string;\n\n /** Optional: reason for deletion */\n deletionReason?: string;\n};\n\n/**\n * The document's authorization policy: an ordered, stacked list of grants,\n * where the last matching grant wins. `{ version: 0, grants: [] }` is\n * uninitialized and leaves the document open.\n */\nexport type PHAuthState = {\n /**\n * Policy language version. 0 is the uninitialized state; INITIALIZE_AUTH\n * sets an integer >= 1.\n */\n version: number;\n grants: Grant[];\n /**\n * The did:key of the auth-policy creator, captured from the INITIALIZE_AUTH\n * signer. The creator may always administer the auth scope, so a grant policy\n * can never lock administration out of itself. Absent for an unsigned genesis.\n */\n creator?: string;\n};\n\nexport type Grant = {\n /** Stable id. */\n id: string;\n description: string;\n effect: \"allow\" | \"deny\";\n principal: Principal;\n capability: Capability;\n /**\n * The grant applies only when this condition holds. Until conditions are\n * evaluated, a grant carrying one never applies.\n */\n where?: Condition;\n};\n\nexport type Principal =\n | { anyone: true }\n | { address: string }\n | { group: string }\n | { match: Condition };\n\n/**\n * The folded global state of a PHGroup (powerhouse/reactor-group) document,\n * narrowed to what auth evaluation reads. Membership is matched\n * case-insensitively against the subject's address.\n */\nexport type PHGroupState = {\n members: string[];\n};\n\n/**\n * Folded group states keyed by group document id, as the groups projection\n * provides them. A group id a policy names but the map does not hold fails\n * closed: the principal does not match.\n */\nexport type AuthGroups = Record<string, PHGroupState>;\n\nexport type Capability =\n | { can: \"read\"; scope?: string }\n | { can: \"execute\"; scope?: string; operation?: string[] };\n\n/**\n * Boolean condition language for grants: deterministic, total, and\n * JSON-serializable, versioned by `PHAuthState.version`. Defined now but not\n * yet evaluated or enforced.\n */\nexport type Condition =\n | { eq: [Operand, Operand] }\n | { ne: [Operand, Operand] }\n | { in: [Operand, Operand[]] }\n | { notIn: [Operand, Operand[]] }\n | { lt: [Operand, Operand] }\n | { lte: [Operand, Operand] }\n | { gt: [Operand, Operand] }\n | { gte: [Operand, Operand] }\n | { exists: Operand }\n | { and: Condition[] }\n | { or: Condition[] }\n | { not: Condition };\n\n/**\n * A condition operand: `attr` is a dotted path into the decision context\n * (e.g. \"doc.global.status\", \"subject.address\"); `lit` is a constant value.\n */\nexport type Operand =\n | { attr: string }\n | { lit: string | number | boolean | null };\n\n/**\n * The base state of the document.\n */\nexport type PHBaseState = {\n /** Carries authentication information. */\n auth: PHAuthState;\n\n /** Carries information about the document. */\n document: PHDocumentState;\n};\n\nexport function defaultGlobalState(): DocumentModelGlobalState {\n return {\n ...defaultBaseState(),\n author: {\n name: \"\",\n website: \"\",\n },\n description: \"\",\n extension: \"\",\n id: \"\",\n name: \"\",\n specifications: [],\n };\n}\n\nexport function defaultLocalState(): DocumentModelLocalState {\n return {};\n}\n\nexport function defaultPHState(): DocumentModelPHState {\n return {\n ...defaultBaseState(),\n global: defaultGlobalState(),\n local: defaultLocalState(),\n };\n}\n\nexport function createGlobalState(\n state?: Partial<DocumentModelGlobalState>,\n): DocumentModelGlobalState {\n return {\n ...defaultGlobalState(),\n ...(state || {}),\n } as DocumentModelGlobalState;\n}\n\nexport function createLocalState(\n state?: Partial<DocumentModelLocalState>,\n): DocumentModelLocalState {\n return {\n ...defaultLocalState(),\n ...(state || {}),\n } as DocumentModelLocalState;\n}\n\nexport function createState(\n baseState?: Partial<PHBaseState>,\n globalState?: Partial<DocumentModelGlobalState>,\n localState?: Partial<DocumentModelLocalState>,\n): DocumentModelPHState {\n return {\n ...createBaseState(baseState?.auth, baseState?.document),\n global: createGlobalState(globalState),\n local: createLocalState(localState),\n };\n}\n","import { stringify } from \"safe-stable-stringify\";\nimport { z } from \"zod\";\nimport { createAction, type Action } from \"./actions.js\";\nimport {\n assertAuthAdministrationRetained,\n assertValidGrantUpsert,\n assertValidInitialGrants,\n evaluateGrantStack,\n GrantSchema,\n isPlainValue,\n MAX_AUTH_GRANTS,\n} from \"./auth-v1.js\";\nimport { base58Decode, base64UrlToBytes } from \"./crypto.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport {\n AuthActionNotAllowedError,\n AuthAlreadyInitializedError,\n AuthInitializerNotCreatorError,\n AuthPolicyNotPreservedError,\n GrantNotFoundError,\n InvalidActionInputError,\n InvalidAuthVersionError,\n} from \"./errors.js\";\nimport {\n createAuthState,\n type AuthGroups,\n type Grant,\n type PHAuthState,\n type PHBaseState,\n} from \"./state.js\";\n\n// --- Action types --------------------------------------------------------\n\nexport type InitializeAuthActionInput = {\n version: number;\n grants: Grant[];\n};\n\nexport type SetGrantActionInput = {\n grant: Grant;\n};\n\nexport type RemoveGrantActionInput = {\n id: string;\n};\n\nexport type MoveGrantActionInput = {\n id: string;\n /** Target index in the grant list; clamped to the valid range. */\n index: number;\n};\n\nexport type InitializeAuthAction = Action & {\n type: \"INITIALIZE_AUTH\";\n input: InitializeAuthActionInput;\n};\n\nexport type SetGrantAction = Action & {\n type: \"SET_GRANT\";\n input: SetGrantActionInput;\n};\n\nexport type RemoveGrantAction = Action & {\n type: \"REMOVE_GRANT\";\n input: RemoveGrantActionInput;\n};\n\nexport type MoveGrantAction = Action & {\n type: \"MOVE_GRANT\";\n input: MoveGrantActionInput;\n};\n\nexport type AuthAction =\n | InitializeAuthAction\n | SetGrantAction\n | RemoveGrantAction\n | MoveGrantAction;\n\nexport const AUTH_ACTION_TYPES = [\n \"INITIALIZE_AUTH\",\n \"SET_GRANT\",\n \"REMOVE_GRANT\",\n \"MOVE_GRANT\",\n] as const;\n\nexport function isAuthAction(action: Action): action is AuthAction {\n return (AUTH_ACTION_TYPES as readonly string[]).includes(action.type);\n}\n\n// --- Version-1 grant validation ------------------------------------------\n\n/** Highest known policy version; decide() fails closed above it. */\nexport const MAX_SUPPORTED_AUTH_VERSION = 1;\n\n// --- Input schemas -------------------------------------------------------\n\nexport const InitializeAuthActionInputSchema = () =>\n z.object({\n version: z.number().int().min(1),\n grants: z.array(GrantSchema()).max(MAX_AUTH_GRANTS),\n });\n\nexport const SetGrantActionInputSchema = () =>\n z.object({\n grant: GrantSchema(),\n });\n\nexport const RemoveGrantActionInputSchema = () =>\n z.object({\n id: z.string(),\n });\n\nexport const MoveGrantActionInputSchema = () =>\n z.object({\n id: z.string(),\n index: z.number(),\n });\n\n// --- Action creators -----------------------------------------------------\n\nexport const initializeAuth = (input: InitializeAuthActionInput) =>\n createAction<InitializeAuthAction>(\n \"INITIALIZE_AUTH\",\n input,\n undefined,\n InitializeAuthActionInputSchema,\n \"auth\",\n );\n\nexport const setGrant = (input: SetGrantActionInput) =>\n createAction<SetGrantAction>(\n \"SET_GRANT\",\n input,\n undefined,\n SetGrantActionInputSchema,\n \"auth\",\n );\n\nexport const removeGrant = (input: RemoveGrantActionInput) =>\n createAction<RemoveGrantAction>(\n \"REMOVE_GRANT\",\n input,\n undefined,\n RemoveGrantActionInputSchema,\n \"auth\",\n );\n\nexport const moveGrant = (input: MoveGrantActionInput) =>\n createAction<MoveGrantAction>(\n \"MOVE_GRANT\",\n input,\n undefined,\n MoveGrantActionInputSchema,\n \"auth\",\n );\n\n// --- Handlers ------------------------------------------------------------\n\n/**\n * Destructuring a null input (reachable via raw synced operations) would\n * store an engine-specific TypeError message on the error operation.\n */\nfunction assertActionInputShape(input: unknown): void {\n if (!isPlainValue(input)) {\n throw new InvalidActionInputError({ input: \"must be an object\" });\n }\n}\n\nfunction withGrants<TState extends PHBaseState>(\n document: PHDocument<TState>,\n grants: Grant[],\n): PHDocument<TState> {\n return {\n ...document,\n state: {\n ...document.state,\n auth: { ...document.state.auth, grants },\n },\n };\n}\n\nconst P256_PUBKEY_MULTICODEC = [0x80, 0x24] as const;\nconst DID_KEY_PREFIX = \"did:key:z\";\n\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * True when `signerKey` (an ActionSigner app key, a did:key) identifies the same\n * key recorded as the document creator. Returns false\n * when there is no creator (empty JWK) or no signer key.\n */\nexport function isDocumentCreator(\n creatorKey: JsonWebKey | undefined,\n signerKey: string | undefined,\n): boolean {\n if (!creatorKey?.x || !creatorKey.y) {\n return false;\n }\n if (!signerKey || !signerKey.startsWith(DID_KEY_PREFIX)) {\n return false;\n }\n const decoded = base58Decode(signerKey.slice(DID_KEY_PREFIX.length));\n // 2-byte P-256 multicodec + 33-byte compressed point (prefix + 32-byte x).\n if (!decoded || decoded.length !== 35) {\n return false;\n }\n if (\n decoded[0] !== P256_PUBKEY_MULTICODEC[0] ||\n decoded[1] !== P256_PUBKEY_MULTICODEC[1]\n ) {\n return false;\n }\n const parityPrefix = decoded[2];\n if (parityPrefix !== 0x02 && parityPrefix !== 0x03) {\n return false;\n }\n const didX = decoded.subarray(3, 35);\n const jwkX = base64UrlToBytes(creatorKey.x);\n const jwkY = base64UrlToBytes(creatorKey.y);\n if (jwkX.length !== 32 || jwkY.length !== 32) {\n return false;\n }\n if (!bytesEqual(didX, jwkX)) {\n return false;\n }\n const jwkYIsOdd = (jwkY[31] & 1) === 1;\n const didYIsOdd = parityPrefix === 0x03;\n return jwkYIsOdd === didYIsOdd;\n}\n\n/**\n * Sets the initial policy. Valid only while the auth scope is uninitialized\n * (version 0). The input version is the policy language version and must be an\n * integer >= 1; 0 is reserved for the uninitialized state. On a signed-header\n * document it must be signed by the document creator (`header.sig.publicKey`).\n * A creator-less policy must include a grant permitting execute on the auth\n * scope, or it would be born locked out.\n */\nexport function applyInitializeAuthAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: InitializeAuthAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { version, grants } = action.input;\n if (!Number.isInteger(version) || version < 1) {\n throw new InvalidAuthVersionError(document.header.id, version);\n }\n if (document.state.auth.version !== 0) {\n throw new AuthAlreadyInitializedError(document.header.id);\n }\n if (!Array.isArray(grants)) {\n throw new InvalidActionInputError({ grants: \"must be an array\" });\n }\n const creatorKey = document.header.sig.publicKey;\n const signerKey = action.context?.signer?.app.key;\n // Any key material marks a signed header. Unsupported key types then fail\n // closed through isDocumentCreator instead of degrading to an open genesis.\n const hasCreator = Boolean(creatorKey.kty || creatorKey.x || creatorKey.y);\n if (hasCreator && !isDocumentCreator(creatorKey, signerKey)) {\n throw new AuthInitializerNotCreatorError(document.header.id);\n }\n const creator = hasCreator ? signerKey : undefined;\n assertValidInitialGrants(grants, document.header.documentType, creator);\n return {\n ...document,\n state: {\n ...document.state,\n auth: createAuthState(\n creator ? { version, grants, creator } : { version, grants },\n ),\n },\n };\n}\n\n/** Upserts a grant by id: replaces in place if present, otherwise appends. */\nexport function applySetGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: SetGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { grant } = action.input;\n const grants = document.state.auth.grants;\n assertValidGrantUpsert(\n grant,\n grants,\n document.header.documentType,\n document.state.auth.creator,\n );\n const exists = grants.some((g) => g.id === grant.id);\n const next = exists\n ? grants.map((g) => (g.id === grant.id ? grant : g))\n : [...grants, grant];\n return withGrants(document, next);\n}\n\n/**\n * Removes a grant by id; throws if the id is not present or if the removal\n * would leave a creator-less policy with no auth-administration grant.\n */\nexport function applyRemoveGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: RemoveGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { id } = action.input;\n const { grants, creator } = document.state.auth;\n if (!grants.some((g) => g.id === id)) {\n throw new GrantNotFoundError(id);\n }\n const next = grants.filter((g) => g.id !== id);\n assertAuthAdministrationRetained(creator, grants, next, id);\n return withGrants(document, next);\n}\n\n/**\n * Moves a grant by id to a new index. Order is load-bearing (the last\n * applicable grant wins), so the relative order of the other grants is kept.\n * The target index is clamped to the valid range; an unknown id throws.\n *\n * Order alone decides which grant wins, so a move can take administration away\n * without changing the list's contents. It carries the same retention rule as\n * the two mutation paths.\n */\nexport function applyMoveGrantAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: MoveGrantAction,\n): PHDocument<TState> {\n assertActionInputShape(action.input);\n const { id, index } = action.input;\n const { grants, creator } = document.state.auth;\n const from = grants.findIndex((g) => g.id === id);\n if (from === -1) {\n throw new GrantNotFoundError(id);\n }\n const next = [...grants];\n const [moved] = next.splice(from, 1);\n const to = Math.max(0, Math.min(index, next.length));\n next.splice(to, 0, moved);\n assertAuthAdministrationRetained(creator, grants, next, id);\n return withGrants(document, next);\n}\n\n/**\n * Dispatches an auth-scope action to its handler. This is the auth scope's\n * dedicated reducer: it is applied by the base reducer instead of the model\n * reducer, mirroring the document-scope platform handlers. Unknown types are a\n * no-op, matching the model-reducer default.\n */\nexport function applyAuthAction<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n): PHDocument<TState> {\n switch (action.type) {\n case \"INITIALIZE_AUTH\":\n return applyInitializeAuthAction(\n document,\n action as InitializeAuthAction,\n );\n case \"SET_GRANT\":\n return applySetGrantAction(document, action as SetGrantAction);\n case \"REMOVE_GRANT\":\n return applyRemoveGrantAction(document, action as RemoveGrantAction);\n case \"MOVE_GRANT\":\n return applyMoveGrantAction(document, action as MoveGrantAction);\n default:\n return document;\n }\n}\n\n/**\n * Because only creators can initialize auth scopes, we must verify that either\n * the document has no auth or the version and creator match.\n */\nexport function assertAuthPreservedOnDuplicate(\n documentId: string,\n source: PHAuthState | undefined,\n duplicated: PHAuthState | undefined,\n): void {\n if (!source || source.version === 0) {\n return;\n }\n if (\n duplicated === undefined ||\n duplicated.version !== source.version ||\n duplicated.creator !== source.creator\n ) {\n throw new AuthPolicyNotPreservedError(documentId);\n }\n}\n\n/**\n * The auth scope a state snapshot may install, given the policy already there.\n *\n * `applyAuthAction` is the validated door onto `state.auth`, but a whole-state\n * snapshot (UPGRADE_DOCUMENT's `initialState`, LOAD_STATE's `data`) replaces the\n * scope wholesale and is authorized as a `document`-scope write. Without this,\n * a subject holding `execute` on `document` and no auth grant at all can install\n * a policy of its choosing, name itself `creator` (which exempts the policy from\n * the retention rule for good), or wipe an existing policy by carrying the\n * default uninitialized one.\n *\n * Three cases:\n *\n * - the snapshot carries no policy, or an uninitialized one: the document\n * keeps the policy it has, so a default-state upgrade cannot reset it;\n * - the document is uninitialized and the snapshot carries a policy: the\n * policy is installed after the same validation genesis applies, so it\n * cannot be born locked out;\n * - both carry a policy: they must agree. A duplicate preserves its source's\n * policy (see {@link assertAuthPreservedOnDuplicate}), and anything else is\n * an attempt to replace one policy with another.\n */\nexport function resolveSnapshotAuth(\n documentId: string,\n documentType: string,\n current: PHAuthState | undefined,\n incoming: PHAuthState | undefined,\n): PHAuthState {\n const currentAuth = current ?? createAuthState({ version: 0, grants: [] });\n\n if (!incoming || !incoming.version) {\n return currentAuth;\n }\n\n if (currentAuth.version !== 0) {\n // The whole policy has to match, grants included: version and creator alone\n // would let one policy be swapped for another with the same version and no\n // creator. Serialized with sorted keys, because jsonb storage does not\n // preserve key order.\n if (stringify(incoming) !== stringify(currentAuth)) {\n throw new AuthPolicyNotPreservedError(documentId);\n }\n return incoming;\n }\n\n if (!Array.isArray(incoming.grants)) {\n throw new InvalidActionInputError({ grants: \"must be an array\" });\n }\n assertValidInitialGrants(incoming.grants, documentType, incoming.creator);\n return incoming;\n}\n\n/** UNDO, REDO and PRUNE are rejected on the auth scope. */\nexport function assertAuthScopeActionAllowed(action: Action): void {\n if (\n action.scope === \"auth\" &&\n [\"UNDO\", \"REDO\", \"PRUNE\"].includes(action.type)\n ) {\n throw new AuthActionNotAllowedError(action.type);\n }\n}\n\n// --- Decision (read-only policy evaluation) ------------------------------\n\nexport type AuthVerb = \"read\" | \"execute\";\n\nexport type AuthRequest = {\n verb: AuthVerb;\n scope: string;\n /** For execute: the operation (action type) being attempted. Omitted for reads. */\n operation?: string;\n};\n\nexport type AuthSubject = {\n /** Verified signer address; undefined for an anonymous subject. */\n address?: string;\n /** The signer's app key (a did:key), used to match the document creator. */\n key?: string;\n};\n\n/**\n * What condition attr paths resolve against, beyond the subject. Supplied\n * only while authConditions enforcement is on: with no context a grant\n * carrying `where` or a { match } principal never applies.\n */\nexport type ConditionContext = {\n /** The executing scope's own state, for `doc.<scope>.*` paths. */\n scopeState: unknown;\n /** The action's input, for `action.input.*` paths. Absent for reads. */\n actionInput?: unknown;\n};\n\nexport type AuthDecision = \"allow\" | \"deny\";\n\n/** Why the policy refused a request. */\nexport type AuthRefusal =\n | \"version-unsupported\"\n | \"no-applicable-grant\"\n | \"denied-by-grant\";\n\n/**\n * A decision together with why it refused. A refusal names which of the\n * policy's rules produced it, so an operation records the reason it was refused\n * rather than one reason standing for every refusal.\n */\nexport type AuthEvaluation =\n | { decision: \"allow\" }\n | { decision: \"deny\"; refusal: AuthRefusal; grantId?: string };\n\n/**\n * Evaluates the auth policy for a single request and reports why it refused.\n * Pure and deterministic.\n *\n * An uninitialized policy (version 0, absent auth state, or a legacy `{}`\n * auth scope serialized before PHAuthState had a version) leaves the document\n * open. Once a policy exists the default is deny, and grants stack in order.\n *\n * Group principals match only against a supplied groups map (the groups\n * projection, present when authGroups is on); with no map they never apply.\n * `where` clauses and { match } principals likewise evaluate only against a\n * supplied condition context (present when authConditions is on).\n */\nexport function evaluate(\n auth: PHAuthState | undefined,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthEvaluation {\n if (!auth || !auth.version) {\n return { decision: \"allow\" };\n }\n\n // creators can always administer the auth scope, checked before the version\n // gate so an unknown policy version cannot brick its own administration\n if (\n request.verb === \"execute\" &&\n request.scope === \"auth\" &&\n subject.key !== undefined &&\n subject.key === auth.creator\n ) {\n return { decision: \"allow\" };\n }\n\n if (auth.version > MAX_SUPPORTED_AUTH_VERSION) {\n return { decision: \"deny\", refusal: \"version-unsupported\" };\n }\n\n return evaluateGrantStack(auth.grants, subject, request, groups, conditions);\n}\n\n/**\n * Evaluates the auth policy for a single request. Pure and deterministic. This\n * is {@link evaluate} with the reason dropped.\n */\nexport function decide(\n auth: PHAuthState | undefined,\n subject: AuthSubject,\n request: AuthRequest,\n groups?: AuthGroups,\n conditions?: ConditionContext,\n): AuthDecision {\n return evaluate(auth, subject, request, groups, conditions).decision;\n}\n\n/**\n * The group document ids a single auth action's input names with `{ group }`\n * principals. INITIALIZE_AUTH contributes the groups named across its grants,\n * SET_GRANT the groups named by its one grant; REMOVE_GRANT and MOVE_GRANT\n * contribute nothing. Total over any input shape, because references are read\n * from the input as it arrived, including inputs later stored as errors.\n */\nexport function mentionedGroupIds(action: Action): string[] {\n const input = action.input as Record<string, unknown> | null | undefined;\n const candidates: unknown[] = [];\n\n if (action.type === \"INITIALIZE_AUTH\" && Array.isArray(input?.grants)) {\n candidates.push(...(input.grants as unknown[]));\n }\n if (action.type === \"SET_GRANT\" && input?.grant !== undefined) {\n candidates.push(input.grant);\n }\n\n const ids: string[] = [];\n for (const candidate of candidates) {\n if (typeof candidate !== \"object\" || candidate === null) {\n continue;\n }\n const principal = (candidate as Record<string, unknown>).principal;\n if (typeof principal !== \"object\" || principal === null) {\n continue;\n }\n const group = (principal as Record<string, unknown>).group;\n if (typeof group === \"string\" && group !== \"\" && !ids.includes(group)) {\n ids.push(group);\n }\n }\n return ids;\n}\n","// Kept out of operations.ts so documents.ts can read the denial verdict without\n// a value import back into operations.ts, which closes a runtime cycle\n// (operations.ts already imports nextSkipNumber/sortOperations from documents.ts).\n// The only import here is type-only, so this module can never join a cycle.\nimport type { Operation } from \"./operations.js\";\n\n/**\n * True iff authorization rejected the action.\n */\nexport function isDenied(operation: Operation): boolean {\n return operation.deniedReason !== undefined;\n}\n\n/**\n * The closed set of strings persisted as `deniedReason`. Re-evaluation compares\n * them, so they are consensus data: exact strings that embed no grant id,\n * subject or timestamp. Changing one is history-visible.\n */\nexport const DOCUMENT_DELETED_REASON = \"document deleted\";\nexport const AUTH_VERSION_UNSUPPORTED_REASON =\n \"auth policy version unsupported\";\nexport const AUTH_NO_GRANT_REASON = \"no grant permits this operation\";\nexport const AUTH_DENIED_BY_GRANT_REASON = \"denied by grant\";\n","import { z } from \"zod\";\nimport { documentModelDocumentType } from \"./document-type.js\";\nimport { DocumentModelGlobalStateSchema } from \"./schemas.js\";\nimport type { DocumentModelDocument, DocumentModelPHState } from \"./types.js\";\n\nexport const BaseDocumentHeaderSchema = z.object({\n id: z.string(),\n name: z.string(),\n createdAtUtcIso: z.string(),\n lastModifiedAtUtcIso: z.string(),\n documentType: z.string(),\n});\n\nexport const BaseDocumentStateSchema = z.object({\n global: z.unknown(),\n});\n\n/** Schema for validating the header object of a DocumentModel document */\nexport const DocumentModelHeaderSchema = BaseDocumentHeaderSchema.extend({\n documentType: z.literal(documentModelDocumentType),\n});\n\n/** Schema for validating the state object of a DocumentModel document */\nexport const DocumentModelPHStateSchema = BaseDocumentStateSchema.extend({\n global: DocumentModelGlobalStateSchema(),\n});\n\nexport const DocumentModelSchema = z.object({\n header: DocumentModelHeaderSchema,\n state: DocumentModelPHStateSchema,\n initialState: DocumentModelPHStateSchema,\n});\n\n/** Simple helper function to check if a state object is a DocumentModel document state object */\nexport function isDocumentModelState(\n state: unknown,\n): state is DocumentModelPHState {\n return DocumentModelPHStateSchema.safeParse(state).success;\n}\n\n/** Simple helper function to assert that a document state object is a DocumentModel document state object */\nexport function assertIsDocumentModelState(\n state: unknown,\n): asserts state is DocumentModelPHState {\n DocumentModelPHStateSchema.parse(state);\n}\n\n/** Simple helper function to check if a document is a DocumentModel document */\nexport function isDocumentModelDocument(\n document: unknown,\n): document is DocumentModelDocument {\n return DocumentModelSchema.safeParse(document).success;\n}\n\n/** Simple helper function to assert that a document is a DocumentModel document */\nexport function assertIsDocumentModelDocument(\n document: unknown,\n): asserts document is DocumentModelDocument {\n DocumentModelSchema.parse(document);\n}\n","import type { Action } from \"./actions.js\";\nimport type { PHDocumentHeader } from \"./documents.js\";\nimport type { Signature } from \"./signatures.js\";\nimport type { ISigner, SigningParameters } from \"./types.js\";\nimport { generateId } from \"./utils.js\";\n\n/**\n * Generates a deterministic payload from signing parameters\n */\nconst generateStablePayload = (parameters: SigningParameters): string =>\n `${parameters.documentType}:${parameters.createdAtUtcIso}:${parameters.nonce}`;\n\n/**\n * Creates a verification-only signer from a public key.\n * This signer can only verify signatures, not sign data.\n *\n * @param pubKey - The public key to use for verification.\n * @returns An ISigner that can only verify signatures.\n */\nexport async function createVerificationSigner(\n pubKey: JsonWebKey,\n): Promise<ISigner> {\n const cryptoKey = await crypto.subtle.importKey(\n \"jwk\",\n pubKey,\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"verify\"],\n );\n return {\n publicKey: cryptoKey,\n\n async sign(_data: Uint8Array): Promise<Uint8Array> {\n throw new Error(\"verification-only signer cannot sign data\");\n },\n\n async signAction(\n _action: Action,\n _abortSignal?: AbortSignal,\n ): Promise<Signature> {\n throw new Error(\"verification-only signer cannot sign actions\");\n },\n\n async verify(data: Uint8Array, signature: Uint8Array): Promise<void> {\n let isValid: boolean;\n try {\n isValid = await crypto.subtle.verify(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n cryptoKey,\n new Uint8Array(signature),\n new Uint8Array(data),\n );\n } catch {\n throw new Error(\"invalid signature\");\n }\n\n if (!isValid) {\n throw new Error(\"invalid signature\");\n }\n },\n };\n}\n\n/**\n * Creates a verification-only signer from a header.\n *\n * @param header - The header to create a signer from.\n * @returns A signer that can verify the header's signature.\n */\nconst createSignerFromHeader = async (\n header: PHDocumentHeader,\n): Promise<ISigner> => {\n return createVerificationSigner(header.sig.publicKey);\n};\n\n/**\n * Signs a header. Generally, this is not called directly, but rather through\n * {@link createSignedHeader}.\n *\n * @param parameters - The parameters used to sign the header.\n * @param signer - The signer of the document.\n *\n * @returns The signature of the header.\n */\nexport const sign = async (\n parameters: SigningParameters,\n signer: ISigner,\n): Promise<string> => {\n // Generate stable payload\n const payload = generateStablePayload(parameters);\n\n // Convert payload to Uint8Array for signing\n const encoder = new TextEncoder();\n const data = encoder.encode(payload);\n\n // Create signature using Web Crypto API with Ed25519\n const signature = await signer.sign(data);\n\n // Convert signature to base64 string for JSON serialization\n const signatureArray = new Uint8Array(signature);\n const signatureBase64 = btoa(String.fromCharCode(...signatureArray));\n return signatureBase64;\n};\n\n/**\n * Verifies a header signature. Generally, this is not called directly, but\n * rather through {@link validateHeader}.\n *\n * @param parameters - The parameters used to sign the header.\n * @param signature - The signature to verify.\n * @param signer - The signer of the document.\n */\nexport const verify = async (\n parameters: SigningParameters,\n signature: string,\n signer: ISigner,\n): Promise<void> => {\n // Generate the same stable payload that was signed\n const payload = generateStablePayload(parameters);\n\n // Convert payload to Uint8Array for verification\n const encoder = new TextEncoder();\n const data = encoder.encode(payload);\n\n // Decode the base64 signature back to binary\n const signatureBytes = Uint8Array.from(atob(signature), (c) =>\n c.charCodeAt(0),\n );\n\n await signer.verify(data, signatureBytes);\n};\n\n/**\n * Validates a header signature.\n */\nexport const validateHeader = async (\n header: PHDocumentHeader,\n): Promise<void> => {\n const signer = await createSignerFromHeader(header);\n\n return verify(\n {\n documentType: header.documentType,\n createdAtUtcIso: header.createdAtUtcIso,\n nonce: header.sig.nonce,\n },\n header.id,\n signer,\n );\n};\n\n/**\n * Creates a header that has yet to be signed. This header is not valid, but\n * can be input into {@link createSignedHeader} to create a signed header.\n *\n * @returns An unsigned header for a document.\n */\nexport const createPresignedHeader = (\n id: string = generateId(),\n documentType = \"\",\n): PHDocumentHeader => {\n return {\n id,\n sig: {\n publicKey: {},\n nonce: \"\",\n },\n documentType,\n createdAtUtcIso: new Date().toISOString(),\n slug: \"\",\n name: \"\",\n branch: \"main\",\n revision: {\n document: 0,\n },\n lastModifiedAtUtcIso: new Date().toISOString(),\n meta: {},\n };\n};\n\n/**\n * Creates a new, signed header for a document. This will replace the id of the\n * document.\n *\n * @param unsignedHeader - The unsigned header to created the signed header from.\n * @param signer - The signer of the document.\n *\n * @returns A new signed header for a document. Some fields are mutable and\n * some are not. See the PHDocumentHeader type for more information.\n */\nexport const createSignedHeader = async (\n unsignedHeader: PHDocumentHeader,\n documentType: string,\n signer: ISigner,\n): Promise<PHDocumentHeader> => {\n const parameters: SigningParameters = {\n documentType,\n createdAtUtcIso: unsignedHeader.createdAtUtcIso,\n nonce: generateId(),\n };\n\n const signature = await sign(parameters, signer);\n\n const jsonPublicKey = await crypto.subtle.exportKey(\"jwk\", signer.publicKey);\n\n return {\n // immutable fields\n id: signature,\n sig: {\n publicKey: jsonPublicKey,\n nonce: parameters.nonce,\n },\n documentType,\n createdAtUtcIso: unsignedHeader.createdAtUtcIso,\n\n // mutable fields\n slug: unsignedHeader.slug,\n name: unsignedHeader.name,\n branch: unsignedHeader.branch,\n revision: unsignedHeader.revision,\n lastModifiedAtUtcIso: unsignedHeader.lastModifiedAtUtcIso,\n meta: unsignedHeader.meta,\n };\n};\n\n/**\n * Creates a signed header for a document. The document header requires a signer\n * as the document id is a cryptographic signature.\n *\n * @param documentType - The type of the document.\n * @param signer - The signer of the document.\n *\n * @returns The signed header for a document. Some fields are mutable and\n * some are not. See the PHDocumentHeader type for more information.\n */\nexport const createSignedHeaderForSigner = async (\n documentType: string,\n signer: ISigner,\n): Promise<PHDocumentHeader> => {\n const unsignedHeader = createPresignedHeader();\n const signedHeader = await createSignedHeader(\n unsignedHeader,\n documentType,\n signer,\n );\n\n return signedHeader;\n};\n","import { stringify } from \"safe-stable-stringify\";\nimport type { Action } from \"./actions.js\";\nimport { hashBrowser } from \"./crypto.js\";\nimport { isDenied } from \"./denied.js\";\nimport { HashMismatchError } from \"./errors.js\";\nimport { createPresignedHeader } from \"./header.js\";\nimport type { DocumentOperations, Operation } from \"./operations.js\";\nimport type { PHDocumentSignatureInfo } from \"./signatures.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n CreateDocumentActionInput,\n CreateState,\n DocumentAction,\n DocumentOperationsIgnoreMap,\n MappedOperation,\n OperationIndex,\n OperationsByScope,\n Reducer,\n ReplayDocumentOptions,\n SignalDispatch,\n SkipHeaderOperationIndex,\n SkipHeaderOperations,\n UndoAction,\n UndoRedoAction,\n UpgradeDocumentActionInput,\n} from \"./types.js\";\nimport { deriveOperationId, generateId } from \"./utils.js\";\n\n/** Meta information about the document. */\nexport type PHDocumentMeta = {\n /** The preferred editor for the document. */\n preferredEditor?: string;\n};\n\n/**\n * The header of a document.\n */\nexport type PHDocumentHeader = {\n /**\n * The id of the document.\n *\n * This is a Ed25519 signature and is immutable.\n **/\n id: string;\n\n /**\n * Information to verify the document creator.\n *\n * This is immutable.\n **/\n sig: PHDocumentSignatureInfo;\n\n /**\n * The type of the document.\n *\n * This is used as part of the signature payload and thus, cannot be changed\n * after the document header has been created.\n **/\n documentType: string;\n\n /**\n * The timestamp of the creation date of the document, in UTC ISO format.\n *\n * This is used as part of the signature payload and thus, cannot be changed\n * after the document header has been created.\n **/\n createdAtUtcIso: string;\n\n /** The slug of the document. */\n slug: string;\n\n /** The name of the document. */\n name: string;\n\n /** The branch of this document. */\n branch: string;\n\n /**\n * The revision of each scope of the document. This object is updated every\n * time any _other_ scope is updated.\n */\n revision: {\n [scope: string]: number;\n };\n\n /**\n * The timestamp of the last change in the document, in UTC ISO format.\n **/\n lastModifiedAtUtcIso: string;\n\n /**\n * This is a map from protocol name to version. A protocol can be any set of\n * rules that are applied to the document.\n *\n * Examples of protocols include:\n *\n * - \"base-reducer\"\n */\n protocolVersions?: { [key: string]: number };\n\n /** Meta information about the document. */\n meta?: PHDocumentMeta;\n};\n\n/**\n * The base type of a document model.\n *\n * @remarks\n * This type is extended by all Document models.\n *\n * @typeParam TState - The type of the document state.\n */\nexport type PHDocument<TState extends PHBaseState = PHBaseState> = {\n /** The header of the document. */\n header: PHDocumentHeader;\n\n /** The document model specific state. */\n state: TState;\n\n /**\n * The initial state of the document, enabling replaying operations.\n *\n * This will be removed in a future release.\n */\n initialState: TState;\n\n /**\n * The operations history of the document.\n *\n * This will be removed in a future release.\n */\n operations: DocumentOperations;\n\n /**\n * A list of undone operations\n *\n * This will be removed in a future release.\n */\n clipboard: Operation[];\n};\n\nexport function isNoopOperation<\n TOp extends {\n type: string;\n skip: number;\n hash: string;\n },\n>(op: Partial<TOp>): boolean {\n return (\n op.type === \"NOOP\" &&\n op.skip !== undefined &&\n op.skip > 0 &&\n op.hash !== undefined\n );\n}\n\nexport function isUndoRedo(action: Action): action is UndoRedoAction {\n return [\"UNDO\", \"REDO\"].includes(action.type);\n}\n\nexport function isUndo(action: Action): action is UndoAction {\n return action.type === \"UNDO\";\n}\n\nexport function isDocumentAction(action: Action): action is DocumentAction {\n return [\n \"SET_NAME\",\n \"SET_PREFERRED_EDITOR\",\n \"UNDO\",\n \"REDO\",\n \"PRUNE\",\n \"LOAD_STATE\",\n ].includes(action.type);\n}\n\n/**\n * The document-scope operations a reactor mints on `create`, so a standalone\n * document carries its initial state when exported outside a reactor.\n */\nfunction createDocumentScopeOperations<TState extends PHBaseState>(\n header: PHDocumentHeader,\n state: TState,\n): Operation[] {\n const createInput: CreateDocumentActionInput = {\n model: header.documentType,\n version: 0,\n documentId: header.id,\n signing: {\n signature: header.id,\n publicKey: header.sig.publicKey,\n nonce: header.sig.nonce,\n createdAtUtcIso: header.createdAtUtcIso,\n documentType: header.documentType,\n },\n slug: header.slug,\n name: header.name,\n branch: header.branch,\n meta: header.meta,\n protocolVersions: header.protocolVersions ?? { \"base-reducer\": 2 },\n };\n const upgradeInput: UpgradeDocumentActionInput = {\n model: header.documentType,\n fromVersion: 0,\n toVersion: state.document.version,\n documentId: header.id,\n initialState: state,\n };\n\n const actions: Action[] = [\n {\n id: generateId(),\n type: \"CREATE_DOCUMENT\",\n scope: \"document\",\n timestampUtcMs: header.createdAtUtcIso,\n input: createInput,\n },\n {\n id: generateId(),\n type: \"UPGRADE_DOCUMENT\",\n scope: \"document\",\n timestampUtcMs: header.createdAtUtcIso,\n input: upgradeInput,\n },\n ];\n\n return actions.map((action, index) => ({\n ...action,\n action,\n id: deriveOperationId(header.id, \"document\", header.branch, action.id),\n hash: \"\",\n error: undefined,\n index,\n skip: 0,\n }));\n}\n\n/**\n * Creates a new document. When `documentType` is given the header is stamped\n * with it and the document-scope operations are seeded.\n */\nexport function baseCreateDocument<TState extends PHBaseState = PHBaseState>(\n createState: CreateState<TState>,\n initialState?: Partial<TState>,\n documentType = \"\",\n): PHDocument<TState> {\n const state = createState(initialState);\n const header = createPresignedHeader(generateId(), documentType);\n\n // The document's own CREATE_DOCUMENT operation records this, so the header\n // has to agree with it. Left off the header factory itself, because that is\n // also how a rebuild starts and a rebuild must take the version from the\n // stored operation rather than assume one.\n header.protocolVersions = { \"base-reducer\": 2 };\n\n const phDocument: PHDocument<TState> = {\n header,\n state,\n initialState: state,\n operations: documentType\n ? {\n global: [],\n local: [],\n document: createDocumentScopeOperations(header, state),\n }\n : { global: [], local: [] },\n clipboard: [],\n };\n\n return phDocument;\n}\n\nexport function hashDocumentStateForScope(\n document: {\n state: {\n [key: string]: unknown;\n };\n },\n scope = \"global\",\n) {\n const stateString = stringify(document.state[scope] || \"\");\n return hashBrowser(stateString);\n}\n\nexport function readOnly<T>(value: T): Readonly<T> {\n return Object.freeze(value);\n}\n\n/**\n * Maps skipped operations in an array of operations.\n * Skipped operations are operations that are ignored during processing.\n * @param operations - The array of operations to map.\n * @param skippedHeadOperations - The number of operations to skip at the head of the array of operations.\n * @returns An array of mapped operations with ignore flag indicating if the operation is skipped.\n * @throws Error if the operation index is invalid and there are missing operations.\n */\nexport function mapSkippedOperations(\n operations: Operation[],\n skippedHeadOperations?: number,\n): MappedOperation[] {\n const ops = [...operations];\n\n let skipped = skippedHeadOperations || 0;\n let latestOpIndex = ops.length > 0 ? ops[ops.length - 1].index : 0;\n\n const scopeOpsWithIgnore: MappedOperation[] = [];\n\n for (const operation of ops.reverse()) {\n if (skipped > 0) {\n const operationsDiff = latestOpIndex - operation.index;\n skipped -= operationsDiff;\n }\n\n if (skipped < 0) {\n throw new Error(\"Invalid operation index, missing operations\");\n }\n\n const mappedOp = {\n ignore: skipped > 0,\n operation,\n };\n\n // here we add 1 to the skip number because we want to get the number of\n // operations that we want to move the pointer back to get the latest valid operation\n // operation.skip = 1 means that we want to move the pointer back 2 operations to get to the latest valid operation\n const operationSkip = operation.skip > 0 ? operation.skip + 1 : 0;\n\n if (operationSkip > 0 && operationSkip > skipped) {\n const skipDiff = operationSkip - skipped;\n skipped = skipped + skipDiff;\n }\n\n latestOpIndex = operation.index;\n scopeOpsWithIgnore.push(mappedOp);\n }\n\n return scopeOpsWithIgnore.reverse();\n}\n\n/**\n * V2 version of mapSkippedOperations for protocol version 2+.\n * In V2, all NOOPs have skip=1 and consecutive NOOPs form chains.\n * N consecutive NOOPs at any point skip N preceding content operations.\n *\n * Algorithm: Process from end to start\n * - When hitting a NOOP: increment chain length, mark as ignored\n * - When hitting a non-NOOP:\n * - If chain > 0: decrement chain, mark as ignored (this op was undone)\n * - If chain == 0: mark as not ignored (apply this op)\n */\nexport function mapSkippedOperationsV2(\n operations: Operation[],\n): MappedOperation[] {\n const ops = [...operations];\n const result: MappedOperation[] = [];\n\n let noopChainLength = 0;\n\n for (let i = ops.length - 1; i >= 0; i--) {\n const operation = ops[i];\n const isNoop = operation.action.type === \"NOOP\";\n\n if (isNoop) {\n noopChainLength++;\n result.unshift({ ignore: true, operation });\n } else if (noopChainLength > 0) {\n noopChainLength--;\n result.unshift({ ignore: true, operation });\n } else {\n result.unshift({ ignore: false, operation });\n }\n }\n\n return result;\n}\n\n/**\n * V2 garbage collect that returns only operations that should be applied for state.\n * Uses the V2 model where consecutive NOOPs form chains.\n * Unlike V1 garbageCollect, this preserves ALL operations but marks which to apply.\n */\n/**\n * The base-reducer protocol version a document is written against. Every\n * document carries one, set from the CREATE_DOCUMENT input. A header without\n * one was built outside that path, and choosing a version on its behalf would\n * replay the document through a reducer it was not written for, so it is an\n * error rather than a default.\n */\nexport function baseReducerVersion(header: PHDocumentHeader): number {\n const version = header.protocolVersions?.[\"base-reducer\"];\n\n if (typeof version !== \"number\") {\n throw new Error(\n `Document ${header.id} carries no base-reducer protocol version`,\n );\n }\n\n return version;\n}\n\nexport function garbageCollectV2<TOpIndex extends OperationIndex>(\n sortedOperations: TOpIndex[],\n): TOpIndex[] {\n const result: TOpIndex[] = [];\n let noopChainLength = 0;\n\n for (let i = sortedOperations.length - 1; i >= 0; i--) {\n const op = sortedOperations[i];\n // Check if this is a NOOP operation\n const isNoop =\n \"action\" in op &&\n (op as unknown as Operation).action.type === \"NOOP\" &&\n op.skip > 0;\n\n if (isNoop) {\n noopChainLength++;\n // Include the NOOP in result (for operation history)\n result.unshift(op);\n } else if (noopChainLength > 0) {\n noopChainLength--;\n // Skip this operation - it was undone\n } else {\n // Include this operation\n result.unshift(op);\n }\n }\n\n return result;\n}\n\n// Flattens the mapped operations (with ignore flag) from all scopes into\n// a single array and sorts them by timestamp\nexport function sortMappedOperations(operations: DocumentOperationsIgnoreMap) {\n return Object.values(operations)\n .flatMap((array) => array)\n .sort(\n (a, b) =>\n new Date(a.operation.timestampUtcMs).getTime() -\n new Date(b.operation.timestampUtcMs).getTime(),\n );\n}\n\n// Default createState function that just returns the state as-is\nconst defaultCreateState = <TState extends PHBaseState = PHBaseState>(\n state?: Partial<TState>,\n) => {\n return state as TState;\n};\n\n/**\n * Records an operation in the history without applying it, which is what a\n * denied operation needs: it occupies its index and contributes no state.\n *\n * The scope defaults to the action's own, and is passed explicitly by a rebuild\n * that is walking one stream and does not want to trust the action's copy.\n */\nexport function appendWithoutApplying<TState extends PHBaseState>(\n document: PHDocument<TState>,\n operation: Operation,\n scope: string = operation.action.scope,\n): PHDocument<TState> {\n return {\n ...document,\n operations: {\n ...document.operations,\n [scope]: [...(document.operations[scope] ?? []), operation],\n },\n };\n}\n\n// Runs the operations on the initial data using the\n// provided document reducer.\n// This rebuilds the document according to the provided actions.\nexport function replayDocument<TState extends PHBaseState = PHBaseState>(\n initialState: TState,\n operations: DocumentOperations,\n reducer: Reducer<TState>,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n skipHeaderOperations: SkipHeaderOperations = {},\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n const {\n checkHashes = true,\n reuseOperationResultingState,\n operationResultingStateParser = parseResultingState,\n skipIndexValidation,\n } = options || {};\n\n const backfilledInitialState = backfillAuthState(initialState);\n let documentState = backfilledInitialState;\n const operationsToReplay: Operation[] = [];\n // Initialize with all scopes found in operations, plus global and local for backward compatibility\n const allScopes = new Set([...Object.keys(operations), \"global\", \"local\"]);\n const initialOperations: DocumentOperations = {};\n for (const scope of allScopes) {\n initialOperations[scope] = [];\n }\n\n // if operation resulting state is to be used then\n // looks for the last operation with state of each\n // scope to use it as the starting point and only\n // replay operations that follow it\n if (reuseOperationResultingState) {\n for (const [scope, scopeOperations] of Object.entries(operations)) {\n if (!scopeOperations) {\n continue;\n }\n const index = scopeOperations.findLastIndex((s) => !!s.resultingState);\n if (index < 0) {\n operationsToReplay.push(...scopeOperations);\n continue;\n }\n const opWithState = scopeOperations[index];\n if (!opWithState || !opWithState.resultingState) continue;\n try {\n const scopeState = operationResultingStateParser(\n opWithState.resultingState,\n );\n documentState = {\n ...documentState,\n [scope]: scopeState,\n };\n const scopeInitialOps =\n initialOperations[scope as keyof typeof initialOperations];\n if (scopeInitialOps) {\n scopeInitialOps.push(...scopeOperations.slice(0, index + 1));\n }\n operationsToReplay.push(...scopeOperations.slice(index + 1));\n } catch {\n /* if parsing fails then keeps replays all scope operations */\n operationsToReplay.push(...scopeOperations);\n }\n }\n } else {\n operationsToReplay.push(\n ...Object.values(operations).flatMap((ops) => ops || []),\n );\n }\n\n // builds a new document using the provided header (no generated header)\n const document: PHDocument<TState> = {\n header,\n state: defaultCreateState<TState>(documentState),\n initialState: backfilledInitialState,\n operations: initialOperations,\n clipboard: [],\n };\n\n let result = document;\n\n // if there are operations left without resulting state\n // then replays them\n if (operationsToReplay.length) {\n result = operationsToReplay.reduce((document, operation) => {\n // A denied operation holds its position without contributing state. The\n // reactor skips it on every rebuild, so a replay that applied it would\n // produce different state from the reactor that served the history. It\n // still occupies its index, so the scope's revision counts it.\n if (isDenied(operation)) {\n return updateHeaderRevision(\n appendWithoutApplying(document, operation),\n operation.action.scope,\n operation.timestampUtcMs,\n ) as PHDocument<TState>;\n }\n\n const doc = reducer(document, operation.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: {\n operation,\n },\n });\n\n return doc;\n }, document);\n }\n // if not then updates the document header according\n // to the latest operation of each scope\n else {\n for (const scopeOperations of Object.values(initialOperations)) {\n if (!scopeOperations) {\n continue;\n }\n const lastOperation = scopeOperations.at(-1);\n if (lastOperation) {\n result = updateHeaderRevision(\n result,\n lastOperation.action.scope,\n lastOperation.timestampUtcMs,\n ) as PHDocument<TState>;\n }\n }\n }\n\n // if hash generation was skipped then checks if the hash\n // of each scope matches the hash of last operation\n if (!checkHashes) {\n for (const scope of Object.keys(result.state)) {\n for (let i = operationsToReplay.length - 1; i >= 0; i--) {\n const operation = operationsToReplay[i];\n\n if (operation.action.scope !== scope) {\n continue;\n }\n if (operation.hash !== hashDocumentStateForScope(result, scope)) {\n throw new HashMismatchError(scope, result, operation);\n } else {\n break;\n }\n }\n }\n }\n\n // reuses operation timestamp if provided\n // Initialize with all scopes from both result.operations and input operations\n const allResultScopes = new Set([\n ...Object.keys(result.operations),\n ...Object.keys(operations),\n \"global\",\n \"local\",\n ]);\n const initialResultOperations: DocumentOperations = {};\n for (const scope of allResultScopes) {\n initialResultOperations[scope] = [];\n }\n\n // Iterate over all scopes (not just result.operations) to preserve empty scopes\n const resultOperations: DocumentOperations = Array.from(\n allResultScopes,\n ).reduce((acc, scope) => {\n const scopeOps = result.operations[scope] || [];\n\n return {\n ...acc,\n [scope]: [\n ...scopeOps.map((operation, index) => {\n return {\n ...operation,\n timestamp:\n operations[scope]?.[index]?.timestampUtcMs ??\n operation.timestampUtcMs,\n };\n }),\n ],\n };\n }, initialResultOperations);\n\n // gets the last modified timestamp from the latest operation\n const lastModified = header\n ? header.lastModifiedAtUtcIso\n : Object.values(resultOperations).reduce((acc, curr) => {\n if (!curr) {\n return acc;\n }\n const operation = curr.at(-1);\n if (operation) {\n if (operation.timestampUtcMs > acc) {\n return operation.timestampUtcMs;\n }\n }\n\n return acc;\n }, document.header.lastModifiedAtUtcIso);\n\n if (header) {\n result.header = {\n ...header,\n revision: result.header.revision,\n lastModifiedAtUtcIso: lastModified,\n };\n }\n\n return {\n ...result,\n operations: resultOperations,\n } as PHDocument<TState>;\n}\n\nexport function parseResultingState<TState>(\n state: string | null | undefined,\n): TState {\n const stateType = typeof state;\n if (stateType === \"string\") {\n return JSON.parse(state!) as TState;\n } else if (stateType === \"object\") {\n return state as TState;\n } else {\n throw new Error(`Providing resulting state is of type: ${stateType}`);\n }\n}\n\nexport enum IntegrityIssueType {\n UNEXPECTED_INDEX = \"UNEXPECTED_INDEX\",\n}\n\nexport enum IntegrityIssueSubType {\n DUPLICATED_INDEX = \"DUPLICATED_INDEX\",\n MISSING_INDEX = \"MISSING_INDEX\",\n}\n\ntype IntegrityIssue = {\n operation: OperationIndex;\n issue: IntegrityIssueType;\n category: IntegrityIssueSubType;\n message: string;\n};\n\ntype Reshuffle = (\n startIndex: OperationIndex,\n opsA: Operation[],\n opsB: Operation[],\n) => Operation[];\n\nexport function checkCleanedOperationsIntegrity(\n sortedOperations: OperationIndex[],\n): IntegrityIssue[] {\n const result: IntegrityIssue[] = [];\n\n // 1:1 1\n // 0:0 0 -> 1:0 1 -> 2:0 -> 3:0 -> 4:0 -> 5:0\n // 0:0 0 -> 2:1 1 -> 3:0 -> 4:0 -> 5:0\n // 0:0 0 -> 3:2 1 -> 4:0 -> 5:0\n // 0:0 0 -> 3:2 1 -> 5:1\n\n // 0:3 (expected 0, got -3)\n // 1:2 (expected 0, got -1)\n // 0:0 -> 1:1\n // 0:0 -> 2:2\n // 0:0 -> 3:2 -> 5:2\n\n let currentIndex = -1;\n for (const nextOperation of sortedOperations) {\n const nextIndex = nextOperation.index - nextOperation.skip;\n\n if (nextIndex !== currentIndex + 1) {\n result.push({\n operation: {\n index: nextOperation.index,\n skip: nextOperation.skip,\n },\n issue: IntegrityIssueType.UNEXPECTED_INDEX,\n category:\n nextIndex > currentIndex + 1\n ? IntegrityIssueSubType.MISSING_INDEX\n : IntegrityIssueSubType.DUPLICATED_INDEX,\n message: `Expected index ${currentIndex + 1} with skip 0 or equivalent, got index ${nextOperation.index} with skip ${nextOperation.skip}`,\n });\n }\n\n currentIndex = nextOperation.index;\n }\n\n return result;\n}\n\n// [] -> []\n// [0:0] -> [0:0]\n\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:1 2:0 => 1:1 2:0, removals 1, no issues\n\n// 0:0 1:1 2:0 3:1 => 1:1 3:1, removals 2, no issues\n// 0:0 1:1 2:0 3:3 => 3:3\n\n// 1:1 2:0 3:0 => 1:1 2:0 3:0, removals 0, no issues\n// 1:0 0:0 2:0 => 2:0, removals 2, issues [UNEXPECTED_INDEX, INDEX_OUT_OF_ORDER]\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n// 0:0 1:0 2:0 => 0:0 1:0 2:0, removals 0, no issues\n\nexport function garbageCollect<TOpIndex extends OperationIndex>(\n sortedOperations: TOpIndex[],\n) {\n const result: TOpIndex[] = [];\n\n let i = sortedOperations.length - 1;\n\n while (i > -1) {\n result.unshift(sortedOperations[i]);\n const skipUntil =\n (sortedOperations[i]?.index || 0) - (sortedOperations[i]?.skip || 0) - 1;\n\n let j = i - 1;\n while (j > -1 && (sortedOperations[j]?.index || 0) > skipUntil) {\n j--;\n }\n\n i = j;\n }\n\n return result;\n}\nexport function addUndo(sortedOperations: Operation[]) {\n const operationsCopy = [...sortedOperations];\n const latestOperation = operationsCopy[operationsCopy.length - 1];\n\n if (!latestOperation) return operationsCopy;\n\n if (latestOperation.action.type === \"NOOP\") {\n operationsCopy.push({\n ...latestOperation,\n index: latestOperation.index,\n skip: nextSkipNumber(sortedOperations),\n action: {\n ...latestOperation.action,\n\n // TODO: this will break the signature...\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type: \"NOOP\",\n },\n });\n } else {\n operationsCopy.push({\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n index: latestOperation.index + 1,\n skip: 1,\n hash: latestOperation.hash,\n action: {\n id: generateId(),\n timestampUtcMs: new Date().toISOString(),\n type: \"NOOP\",\n input: {},\n scope: latestOperation.action.scope,\n },\n });\n }\n\n return operationsCopy;\n}\n\n// [0:0 2:0 1:0 3:3 3:1] => [0:0 1:0 2:0 3:1 3:3]\n// Sort by index _and_ skip number\nexport function sortOperations<TOpIndex extends OperationIndex>(\n operations: TOpIndex[],\n): TOpIndex[] {\n return operations\n .slice()\n .sort((a, b) => a.skip - b.skip)\n .sort((a, b) => a.index - b.index);\n}\n\n// [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n// GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n// Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n// Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n// merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\nexport function reshuffleByTimestamp<TOp extends OperationIndex>(\n startIndex: OperationIndex,\n opsA: TOp[],\n opsB: TOp[],\n): TOp[] {\n return [...opsA, ...opsB]\n .sort((a, b) => {\n const timestampDiff =\n new Date(a.timestampUtcMs || \"\").getTime() -\n new Date(b.timestampUtcMs || \"\").getTime();\n if (timestampDiff !== 0) {\n return timestampDiff;\n }\n return (a.id || \"\").localeCompare(b.id || \"\");\n })\n .map((op, i) => ({\n ...op,\n index: startIndex.index + i,\n skip: i === 0 ? startIndex.skip : 0,\n }));\n}\n\nexport function reshuffleByTimestampAndIndex<TOp extends OperationIndex>(\n startIndex: OperationIndex,\n opsA: TOp[],\n opsB: TOp[],\n): TOp[] {\n return [...opsA, ...opsB]\n .sort((a, b) => {\n const indexDiff = a.index - b.index;\n if (indexDiff !== 0) {\n return indexDiff;\n }\n const timestampDiff =\n new Date(a.timestampUtcMs || \"\").getTime() -\n new Date(b.timestampUtcMs || \"\").getTime();\n if (timestampDiff !== 0) {\n return timestampDiff;\n }\n return (a.id || \"\").localeCompare(b.id || \"\");\n })\n .map((op, i) => ({\n ...op,\n index: startIndex.index + i,\n skip: i === 0 ? startIndex.skip : 0,\n }));\n}\n\n// TODO: implement better operation equality function\nexport function operationsAreEqual<\n TOp extends {\n index: number;\n skip: number;\n type?: string;\n scope?: string;\n input?: unknown;\n },\n>(op1: TOp, op2: TOp): boolean {\n const a = op1;\n const b = op2;\n\n const aComparable = {\n index: a.index,\n skip: a.skip,\n type: a.type ?? null,\n scope: a.scope ?? null,\n input: a.input ?? null,\n };\n\n const bComparable = {\n index: b.index,\n skip: b.skip,\n type: b.type ?? null,\n scope: b.scope ?? null,\n input: b.input ?? null,\n };\n\n return stringify(aComparable) === stringify(bComparable);\n}\n\n// [T0:0 T1:0 T2:0 T3:0] + [B4:0 B5:0] = [T0:0 T1:0 T2:0 T3:0 B4:0 B5:0]\n// [T0:0 T1:0 T2:0 T3:0] + [B3:0 B4:0] = [T0:0 T1:0 T2:0 B3:0 B4:0]\n// [T0:0 T1:0 T2:0 T3:0] + [B2:0 B3:0] = [T0:0 T1:0 B2:0 B3:0]\n\n// [T0:0 T1:0 T2:0 T3:0] + [B4:0 B4:2] = [T0:0 T1:0 T2:0 T3:0 B4:0 B4:2]\n// [T0:0 T1:0 T2:0 T3:0] + [B3:0 B3:2] = [T0:0 T1:0 T2:0 B3:0 B3:2]\n// [T0:0 T1:0 T2:0 T3:0] + [B2:3 B3:0] = [T0:0 T1:0 B2:3 B3:0]\n\nexport function attachBranch(\n trunk: Operation[],\n newBranch: Operation[],\n): [Operation[], Operation[]] {\n const trunkCopy = garbageCollect(sortOperations(trunk.slice()));\n const newOperations = garbageCollect(sortOperations(newBranch.slice()));\n if (trunkCopy.length < 1) {\n return [newOperations, []];\n }\n\n const result: Operation[] = [];\n let enteredBranch = false;\n\n while (newOperations.length > 0) {\n const newOperationCandidate = newOperations[0];\n\n let nextTrunkOperation = trunkCopy.shift();\n while (\n nextTrunkOperation &&\n precedes(nextTrunkOperation, newOperationCandidate)\n ) {\n result.push(nextTrunkOperation);\n nextTrunkOperation = trunkCopy.shift();\n }\n\n if (!nextTrunkOperation) {\n enteredBranch = true;\n } else if (!enteredBranch) {\n if (operationsAreEqual(nextTrunkOperation, newOperationCandidate)) {\n newOperations.shift();\n result.push(nextTrunkOperation);\n } else {\n trunkCopy.unshift(nextTrunkOperation);\n enteredBranch = true;\n }\n }\n\n if (enteredBranch) {\n let nextAppend = newOperations.shift();\n while (nextAppend) {\n result.push(nextAppend);\n nextAppend = newOperations.shift();\n }\n }\n }\n\n if (!enteredBranch) {\n let nextAppend = trunkCopy.shift();\n while (nextAppend) {\n result.push(nextAppend);\n nextAppend = trunkCopy.shift();\n }\n }\n\n return [garbageCollect(result), trunkCopy];\n}\n\nexport function precedes(op1: OperationIndex, op2: OperationIndex) {\n return (\n op1.index < op2.index ||\n (op1.index === op2.index && op1.id === op2.id && op1.skip < op2.skip)\n );\n}\n\nexport function split(\n sortedTargetOperations: Operation[],\n sortedMergeOperations: Operation[],\n): [Operation[], Operation[], Operation[]] {\n const commonOperations: Operation[] = [];\n const targetDiffOperations: Operation[] = [];\n const mergeDiffOperations: Operation[] = [];\n\n // get bigger array length\n const maxLength = Math.max(\n sortedTargetOperations.length,\n sortedMergeOperations.length,\n );\n\n let splitHappened = false;\n for (let i = 0; i < maxLength; i++) {\n const targetOperation = sortedTargetOperations[i];\n const mergeOperation = sortedMergeOperations[i];\n\n if (targetOperation && mergeOperation) {\n if (\n !splitHappened &&\n operationsAreEqual(targetOperation, mergeOperation)\n ) {\n commonOperations.push(targetOperation);\n } else {\n splitHappened = true;\n targetDiffOperations.push(targetOperation);\n mergeDiffOperations.push(mergeOperation);\n }\n } else if (targetOperation) {\n targetDiffOperations.push(targetOperation);\n } else if (mergeOperation) {\n mergeDiffOperations.push(mergeOperation);\n }\n }\n\n return [commonOperations, targetDiffOperations, mergeDiffOperations];\n}\n\n// [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, 2:0, B3:0, B4:2, B5:0]\n// GC => [0:0, 1:0, 2:0, A3:0, A4:0, A5:0] + [0:0, 1:0, B4:2, B5:0]\n// Split => [0:0, 1:0] + [2:0, A3:0, A4:0, A5:0] + [B4:2, B5:0]\n// Reshuffle(6:4) => [6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\n// merge => [0:0, 1:0, 6:4, 7:0, 8:0, 9:0, 10:0, 11:0]\nexport function merge(\n sortedTargetOperations: Operation[],\n sortedMergeOperations: Operation[],\n reshuffle: Reshuffle,\n): Operation[] {\n const [_commonOperations, _targetOperations, _mergeOperations] = split(\n garbageCollect(sortedTargetOperations),\n garbageCollect(sortedMergeOperations),\n );\n\n const maxCommonIndex = getMaxIndex(_commonOperations);\n const nextIndex =\n 1 +\n Math.max(\n maxCommonIndex,\n getMaxIndex(_targetOperations),\n getMaxIndex(_mergeOperations),\n );\n\n const filteredMergeOperations = filterDuplicatedOperations(\n _mergeOperations,\n _targetOperations,\n );\n\n const newOperationHistory = reshuffle(\n {\n index: nextIndex,\n skip: nextIndex - (maxCommonIndex + 1),\n },\n _targetOperations,\n filteredMergeOperations,\n );\n\n return _commonOperations.concat(newOperationHistory);\n}\n\nfunction getMaxIndex(sortedOperations: OperationIndex[]) {\n const lastElement = sortedOperations[sortedOperations.length - 1];\n if (!lastElement) {\n return -1;\n }\n\n return lastElement.index;\n}\n\n// [] => -1\n// [0:0] => -1\n// [0:0 1:0] => 1\n// [0:0 1:1] => -1\n// [1:1] => -1\n// [0:0 1:0 2:0] => 1\n// [0:0 1:0 2:0 2:1] => 2\n// [0:0 1:0 2:0 2:1 2:2] => -1\n// [0:0 1:1 2:0] => 2\n// [0:0 1:1 2:2] => -1\n// [0:0 1:1 2:0 3:0] => 1\n// [0:0 1:1 2:0 3:1] => 3\n// [0:0 1:1 2:0 3:3] => -1\n// [50:50 100:50 150:50 151:0 152:0 153:0 154:3] => 53\n\nexport function nextSkipNumber(sortedOperations: OperationIndex[]) {\n if (sortedOperations.length < 1) {\n return -1;\n }\n\n const cleanedOperations = garbageCollect(sortedOperations);\n\n let nextSkip =\n (cleanedOperations[cleanedOperations.length - 1]?.skip || 0) + 1;\n\n if (cleanedOperations.length > 1) {\n nextSkip += cleanedOperations[cleanedOperations.length - 2]?.skip || 0;\n }\n\n return (cleanedOperations[cleanedOperations.length - 1]?.index || -1) <\n nextSkip\n ? -1\n : nextSkip;\n}\n\nexport function checkOperationsIntegrity(operations: Operation[]) {\n return checkCleanedOperationsIntegrity(\n garbageCollect(sortOperations(operations)),\n );\n}\nexport function groupOperationsByScope(operations: Operation[]) {\n const result = operations.reduce<OperationsByScope>((acc, operation) => {\n if (!acc[operation.action.scope]) {\n acc[operation.action.scope] = [];\n }\n\n acc[operation.action.scope]?.push(operation);\n\n return acc;\n }, {});\n\n return result;\n}\n\ntype PrepareOperationsResult = {\n validOperations: Operation[];\n invalidOperations: Operation[];\n duplicatedOperations: Operation[];\n integrityIssues: IntegrityIssue[];\n};\n\nexport function prepareOperations(\n operationsHistory: Operation[],\n newOperations: Operation[],\n) {\n const result: PrepareOperationsResult = {\n integrityIssues: [],\n validOperations: [],\n invalidOperations: [],\n duplicatedOperations: [],\n };\n\n const sortedOperationsHistory = sortOperations(operationsHistory);\n const sortedOperations = sortOperations(newOperations);\n\n const integrityErrors = checkCleanedOperationsIntegrity([\n ...sortedOperationsHistory,\n ...sortedOperations,\n ]);\n\n const missingIndexErrors = integrityErrors.filter(\n (integrityIssue) =>\n integrityIssue.category === IntegrityIssueSubType.MISSING_INDEX,\n );\n\n // get the integrity error with the lowest index operation\n const firstMissingIndexOperation = [...missingIndexErrors]\n .sort((a, b) => b.operation.index - a.operation.index)\n .pop()?.operation;\n\n for (const newOperation of sortedOperations) {\n // Operation is missing index or it follows an operation that is missing index\n if (\n firstMissingIndexOperation &&\n newOperation.index >= firstMissingIndexOperation.index\n ) {\n result.invalidOperations.push(newOperation);\n continue;\n }\n\n // check if operation is duplicated\n const isDuplicatedOperation = integrityErrors.some((integrityError) => {\n return (\n integrityError.operation.index === newOperation.index &&\n integrityError.operation.skip === newOperation.skip &&\n integrityError.category === IntegrityIssueSubType.DUPLICATED_INDEX\n );\n });\n\n // add to duplicated operations if it is duplicated\n if (isDuplicatedOperation) {\n result.duplicatedOperations.push(newOperation);\n continue;\n }\n\n // otherwise, add to valid operations\n result.validOperations.push(newOperation);\n }\n\n result.integrityIssues.push(...integrityErrors);\n return result;\n}\n\nexport function removeExistingOperations(\n newOperations: Operation[],\n operationsHistory: Operation[],\n) {\n return newOperations.filter((newOperation) => {\n return !operationsHistory.some((historyOperation) => {\n return (\n (newOperation.action.type === \"NOOP\" &&\n newOperation.skip === 0 &&\n newOperation.index === historyOperation.index) ||\n (newOperation.index === historyOperation.index &&\n newOperation.skip === historyOperation.skip &&\n newOperation.action.scope === historyOperation.action.scope &&\n newOperation.hash === historyOperation.hash &&\n newOperation.action.type === historyOperation.action.type)\n );\n });\n });\n}\n\n/**\n * Skips header operations and returns the remaining operations.\n *\n * @param operations - The array of operations.\n * @param skipHeaderOperation - The skip header operation index.\n * @returns The remaining operations after skipping header operations.\n */\nexport function skipHeaderOperations(\n operations: Operation[],\n skipHeaderOperation: SkipHeaderOperationIndex,\n): Operation[] {\n const lastOperation = sortOperations(operations).at(-1);\n const lastIndex = lastOperation?.index ?? -1;\n const nextIndex = lastIndex + 1;\n\n const skipOperationIndex = {\n ...skipHeaderOperation,\n index: skipHeaderOperation.index ?? nextIndex,\n };\n\n if (skipOperationIndex.index < lastIndex) {\n throw new Error(\n `The skip header operation index must be greater than or equal to ${lastIndex}`,\n );\n }\n\n const clearedOperations = garbageCollect(\n sortOperations([...operations, skipOperationIndex]),\n );\n\n return clearedOperations.slice(0, -1) as Operation[]; //clearedOperation ? [clearedOperation as TOpIndex] : [];\n}\n\nexport function garbageCollectDocumentOperations(\n documentOperations: DocumentOperations,\n) {\n const clearedOperations = Object.entries(documentOperations).reduce(\n (acc, entry) => {\n const [scope, ops] = entry;\n if (!ops) {\n return acc;\n }\n\n return {\n ...acc,\n [scope]: garbageCollect(sortOperations(ops)),\n };\n },\n {},\n );\n\n return clearedOperations as DocumentOperations;\n}\n\n/**\n * Filters out duplicated operations from the target operations array based on their IDs.\n * If an operation has an ID, it is considered duplicated if there is another operation in the source operations array with the same ID.\n * If an operation does not have an ID, it is considered unique and will not be filtered out.\n * @param targetOperations - The array of target operations to filter.\n * @param sourceOperations - The array of source operations to compare against.\n * @returns An array of operations with duplicates filtered out.\n */\nexport function filterDuplicatedOperations<T extends { id?: string | number }>(\n targetOperations: T[],\n sourceOperations: T[],\n): T[] {\n return targetOperations.filter((op) => {\n if (op.id) {\n return !sourceOperations.some((targetOp) => targetOp.id === op.id);\n }\n\n return true;\n });\n}\n\nexport function filterDocumentOperationsResultingState(\n documentOperations?: DocumentOperations,\n) {\n if (!documentOperations) {\n return {} as DocumentOperations;\n }\n\n const entries = Object.entries(documentOperations);\n\n return entries.reduce((acc, [scope, operations]) => {\n if (!operations) {\n return acc;\n }\n return {\n ...acc,\n [scope]: operations.map((op) => {\n const { resultingState, ...restProps } = op;\n\n return restProps;\n }),\n };\n }, {} as DocumentOperations);\n}\n\n/**\n * Calculates the difference between two arrays of operations.\n * Returns an array of operations that are present in `clearedOperationsA` but not in `clearedOperationsB`.\n *\n * @template TOp - The type of the operations.\n * @param {TOp[]} clearedOperationsA - The first array of operations.\n * @param {TOp[]} clearedOperationsB - The second array of operations.\n * @returns {TOp[]} - The difference between the two arrays of operations.\n */\nexport function diffOperations<TOp extends OperationIndex>(\n clearedOperationsA: TOp[],\n clearedOperationsB: TOp[],\n): TOp[] {\n return clearedOperationsA.filter(\n (operationA) =>\n !clearedOperationsB.some(\n (operationB) => operationA.index === operationB.index,\n ),\n );\n}\n\n// Returns the timestamp of the latest operation by index (and skip as tiebreaker),\n// falling back to the document header's lastModifiedAtUtcIso\nexport function getDocumentLastModified(document: PHDocument) {\n let latest: Operation | undefined;\n\n for (const ops of Object.values(document.operations)) {\n if (!ops) continue;\n for (const op of ops) {\n if (\n !latest ||\n op.index > latest.index ||\n (op.index === latest.index && op.skip > latest.skip)\n ) {\n latest = op;\n }\n }\n }\n\n return latest?.timestampUtcMs || document.header.lastModifiedAtUtcIso;\n}\n\n/**\n * Gets the next revision number based on the provided scope.\n *\n * @param state The current state of the document.\n * @param scope The scope of the operation.\n * @returns The next revision number.\n */\nfunction getNextRevision(document: PHDocument, scope: string) {\n const scopeOperations = document.operations[scope];\n const maxIndex = scopeOperations?.at(-1)?.index ?? -1;\n return maxIndex + 1;\n}\n\n/**\n * Updates the document header with the latest revision number and\n * date of last modification.\n *\n * @param document The current state of the document.\n * @param scope The scope of the operation.\n * @param lastModifiedTimestamp Optional timestamp to use directly, avoiding a scan of all operations.\n * @returns The updated document state.\n */\nexport function updateHeaderRevision(\n document: PHDocument,\n scope: string,\n lastModifiedTimestamp?: string,\n): PHDocument {\n const newTimestamp =\n lastModifiedTimestamp ?? getDocumentLastModified(document);\n const currentTimestamp = document.header.lastModifiedAtUtcIso;\n\n const header: PHDocumentHeader = {\n ...document.header,\n revision: {\n ...document.header.revision,\n [scope]: getNextRevision(document, scope),\n },\n lastModifiedAtUtcIso:\n !currentTimestamp || newTimestamp > currentTimestamp\n ? newTimestamp\n : currentTimestamp,\n };\n\n return {\n ...document,\n header,\n };\n}\n","import type { Draft } from \"mutative\";\nimport { castDraft, create } from \"mutative\";\nimport { noop, type Action } from \"./actions.js\";\nimport { resolveSnapshotAuth } from \"./auth.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport { nextSkipNumber, sortOperations } from \"./documents.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type { LoadStateActionInput } from \"./types.js\";\n\n// updates the name of the document\nexport function setNameOperation<TDocument extends PHDocument>(\n document: TDocument,\n input: { name: string },\n) {\n return { ...document, header: { ...document.header, name: input.name } };\n}\n\n// updates the preferred editor in the document header meta; clears it when input is null/empty\nexport function setPreferredEditorOperation<TDocument extends PHDocument>(\n document: TDocument,\n input: { preferredEditor: string | null },\n): TDocument {\n const existingMeta = document.header.meta ?? {};\n if (input.preferredEditor) {\n return {\n ...document,\n header: {\n ...document.header,\n meta: { ...existingMeta, preferredEditor: input.preferredEditor },\n },\n };\n }\n const { preferredEditor: _removed, ...rest } = existingMeta;\n return {\n ...document,\n header: { ...document.header, meta: rest },\n };\n}\n\nexport function undoOperation<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n // const scope = action.scope;\n const { scope } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false,\n };\n\n return create(defaultResult, (draft) => {\n const operations = [...document.operations[scope]];\n const sortedOperations = sortOperations(operations);\n\n draft.action = noop(scope) as Draft<Action>;\n\n const lastOperation = sortedOperations.at(-1);\n let nextIndex = lastOperation?.index ?? -1;\n\n const isNewNoop = lastOperation?.action.type !== \"NOOP\";\n\n if (isNewNoop) {\n nextIndex = nextIndex + 1;\n } else {\n draft.reuseLastOperationIndex = true;\n }\n\n const nextOperationHistory = isNewNoop\n ? [...sortedOperations, { index: nextIndex, skip: 0 }]\n : sortedOperations;\n\n draft.skip = nextSkipNumber(nextOperationHistory);\n\n if (lastOperation && draft.skip > lastOperation.skip + 1) {\n // there's an overlap with a previous skip operation\n // (add 1 to the skip value because we are adding a new operation to the history)\n draft.skip = draft.skip + 1;\n }\n\n if (draft.skip < 0) {\n throw new Error(\n `Cannot undo: you can't undo more operations than the ones in the scope history`,\n );\n }\n });\n}\n\n/**\n * V2 of undoOperation for protocol version 2+.\n * Key differences from undoOperation:\n * - Never reuses operation index (always increments)\n * - Always sets skip=1 (consecutive NOOPs are handled during rebuild/GC)\n * - No complex skip calculation - simpler model where each UNDO is independent\n */\nexport function undoOperationV2<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: false;\n} {\n const { scope } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false as const,\n };\n\n return create(defaultResult, (draft) => {\n const operations = document.operations[scope] || [];\n const sortedOperations = sortOperations([...operations]);\n\n // Count non-NOOP operations to determine if there's anything to undo\n const nonNoopOps = sortedOperations.filter(\n (op) => op.action.type !== \"NOOP\",\n );\n\n // Count consecutive NOOPs at the end (these represent pending undos)\n let noopChainLength = 0;\n for (let i = sortedOperations.length - 1; i >= 0; i--) {\n if (sortedOperations[i].action.type === \"NOOP\") {\n noopChainLength++;\n } else {\n break;\n }\n }\n\n // Check if we can undo: need more non-NOOP ops than the current NOOP chain\n if (nonNoopOps.length <= noopChainLength) {\n throw new Error(\n `Cannot undo: no more operations to undo in scope history`,\n );\n }\n\n draft.action = noop(scope) as Draft<Action>;\n draft.skip = 1;\n });\n}\n\nexport function redoOperation<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n skip: number,\n): {\n document: TDocument;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n const { scope, input } = action;\n\n const defaultResult = {\n document,\n action,\n skip,\n reuseLastOperationIndex: false,\n };\n\n return create(defaultResult, (draft) => {\n if (draft.skip > 0) {\n throw new Error(\n `Cannot redo: skip value from reducer cannot be used with REDO action`,\n );\n }\n\n // Handle both object format { count: number } and legacy number format\n const count =\n typeof input === \"object\" && input !== null && \"count\" in input\n ? (input as { count: number }).count\n : input;\n\n if (typeof count !== \"number\" || count > 1) {\n throw new Error(`Cannot redo: you can only redo one operation at a time`);\n }\n\n if (typeof count !== \"number\" || count < 1) {\n throw new Error(`Invalid REDO action: invalid redo input value`);\n }\n\n if (draft.document.clipboard.length < 1) {\n throw new Error(`Cannot redo: no operations in the clipboard`);\n }\n\n const operationIndex = draft.document.clipboard.findLastIndex(\n (op) => op.action.scope === scope,\n );\n if (operationIndex < 0) {\n throw new Error(\n `Cannot redo: no operations in clipboard for scope \"${scope}\"`,\n );\n }\n\n const operation = draft.document.clipboard.splice(operationIndex, 1)[0];\n\n draft.action = castDraft({\n type: operation.action.type,\n scope: operation.action.scope,\n input: operation.action.input,\n } as Action);\n });\n}\n\nexport function loadStateOperation<TState extends PHBaseState>(\n document: PHDocument<TState>,\n action: LoadStateActionInput,\n): PHDocument<TState> {\n const loaded = backfillAuthState(action.state.data as TState);\n // A loaded snapshot does not get to install or replace a policy; see\n // resolveSnapshotAuth.\n loaded.auth = resolveSnapshotAuth(\n document.header.id,\n document.header.documentType,\n backfillAuthState({ ...document.state }).auth,\n loaded.auth,\n );\n return {\n ...document,\n header: { ...document.header, name: action.state.name },\n state: loaded,\n };\n}\n\n/**\n * An operation that was applied to a {@link BaseDocument}.\n *\n * @remarks\n * Wraps an action with an index, to be added to the operations history of a Document.\n * The `index` field is used to keep all operations in order and enable replaying the\n * document's history from the beginning. Note that indices and skips are relative to\n * a specific reactor. Example below:\n *\n * For (index, skip, ts, action)\n * A - [(0, 0, 1, \"A0\"), (1, 0, 2, \"A1\")]\n * B - [(0, 0, 0, \"B0\"), (1, 0, 3, \"B1\")]\n * ...\n * B gets A's Operations Scenario:\n * B' - [(0, 0, 0, \"B0\"), (1, 0, 3, \"B1\"), (2, 1, 1, \"A0\"), (3, 0, 2, \"A1\"), (4, 0, 3, \"B1\")]\n * Then A needs to end up with:\n * A' - [(0, 0, 1, \"A0\"), (1, 0, 2, \"A1\"), (2, 2, 0, \"B0\"), (3, 0, 1, \"A0\"), (4, 0, 2, \"A1\"), (5, 0, 3, \"B1\")]\n * So that both A and B end up with the stream of actions (action):\n * [(\"B0\"), (\"A0\"), (\"A1\"), (\"B1\")]\n *\n * @typeParam A - The type of the action.\n */\nexport type Operation = {\n /**\n * This is a stable id, derived from various document and action properties\n * in deriveOperationId().\n *\n * It _cannot_ be an arbitrary string.\n *\n * It it also not unique per operation, as reshuffled operations will keep'\n * the same id they had before they were reshuffled. This means that the\n * IOperationStore may have multiple operations with the same operation id.\n **/\n id: string;\n\n /** Position of the operation in the history. This is relative to a specific reactor -- they may not all agree on this value. */\n index: number;\n\n /** The number of operations skipped with this Operation. This is relative to a specific reactor -- they may not all agree on this value. */\n skip: number;\n\n /** Timestamp of when the operation was added */\n timestampUtcMs: string;\n\n /** Hash of the resulting document data after the operation */\n hash: string;\n\n /** Error message for a failed action */\n error?: string;\n\n /**\n * If authorization rejected the action, this records the reason why.\n */\n deniedReason?: string;\n\n /** The resulting state after the operation */\n resultingState?: string;\n\n /**\n * The action that was applied to the document to produce this operation.\n */\n action: Action;\n};\n\n/**\n * The operations history of the document by scope.\n *\n * This will be removed in a future release.\n *\n * TODO: Type should be Partial<Record<string, Operation[]>>,\n * but that is a breaking change for codegen + external doc models.\n */\nexport type DocumentOperations = Record<string, Operation[]>;\n\n/**\n * What happened to an operation. An operation that is not `applied` still\n * occupies its index but contributes nothing to the document's state.\n */\nexport type OperationOutcome =\n | { kind: \"applied\" }\n | { kind: \"reducer-error\"; message: string }\n | { kind: \"denied\"; reason: string };\n\n/**\n * Reads an operation's outcome. A denial takes precedence over a reducer\n * error, since a denied operation never reaches its reducer.\n */\nexport function operationOutcome(operation: Operation): OperationOutcome {\n if (operation.deniedReason !== undefined) {\n return { kind: \"denied\", reason: operation.deniedReason };\n }\n\n if (operation.error !== undefined) {\n return { kind: \"reducer-error\", message: operation.error };\n }\n\n return { kind: \"applied\" };\n}\n\nexport type OperationContext = {\n documentId: string;\n documentType: string;\n scope: string;\n branch: string;\n resultingState?: string;\n\n // This is a _global_ ordinal that is increasing across all documents and scopes.\n ordinal: number;\n};\n\nexport type OperationWithContext = {\n operation: Operation;\n context: OperationContext;\n};\n","import { castDraft, create, unsafe } from \"mutative\";\nimport type { Action } from \"./actions.js\";\nimport {\n actionFromAction,\n loadState,\n operationFromAction,\n operationFromOperation,\n} from \"./actions.js\";\nimport { applyAuthAction, assertAuthScopeActionAllowed } from \"./auth.js\";\nimport {\n baseReducerVersion,\n diffOperations,\n garbageCollect,\n garbageCollectDocumentOperations,\n garbageCollectV2,\n hashDocumentStateForScope,\n isDocumentAction,\n isUndo,\n isUndoRedo,\n parseResultingState,\n replayDocument,\n skipHeaderOperations,\n sortOperations,\n updateHeaderRevision,\n type PHDocument,\n type PHDocumentHeader,\n} from \"./documents.js\";\nimport {\n loadStateOperation,\n redoOperation,\n setNameOperation,\n setPreferredEditorOperation,\n undoOperation,\n undoOperationV2,\n type DocumentOperations,\n type Operation,\n type OperationContext,\n} from \"./operations.js\";\nimport { DocumentActionSchema } from \"./schemas.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n PruneActionInput,\n Reducer,\n ReducerOptions,\n ReplayDocumentOptions,\n SignalDispatch,\n SkipHeaderOperations,\n StateReducer,\n} from \"./types.js\";\n\n// This rebuilds the document according to the provided actions.\nexport function replayOperations<TState extends PHBaseState = PHBaseState>(\n initialState: TState,\n clearedOperations: DocumentOperations,\n stateReducer: StateReducer<TState>,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n documentReducer = baseReducer,\n skipHeaderOperations: SkipHeaderOperations = {},\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n // wraps the provided custom reducer with the\n // base document reducer\n const wrappedReducer = createReducer(stateReducer, documentReducer);\n\n return replayDocument<TState>(\n initialState,\n clearedOperations,\n wrappedReducer,\n header,\n dispatch,\n skipHeaderOperations,\n options,\n );\n}\n\n/**\n * Updates the operations history of the document based on the provided action.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param index The index of the operation to update.\n * @param skip The number of operations to skip before applying the action.\n * @param reuseLastOperationIndex Whether to reuse the last operation index (used when a an UNDO operation is performed after an existing one).\n * @param context The operation context for deterministic ID generation.\n * @returns The updated document state.\n */\nfunction updateOperationsForAction<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n): TDocument {\n // UNDO, REDO and PRUNE are meta operations\n // that alter the operations history themselves\n if ([\"UNDO\", \"REDO\", \"PRUNE\"].includes(action.type)) {\n return document;\n }\n\n const scope = action.scope;\n const existing = document.operations[scope];\n // Relies on ops being sorted ascending by index — see reactor CLAUDE.md invariants.\n const lastOperationIndex = existing?.at(-1)?.index ?? -1;\n\n const index = reuseLastOperationIndex\n ? lastOperationIndex\n : lastOperationIndex + 1;\n\n const newOperation = operationFromAction(action, index, skip, context);\n\n const operations = [...(existing ?? []), newOperation];\n\n return {\n ...document,\n operations: { ...document.operations, [scope]: operations },\n };\n}\n\nfunction updateOperationsForOperation<TDocument extends PHDocument>(\n document: TDocument,\n operation: Operation,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n skipIndexValidation?: boolean,\n): TDocument {\n const scope = operation.action.scope;\n const existing = document.operations[scope];\n // Relies on ops being sorted ascending by index — see reactor CLAUDE.md invariants.\n const lastOperationIndex = existing?.at(-1)?.index ?? -1;\n\n const nextIndex = reuseLastOperationIndex\n ? lastOperationIndex\n : lastOperationIndex + 1;\n\n if (!skipIndexValidation && operation.index - skip > nextIndex) {\n throw new Error(\n `Missing operations: expected ${nextIndex} with skip 0 or equivalent, got index ${operation.index} with skip ${skip}`,\n );\n }\n\n const newOperation = operationFromOperation(\n operation,\n operation.index,\n skip,\n context,\n );\n\n const operations = [...(existing ?? []), newOperation];\n\n return {\n ...document,\n operations: { ...document.operations, [scope]: operations },\n };\n}\n\n/**\n * Updates the document state based on the provided action.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param skip The number of operations to skip before applying the action.\n * @param reuseLastOperationIndex Whether to reuse the last operation index (used when a an UNDO operation is performed after an existing one).\n * @param context The operation context for deterministic ID generation.\n * @returns The updated document state.\n */\nexport function updateDocument<TDocument extends PHDocument>(\n document: TDocument,\n action: Action,\n reuseLastOperationIndex: boolean,\n skip: number,\n context: OperationContext,\n operation?: Operation,\n skipIndexValidation?: boolean,\n): TDocument {\n let newDocument: TDocument;\n if (operation) {\n // operation\n newDocument = updateOperationsForOperation(\n document,\n operation,\n reuseLastOperationIndex,\n skip,\n context,\n skipIndexValidation,\n ) as TDocument;\n } else {\n // action\n newDocument = updateOperationsForAction(\n document,\n action,\n reuseLastOperationIndex,\n skip,\n context,\n ) as TDocument;\n }\n\n newDocument = updateHeaderRevision(\n newDocument,\n action.scope,\n action.timestampUtcMs,\n ) as TDocument;\n return newDocument;\n}\n\n/**\n * The base document reducer function that wraps a custom reducer function.\n *\n * @param state The current state of the document.\n * @param action The action being applied to the document.\n * @param wrappedReducer The custom reducer function being wrapped by the base reducer.\n * @returns The updated document state.\n */\nfunction _baseReducer<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n wrappedReducer: StateReducer<TState>,\n): PHDocument<TState> {\n // throws if action is not valid base action\n const parsedAction = DocumentActionSchema().parse(action);\n\n switch (parsedAction.type) {\n // TODO: This needs to be changed to a HEADER scope action if it's changing the header.\n case \"SET_NAME\":\n return setNameOperation(document, parsedAction.input);\n case \"SET_PREFERRED_EDITOR\":\n return setPreferredEditorOperation(document, parsedAction.input);\n case \"PRUNE\":\n return pruneOperation(document, parsedAction.input, wrappedReducer);\n case \"LOAD_STATE\":\n return loadStateOperation(document, parsedAction.input);\n default:\n return document;\n }\n}\n\n/**\n * Processes an UNDO or REDO action.\n *\n * @param document The current state of the document.\n * @param action The action being applied to the document.\n * @param skip The number of operations to skip before applying the action.\n * @returns The updated document, calculated skip value and transformed action (if applied).\n */\nexport function processUndoRedo<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n skip: number,\n protocolVersion = 1,\n): {\n document: PHDocument<TState>;\n action: Action;\n skip: number;\n reuseLastOperationIndex: boolean;\n} {\n switch (action.type) {\n case \"UNDO\":\n if (protocolVersion >= 2) {\n return undoOperationV2(document, action, skip);\n }\n return undoOperation(document, action, skip);\n case \"REDO\":\n return redoOperation(document, action, skip);\n default:\n return { document, action, skip, reuseLastOperationIndex: false };\n }\n}\n\nfunction processSkipOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n customReducer: StateReducer<TState>,\n skipValue: number,\n reuseOperationResultingState = false,\n resultingStateParser = parseResultingState,\n): PHDocument<TState> {\n const scope = action.scope;\n\n const scopeOperations = document.operations[scope];\n if (!scopeOperations) {\n return document;\n }\n\n const latestOperation = scopeOperations.at(-1);\n\n if (!latestOperation) return document;\n\n const documentOperations = garbageCollectDocumentOperations({\n ...document.operations,\n [scope]: skipHeaderOperations(scopeOperations, latestOperation),\n });\n\n let scopeState: unknown = undefined;\n const documentScopeOps = documentOperations[scope];\n const lastRemainingOperation = documentScopeOps?.at(-1);\n\n // if the last operation has the resulting state and\n // reuseOperationResultingState is true then reuses it\n // instead of replaying the operations from the beginning\n if (reuseOperationResultingState && lastRemainingOperation?.resultingState) {\n scopeState = resultingStateParser(lastRemainingOperation.resultingState);\n } else {\n const { state } = replayOperations(\n document.initialState,\n documentOperations,\n customReducer,\n document.header,\n undefined,\n undefined,\n undefined,\n {\n reuseOperationResultingState,\n operationResultingStateParser: resultingStateParser,\n skipIndexValidation: true,\n },\n );\n\n scopeState = (state as Record<string, unknown>)[scope];\n }\n\n return {\n ...document,\n state: {\n ...document.state,\n [scope]: scopeState,\n },\n operations: garbageCollectDocumentOperations({\n ...document.operations,\n }),\n };\n}\n\nfunction processUndoOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n scope: string,\n customReducer: StateReducer<TState>,\n reuseOperationResultingState = false,\n resultingStateParser = parseResultingState,\n): PHDocument<TState> {\n const scopeOperations = document.operations[scope];\n if (!scopeOperations) {\n return document;\n }\n const operations = [...scopeOperations];\n const sortedOperations = sortOperations(operations);\n\n sortedOperations.pop();\n\n const documentOperations = garbageCollectDocumentOperations({\n ...document.operations,\n });\n\n const documentScopeOps = documentOperations[scope];\n if (!documentScopeOps) {\n return document;\n }\n const clearedOperations = [...documentScopeOps];\n const diff = diffOperations(\n garbageCollect(sortedOperations),\n clearedOperations,\n );\n\n const doc = replayOperations(\n document.initialState,\n documentOperations,\n customReducer,\n document.header,\n undefined,\n undefined,\n undefined,\n {\n reuseOperationResultingState,\n operationResultingStateParser: resultingStateParser,\n },\n );\n\n const clipboard = sortOperations(\n [...document.clipboard, ...diff].filter((op) => op.action.type !== \"NOOP\"),\n ).reverse();\n\n return { ...doc, clipboard } as PHDocument<TState>;\n}\n\n/**\n * Base document reducer that wraps a custom document reducer and handles\n * document-level actions such as undo, redo, prune, and set name.\n *\n * @template TGlobalState - The type of the state of the custom reducer.\n * @template TAction - The type of the actions of the custom reducer.\n * @param state - The current state of the document.\n * @param action - The action object to apply to the state.\n * @param customReducer - The custom reducer that implements the application logic\n * specific to the document's state.\n * @returns The new state of the document.\n */\nexport function baseReducer<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n action: Action,\n customReducer: StateReducer<TState>,\n dispatch?: SignalDispatch,\n options: ReducerOptions = {},\n): PHDocument<TState> {\n const {\n skip,\n ignoreSkipOperations = false,\n reuseOperationResultingState = false,\n operationResultingStateParser,\n pruneOnSkip = true,\n branch = \"main\",\n } = options;\n\n let _action: Action = actionFromAction(action);\n\n // UNDO/REDO/PRUNE are rejected on the auth scope (PRUNE is hardcoded to the\n // global scope, so an auth PRUNE would otherwise corrupt global history).\n assertAuthScopeActionAllowed(_action);\n\n let skipValue = skip ?? options.replayOptions?.operation.skip ?? 0;\n let newDocument = {\n ...document,\n };\n let reuseLastOperationIndex = false;\n\n const shouldProcessSkipOperation = !ignoreSkipOperations && skipValue > 0;\n\n if (isUndoRedo(_action)) {\n const {\n skip: calculatedSkip,\n action: transformedAction,\n document: processedDocument,\n reuseLastOperationIndex: reuseIndex,\n } = processUndoRedo(\n document,\n _action,\n skipValue,\n options.protocolVersion ?? baseReducerVersion(document.header),\n );\n\n _action = transformedAction;\n skipValue = calculatedSkip;\n newDocument = processedDocument;\n reuseLastOperationIndex = reuseIndex;\n } else {\n newDocument = {\n ...newDocument,\n clipboard: [],\n };\n }\n\n // if the action is one the base document actions (SET_NAME, UNDO, REDO, PRUNE)\n // then runs the base reducer first\n if (isDocumentAction(_action)) {\n newDocument = _baseReducer(newDocument, _action, customReducer);\n }\n\n // updates the document revision number, last modified date\n // and operation history\n const operationContext = {\n documentId: document.header.id,\n scope: _action.scope,\n branch,\n } as OperationContext;\n\n newDocument = updateDocument(\n newDocument,\n _action,\n reuseLastOperationIndex,\n skipValue,\n operationContext,\n options.replayOptions?.operation,\n options.skipIndexValidation,\n );\n\n // Only process undo for actual UNDO actions in protocol v1\n // For v2, NOOPs always have skip=1 and indices increment\n // NOOP operations with skip > 0 will have their clipboard populated server-side\n const protocolVersion =\n options.protocolVersion ?? baseReducerVersion(document.header);\n if (isUndo(action) && protocolVersion < 2) {\n const result = processUndoOperation(\n newDocument,\n action.scope,\n customReducer,\n );\n return result;\n }\n\n // V2 UNDO: Rebuild state using garbageCollectV2 which handles consecutive NOOPs as chains\n // Also trigger for NOOP operations loaded from sync (they have skip > 0)\n const isNoopWithSkip = _action.type === \"NOOP\" && skipValue > 0;\n if ((isUndo(action) || isNoopWithSkip) && protocolVersion >= 2) {\n const scope = _action.scope;\n const scopeOperations = newDocument.operations[scope] || [];\n const sortedOps = sortOperations([...scopeOperations]);\n\n // Get operations that should be applied (excludes undone operations)\n const effectiveOps = garbageCollectV2(sortedOps) as Operation[];\n\n // Build operations for replay - only include non-NOOP operations\n const opsToReplay = effectiveOps.filter(\n (op: Operation) => op.action.type !== \"NOOP\",\n );\n\n // Create document operations with only the effective ops for this scope\n const replayOps: DocumentOperations = {\n ...newDocument.operations,\n [scope]: opsToReplay,\n };\n\n // Replay to rebuild state using replayOperations which wraps the reducer\n // Pass skipIndexValidation since garbageCollectV2 creates gapped indices\n const rebuiltDoc = replayOperations(\n newDocument.initialState,\n replayOps,\n customReducer,\n newDocument.header,\n dispatch,\n baseReducer,\n {},\n { skipIndexValidation: true },\n );\n\n // Return document with rebuilt state but original operations (including all NOOPs)\n return {\n ...rebuiltDoc,\n operations: newDocument.operations,\n clipboard: [],\n } as PHDocument<TState>;\n }\n\n if (shouldProcessSkipOperation) {\n const processed = processSkipOperation(\n newDocument,\n _action,\n customReducer,\n skipValue,\n reuseOperationResultingState,\n operationResultingStateParser,\n );\n\n // Preserve operations when pruneOnSkip is false\n if (!pruneOnSkip) {\n newDocument = {\n ...processed,\n operations: newDocument.operations,\n };\n } else {\n newDocument = processed;\n }\n }\n\n // wraps the custom reducer with Mutative to avoid\n // mutation bugs and allow writing reducers with\n // mutating code\n newDocument = create(newDocument, (draft) => {\n // the reducer runs on a immutable version of\n // provided state\n try {\n // auth scope actions have a specialized handler, but we need to catch failures\n // on load (not mutate) to log them\n if (_action.scope === \"auth\") {\n const authState = applyAuthAction(newDocument, _action).state;\n unsafe(() => {\n draft.state = castDraft(authState);\n });\n return;\n }\n const newState = customReducer(draft.state, _action, dispatch);\n\n // const clipboardValue = isUndoRedo(action) ? [...clipboard] : [];\n\n // if the reducer creates a new state object instead\n // of mutating the draft then returns the new state\n if (newState) {\n // Object.assign(draft.state, newState);\n unsafe(() => {\n // casts new state as draft to comply with typescript\n draft.state = castDraft(newState);\n // clipboard: [...clipboardValue],\n });\n } else {\n // unsafe(() => {\n // draft.clipboard = castDraft([...clipboardValue]);\n // });\n }\n } catch (error) {\n // if the reducer throws an error then we should keep the previous state (before replayOperations)\n // and remove skip number from action/operation\n const actionScopeOps = newDocument.operations[_action.scope];\n if (!actionScopeOps) {\n throw new Error(`No operations found for scope: ${_action.scope}`, {\n cause: error,\n });\n }\n const lastOperationIndex = actionScopeOps.length - 1;\n const draftScopeOps = draft.operations[_action.scope];\n if (!draftScopeOps) {\n throw new Error(\n `No operations found in draft for scope: ${_action.scope}`,\n { cause: error },\n );\n }\n draftScopeOps[lastOperationIndex].error = (error as Error).message;\n\n draftScopeOps[lastOperationIndex].skip = 0;\n\n if (shouldProcessSkipOperation) {\n draft.state = castDraft({\n ...document.state,\n });\n const documentScopeOps = document.operations[_action.scope];\n if (!documentScopeOps) {\n throw new Error(`No operations found for scope: ${_action.scope}`, {\n cause: error,\n });\n }\n draft.operations = castDraft({\n ...document.operations,\n [_action.scope]: [\n ...documentScopeOps,\n {\n ...draftScopeOps[lastOperationIndex],\n },\n ],\n });\n }\n }\n });\n // updates the document history\n // meta operations are not added to the operations history\n if ([\"UNDO\", \"REDO\", \"PRUNE\"].includes(_action.type)) {\n return newDocument;\n }\n\n // if the replayed operation carries a hash then it is reused instead of\n // generating one, which also skips hashing the whole scope state\n const scope = _action.scope || \"global\";\n const replayHash = options.replayOptions?.operation.hash;\n const hash = replayHash\n ? replayHash\n : hashDocumentStateForScope(newDocument, scope);\n\n // updates the last operation with the hash of the resulting state\n const scopeOperations = newDocument.operations[scope];\n const lastOperation = scopeOperations?.at(-1);\n if (lastOperation) {\n lastOperation.hash = hash;\n\n if (reuseOperationResultingState) {\n lastOperation.resultingState = JSON.stringify(\n (newDocument.state as Record<string, unknown>)[scope],\n );\n }\n }\n\n return newDocument;\n}\n\n/**\n * Helper function to create a document model reducer.\n *\n * @remarks\n * This function creates a new reducer that wraps the provided `reducer` with\n * `documentReducer`, adding support for document actions:\n * - `SET_NAME`\n * - `UNDO`\n * - `REDO`\n * - `PRUNE`\n *\n * It also updates the document-related attributes on every operation.\n *\n * @param reducer - The custom reducer to wrap.\n * @param documentReducer - The document reducer to use.\n *\n * @returns The new reducer.\n */\nexport function createReducer<TState extends PHBaseState = PHBaseState>(\n stateReducer: StateReducer<TState>,\n documentReducer = baseReducer,\n): Reducer<TState> {\n const reducer: Reducer<TState> = (\n document: PHDocument<TState>,\n action: Action,\n dispatch?: SignalDispatch,\n options?: ReducerOptions,\n ) => {\n return documentReducer(document, action, stateReducer, dispatch, options);\n };\n return reducer;\n}\n\nexport function pruneOperation<TState extends PHBaseState = PHBaseState>(\n document: PHDocument<TState>,\n input: PruneActionInput,\n wrappedReducer: StateReducer<TState>,\n): PHDocument<TState> {\n const operations = document.operations.global;\n if (!operations) {\n throw new Error(\"No global operations found\");\n }\n\n let { start, end } = input;\n start = start || 0;\n end = end || operations.length;\n\n const actionsToPrune = operations.slice(start, end);\n const actionsToKeepStart = operations.slice(0, start);\n const actionsToKeepEnd = operations.slice(end);\n\n // runs all operations from the initial state to\n // the end of prune to get name and data\n const newDocument = replayOperations(\n document.initialState,\n {\n ...document.operations,\n global: actionsToKeepStart.concat(actionsToPrune),\n },\n wrappedReducer,\n document.header,\n );\n\n const newState = newDocument.state;\n const name = newDocument.header.name;\n\n // the new operation has the index of the first pruned operation\n const loadStateIndex = actionsToKeepStart.length;\n\n // if and operation is pruned then reuses the timestamp of the last operation\n // if not then assigns the timestamp of the following unpruned operation\n const loadStateTimestamp = actionsToKeepStart.length\n ? actionsToKeepStart[actionsToKeepStart.length - 1].timestampUtcMs\n : actionsToKeepEnd.length\n ? actionsToKeepEnd[0].timestampUtcMs\n : new Date().toISOString();\n\n const action = loadState({ name, ...newState }, actionsToPrune.length);\n\n // replaces pruned operations with LOAD_STATE\n return replayOperations(\n document.initialState,\n {\n ...document.operations,\n global: [\n ...actionsToKeepStart,\n {\n skip: 0,\n ...action,\n action,\n timestampUtcMs: loadStateTimestamp,\n index: loadStateIndex,\n hash: hashDocumentStateForScope({ state: newState }, \"global\"),\n },\n ...actionsToKeepEnd\n // updates the index for all the following operations\n .map((action, index) => ({\n ...action,\n index: loadStateIndex + index + 1,\n })),\n ],\n },\n wrappedReducer,\n document.header,\n );\n}\n","import { constantCase, pascalCase } from \"change-case\";\nimport type { DocumentOperations } from \"./operations.js\";\nimport type {\n CodeExample,\n DocumentModelGlobalState,\n ModuleSpecification,\n OperationErrorSpecification,\n OperationSpecification,\n ValidationError,\n} from \"./types.js\";\n\n/**\n * Reserved operation names from base reducer (core/actions.ts).\n * These names cannot be used for custom operations.\n */\nexport const RESERVED_OPERATION_NAMES = [\n \"UNDO\",\n \"REDO\",\n \"PRUNE\",\n \"LOAD_STATE\",\n \"SET_NAME\",\n \"SET_PREFERRED_EDITOR\",\n \"NOOP\",\n] as const;\n\nexport type ReservedOperationName = (typeof RESERVED_OPERATION_NAMES)[number];\n\n/**\n * Operation names become the literal action `type` string at runtime and the\n * key for codegen's action union. They must be SCREAMING_SNAKE_CASE so the\n * generated TypeScript is valid.\n */\nexport const OPERATION_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;\n\nexport function isValidOperationNameFormat(name: string): boolean {\n return OPERATION_NAME_PATTERN.test(name);\n}\n\n/**\n * Check if name conflicts with base reducer actions (case-insensitive).\n */\nexport function isReservedOperationName(name: string): boolean {\n return RESERVED_OPERATION_NAMES.includes(\n name.toUpperCase() as ReservedOperationName,\n );\n}\n\n/**\n * Get all operation names from all modules in the latest specification.\n * Returns names in uppercase for case-insensitive comparison.\n */\nexport function getAllOperationNames(\n state: DocumentModelGlobalState,\n excludeOperationId?: string,\n): string[] {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!latestSpec) return [];\n\n const names: string[] = [];\n for (const module of latestSpec.modules) {\n for (const operation of module.operations) {\n if (excludeOperationId && operation.id === excludeOperationId) continue;\n if (operation.name) names.push(operation.name.toUpperCase());\n }\n }\n return names;\n}\n\n/**\n * Validate operation name is not reserved or duplicate. Throws on failure.\n *\n * @param name - The operation name to validate\n * @param state - The document model global state\n * @param excludeOperationId - Optional operation ID to exclude (for rename validation)\n * @throws Error if the name is reserved or a duplicate\n */\nexport function validateOperationName(\n name: string,\n state: DocumentModelGlobalState,\n excludeOperationId?: string,\n): void {\n if (!name) return; // Empty names handled by existing validation\n\n if (!isValidOperationNameFormat(name)) {\n const suggestion = constantCase(name);\n const hint =\n suggestion &&\n suggestion !== name &&\n isValidOperationNameFormat(suggestion)\n ? ` Did you mean \"${suggestion}\"?`\n : \"\";\n throw new Error(\n `Operation name \"${name}\" is invalid. Names must be SCREAMING_SNAKE_CASE (matching ${OPERATION_NAME_PATTERN.source}).${hint}`,\n );\n }\n\n const upperName = name.toUpperCase();\n\n if (isReservedOperationName(name)) {\n throw new Error(\n `Operation name \"${name}\" is reserved. Please use a different name.`,\n );\n }\n\n const existingNames = getAllOperationNames(state, excludeOperationId);\n if (existingNames.includes(upperName)) {\n throw new Error(\n `Operation name \"${name}\" is already used by another operation. Operation names must be unique across all modules.`,\n );\n }\n}\n\nexport function validateInitialState(\n initialState: string,\n allowEmptyState = false,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (allowEmptyState && initialState === \"\") return errors;\n\n try {\n const state = JSON.parse(initialState) as object;\n\n if (!allowEmptyState && !Object.keys(state).length) {\n errors.push({\n message: \"Initial state cannot be empty\",\n details: {\n initialState,\n },\n });\n }\n } catch {\n errors.push({\n message: \"Invalid initial state\",\n details: {\n initialState,\n },\n });\n }\n\n return errors;\n}\n\nexport function validateStateSchemaName(\n schema: string,\n documentName: string,\n scope = \"\",\n allowEmptySchema = true,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!allowEmptySchema && !schema) {\n errors.push({\n message: \"State schema is required\",\n details: {\n schema,\n },\n });\n\n return errors;\n }\n\n if (allowEmptySchema && !schema) return errors;\n\n const expectedTypeName = `${pascalCase(documentName)}${pascalCase(scope)}State`;\n\n // Use regex to match exact type name definition\n // Pattern matches: type TypeName followed by whitespace, {, @, or end of string\n // This ensures we match \"type TodoState\" but NOT \"type TodoState2\"\n const typePattern = new RegExp(\n `\\\\btype\\\\s+${expectedTypeName}(?:\\\\s|\\\\{|@|$)`,\n );\n\n if (!typePattern.test(schema)) {\n errors.push({\n message: `Invalid state schema name. Expected type ${expectedTypeName}`,\n details: {\n schema,\n },\n });\n }\n\n return errors;\n}\n\nexport function validateModules(\n modules: ModuleSpecification[],\n): ValidationError[] {\n const errors: ValidationError[] = [];\n if (!modules.length) {\n errors.push({\n message: \"Modules are required\",\n details: {\n modules,\n },\n });\n }\n\n const modulesError = modules.reduce<ValidationError[]>(\n (acc, mod) => [...acc, ...validateModule(mod)],\n [],\n );\n\n return [...errors, ...modulesError];\n}\n\nexport function validateModule(mod: ModuleSpecification): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!mod.name) {\n errors.push({\n message: \"Module name is required\",\n details: {\n module: mod,\n },\n });\n }\n\n if (!mod.operations.length) {\n errors.push({\n message: \"Module operations are required\",\n details: {\n module: mod,\n },\n });\n }\n\n const operationErrors = mod.operations.reduce<ValidationError[]>(\n (acc, operation) => [...acc, ...validateModuleOperation(operation)],\n [],\n );\n\n return [...errors, ...operationErrors];\n}\n\nexport function validateModuleOperation(\n operation: OperationSpecification,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!operation.name) {\n errors.push({\n message: \"Operation name is required\",\n details: {\n operation,\n },\n });\n }\n\n if (!operation.schema) {\n errors.push({\n message: \"Operation schema is required\",\n details: {\n operation,\n },\n });\n }\n\n return errors;\n}\n\n/**\n * Find a module in the latest specification by id, or throw. Reducers that\n * mutate-by-id should call this up front so an unknown id fails loudly\n * instead of silently no-opping.\n */\nexport function findModuleOrThrow(\n state: DocumentModelGlobalState,\n moduleId: string,\n): ModuleSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const mod = latestSpec?.modules.find((m) => m.id === moduleId);\n if (!mod) {\n throw new Error(\n `Module \"${moduleId}\" not found in the latest specification`,\n );\n }\n return mod;\n}\n\n/**\n * Find an operation in the latest specification by id, or throw. Same\n * rationale as findModuleOrThrow — reducers that target an operation must\n * fail loudly when the operation doesn't exist.\n */\nexport function findOperationOrThrow(\n state: DocumentModelGlobalState,\n operationId: string,\n): OperationSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (latestSpec) {\n for (const mod of latestSpec.modules) {\n const op = mod.operations.find((o) => o.id === operationId);\n if (op) return op;\n }\n }\n throw new Error(\n `Operation \"${operationId}\" not found in the latest specification`,\n );\n}\n\n/**\n * Find an operation error by id across all operations in the latest\n * specification, or throw. Throws on a duplicate id too: setters act on a\n * single error, so an ambiguous id must fail loudly rather than mutate an\n * arbitrary match.\n */\nexport function findOperationErrorOrThrow(\n state: DocumentModelGlobalState,\n errorId: string,\n): OperationErrorSpecification {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const matches =\n latestSpec?.modules.flatMap((mod) =>\n mod.operations.flatMap((op) => op.errors.filter((e) => e.id === errorId)),\n ) ?? [];\n if (matches.length === 0) {\n throw new Error(\n `Operation error \"${errorId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation error \"${errorId}\" is duplicated in the latest specification`,\n );\n }\n return matches[0];\n}\n\n/**\n * Find an operation example (code example) by id across all operations in the\n * latest specification, or throw. Throws on a duplicate id for the same reason\n * as findOperationErrorOrThrow.\n */\nexport function findOperationExampleOrThrow(\n state: DocumentModelGlobalState,\n exampleId: string,\n): CodeExample {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const matches =\n latestSpec?.modules.flatMap((mod) =>\n mod.operations.flatMap((op) =>\n op.examples.filter((e) => e.id === exampleId),\n ),\n ) ?? [];\n if (matches.length === 0) {\n throw new Error(\n `Operation example \"${exampleId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation example \"${exampleId}\" is duplicated in the latest specification`,\n );\n }\n return matches[0];\n}\n\n/**\n * Assert no module in the latest specification already uses `id`. Modules are\n * targeted by id by the setter/delete/reorder reducers, so a duplicate id makes\n * those operations ambiguous.\n */\nexport function assertModuleIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (latestSpec?.modules.some((m) => m.id === id)) {\n throw new Error(\n `Module \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation in the latest specification already uses `id`. Operations\n * are targeted by id across all modules, so the id must be unique document-wide.\n */\nexport function assertOperationIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.id === id),\n );\n if (exists) {\n throw new Error(\n `Operation \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation error in the latest specification already uses `id`.\n * Error ids are targeted document-wide by the setter/delete reducers, so the id\n * must be unique to keep those operations unambiguous.\n */\nexport function assertOperationErrorIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.errors.some((e) => e.id === id)),\n );\n if (exists) {\n throw new Error(\n `Operation error \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\n/**\n * Assert no operation example in the latest specification already uses `id`.\n * Example ids are targeted document-wide by the update/delete reducers, so the\n * id must be unique to keep those operations unambiguous.\n */\nexport function assertOperationExampleIdUnique(\n state: DocumentModelGlobalState,\n id: string,\n): void {\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec?.modules.some((m) =>\n m.operations.some((o) => o.examples.some((e) => e.id === id)),\n );\n if (exists) {\n throw new Error(\n `Operation example \"${id}\" already exists in the latest specification`,\n );\n }\n}\n\nexport function validateOperations(operations: DocumentOperations) {\n const errors: ValidationError[] = [];\n const scopes = Object.keys(operations);\n\n for (const scope of scopes) {\n const scopeOperations = operations[scope];\n if (!scopeOperations) {\n continue;\n }\n const ops = scopeOperations.sort((a, b) => a.index - b.index);\n\n let opIndex = -1;\n\n for (let i = 0; i < ops.length; i++) {\n opIndex = opIndex + 1 + ops[i].skip;\n if (ops[i].index !== opIndex) {\n errors.push({\n message: `Invalid operation index ${ops[i].index} at position ${i}`,\n details: {\n position: i,\n operation: ops[i],\n scope: ops[i].action.scope,\n },\n });\n }\n }\n }\n\n return errors;\n}\n","import { isDocumentAction } from \"./documents.js\";\nimport { createReducer } from \"./reducer.js\";\nimport {\n AddChangeLogItemInputSchema,\n AddModuleInputSchema,\n AddOperationErrorInputSchema,\n AddOperationExampleInputSchema,\n AddOperationInputSchema,\n AddStateExampleInputSchema,\n DeleteChangeLogItemInputSchema,\n DeleteModuleInputSchema,\n DeleteOperationErrorInputSchema,\n DeleteOperationExampleInputSchema,\n DeleteOperationInputSchema,\n DeleteStateExampleInputSchema,\n MoveOperationInputSchema,\n ReorderChangeLogItemsInputSchema,\n ReorderModuleOperationsInputSchema,\n ReorderModulesInputSchema,\n ReorderOperationErrorsInputSchema,\n ReorderOperationExamplesInputSchema,\n ReorderStateExamplesInputSchema,\n SetAuthorNameInputSchema,\n SetAuthorWebsiteInputSchema,\n SetInitialStateInputSchema,\n SetModelDescriptionInputSchema,\n SetModelExtensionInputSchema,\n SetModelIdInputSchema,\n SetModelNameInputSchema,\n SetModuleDescriptionInputSchema,\n SetModuleNameInputSchema,\n SetOperationDescriptionInputSchema,\n SetOperationErrorCodeInputSchema,\n SetOperationErrorDescriptionInputSchema,\n SetOperationErrorNameInputSchema,\n SetOperationErrorTemplateInputSchema,\n SetOperationNameInputSchema,\n SetOperationReducerInputSchema,\n SetOperationSchemaInputSchema,\n SetOperationScopeInputSchema,\n SetOperationTemplateInputSchema,\n SetStateSchemaInputSchema,\n UpdateChangeLogItemInputSchema,\n UpdateOperationExampleInputSchema,\n UpdateStateExampleInputSchema,\n} from \"./schemas.js\";\nimport type {\n AddChangeLogItemAction,\n AddModuleAction,\n AddOperationAction,\n AddOperationErrorAction,\n AddOperationExampleAction,\n AddStateExampleAction,\n DeleteChangeLogItemAction,\n DeleteModuleAction,\n DeleteOperationAction,\n DeleteOperationErrorAction,\n DeleteOperationExampleAction,\n DeleteStateExampleAction,\n DocumentModelHeaderOperations,\n DocumentModelModuleOperations,\n DocumentModelOperationErrorOperations,\n DocumentModelOperationExampleOperations,\n DocumentModelOperationOperations,\n DocumentModelPHState,\n DocumentModelStateOperations,\n DocumentModelVersioningOperations,\n MoveOperationAction,\n OperationSpecification,\n ReleaseNewVersionAction,\n ReorderChangeLogItemsAction,\n ReorderModuleOperationsAction,\n ReorderModulesAction,\n ReorderOperationErrorsAction,\n ReorderOperationExamplesAction,\n ReorderStateExamplesAction,\n ScopeState,\n SetAuthorNameAction,\n SetAuthorWebsiteAction,\n SetInitialStateAction,\n SetModelDescriptionAction,\n SetModelExtensionAction,\n SetModelIdAction,\n SetModelNameAction,\n SetModuleDescriptionAction,\n SetModuleNameAction,\n SetOperationDescriptionAction,\n SetOperationErrorCodeAction,\n SetOperationErrorDescriptionAction,\n SetOperationErrorNameAction,\n SetOperationErrorTemplateAction,\n SetOperationNameAction,\n SetOperationReducerAction,\n SetOperationSchemaAction,\n SetOperationScopeAction,\n SetOperationTemplateAction,\n SetStateSchemaAction,\n StateReducer,\n UpdateChangeLogItemAction,\n UpdateOperationExampleAction,\n UpdateStateExampleAction,\n} from \"./types.js\";\nimport {\n assertModuleIdUnique,\n assertOperationErrorIdUnique,\n assertOperationExampleIdUnique,\n assertOperationIdUnique,\n findModuleOrThrow,\n findOperationErrorOrThrow,\n findOperationExampleOrThrow,\n findOperationOrThrow,\n validateOperationName,\n} from \"./validation.js\";\n\n/**\n * Reorder `items` by the position of their id in `order`. Ids not listed in\n * `order` keep their relative position after the listed ones. Throws if `order`\n * references an id that isn't present, so a stale or mistyped id fails loudly\n * instead of silently producing an arbitrary order.\n */\nfunction orderBy<TItem extends { id: string }>(\n items: TItem[],\n order: string[],\n): TItem[] {\n const ids = new Set(items.map((item) => item.id));\n for (const id of order) {\n if (!ids.has(id)) {\n throw new Error(`Cannot reorder: unknown id \"${id}\"`);\n }\n }\n const rank = new Map(order.map((id, index) => [id, index]));\n return items\n .map((item, index) => ({ item, index }))\n .sort((a, b) => {\n const ra = rank.get(a.item.id) ?? Number.MAX_SAFE_INTEGER;\n const rb = rank.get(b.item.id) ?? Number.MAX_SAFE_INTEGER;\n return ra - rb || a.index - b.index;\n })\n .map(({ item }) => item);\n}\n\nexport const documentModelHeaderReducer: DocumentModelHeaderOperations = {\n setModelNameOperation(state, action) {\n state.name = action.input.name;\n },\n\n setModelIdOperation(state, action) {\n state.id = action.input.id;\n },\n\n setModelExtensionOperation(state, action) {\n state.extension = action.input.extension;\n },\n\n setModelDescriptionOperation(state, action) {\n state.description = action.input.description;\n },\n\n setAuthorNameOperation(state, action) {\n state.author = state.author || { name: \"\", website: null };\n state.author.name = action.input.authorName;\n },\n\n setAuthorWebsiteOperation(state, action) {\n state.author = state.author || { name: \"\", website: null };\n state.author.website = action.input.authorWebsite;\n },\n};\nexport const documentModelModuleReducer: DocumentModelModuleOperations = {\n addModuleOperation(state, action) {\n assertModuleIdUnique(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || \"\",\n operations: [],\n });\n },\n\n setModuleNameOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.id);\n targetModule.name = action.input.name || \"\";\n },\n\n setModuleDescriptionOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.id);\n targetModule.description = action.input.description || \"\";\n },\n\n deleteModuleOperation(state, action) {\n findModuleOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules = latestSpec.modules.filter(\n (m) => m.id != action.input.id,\n );\n },\n\n reorderModulesOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n latestSpec.modules = orderBy(latestSpec.modules, action.input.order);\n },\n};\nexport const documentModelOperationErrorReducer: DocumentModelOperationErrorOperations =\n {\n addOperationErrorOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n assertOperationErrorIdUnique(state, action.input.id);\n targetOp.errors.push({\n id: action.input.id,\n name: action.input.errorName || \"\",\n code: action.input.errorCode || \"\",\n description: action.input.errorDescription || \"\",\n template: action.input.errorTemplate || \"\",\n });\n },\n\n setOperationErrorCodeOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.code = action.input.errorCode || \"\";\n },\n\n setOperationErrorNameOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.name = action.input.errorName || \"\";\n },\n\n setOperationErrorDescriptionOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.description = action.input.errorDescription || \"\";\n },\n\n setOperationErrorTemplateOperation(state, action) {\n const error = findOperationErrorOrThrow(state, action.input.id);\n error.template = action.input.errorTemplate || \"\";\n },\n\n deleteOperationErrorOperation(state, action) {\n // Tolerate duplicate ids here: the filter removes every copy, so delete\n // is the recovery path for a document that already holds duplicates.\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec.modules.some((mod) =>\n mod.operations.some((op) =>\n op.errors.some((e) => e.id === action.input.id),\n ),\n );\n if (!exists) {\n throw new Error(\n `Operation error \"${action.input.id}\" not found in the latest specification`,\n );\n }\n for (const mod of latestSpec.modules) {\n for (const op of mod.operations) {\n op.errors = op.errors.filter((e) => e.id != action.input.id);\n }\n }\n },\n\n reorderOperationErrorsOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n targetOp.errors = orderBy(targetOp.errors, action.input.order);\n },\n };\n\nexport const documentModelOperationExampleReducer: DocumentModelOperationExampleOperations =\n {\n addOperationExampleOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n assertOperationExampleIdUnique(state, action.input.id);\n targetOp.examples.push({\n id: action.input.id,\n value: action.input.example,\n });\n },\n\n updateOperationExampleOperation(state, action) {\n const example = findOperationExampleOrThrow(state, action.input.id);\n example.value = action.input.example;\n },\n\n deleteOperationExampleOperation(state, action) {\n // Tolerate duplicate ids here: the filter removes every copy, so delete\n // is the recovery path for a document that already holds duplicates.\n const latestSpec = state.specifications[state.specifications.length - 1];\n const exists = latestSpec.modules.some((mod) =>\n mod.operations.some((op) =>\n op.examples.some((e) => e.id === action.input.id),\n ),\n );\n if (!exists) {\n throw new Error(\n `Operation example \"${action.input.id}\" not found in the latest specification`,\n );\n }\n for (const mod of latestSpec.modules) {\n for (const op of mod.operations) {\n op.examples = op.examples.filter((e) => e.id != action.input.id);\n }\n }\n },\n\n reorderOperationExamplesOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.operationId);\n targetOp.examples = orderBy(targetOp.examples, action.input.order);\n },\n };\nexport const documentModelOperationReducer: DocumentModelOperationOperations = {\n addOperationOperation(state, action) {\n validateOperationName(action.input.name, state);\n assertOperationIdUnique(state, action.input.id);\n const targetModule = findModuleOrThrow(state, action.input.moduleId);\n targetModule.operations.push({\n id: action.input.id,\n name: action.input.name,\n description: action.input.description || \"\",\n schema: action.input.schema || \"\",\n template: action.input.template || action.input.description || \"\",\n reducer: action.input.reducer || \"\",\n errors: [],\n examples: [],\n scope: action.input.scope || \"global\",\n });\n },\n\n setOperationNameOperation(state, action) {\n if (action.input.name) {\n validateOperationName(action.input.name, state, action.input.id);\n }\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.name = action.input.name || \"\";\n },\n\n setOperationScopeOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n const allowedScopes = Object.keys(latestSpec.state);\n if (action.input.scope && !allowedScopes.includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n targetOp.scope = action.input.scope || \"global\";\n },\n\n setOperationSchemaOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.schema = action.input.schema || \"\";\n },\n\n setOperationDescriptionOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.description = action.input.description || \"\";\n },\n\n setOperationTemplateOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.template = action.input.template || \"\";\n },\n\n setOperationReducerOperation(state, action) {\n const targetOp = findOperationOrThrow(state, action.input.id);\n targetOp.reducer = action.input.reducer || \"\";\n },\n\n moveOperationOperation(state, action) {\n // Validate fully before mutating: resolve the destination module and the\n // operation to move first, so a missing/ambiguous target aborts the move\n // without having already removed the operation from its source module.\n const targetModule = findModuleOrThrow(state, action.input.newModuleId);\n const latestSpec = state.specifications[state.specifications.length - 1];\n\n const matches = latestSpec.modules.flatMap((mod) =>\n mod.operations.filter((op) => op.id === action.input.operationId),\n );\n if (matches.length === 0) {\n throw new Error(\n `Operation \"${action.input.operationId}\" not found in the latest specification`,\n );\n }\n if (matches.length > 1) {\n throw new Error(\n `Operation \"${action.input.operationId}\" is duplicated in the latest specification`,\n );\n }\n const moved = matches[0];\n\n for (const mod of latestSpec.modules) {\n mod.operations = mod.operations.filter(\n (op) => op.id !== action.input.operationId,\n );\n }\n targetModule.operations.push(moved);\n },\n\n deleteOperationOperation(state, action) {\n findOperationOrThrow(state, action.input.id);\n const latestSpec = state.specifications[state.specifications.length - 1];\n for (const mod of latestSpec.modules) {\n mod.operations = mod.operations.filter(\n (operation) => operation.id != action.input.id,\n );\n }\n },\n\n reorderModuleOperationsOperation(state, action) {\n const targetModule = findModuleOrThrow(state, action.input.moduleId);\n targetModule.operations = orderBy(\n targetModule.operations,\n action.input.order,\n );\n },\n};\nexport const documentModelStateSchemaReducer: DocumentModelStateOperations = {\n setStateSchemaOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].schema =\n action.input.schema;\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n setInitialStateOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].initialValue =\n action.input.initialValue;\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n addStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (Object.keys(latestSpec.state).includes(action.input.scope)) {\n latestSpec.state[action.input.scope as keyof ScopeState].examples.push({\n id: action.input.id,\n value: action.input.example,\n });\n } else {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n },\n\n updateStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const examples =\n latestSpec.state[action.input.scope as keyof ScopeState].examples;\n\n const example = examples.find((e) => e.id == action.input.id);\n if (!example) {\n throw new Error(\n `State example \"${action.input.id}\" not found in scope \"${action.input.scope}\"`,\n );\n }\n example.value = action.input.newExample;\n },\n\n deleteStateExampleOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const scopeState = latestSpec.state[action.input.scope as keyof ScopeState];\n if (!scopeState.examples.some((e) => e.id == action.input.id)) {\n throw new Error(\n `State example \"${action.input.id}\" not found in scope \"${action.input.scope}\"`,\n );\n }\n scopeState.examples = scopeState.examples.filter(\n (e) => e.id != action.input.id,\n );\n },\n\n reorderStateExamplesOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n if (!Object.keys(latestSpec.state).includes(action.input.scope)) {\n throw new Error(`Invalid scope: ${action.input.scope}`);\n }\n const scopeState = latestSpec.state[action.input.scope as keyof ScopeState];\n scopeState.examples = orderBy(scopeState.examples, action.input.order);\n },\n};\n\nexport const documentModelVersioningReducer: DocumentModelVersioningOperations =\n {\n addChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"addChangeLogItemOperation\" not yet implemented',\n );\n },\n\n updateChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"updateChangeLogItemOperation\" not yet implemented',\n );\n },\n\n deleteChangeLogItemOperation(state, action) {\n throw new Error(\n 'Reducer \"deleteChangeLogItemOperation\" not yet implemented',\n );\n },\n\n reorderChangeLogItemsOperation(state, action) {\n throw new Error(\n 'Reducer \"reorderChangeLogItemsOperation\" not yet implemented',\n );\n },\n\n releaseNewVersionOperation(state, action) {\n const latestSpec = state.specifications[state.specifications.length - 1];\n\n const copiedModules = latestSpec.modules.map((module) => ({\n ...module,\n operations: module.operations.map((op) => ({\n ...op,\n errors: op.errors.map((err) => ({ ...err })),\n examples: op.examples.map((ex) => ({ ...ex })),\n })),\n }));\n\n const copiedState = {\n global: {\n ...latestSpec.state.global,\n examples: latestSpec.state.global.examples.map((ex) => ({ ...ex })),\n },\n local: {\n ...latestSpec.state.local,\n examples: latestSpec.state.local.examples.map((ex) => ({ ...ex })),\n },\n };\n\n const newSpec = {\n version: latestSpec.version + 1,\n changeLog: [],\n state: copiedState,\n modules: copiedModules,\n };\n\n state.specifications.push(newSpec);\n },\n };\n\nexport const documentModelStateReducer: StateReducer<DocumentModelPHState> = (\n state,\n action,\n) => {\n if (isDocumentAction(action)) {\n return state;\n }\n\n switch (action.type) {\n case \"SET_MODEL_NAME\":\n SetModelNameInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelNameOperation(\n state.global,\n action as SetModelNameAction,\n );\n break;\n\n case \"SET_MODEL_ID\":\n SetModelIdInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelIdOperation(\n state.global,\n action as SetModelIdAction,\n );\n break;\n\n case \"SET_MODEL_EXTENSION\":\n SetModelExtensionInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelExtensionOperation(\n state.global,\n action as SetModelExtensionAction,\n );\n break;\n\n case \"SET_MODEL_DESCRIPTION\":\n SetModelDescriptionInputSchema().parse(action.input);\n documentModelHeaderReducer.setModelDescriptionOperation(\n state.global,\n action as SetModelDescriptionAction,\n );\n break;\n\n case \"SET_AUTHOR_NAME\":\n SetAuthorNameInputSchema().parse(action.input);\n documentModelHeaderReducer.setAuthorNameOperation(\n state.global,\n action as SetAuthorNameAction,\n );\n break;\n\n case \"SET_AUTHOR_WEBSITE\":\n SetAuthorWebsiteInputSchema().parse(action.input);\n documentModelHeaderReducer.setAuthorWebsiteOperation(\n state.global,\n action as SetAuthorWebsiteAction,\n );\n break;\n\n case \"ADD_CHANGE_LOG_ITEM\":\n AddChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.addChangeLogItemOperation(\n state.global,\n action as AddChangeLogItemAction,\n );\n break;\n\n case \"UPDATE_CHANGE_LOG_ITEM\":\n UpdateChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.updateChangeLogItemOperation(\n state.global,\n action as UpdateChangeLogItemAction,\n );\n break;\n\n case \"DELETE_CHANGE_LOG_ITEM\":\n DeleteChangeLogItemInputSchema().parse(action.input);\n documentModelVersioningReducer.deleteChangeLogItemOperation(\n state.global,\n action as DeleteChangeLogItemAction,\n );\n break;\n\n case \"REORDER_CHANGE_LOG_ITEMS\":\n ReorderChangeLogItemsInputSchema().parse(action.input);\n documentModelVersioningReducer.reorderChangeLogItemsOperation(\n state.global,\n action as ReorderChangeLogItemsAction,\n );\n break;\n\n case \"RELEASE_NEW_VERSION\":\n if (Object.keys(action.input as object).length > 0)\n throw new Error(\"Expected empty input for action RELEASE_NEW_VERSION\");\n documentModelVersioningReducer.releaseNewVersionOperation(\n state.global,\n action as ReleaseNewVersionAction,\n );\n break;\n\n case \"ADD_MODULE\":\n AddModuleInputSchema().parse(action.input);\n documentModelModuleReducer.addModuleOperation(\n state.global,\n action as AddModuleAction,\n );\n break;\n\n case \"SET_MODULE_NAME\":\n SetModuleNameInputSchema().parse(action.input);\n documentModelModuleReducer.setModuleNameOperation(\n state.global,\n action as SetModuleNameAction,\n );\n break;\n\n case \"SET_MODULE_DESCRIPTION\":\n SetModuleDescriptionInputSchema().parse(action.input);\n documentModelModuleReducer.setModuleDescriptionOperation(\n state.global,\n action as SetModuleDescriptionAction,\n );\n break;\n\n case \"DELETE_MODULE\":\n DeleteModuleInputSchema().parse(action.input);\n documentModelModuleReducer.deleteModuleOperation(\n state.global,\n action as DeleteModuleAction,\n );\n break;\n\n case \"REORDER_MODULES\":\n ReorderModulesInputSchema().parse(action.input);\n documentModelModuleReducer.reorderModulesOperation(\n state.global,\n action as ReorderModulesAction,\n );\n break;\n\n case \"ADD_OPERATION_ERROR\":\n AddOperationErrorInputSchema().parse(action.input);\n documentModelOperationErrorReducer.addOperationErrorOperation(\n state.global,\n action as AddOperationErrorAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_CODE\":\n SetOperationErrorCodeInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorCodeOperation(\n state.global,\n action as SetOperationErrorCodeAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_NAME\":\n SetOperationErrorNameInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorNameOperation(\n state.global,\n action as SetOperationErrorNameAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_DESCRIPTION\":\n SetOperationErrorDescriptionInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorDescriptionOperation(\n state.global,\n action as SetOperationErrorDescriptionAction,\n );\n break;\n\n case \"SET_OPERATION_ERROR_TEMPLATE\":\n SetOperationErrorTemplateInputSchema().parse(action.input);\n documentModelOperationErrorReducer.setOperationErrorTemplateOperation(\n state.global,\n action as SetOperationErrorTemplateAction,\n );\n break;\n\n case \"DELETE_OPERATION_ERROR\":\n DeleteOperationErrorInputSchema().parse(action.input);\n documentModelOperationErrorReducer.deleteOperationErrorOperation(\n state.global,\n action as DeleteOperationErrorAction,\n );\n break;\n\n case \"REORDER_OPERATION_ERRORS\":\n ReorderOperationErrorsInputSchema().parse(action.input);\n documentModelOperationErrorReducer.reorderOperationErrorsOperation(\n state.global,\n action as ReorderOperationErrorsAction,\n );\n break;\n\n case \"ADD_OPERATION_EXAMPLE\":\n AddOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.addOperationExampleOperation(\n state.global,\n action as AddOperationExampleAction,\n );\n break;\n\n case \"UPDATE_OPERATION_EXAMPLE\":\n UpdateOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.updateOperationExampleOperation(\n state.global,\n action as UpdateOperationExampleAction,\n );\n break;\n\n case \"DELETE_OPERATION_EXAMPLE\":\n DeleteOperationExampleInputSchema().parse(action.input);\n documentModelOperationExampleReducer.deleteOperationExampleOperation(\n state.global,\n action as DeleteOperationExampleAction,\n );\n break;\n\n case \"REORDER_OPERATION_EXAMPLES\":\n ReorderOperationExamplesInputSchema().parse(action.input);\n documentModelOperationExampleReducer.reorderOperationExamplesOperation(\n state.global,\n action as ReorderOperationExamplesAction,\n );\n break;\n\n case \"ADD_OPERATION\":\n AddOperationInputSchema().parse(action.input);\n documentModelOperationReducer.addOperationOperation(\n state.global,\n action as AddOperationAction,\n );\n break;\n\n case \"SET_OPERATION_NAME\":\n SetOperationNameInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationNameOperation(\n state.global,\n action as SetOperationNameAction,\n );\n break;\n\n case \"SET_OPERATION_SCOPE\":\n SetOperationScopeInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationScopeOperation(\n state.global,\n action as SetOperationScopeAction,\n );\n break;\n\n case \"SET_OPERATION_SCHEMA\":\n SetOperationSchemaInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationSchemaOperation(\n state.global,\n action as SetOperationSchemaAction,\n );\n break;\n\n case \"SET_OPERATION_DESCRIPTION\":\n SetOperationDescriptionInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationDescriptionOperation(\n state.global,\n action as SetOperationDescriptionAction,\n );\n break;\n\n case \"SET_OPERATION_TEMPLATE\":\n SetOperationTemplateInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationTemplateOperation(\n state.global,\n action as SetOperationTemplateAction,\n );\n break;\n\n case \"SET_OPERATION_REDUCER\":\n SetOperationReducerInputSchema().parse(action.input);\n documentModelOperationReducer.setOperationReducerOperation(\n state.global,\n action as SetOperationReducerAction,\n );\n break;\n\n case \"MOVE_OPERATION\":\n MoveOperationInputSchema().parse(action.input);\n documentModelOperationReducer.moveOperationOperation(\n state.global,\n action as MoveOperationAction,\n );\n break;\n\n case \"DELETE_OPERATION\":\n DeleteOperationInputSchema().parse(action.input);\n documentModelOperationReducer.deleteOperationOperation(\n state.global,\n action as DeleteOperationAction,\n );\n break;\n\n case \"REORDER_MODULE_OPERATIONS\":\n ReorderModuleOperationsInputSchema().parse(action.input);\n documentModelOperationReducer.reorderModuleOperationsOperation(\n state.global,\n action as ReorderModuleOperationsAction,\n );\n break;\n\n case \"SET_STATE_SCHEMA\":\n SetStateSchemaInputSchema().parse(action.input);\n documentModelStateSchemaReducer.setStateSchemaOperation(\n state.global,\n action as SetStateSchemaAction,\n );\n break;\n\n case \"SET_INITIAL_STATE\":\n SetInitialStateInputSchema().parse(action.input);\n documentModelStateSchemaReducer.setInitialStateOperation(\n state.global,\n action as SetInitialStateAction,\n );\n break;\n\n case \"ADD_STATE_EXAMPLE\":\n AddStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.addStateExampleOperation(\n state.global,\n action as AddStateExampleAction,\n );\n break;\n\n case \"UPDATE_STATE_EXAMPLE\":\n UpdateStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.updateStateExampleOperation(\n state.global,\n action as UpdateStateExampleAction,\n );\n break;\n\n case \"DELETE_STATE_EXAMPLE\":\n DeleteStateExampleInputSchema().parse(action.input);\n documentModelStateSchemaReducer.deleteStateExampleOperation(\n state.global,\n action as DeleteStateExampleAction,\n );\n break;\n\n case \"REORDER_STATE_EXAMPLES\":\n ReorderStateExamplesInputSchema().parse(action.input);\n documentModelStateSchemaReducer.reorderStateExamplesOperation(\n state.global,\n action as ReorderStateExamplesAction,\n );\n break;\n\n default:\n return state;\n }\n};\n\nexport const documentModelReducer = createReducer<DocumentModelPHState>(\n documentModelStateReducer,\n);\n","import type { Action } from \"./actions.js\";\nimport { resolveSnapshotAuth } from \"./auth.js\";\nimport type { PHDocument } from \"./documents.js\";\nimport { DowngradeNotSupportedError } from \"./errors.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type { DeleteDocumentAction, UpgradeDocumentAction } from \"./types.js\";\n\n/** Upgrade reducer transforms a document from one version to another */\nexport type UpgradeReducer<\n TFrom extends PHBaseState,\n TTo extends PHBaseState,\n> = (document: PHDocument<TFrom>, action: Action) => PHDocument<TTo>;\ntype ModelVersion = number;\n\n/** Metadata about a version transition */\nexport type UpgradeTransition = {\n toVersion: ModelVersion;\n upgradeReducer: UpgradeReducer<any, any>;\n description?: string;\n};\n\ntype TupleMember<T extends readonly unknown[]> = T[number];\n\n/** Manifest declaring all supported versions and upgrade paths */\nexport type UpgradeManifest<TVersions extends readonly number[]> = {\n documentType: string;\n // union of all versions, e.g. 1 | 2 | 3 for [1, 2, 3]\n latestVersion: TupleMember<TVersions>;\n // the tuple itself, e.g. [1, 2, 3]\n supportedVersions: TVersions;\n // mapped over each version in the tuple\n upgrades: {\n // keys: \"v2\" | \"v3\" | ... (no \"v1\")\n [V in Exclude<TupleMember<TVersions>, 1> as `v${V}`]: UpgradeTransition;\n };\n};\n\n/**\n * Canonical document-model version normalization: documents stamped with 0\n * or nothing at all predate versioning and are treated as version 1, the\n * same version the registry assigns unversioned modules. Every consumer\n * that resolves a module or compares versions must use this rule; resolving\n * 0 to \"latest\" instead re-pins a legacy document's history to whichever\n * module happens to be newest.\n */\nexport function normalizeDocumentModelVersion(\n version: number | undefined | null,\n): number {\n return version && version > 0 ? version : 1;\n}\n\nfunction applyInitialState(\n document: PHDocument,\n action: UpgradeDocumentAction,\n): void {\n const input = action.input as {\n initialState?: PHDocument[\"state\"];\n state?: PHDocument[\"state\"];\n };\n\n const newState = input.initialState || input.state;\n if (newState) {\n // snapshots serialized before PHAuthState had a version carry auth: {}\n const merged = backfillAuthState({ ...document.state, ...newState });\n // The snapshot is authorized as a document-scope write, so it does not get\n // to install or replace a policy on its own terms.\n merged.auth = resolveSnapshotAuth(\n document.header.id,\n document.header.documentType,\n backfillAuthState({ ...document.state }).auth,\n merged.auth,\n );\n document.state = merged;\n document.initialState = document.state;\n }\n}\n\n/**\n * Applies an UPGRADE_DOCUMENT action to a document.\n * Handles all upgrade scenarios including initial upgrades, no-ops, and multi-step upgrades.\n *\n * Behavior based on fromVersion/toVersion:\n * - fromVersion === toVersion (and fromVersion > 0): No-op - return unchanged document\n * - fromVersion > toVersion: Throw DowngradeNotSupportedError\n * - All other cases: Apply upgradePath transitions (if provided), then apply initialState, set version\n */\nexport function applyUpgradeDocumentAction(\n document: PHDocument,\n action: UpgradeDocumentAction,\n upgradePath?: UpgradeTransition[],\n): PHDocument {\n const fromVersion = action.input.fromVersion;\n const toVersion = action.input.toVersion;\n\n if (fromVersion === toVersion && fromVersion > 0) {\n return document;\n }\n\n if (fromVersion > toVersion) {\n throw new DowngradeNotSupportedError(\n document.header.documentType,\n fromVersion,\n toVersion,\n );\n }\n\n if (upgradePath) {\n for (const transition of upgradePath) {\n document = transition.upgradeReducer(document, action);\n }\n }\n\n applyInitialState(document, action);\n\n document.state.document = {\n ...document.state.document,\n version: toVersion,\n };\n return document;\n}\n\n/**\n * Applies a DELETE_DOCUMENT action to a document.\n * Marks the document as deleted in the document scope state.\n */\nexport function applyDeleteDocumentAction(\n document: PHDocument,\n action: DeleteDocumentAction,\n): PHDocument {\n const deletedAt = action.timestampUtcMs || new Date().toISOString();\n\n document.state = {\n ...document.state,\n document: {\n ...document.state.document,\n isDeleted: true,\n deletedAtUtcIso: deletedAt,\n },\n };\n\n return document;\n}\n\n/**\n * Computes the ordered list of upgrade transitions needed to move from\n * fromVersion to toVersion using the provided manifest.\n * Walks keys v(fromVersion+1)..v(toVersion) and throws a descriptive Error\n * if the manifest is absent or any step is missing.\n */\nexport function computeUpgradeTransitions(\n manifest: UpgradeManifest<readonly number[]> | undefined,\n fromVersion: number,\n toVersion: number,\n): UpgradeTransition[] {\n if (!manifest) {\n throw new Error(\n `No upgrade manifest provided for transition from version ${fromVersion} to ${toVersion}`,\n );\n }\n\n const transitions: UpgradeTransition[] = [];\n const upgrades = manifest.upgrades as Record<string, UpgradeTransition>;\n\n for (let v = fromVersion + 1; v <= toVersion; v++) {\n const key = `v${v}`;\n const transition = upgrades[key];\n if (!transition) {\n throw new Error(\n `Upgrade manifest for \"${manifest.documentType}\" is missing step \"${key}\" (from v${fromVersion} to v${toVersion}). Available keys: ${Object.keys(upgrades).join(\", \")}`,\n );\n }\n transitions.push(transition);\n }\n\n return transitions;\n}\n","import { isDenied } from \"./denied.js\";\nimport {\n appendWithoutApplying,\n baseReducerVersion,\n hashDocumentStateForScope,\n replayDocument,\n updateHeaderRevision,\n type PHDocument,\n type PHDocumentHeader,\n} from \"./documents.js\";\nimport {\n HashMismatchError,\n UnsupportedDocumentModelVersionError,\n} from \"./errors.js\";\nimport type { DocumentOperations, Operation } from \"./operations.js\";\nimport { backfillAuthState } from \"./state.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n Reducer,\n ReplayDocumentOptions,\n SignalDispatch,\n UpgradeDocumentAction,\n} from \"./types.js\";\nimport {\n applyDeleteDocumentAction,\n applyUpgradeDocumentAction,\n computeUpgradeTransitions,\n type UpgradeManifest,\n} from \"./upgrades.js\";\n\nexport type VersionedReducers = Record<number, Reducer<PHBaseState>>;\n\nexport type VersionedReplayConfig = {\n reducers: VersionedReducers;\n upgradeManifest?: UpgradeManifest<readonly number[]>;\n};\n\nfunction highestReducerVersion(reducers: VersionedReducers): number {\n const keys = Object.keys(reducers).map(Number);\n if (keys.length === 0) {\n throw new Error(\"VersionedReplayConfig.reducers must not be empty\");\n }\n return Math.max(...keys);\n}\n\n/**\n * Version-aware document replay. Replays a versioned document through per-version\n * reducers, applying upgrade transitions at segment boundaries.\n *\n * Algorithm (D5):\n * a. Build spine from operations[\"document\"]. Empty spine or no upgrades → legacy fallback.\n * b. Collect UPGRADE_DOCUMENT ops from the spine.\n * c. Seed state from the creation upgrade (fromVersion===0). Missing seed with validated\n * upgrades throws; otherwise falls back to legacy.\n * d. Identify validated upgrades (fromVersion > 0, version increases). Compute per-scope\n * boundaries using revision snapshot (preferred) or timestamp fallback.\n * e. Loop over version segments, replaying each scope's ops through the matching reducer,\n * then applying the upgrade transition before the next segment.\n * f. Set header.revision[\"document\"], verify per-scope hashes against state at op-time\n * (not post-upgrade state) when checkHashes is false, and map timestamps from input.\n *\n * operations must include ALL scopes (document scope is NOT stripped).\n * reuseOperationResultingState is ignored by this function — zip operations never carry\n * resultingState.\n */\nexport function replayDocumentVersioned<TState extends PHBaseState>(\n initialState: TState,\n operations: DocumentOperations,\n config: VersionedReplayConfig,\n header: PHDocumentHeader,\n dispatch?: SignalDispatch,\n options?: ReplayDocumentOptions,\n): PHDocument<TState> {\n const { checkHashes = true, skipIndexValidation } = options || {};\n\n const protocolVersion = baseReducerVersion(header);\n\n const spine = (operations[\"document\"] ?? [])\n .slice()\n .sort((a, b) => a.index - b.index);\n\n const upgrades = spine.filter((op) => op.action.type === \"UPGRADE_DOCUMENT\");\n\n const legacyFallback = (): PHDocument<TState> => {\n // document-scope ops are applied by dedicated platform handlers; auth ops replay here\n const replayOps = Object.fromEntries(\n Object.entries(operations).filter(([s]) => s !== \"document\"),\n ) as DocumentOperations;\n const latestVersion = highestReducerVersion(config.reducers);\n const reducer = config.reducers[\n latestVersion\n ] as unknown as Reducer<TState>;\n const result = replayDocument(\n initialState,\n replayOps,\n reducer,\n header,\n dispatch,\n {},\n options,\n );\n return { ...result, operations };\n };\n\n if (spine.length === 0 || upgrades.length === 0) {\n return legacyFallback();\n }\n\n const seedOp = upgrades[0];\n if (!seedOp) {\n return legacyFallback();\n }\n const seedAction = seedOp.action as UpgradeDocumentAction;\n if (seedAction.input.fromVersion !== 0) {\n return legacyFallback();\n }\n\n const seedInput = seedAction.input as {\n initialState?: TState;\n state?: TState;\n };\n const seedState = (seedInput.initialState ?? seedInput.state) as\n | TState\n | undefined;\n\n if (!seedState) {\n const validatedUpgradeCount = upgrades.filter((op) => {\n const a = op.action as UpgradeDocumentAction;\n return a.input.fromVersion > 0 && a.input.fromVersion < a.input.toVersion;\n }).length;\n\n if (validatedUpgradeCount > 0) {\n throw new Error(\n `Cannot reconstruct versioned history: the creation UPGRADE_DOCUMENT operation ` +\n `carries no initialState, but the document has ${validatedUpgradeCount} version-changing ` +\n `upgrade(s) recorded after creation. Pre-migration states cannot be reconstructed without the seeded initialState.`,\n );\n }\n return legacyFallback();\n }\n\n const startVersion = seedAction.input.toVersion;\n\n const validatedUpgrades = upgrades.filter((op) => {\n const a = op.action as UpgradeDocumentAction;\n return a.input.fromVersion > 0 && a.input.fromVersion < a.input.toVersion;\n });\n\n // the base reducer applies auth ops identically in every version segment\n const replayScopes = Object.keys(operations).filter((s) => s !== \"document\");\n const scopeOps: Record<string, Operation[]> = {};\n for (const s of replayScopes) {\n scopeOps[s] = (operations[s] ?? [])\n .slice()\n .sort((a, b) => a.index - b.index);\n }\n\n const boundaries: Array<Record<string, number>> = validatedUpgrades.map(\n (upgradeOp) => {\n const upgradeAction = upgradeOp.action as UpgradeDocumentAction;\n const revisionSnapshot = upgradeAction.input.revision;\n const upgradeTimestamp = upgradeOp.timestampUtcMs;\n\n const boundary: Record<string, number> = {};\n for (const s of replayScopes) {\n const ops = scopeOps[s] ?? [];\n if (revisionSnapshot !== undefined) {\n const rev = revisionSnapshot[s] ?? 0;\n let b = 0;\n for (let j = 0; j < ops.length; j++) {\n if ((ops[j]?.index ?? 0) < rev) {\n b = j + 1;\n }\n }\n boundary[s] = b;\n } else {\n let b = ops.length;\n for (let j = 0; j < ops.length; j++) {\n const opTs = ops[j]?.timestampUtcMs ?? \"\";\n if (opTs >= upgradeTimestamp) {\n b = j;\n break;\n }\n }\n boundary[s] = b;\n }\n }\n return boundary;\n },\n );\n\n for (let i = 1; i < boundaries.length; i++) {\n for (const s of replayScopes) {\n const prev = boundaries[i - 1]?.[s] ?? 0;\n const curr = boundaries[i]?.[s] ?? 0;\n if (boundaries[i]) {\n boundaries[i][s] = Math.max(prev, curr);\n }\n }\n }\n\n const allScopes = new Set([...Object.keys(operations), \"global\", \"local\"]);\n const initialOperations: DocumentOperations = {};\n for (const s of allScopes) {\n initialOperations[s] = [];\n }\n\n const backfilledSeed = backfillAuthState(seedState);\n let document: PHDocument<TState> = {\n header,\n state: backfilledSeed,\n initialState: backfilledSeed,\n operations: initialOperations,\n clipboard: [],\n };\n\n let currentVersion = startVersion;\n\n const segmentEndHashPerScope = new Map<string, string>();\n\n for (let k = 0; k <= validatedUpgrades.length; k++) {\n const reducer = config.reducers[currentVersion] as unknown as\n | Reducer<TState>\n | undefined;\n if (!reducer) {\n throw new UnsupportedDocumentModelVersionError(\n header.documentType,\n currentVersion,\n Object.keys(config.reducers)\n .map(Number)\n .sort((a, b) => a - b),\n );\n }\n\n for (const s of replayScopes) {\n const ops = scopeOps[s] ?? [];\n const segStart = k === 0 ? 0 : (boundaries[k - 1]?.[s] ?? 0);\n const segEnd =\n k < validatedUpgrades.length\n ? (boundaries[k]?.[s] ?? ops.length)\n : ops.length;\n const segOps = ops.slice(segStart, segEnd);\n\n for (const op of segOps) {\n // A denied operation holds its position without contributing state, the\n // same way the reactor's own rebuild treats it. It is still recorded, or\n // the operation after it fails index validation and the timestamp remap\n // below shifts onto the wrong rows.\n if (isDenied(op)) {\n document = updateHeaderRevision(\n appendWithoutApplying(document, op, s),\n s,\n op.timestampUtcMs,\n ) as PHDocument<TState>;\n } else {\n document = reducer(document, op.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: { operation: op },\n protocolVersion,\n }) as PHDocument<TState>;\n }\n segmentEndHashPerScope.set(s, hashDocumentStateForScope(document, s));\n }\n }\n\n const prevUpgradeSpineIdx =\n k === 0 ? -1 : spine.indexOf(validatedUpgrades[k - 1]!);\n const nextUpgradeSpineIdx =\n k < validatedUpgrades.length\n ? spine.indexOf(validatedUpgrades[k]!)\n : spine.length;\n\n for (let si = prevUpgradeSpineIdx + 1; si < nextUpgradeSpineIdx; si++) {\n const spineOp = spine[si];\n if (!spineOp) continue;\n const spineActionType = spineOp.action.type;\n if (\n spineActionType === \"CREATE_DOCUMENT\" ||\n spineActionType === \"UPGRADE_DOCUMENT\"\n ) {\n continue;\n }\n // As above: refused, so it occupies its position and changes nothing.\n if (isDenied(spineOp)) {\n continue;\n }\n if (spineActionType === \"DELETE_DOCUMENT\") {\n document = applyDeleteDocumentAction(\n document,\n spineOp.action as Parameters<typeof applyDeleteDocumentAction>[1],\n ) as PHDocument<TState>;\n } else {\n document = reducer(document, spineOp.action, dispatch, {\n ignoreSkipOperations: true,\n checkHashes,\n skipIndexValidation,\n replayOptions: { operation: spineOp },\n protocolVersion,\n }) as PHDocument<TState>;\n }\n }\n\n if (k < validatedUpgrades.length) {\n const upgradeOp = validatedUpgrades[k]!;\n const upgradeAction = upgradeOp.action as UpgradeDocumentAction;\n const fromVer = upgradeAction.input.fromVersion;\n const toVer = upgradeAction.input.toVersion;\n\n const transitions = computeUpgradeTransitions(\n config.upgradeManifest,\n fromVer,\n toVer,\n );\n\n document = applyUpgradeDocumentAction(\n document,\n upgradeAction,\n transitions,\n ) as PHDocument<TState>;\n\n currentVersion = toVer;\n }\n }\n\n const lastSpineOp = spine.at(-1);\n if (lastSpineOp !== undefined && validatedUpgrades.length > 0) {\n document = {\n ...document,\n header: {\n ...document.header,\n revision: {\n ...document.header.revision,\n document: lastSpineOp.index + 1,\n },\n },\n };\n }\n\n if (!checkHashes) {\n const allReplayedOps = replayScopes.flatMap((s) => scopeOps[s] ?? []);\n for (const scope of Object.keys(document.state)) {\n const capturedHash = segmentEndHashPerScope.get(scope);\n const scopeHash =\n capturedHash !== undefined\n ? capturedHash\n : hashDocumentStateForScope(document, scope);\n for (let i = allReplayedOps.length - 1; i >= 0; i--) {\n const operation = allReplayedOps[i];\n if (!operation || operation.action.scope !== scope) {\n continue;\n }\n if (operation.hash !== scopeHash) {\n throw new HashMismatchError(scope, document, operation);\n } else {\n break;\n }\n }\n }\n }\n\n const allResultScopes = new Set([\n ...Object.keys(document.operations),\n ...Object.keys(operations),\n \"global\",\n \"local\",\n ]);\n allResultScopes.delete(\"document\");\n const resultOperations: DocumentOperations = {};\n for (const s of allResultScopes) {\n const scopeResultOps = document.operations[s] ?? [];\n resultOperations[s] = scopeResultOps.map((op, index) => ({\n ...op,\n timestamp: operations[s]?.[index]?.timestampUtcMs ?? op.timestampUtcMs,\n }));\n }\n\n const lastModified = header.lastModifiedAtUtcIso\n ? header.lastModifiedAtUtcIso\n : Object.values(resultOperations).reduce((acc, curr) => {\n if (!curr) return acc;\n const last = curr.at(-1);\n if (last && last.timestampUtcMs > acc) {\n return last.timestampUtcMs;\n }\n return acc;\n }, document.header.lastModifiedAtUtcIso);\n\n return {\n ...document,\n header: {\n ...document.header,\n lastModifiedAtUtcIso: lastModified,\n },\n operations: { ...operations, ...resultOperations },\n } as PHDocument<TState>;\n}\n","import {\n strFromU8,\n strToU8,\n unzip,\n zip,\n type Unzipped,\n type Zippable,\n} from \"fflate\";\nimport type { PHDocument, PHDocumentHeader } from \"./documents.js\";\nimport {\n filterDocumentOperationsResultingState,\n garbageCollectDocumentOperations,\n replayDocument,\n} from \"./documents.js\";\nimport { FileSystemError } from \"./errors.js\";\nimport type { DocumentOperations } from \"./operations.js\";\nimport { documentModelReducer } from \"./reducers.js\";\nimport type { PHBaseState } from \"./state.js\";\nimport type {\n DocumentModelPHState,\n FileInput,\n LoadFromInput,\n MinimalBackupData,\n Reducer,\n ReplayDocumentOptions,\n SaveToFileHandle,\n} from \"./types.js\";\nimport { validateOperations } from \"./validation.js\";\nimport {\n replayDocumentVersioned,\n type VersionedReplayConfig,\n} from \"./versioned-replay.js\";\n\nfunction zipAsync(data: Zippable): Promise<Uint8Array> {\n return new Promise((resolve, reject) => {\n zip(data, (err, out) => (err ? reject(err) : resolve(out)));\n });\n}\n\nfunction unzipAsync(data: Uint8Array): Promise<Unzipped> {\n return new Promise((resolve, reject) => {\n unzip(data, (err, out) => (err ? reject(err) : resolve(out)));\n });\n}\n\nconst BASE64_RE = /^[A-Za-z0-9+/]+={0,2}$/;\n\nfunction isLikelyBase64(s: string): boolean {\n // Base64 strings are length % 4 === 0, use only the base64 alphabet,\n // and contain no bytes >= 0x80. A raw binary string (one char per byte)\n // typically has bytes outside that alphabet.\n if (s.length === 0 || s.length % 4 !== 0) return false;\n return BASE64_RE.test(s);\n}\n\nfunction binaryStringToUint8Array(s: string): Uint8Array {\n const arr = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) arr[i] = s.charCodeAt(i) & 0xff;\n return arr;\n}\n\nfunction base64ToUint8Array(s: string): Uint8Array {\n if (typeof atob === \"function\") {\n const bin = atob(s);\n return binaryStringToUint8Array(bin);\n }\n const BufferCtor = (\n globalThis as {\n Buffer?: { from: (s: string, enc: string) => Uint8Array };\n }\n ).Buffer;\n if (!BufferCtor) {\n throw new Error(\n \"Cannot decode base64 string: neither `atob` nor `Buffer` is available in this environment\",\n );\n }\n return BufferCtor.from(s, \"base64\");\n}\n\nasync function toUint8Array(input: FileInput): Promise<Uint8Array> {\n if (input instanceof Uint8Array) return input;\n if (input instanceof ArrayBuffer) return new Uint8Array(input);\n if (typeof Blob !== \"undefined\" && input instanceof Blob) {\n return new Uint8Array(await input.arrayBuffer());\n }\n if (Array.isArray(input)) return new Uint8Array(input);\n if (typeof input === \"string\") {\n // jszip's loadAsync accepted both raw binary strings and base64 strings\n // with auto-detection. Preserve that so callers passing either keep working.\n return isLikelyBase64(input)\n ? base64ToUint8Array(input)\n : binaryStringToUint8Array(input);\n }\n throw new Error(\"Unsupported FileInput type\");\n}\n\nfunction jsonEntry(value: unknown): Uint8Array {\n return strToU8(JSON.stringify(value, null, 2));\n}\n\nexport async function createZip(document: PHDocument): Promise<Uint8Array> {\n return zipAsync({\n \"header.json\": jsonEntry(document.header),\n \"state.json\": jsonEntry(document.initialState || {}),\n \"current-state.json\": jsonEntry(document.state || {}),\n \"operations.json\": jsonEntry(\n filterDocumentOperationsResultingState(document.operations),\n ),\n });\n}\n\n/**\n * Creates a minimal ZIP backup from strand data.\n * Used when the full document is not available (e.g., in onOperations handler).\n * Creates a ZIP with minimal header and empty operations.\n */\nexport async function createMinimalZip(\n data: MinimalBackupData,\n): Promise<Uint8Array> {\n const now = new Date().toISOString();\n const header: PHDocumentHeader = {\n id: data.documentId,\n sig: { publicKey: {}, nonce: \"\" },\n documentType: data.documentType,\n createdAtUtcIso: now,\n slug: data.name,\n name: data.name,\n branch: data.branch,\n revision: {},\n lastModifiedAtUtcIso: now,\n };\n\n return zipAsync({\n \"header.json\": jsonEntry(header),\n \"state.json\": jsonEntry(data.state),\n \"current-state.json\": jsonEntry(data.state),\n \"operations.json\": jsonEntry({}),\n });\n}\n\nexport async function baseSaveToFileHandle(\n document: PHDocument,\n input: FileSystemFileHandle,\n) {\n const data = await createZip(document);\n const writable = await input.createWritable();\n await writable.write(new Uint8Array(data));\n await writable.close();\n}\n\nfunction readEntry(files: Unzipped, name: string): string {\n const entry = files[name];\n if (!entry) {\n throw new Error(`${name} not found in document zip`);\n }\n return strFromU8(entry);\n}\n\ntype ParsedZip<TState> = {\n initialState: TState;\n header: PHDocumentHeader;\n clearedOperations: DocumentOperations;\n};\n\nasync function parseZipData<TState extends PHBaseState>(\n data: Uint8Array,\n): Promise<ParsedZip<TState>> {\n const files = await unzipAsync(data);\n\n if (!files[\"state.json\"]) {\n throw new Error(\"Initial state not found\");\n }\n const initialState = JSON.parse(readEntry(files, \"state.json\")) as TState;\n\n if (!files[\"header.json\"]) {\n throw new Error(\"Document header not found - file format may be outdated\");\n }\n const header = JSON.parse(\n readEntry(files, \"header.json\"),\n ) as PHDocumentHeader;\n\n if (!files[\"operations.json\"]) {\n throw new Error(\"Operations history not found\");\n }\n const operations = JSON.parse(\n readEntry(files, \"operations.json\"),\n ) as DocumentOperations;\n\n const clearedOperations = garbageCollectDocumentOperations(operations);\n\n const operationsError = validateOperations(clearedOperations);\n if (operationsError.length) {\n const errorMessages = operationsError.map((err) => err.message);\n throw new Error(errorMessages.join(\"\\n\"));\n }\n\n return { initialState, header, clearedOperations };\n}\n\nasync function loadFromZipData<TState extends PHBaseState>(\n data: Uint8Array,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const { initialState, header, clearedOperations } =\n await parseZipData<TState>(data);\n\n // document-scope ops are applied by dedicated platform handlers; auth ops replay here\n const replayOperations = Object.fromEntries(\n Object.entries(clearedOperations).filter(([scope]) => scope !== \"document\"),\n ) as DocumentOperations;\n\n const result = replayDocument(\n initialState,\n replayOperations,\n reducer,\n header,\n undefined,\n {},\n options,\n );\n\n return { ...result, operations: clearedOperations };\n}\n\nasync function loadFromZipDataVersioned<TState extends PHBaseState>(\n data: Uint8Array,\n config: VersionedReplayConfig,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const { initialState, header, clearedOperations } =\n await parseZipData<TState>(data);\n\n const result = replayDocumentVersioned<TState>(\n initialState,\n clearedOperations,\n config,\n header,\n undefined,\n options,\n );\n\n return { ...result, operations: clearedOperations };\n}\n\nexport async function baseLoadFromInput<TState extends PHBaseState>(\n input: FileInput,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const data = await toUint8Array(input);\n return loadFromZipData(data, reducer, options);\n}\n\nexport async function baseLoadFromInputVersioned<TState extends PHBaseState>(\n input: FileInput,\n config: VersionedReplayConfig,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const data = await toUint8Array(input);\n return loadFromZipDataVersioned<TState>(data, config, options);\n}\n\nexport type BulkArchiveEntry = {\n /** \"/\"-separated zip path of a file entry (no trailing slash). */\n path: string;\n data: Uint8Array;\n};\n\n/**\n * Whether this zip is a single Powerhouse document: the document's four JSON\n * entries (header/state/current-state/operations) at the archive root. A\n * bulk archive has a folder tree instead. Returns false for any input that\n * is not a readable zip.\n */\nexport async function isDocumentZip(data: Uint8Array): Promise<boolean> {\n let files: Unzipped;\n try {\n files = await unzipAsync(data);\n } catch {\n return false;\n }\n return (\n Boolean(files[\"header.json\"]) &&\n Boolean(files[\"state.json\"]) &&\n Boolean(files[\"operations.json\"])\n );\n}\n\n/**\n * The file entries of a zip (directory entries excluded). Used for bulk\n * archives; throws when the archive holds no files. Note this does NOT\n * validate that the entries are document zips — pair with isDocumentZip.\n */\nexport async function parseBulkArchive(\n data: Uint8Array,\n): Promise<BulkArchiveEntry[]> {\n const files = await unzipAsync(data);\n const entries = Object.entries(files)\n .filter(([name]) => !name.endsWith(\"/\"))\n .map(([path, value]) => ({ path, data: value }));\n if (entries.length === 0) {\n throw new Error(\"Archive contains no files\");\n }\n return entries;\n}\n\n/**\n * Assemble a zip from raw entries. A key ending in \"/\" with empty data is a\n * directory entry, so an archive's folder structure survives a round-trip.\n */\nexport async function zipEntries(\n entries: Record<string, Uint8Array>,\n): Promise<Uint8Array> {\n return zipAsync(entries);\n}\n\nexport const documentModelLoadFromInput: LoadFromInput<DocumentModelPHState> = (\n input,\n) => {\n return baseLoadFromInput(input, documentModelReducer);\n};\n\nexport const documentModelSaveToFileHandle: SaveToFileHandle = (\n document,\n input,\n) => {\n return baseSaveToFileHandle(document, input);\n};\n\nexport function writeFileBrowser(\n path: string,\n name: string,\n stream: Uint8Array,\n): Promise<string> {\n throw FileSystemError;\n}\n\nexport function readFileBrowser(path: string) {\n throw FileSystemError;\n}\n\nexport function fetchFileBrowser(\n url: string,\n): Promise<{ data: Buffer; mimeType?: string }> {\n throw FileSystemError;\n}\n\nexport const getFileBrowser = (file: string): Promise<void> => {\n return Promise.resolve().then(() => readFileBrowser(file));\n};\n"],"mappings":"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CE,4BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,mCACA,SACD;AAEH,MAAa,4BACX,UAEA,aACE,8BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,qCACA,SACD;AAEH,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACD;AAED,MAAa,kBAAkB,UAC7B,aACE,oBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,2BACA,SACD;AAEH,MAAa,mBAAmB,UAC9B,aACE,qBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,4BACA,SACD;AAEH,MAAa,mBAAmB,UAC9B,aACE,qBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,4BACA,SACD;AAEH,MAAa,sBAAsB,UACjC,aACE,wBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,+BACA,SACD;AAEH,MAAa,sBAAsB,UACjC,aACE,wBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,+BACA,SACD;AAEH,MAAa,wBAAwB,UACnC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,iCACA,SACD;AAEH,MAAa,oBAAoB,UAC/B,aACE,uBACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,6BACA,SACD;AAEH,MAAa,uBAAuB,UAClC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,gCACA,SACD;AAEH,MAAa,uBAAuB,UAClC,aACE,0BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,gCACA,SACD;AAEH,MAAa,yBAAyB,UACpC,aACE,4BACA,EAAE,GAAG,OAAO,EACZ,KAAA,GACA,kCACA,SACD;AAEH,MAAa,0BACX,aACE,uBACA,EAAE,EACF,KAAA,GACA,KAAA,GACA,SACD;AAEH,MAAa,cAAc;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAC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"}
|