@istar-ts/actions 0.15.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["metamodelOf","elementBehavesLike","LINK_SELECTOR","linkBehavesLike","effectiveLinkKind","DIAGNOSTIC_SEVERITIES","connectResultToDiagnostic","metamodelOf","TOP_LEVEL_KEYS","FILE_METAMODEL_KEY","inheritMetamodel","inheritSourceLayout","validateModel","toPistarObject","canLink","withFileMetamodel","MetamodelError","hostMetamodelOf","parsePistar","PistarParseError","dependencyEnds","validateModelProperties","ModelOperationError","effectiveLinkKind","metamodelOf","metamodelOf","inheritMetamodel","inheritSourceLayout","ModelOperationError","parsePistar","createEmptyModel","FILE_METAMODEL_KEY","canLink"],"sources":["../src/actions.ts","../src/created-ids.ts","../src/kind-selectors.ts","../src/hints.ts","../src/markers.ts","../src/dispatcher.ts","../src/host.ts","../src/metamodel-context.ts","../src/mirror.ts","../src/transport.ts","../src/index.ts"],"sourcesContent":["/**\n * The action vocabulary: a subset of GLSP's action protocol\n * (https://eclipse.dev/glsp/documentation/protocol/), with GLSP's interface names and `kind`\n * strings where the concept is the same, and iStar extras under `istar.*`.\n *\n * Every action is plain JSON (no Maps, functions or class instances), so a dispatcher can sit\n * on the other side of a `postMessage` or a socket. Requests carry `requestId`; their response\n * carries it back as `responseId`, as in GLSP.\n *\n * Where a shape differs from GLSP's: `args` of the create operations are structured (a name,\n * custom properties, ids) rather than GLSP's flat `Args`; `newSize` of `ElementAndBounds` is\n * optional; `ChangeContainerOperation.targetContainerId` is `null` to take an element out of\n * its actor; `SetModelAction.newRoot` is the piStar file, not a GModel; operations need not\n * carry GLSP's `isOperation: true` (the dispatcher knows them by `kind`).\n */\nimport type {\n CustomProperties,\n DiagnosticSeverity,\n ElementKind,\n FileMetamodel,\n LinkKind,\n ModelChange,\n PistarFile,\n} from '@istar-ts/core';\n\n/** GLSP's custom arguments: a flat map of primitives. */\nexport type Args = Readonly<Record<string, string | number | boolean>>;\n\n/** A value that survives a JSON round trip, for `istar.updateModelExtra`'s `set`. */\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface Dimension {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Action {\n readonly kind: string;\n}\n\nexport interface RequestAction extends Action {\n readonly requestId: string;\n /** Milliseconds the sender is willing to wait (GLSP); the in-process dispatcher ignores it. */\n readonly timeout?: number;\n}\n\nexport interface ResponseAction extends Action {\n /** The `requestId` of the request this answers. */\n readonly responseId: string;\n}\n\n/** An action that edits the model, as one undo step. */\nexport interface Operation extends Action {\n /** GLSP's operation marker. Optional here: the dispatcher knows operations by `kind`. */\n readonly isOperation?: true;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Operations (GLSP)\n\nexport interface CreateNodeArgs {\n /** Default: the kind's label (\"Goal\"), as in piStar. */\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n /** The new element's id. Default: a fresh UUID. Lets a compound operation refer to it. */\n readonly id?: string;\n}\n\nexport interface CreateNodeOperation<EK extends string = ElementKind> extends Operation {\n readonly kind: 'createNode';\n /** The element kind, e.g. `istar.Goal`. */\n readonly elementTypeId: EK;\n /** Default: the container's position, or the origin. */\n readonly location?: Point;\n /** The actor to create the element in. */\n readonly containerId?: string;\n readonly args?: CreateNodeArgs;\n}\n\n/** The dependum a dependency creates between its depender and dependee. */\nexport interface DependumArgs<EK extends string = ElementKind> {\n /** Default: the metamodel's first node kind that can be a dependum. */\n readonly kind?: EK;\n readonly name?: string;\n readonly id?: string;\n /** Default: midway between depender and dependee, as in piStar. */\n readonly location?: Point;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface CreateEdgeArgs<EK extends string = ElementKind> {\n /** A contribution's value (the link's `label`), e.g. `help`. */\n readonly value?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n /**\n * The new link's id: for an n-ary kind whose target is not yet a hub, the new hub's; for an\n * n-ary kind whose target already is a hub, the new leg's (same as `legId` there). Default: a\n * fresh UUID.\n */\n readonly id?: string;\n /** For a dependency kind: the dependum to create. */\n readonly dependum?: DependumArgs<EK>;\n /** For a dependency kind: the ids of its two links. */\n readonly linkIds?: readonly [string, string];\n /**\n * The id of the leg it creates: for a target that is not yet a hub, the new leg from source;\n * for a target that already is a hub, the new leg instead of `id`.\n */\n readonly legId?: string;\n /** For an n-ary kind whose target is not yet a hub: the id of the end it creates. */\n readonly endId?: string;\n}\n\n/**\n * Adds a link. With a dependency kind, adds the dependum and its two links (as `addDependency`\n * does), source being the depender and target the dependee. With an n-ary kind, adds a leg when\n * the target is one of the kind's hubs, else a new hub with a leg and an end.\n */\nexport interface CreateEdgeOperation<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends Operation {\n readonly kind: 'createEdge';\n /** The link kind, e.g. `istar.ContributionLink`. */\n readonly elementTypeId: LK;\n readonly sourceElementId: string;\n readonly targetElementId: string;\n readonly args?: CreateEdgeArgs<EK>;\n}\n\n/** Removes elements and links, with everything that depends on them (as the store does). */\nexport interface DeleteElementOperation extends Operation {\n readonly kind: 'deleteElement';\n /** Element and link ids. */\n readonly elementIds: readonly string[];\n}\n\nexport interface ElementAndBounds {\n readonly elementId: string;\n /** Moving an actor moves its inner elements with it. */\n readonly newPosition?: Point;\n /** Written to the element's `display` (`width`, `height`). */\n readonly newSize?: Dimension;\n}\n\nexport interface ChangeBoundsOperation extends Operation {\n readonly kind: 'changeBounds';\n readonly newBounds: readonly ElementAndBounds[];\n}\n\n/** Moves an inner element into another actor, or out of any actor with `null` (`nestElement`). */\nexport interface ChangeContainerOperation extends Operation {\n readonly kind: 'changeContainer';\n readonly elementId: string;\n readonly targetContainerId: string | null;\n /** The element's new position, if it moves too. */\n readonly location?: Point;\n}\n\n/**\n * Gives a link new ends, keeping its id, kind and properties. A dependency's link keeps its\n * dependum end; an n-ary link's leg keeps its hub (or moves to another hub of the kind), its end\n * keeps the hub.\n */\nexport interface ReconnectEdgeOperation extends Operation {\n readonly kind: 'reconnectEdge';\n readonly edgeElementId: string;\n readonly sourceElementId: string;\n readonly targetElementId: string;\n readonly args?: Args;\n}\n\n/**\n * Sets an element's or link's name (`labelId` = its id), or one of its custom properties\n * (`labelId` = `\"<id>#<key>\"`). An element's name is written as-is (`text`, including `\"\"`, as\n * piStar always keeps the key); a link's name is removed from the file when `text` is `\"\"`, as\n * piStar does for a link whose name was cleared (`fileManager.js` only writes `name` when it is\n * truthy).\n */\nexport interface ApplyLabelEditOperation extends Operation {\n readonly kind: 'applyLabelEdit';\n readonly labelId: string;\n readonly text: string;\n}\n\n/** Applies its operations in order, as one undo step; if one is rejected, none is applied. */\nexport interface CompoundOperation<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends Operation {\n readonly kind: 'compound';\n readonly operationList: readonly IstarOperation<EK, LK>[];\n}\n\n// ---------------------------------------------------------------------------------------------\n// Operations (iStar)\n\n/** Adds a leg from `sourceElementId` to the hub of an n-ary link (`store.addLeg`). */\nexport interface AddLegOperation extends Operation {\n readonly kind: 'istar.addLeg';\n readonly hubId: string;\n readonly sourceElementId: string;\n readonly args?: { readonly id?: string };\n}\n\n/** Removes a leg of an n-ary link; the last one takes the hub and end with it. */\nexport interface RemoveLegOperation extends Operation {\n readonly kind: 'istar.removeLeg';\n readonly legId: string;\n}\n\nexport interface SetCollapsedOperation extends Operation {\n readonly kind: 'istar.setCollapsed';\n /** An actor. */\n readonly elementId: string;\n readonly collapsed: boolean;\n}\n\nexport interface DiagramPatch {\n readonly name?: string;\n readonly width?: number;\n readonly height?: number;\n /** Replaces the diagram's custom properties. */\n readonly customProperties?: CustomProperties;\n}\n\nexport interface UpdateDiagramOperation extends Operation {\n readonly kind: 'istar.updateDiagram';\n readonly diagram: DiagramPatch;\n}\n\n/**\n * Sets custom properties of an element or link: each key is set to its value, or removed when\n * the value is `null`; other keys are kept. Values are strings, as piStar stores them.\n */\nexport interface UpdatePropertiesOperation extends Operation {\n readonly kind: 'istar.updateProperties';\n /** An element or link id. */\n readonly elementId: string;\n readonly properties: Readonly<Record<string, string | null>>;\n}\n\n/**\n * Merges into an element's `display` (colour, the auto-grown height from a label fit): a key set\n * to `undefined` is removed, the rest is written as-is. Same semantics as `ElementPatch.display`\n * (`@istar-ts/core`), which this forwards to.\n */\nexport interface UpdateDisplayOperation extends Operation {\n readonly kind: 'istar.updateDisplay';\n readonly elementId: string;\n readonly patch: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Sets an existing link's contribution value (`label` in the save file), e.g. a Contribution\n * link's make/help/hurt/break. `null` clears it. Rejected when the link's kind has no\n * `possibleLabels`, or `value` is not one of them (as `createEdge.args.value` is checked at\n * creation).\n */\nexport interface SetLinkValueOperation extends Operation {\n readonly kind: 'istar.setLinkValue';\n readonly linkId: string;\n readonly value: string | null;\n}\n\n/**\n * Merges into a link's `display` (its bend points, `vertices`): a key set to `undefined` is\n * removed, the rest is written as-is. Same semantics as `LinkPatch.display` (`@istar-ts/core`),\n * which this forwards to. GLSP's counterpart is `changeRoutingPoints`.\n */\nexport interface UpdateLinkDisplayOperation extends Operation {\n readonly kind: 'istar.updateLinkDisplay';\n readonly linkId: string;\n readonly patch: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Changes the kind of a set of links: each listed link's id, source, target, order in the file,\n * name, value, custom properties and display are kept; other links are untouched. One undo step\n * for the whole set, all or nothing. A link whose kind is already `elementTypeId` is a no-op;\n * an empty `linkIds` is a no-op too. Rejected (model untouched) if `canLink` refuses any listed\n * link's new kind for its unchanged source and target (e.g. a mixed-refinement rule), or if the\n * link keeps a `value` the new kind's `possibleLabels` disallows.\n */\nexport interface ChangeLinkKindOperation<LK extends string = LinkKind> extends Operation {\n readonly kind: 'istar.changeLinkKind';\n readonly linkIds: readonly string[];\n /** The links' new kind, e.g. `istar.OrRefinementLink`. */\n readonly elementTypeId: LK;\n}\n\n/**\n * Sets (or, with `null` or an empty block, removes) the model file's own `\"metamodel\"` block:\n * custom element kinds, groupers, link kinds with their rules and line style (`withFileMetamodel`\n * in `@istar-ts/core`). One undo step; undo restores the previous block exactly. Rejected (model\n * untouched) if the block is malformed, collides with the host's kinds, or drops a kind an\n * element or link still uses. A host's dialect-specific checks (e.g. goal-controller's own\n * validation of the block) run as an `ActionGuard` on this operation's kind, so their refusal\n * also comes back as diagnostics.\n */\nexport interface SetFileMetamodelOperation extends Operation {\n readonly kind: 'istar.setFileMetamodel';\n readonly block: FileMetamodel | null;\n}\n\n/**\n * Sets, removes or reads back the model's own top-level keys that core keeps in `model.extra`\n * (e.g. a dialect's `metamodelVersion`): `set`'s keys are written (other extra keys and their\n * order are kept; a new key is appended where `toPistar` would place it), `remove`'s keys are\n * deleted. `tool` sets (or, with `null`, removes) the model's own `tool` field in the same undo\n * step — `set`/`remove` reject it, and every key core models itself (`actors`, `orphans`,\n * `dependencies`, `links`, `display`, `istar`, `saveDate`, `diagram`), and `\"metamodel\"` (use\n * `istar.setFileMetamodel` for that one). One undo step.\n */\nexport interface UpdateModelExtraOperation extends Operation {\n readonly kind: 'istar.updateModelExtra';\n readonly set?: Readonly<Record<string, JsonValue>>;\n readonly remove?: readonly string[];\n readonly tool?: string | null;\n}\n\n/**\n * Replaces the whole model from a piStar save file, as one undo step: ids, order and extra keys\n * come from `model`, so a parse → `toPistar` round trip is byte-identical to it. Parsed with\n * `parsePistar` under the dispatcher's own metamodel (`fileMetamodel` as in `parsePistar`); a\n * parse error rejects with a typed diagnostic, the model untouched. Pre-guards and postGuards\n * run against this operation, the model before and the model after, like any other operation.\n */\nexport interface ReplaceModelOperation extends Operation {\n readonly kind: 'istar.replaceModel';\n readonly model: PistarFile;\n readonly fileMetamodel?: boolean;\n}\n\n/** Every operation, keyed by `kind`. */\nexport type IstarOperation<EK extends string = ElementKind, LK extends string = LinkKind> =\n | CreateNodeOperation<EK>\n | CreateEdgeOperation<EK, LK>\n | DeleteElementOperation\n | ChangeBoundsOperation\n | ChangeContainerOperation\n | ReconnectEdgeOperation\n | ApplyLabelEditOperation\n | CompoundOperation<EK, LK>\n | AddLegOperation\n | RemoveLegOperation\n | SetCollapsedOperation\n | UpdateDiagramOperation\n | UpdatePropertiesOperation\n | UpdateDisplayOperation\n | SetLinkValueOperation\n | UpdateLinkDisplayOperation\n | ChangeLinkKindOperation<LK>\n | SetFileMetamodelOperation\n | UpdateModelExtraOperation\n | ReplaceModelOperation;\n\n// ---------------------------------------------------------------------------------------------\n// Model\n\nexport interface RequestModelAction extends RequestAction {\n readonly kind: 'requestModel';\n readonly options?: Args;\n}\n\nexport interface SetModelAction extends ResponseAction {\n readonly kind: 'setModel';\n /** The model as a piStar save file (`toPistarObject`). */\n readonly newRoot: PistarFile;\n}\n\n/**\n * The model changed: sent to subscribers after every edit, undo, redo or load, whoever caused\n * it. `source` and `changes` are iStar extras (the store's `ModelChangeEvent`).\n */\nexport interface ModelSourceChangedAction extends Action {\n readonly kind: 'sourceModelChanged';\n /** The dispatcher's `sourceModelName` option. */\n readonly sourceModelName: string;\n readonly source: 'edit' | 'undo' | 'redo' | 'load';\n /** What an edit did; empty for undo, redo and load. */\n readonly changes: readonly ModelChange[];\n /**\n * The new model as a piStar save file (`toPistarObject`), when the dispatcher was created with\n * `sendModel`: what a mirror (`createMirrorStore`) follows without asking for it. An iStar\n * extra.\n */\n readonly newRoot?: PistarFile;\n /**\n * Whether undo is possible, from the remote store after this change (when the dispatcher was\n * created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.\n */\n readonly canUndo?: boolean;\n /**\n * Whether redo is possible, from the remote store after this change (when the dispatcher was\n * created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.\n */\n readonly canRedo?: boolean;\n /**\n * The `origin` the causing `dispatch` was given, echoed back; absent for a change with none\n * (a host's direct `store.load`, for instance). See `ActionDispatcher.dispatch`.\n */\n readonly origin?: string;\n}\n\n/** Saves the model through the host's `save` callback. */\nexport interface SaveModelAction extends Action {\n readonly kind: 'saveModel';\n readonly fileUri?: string;\n}\n\nexport type DirtyStateChangeReason = 'operation' | 'undo' | 'redo' | 'save' | 'external';\n\n/** Sent to subscribers when the model starts or stops differing from the last saved one. */\nexport interface SetDirtyStateAction extends Action {\n readonly kind: 'setDirtyState';\n readonly isDirty: boolean;\n readonly reason?: DirtyStateChangeReason;\n /** The `origin` of the dispatch that caused this dirty-state change, echoed back; see `ModelSourceChangedAction.origin`. */\n readonly origin?: string;\n}\n\nexport interface UndoAction extends Action {\n readonly kind: 'glspUndo';\n}\n\nexport interface RedoAction extends Action {\n readonly kind: 'glspRedo';\n}\n\n// ---------------------------------------------------------------------------------------------\n// Type hints and edge checks\n\nexport interface TypeHint {\n readonly elementTypeId: string;\n readonly repositionable: boolean;\n readonly deletable: boolean;\n}\n\nexport interface ShapeTypeHint extends TypeHint {\n readonly resizable: boolean;\n /** Can move into or out of an actor. */\n readonly reparentable: boolean;\n /** For an actor: the node kinds it can contain. */\n readonly containableElementTypeIds?: readonly string[];\n}\n\nexport interface EdgeTypeHint extends TypeHint {\n readonly routable: boolean;\n /** Element kinds that may be the source; absent when any may. */\n readonly sourceElementTypeIds?: readonly string[];\n /** Element kinds that may be the target; absent when any may. */\n readonly targetElementTypeIds?: readonly string[];\n /** Always true for iStar: kinds alone don't decide (same actor, uniqueness…); ask `requestCheckEdge`. */\n readonly dynamic?: boolean;\n}\n\nexport interface RequestTypeHintsAction extends RequestAction {\n readonly kind: 'requestTypeHints';\n}\n\nexport interface SetTypeHintsAction extends ResponseAction {\n readonly kind: 'setTypeHints';\n readonly shapeHints: readonly ShapeTypeHint[];\n readonly edgeHints: readonly EdgeTypeHint[];\n}\n\n/** Would a link of `edgeType` from source to target be accepted (`canLink`)? */\nexport interface RequestCheckEdgeAction extends RequestAction {\n readonly kind: 'requestCheckEdge';\n readonly edgeType: string;\n readonly sourceElementId: string;\n /** Absent: is the source an acceptable source at all? */\n readonly targetElementId?: string;\n}\n\nexport interface CheckEdgeResultAction extends ResponseAction {\n readonly kind: 'checkEdgeTargetResult';\n readonly isValid: boolean;\n readonly edgeType: string;\n readonly sourceElementId: string;\n readonly targetElementId?: string;\n /** iStar extra: why not, when `isValid` is false. */\n readonly reason?: string;\n /** iStar extra: the constraint that failed (`ConstraintCode`). */\n readonly code?: string;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Context actions (the palette)\n\nexport interface EditorContext {\n readonly selectedElementIds: readonly string[];\n /** Where the user is about to create something, in model coordinates. */\n readonly lastMousePosition?: Point;\n readonly args?: Args;\n}\n\n/** GLSP's context ids. The dispatcher answers every context with the palette. */\nexport type ContextId = 'tool-palette' | 'context-menu' | 'command-palette' | (string & {});\n\nexport interface RequestContextActions extends RequestAction {\n readonly kind: 'requestContextActions';\n readonly contextId: ContextId;\n readonly editorContext: EditorContext;\n}\n\n/** One palette entry: the trigger action(s) a click sends, with the palette's data. */\nexport interface LabeledAction {\n readonly label: string;\n readonly actions: readonly IstarAction[];\n readonly icon?: string;\n /** iStar extras, from the `PaletteDescription` entry. */\n readonly id?: string;\n readonly group?: string;\n readonly section?: string;\n readonly order?: number;\n}\n\nexport interface SetContextActions extends ResponseAction {\n readonly kind: 'setContextActions';\n /** Sorted by `order`. */\n readonly actions: readonly LabeledAction[];\n /** iStar extra: labels of the entries' `group`s (the palette's dropdown buttons). */\n readonly groups?: Readonly<Record<string, { readonly label: string }>>;\n readonly args?: Args;\n}\n\n/** Arms the client's node creation tool; the client then sends a `CreateNodeOperation`. */\nexport interface TriggerNodeCreationAction extends Action {\n readonly kind: 'triggerNodeCreation';\n readonly elementTypeId: string;\n /** Presets for the operation's `args`. */\n readonly args?: { readonly customProperties?: CustomProperties };\n}\n\n/** Arms the client's edge creation tool; the client then sends a `CreateEdgeOperation`. */\nexport interface TriggerEdgeCreationAction extends Action {\n readonly kind: 'triggerEdgeCreation';\n readonly elementTypeId: string;\n /** Presets for the operation's `args`: a contribution's value, a dependency's dependum kind. */\n readonly args?: { readonly value?: string; readonly dependum?: { readonly kind: string } };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Markers\n\n/** GLSP's validation marker; `kind` is a `DiagnosticSeverity`. */\nexport interface Marker {\n /** Short text (the diagnostic's message). */\n readonly label: string;\n /** Full text (the message, with its source when it has one). */\n readonly description: string;\n readonly elementId: string;\n readonly kind: DiagnosticSeverity | (string & {});\n /** iStar extras, kept so a marker converts back to the same `GoalDiagnostic`. */\n readonly key?: string;\n readonly source?: string;\n readonly code?: string;\n}\n\n/**\n * Markers of the model: link constraint violations (`validateModel`), property issues (the\n * dispatcher's `schemas`) and the host's `diagnostics`.\n */\nexport interface RequestMarkersAction extends RequestAction {\n readonly kind: 'requestMarkers';\n /**\n * Elements to report on (GLSP's spelling). Empty, or naming no element or link of the model\n * (a GLSP client sends its root's id), means the whole model.\n */\n readonly elementsIDs: readonly string[];\n readonly reason?: string;\n}\n\nexport interface SetMarkersAction extends ResponseAction {\n readonly kind: 'setMarkers';\n readonly markers: readonly Marker[];\n readonly reason?: string;\n}\n\nexport interface DeleteMarkersAction extends Action {\n readonly kind: 'deleteMarkers';\n readonly markers: readonly Marker[];\n}\n\n// ---------------------------------------------------------------------------------------------\n// Unions\n\nexport type IstarRequestAction =\n | RequestModelAction\n | RequestTypeHintsAction\n | RequestCheckEdgeAction\n | RequestContextActions\n | RequestMarkersAction;\n\nexport type IstarResponseAction =\n | SetModelAction\n | SetTypeHintsAction\n | CheckEdgeResultAction\n | SetContextActions\n | SetMarkersAction;\n\n/**\n * Actions the dispatcher does not act on: it passes them to its subscribers (a server telling\n * its clients), and sends the first two itself.\n */\nexport type IstarNotificationAction =\n | ModelSourceChangedAction\n | SetDirtyStateAction\n | TriggerNodeCreationAction\n | TriggerEdgeCreationAction\n | DeleteMarkersAction;\n\n/** Every action of the protocol, keyed by `kind`. */\nexport type IstarAction<EK extends string = ElementKind, LK extends string = LinkKind> =\n | IstarOperation<EK, LK>\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarRequestAction\n | IstarResponseAction\n | IstarNotificationAction;\n\nconst OPERATION_KIND_LIST: readonly IstarOperation['kind'][] = [\n 'createNode',\n 'createEdge',\n 'deleteElement',\n 'changeBounds',\n 'changeContainer',\n 'reconnectEdge',\n 'applyLabelEdit',\n 'compound',\n 'istar.addLeg',\n 'istar.removeLeg',\n 'istar.setCollapsed',\n 'istar.updateDiagram',\n 'istar.updateProperties',\n 'istar.updateDisplay',\n 'istar.setLinkValue',\n 'istar.updateLinkDisplay',\n 'istar.changeLinkKind',\n 'istar.setFileMetamodel',\n 'istar.updateModelExtra',\n 'istar.replaceModel',\n];\n\nconst REQUEST_KIND_LIST: readonly IstarRequestAction['kind'][] = [\n 'requestModel',\n 'requestTypeHints',\n 'requestCheckEdge',\n 'requestContextActions',\n 'requestMarkers',\n];\n\n/**\n * The other actions the dispatcher accepts: `glspUndo`/`glspRedo`/`saveModel` (acted on), then\n * the notifications it only re-emits to subscribers (`IstarNotificationAction`'s kinds).\n */\nconst NOTIFICATION_KIND_LIST: readonly (\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarNotificationAction\n)['kind'][] = [\n 'glspUndo',\n 'glspRedo',\n 'saveModel',\n 'sourceModelChanged',\n 'setDirtyState',\n 'triggerNodeCreation',\n 'triggerEdgeCreation',\n 'deleteMarkers',\n];\n\nconst OPERATION_KINDS: ReadonlySet<string> = new Set(OPERATION_KIND_LIST);\nconst REQUEST_KINDS: ReadonlySet<string> = new Set(REQUEST_KIND_LIST);\n\n/**\n * The action kinds `createActionDispatcher` accepts, grouped the way it treats them: `operations`\n * edit the model as one undo step, `requests` get a response action, `notifications` (plus\n * `glspUndo`/`glspRedo`/`saveModel`) are acted on or re-emitted as is. Derived from the same\n * lists `isOperation`/`isRequestAction` use, so it can't drift from the dispatcher.\n */\nexport const HANDLED_ACTION_KINDS: {\n readonly operations: readonly IstarOperation['kind'][];\n readonly requests: readonly IstarRequestAction['kind'][];\n readonly notifications: readonly (\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarNotificationAction\n )['kind'][];\n} = {\n operations: OPERATION_KIND_LIST,\n requests: REQUEST_KIND_LIST,\n notifications: NOTIFICATION_KIND_LIST,\n};\n\n/** True for the operations (actions that edit the model). */\nexport function isOperation<EK extends string, LK extends string>(\n action: IstarAction<EK, LK>,\n): action is IstarOperation<EK, LK> {\n return OPERATION_KINDS.has(action.kind);\n}\n\n/** True for the requests (actions answered with a response action). */\nexport function isRequestAction(action: Action): action is IstarRequestAction {\n return REQUEST_KINDS.has(action.kind);\n}\n","/**\n * An accepted operation with the ids it created injected back as explicit ids, so dispatching it\n * again against the same model state creates the same ids. The playground's protocol lab replay\n * (#46) and agent Propose mode (#155, whose apply must reproduce the scratch run's ids for later\n * steps that name them) need it, and so does `@istar-ts/glsp`'s grouping of an MCP tool call\n * (#223), which applies a draft's operations again on the store as one `compound`.\n */\nimport type { IstarOperation } from './actions';\nimport { type AnyIstarModel, type AnyMetamodel, metamodelOf } from '@istar-ts/core';\n\ntype Operation = IstarOperation<string, string>;\n\n/** How many new element ids, then new link ids, `operation` creates, mirroring the dispatcher's\n * `createdIds` diff (`dispatcher.ts`) and `connect`/`addDependency`/`addLeg`\n * (`packages/core/src/operations.ts`). */\nfunction countCreatedIds(\n operation: Operation,\n model: AnyIstarModel,\n): { elements: number; links: number } {\n switch (operation.kind) {\n case 'createNode':\n return { elements: 1, links: 0 };\n case 'createEdge': {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const definition = metamodel.links.get(operation.elementTypeId);\n if (definition?.category === 'dependency') return { elements: 1, links: 2 };\n if (definition?.parts && !targetIsHub(operation, model, metamodel)) {\n // A new hub: hub (element) + leg + end (links).\n return { elements: 1, links: 2 };\n }\n return { elements: 0, links: 1 };\n }\n case 'istar.addLeg':\n return { elements: 0, links: 1 };\n case 'compound': {\n let elements = 0;\n let links = 0;\n for (const child of operation.operationList as readonly Operation[]) {\n const counts = countCreatedIds(child, model);\n elements += counts.elements;\n links += counts.links;\n }\n return { elements, links };\n }\n default:\n return { elements: 0, links: 0 };\n }\n}\n\nfunction targetIsHub(\n operation: Extract<Operation, { kind: 'createEdge' }>,\n model: AnyIstarModel,\n metamodel: AnyMetamodel,\n): boolean {\n const targetKind = model.elements.get(operation.targetElementId)?.kind;\n return targetKind !== undefined && metamodel.elements.get(targetKind)?.role === 'hub';\n}\n\n/** `operation` with ids from `elementIds`/`linkIds` (consumed in model order) injected as the\n * explicit ids its creates take, so a dispatcher that applies it against the same model state\n * creates the same ids. */\nfunction withCreatedIds(\n operation: Operation,\n elementIds: string[],\n linkIds: string[],\n model: AnyIstarModel,\n): Operation {\n switch (operation.kind) {\n case 'createNode': {\n const id = elementIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'createEdge': {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const definition = metamodel.links.get(operation.elementTypeId);\n if (definition?.category === 'dependency') {\n const dependumId = elementIds.shift();\n const linkIds2 = [linkIds.shift(), linkIds.shift()] as const;\n if (dependumId === undefined || linkIds2[0] === undefined || linkIds2[1] === undefined) {\n return operation;\n }\n return {\n ...operation,\n args: {\n ...operation.args,\n dependum: { ...operation.args?.dependum, id: dependumId },\n linkIds: linkIds2 as readonly [string, string],\n },\n };\n }\n if (definition?.parts && !targetIsHub(operation, model, metamodel)) {\n const hubId = elementIds.shift();\n const legId = linkIds.shift();\n const endId = linkIds.shift();\n return hubId === undefined || legId === undefined || endId === undefined\n ? operation\n : { ...operation, args: { ...operation.args, id: hubId, legId, endId } };\n }\n const id = linkIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'istar.addLeg': {\n const id = linkIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'compound':\n return {\n ...operation,\n operationList: (operation.operationList as readonly Operation[]).map((child) =>\n withCreatedIds(child, elementIds, linkIds, model),\n ),\n };\n default:\n return operation;\n }\n}\n\n/** `operation`, with `createdIds` (an accepted result's) injected as explicit ids. */\nexport function injectCreatedIds(\n operation: Operation,\n createdIds: readonly string[],\n model: AnyIstarModel,\n): Operation {\n const counts = countCreatedIds(operation, model);\n const elementIds = createdIds.slice(0, counts.elements);\n const linkIds = createdIds.slice(counts.elements, counts.elements + counts.links);\n return withCreatedIds(operation, [...elementIds], [...linkIds], model);\n}\n","/**\n * Internal: which element and link kinds a rule selector matches, the same way `canLink` does.\n * Shared by `hints.ts` (GLSP type hints) and `metamodel-context.ts` (#240), not part of this\n * package's public API — `index.ts` doesn't re-export this module.\n */\nimport { LINK_SELECTOR, elementBehavesLike, linkBehavesLike } from '@istar-ts/core';\nimport type { AnyMetamodel, ElementKindDefinition } from '@istar-ts/core';\n\n/** A generated kind (a hub, leg or end) that an n-ary link's declaration adds on its own. */\nexport function isHub(definition: ElementKindDefinition): boolean {\n return definition.role === 'hub';\n}\n\n/** Element kinds a rule selector matches, as `canLink` matches elements against it. */\nexport function matching(metamodel: AnyMetamodel, selector: string): string[] {\n const kinds: string[] = [];\n for (const definition of metamodel.elements.values()) {\n // A hub is only matched by its own kind's name: categories never include it.\n const matches = isHub(definition)\n ? definition.kind === selector\n : selector === '*' ||\n selector === definition.category ||\n elementBehavesLike(metamodel, definition.kind, selector);\n if (matches) kinds.push(definition.kind);\n }\n // Link targets: `link` matches every link kind, a link kind itself and the kinds behaving like it.\n if (selector === LINK_SELECTOR) kinds.push(...metamodel.links.keys());\n else if (metamodel.links.has(selector)) {\n for (const kind of metamodel.links.keys()) {\n if (linkBehavesLike(metamodel, kind, selector)) kinds.push(kind);\n }\n }\n return kinds;\n}\n\nexport function union(metamodel: AnyMetamodel, selectors: readonly string[]): string[] {\n return [...new Set(selectors.flatMap((selector) => matching(metamodel, selector)))];\n}\n\n/** Kinds of a category, without hubs. */\nexport function ofCategory(metamodel: AnyMetamodel, category?: 'actor' | 'node'): string[] {\n return [...metamodel.elements.values()]\n .filter((d) => !isHub(d) && (category === undefined || d.category === category))\n .map((d) => d.kind);\n}\n","/**\n * What a client can know before it asks: type hints from the metamodel, and the palette as\n * GLSP context actions. Both are derived from data (`Metamodel`, `PaletteDescription`), so they\n * work for any root or extension.\n */\nimport { effectiveLinkKind } from '@istar-ts/core';\nimport type {\n AnyMetamodel,\n AnyPaletteDescription,\n ElementToolEntryDescription,\n LinkToolEntryDescription,\n Metamodel,\n PaletteEntryDescription,\n} from '@istar-ts/core';\nimport type {\n EdgeTypeHint,\n LabeledAction,\n SetContextActions,\n SetTypeHintsAction,\n ShapeTypeHint,\n} from './actions';\nimport { isHub, ofCategory, union } from './kind-selectors';\n\n/**\n * GLSP type hints of a metamodel. Shapes: every element kind (hubs can't be resized or\n * reparented; actors contain the node kinds that can be inner elements). Edges: every link kind,\n * its sources and targets from its rules, or by category for kinds with built-in rules (iStar\n * 2.0's), plus an n-ary kind's hub (`createEdge` onto a hub adds a leg to that link, #108). Edge\n * hints are `repositionable` (their ends can be reconnected) and `dynamic`: `canLink` checks more\n * than kinds.\n */\nexport function typeHintsFor<EK extends string, LK extends string>(\n metamodel: Metamodel<EK, LK>,\n): Pick<SetTypeHintsAction, 'shapeHints' | 'edgeHints'> {\n const meta = metamodel as unknown as AnyMetamodel;\n const inner = [...meta.elements.values()]\n .filter((d) => d.category === 'node' && !isHub(d) && d.info?.canBeInnerElement !== false)\n .map((d) => d.kind);\n const shapeHints = [...meta.elements.values()].map((d): ShapeTypeHint => {\n const hub = isHub(d);\n return {\n elementTypeId: d.kind,\n repositionable: true,\n deletable: true,\n resizable: !hub,\n reparentable: !hub && d.category === 'node' && d.info?.canBeInnerElement !== false,\n ...(d.category === 'actor' ? { containableElementTypeIds: inner } : {}),\n };\n });\n const edgeHints = [...meta.links.values()].map((d): EdgeTypeHint => {\n const rules = meta.links.get(effectiveLinkKind(meta, d.kind))?.rules;\n const builtIn = d.category === 'dependency' ? ofCategory(meta) : ofCategory(meta, d.category);\n const targets = rules ? union(meta, rules.targets) : builtIn;\n // An n-ary kind's `createEdge` onto its hub adds a leg to that link (#108).\n const hub = d.parts?.hub;\n return {\n elementTypeId: d.kind,\n repositionable: true,\n deletable: true,\n routable: true,\n sourceElementTypeIds: rules ? union(meta, rules.sources) : builtIn,\n targetElementTypeIds: hub === undefined ? targets : [...targets, hub],\n dynamic: true,\n };\n });\n return { shapeHints, edgeHints };\n}\n\nfunction elementEntries(\n kind: string,\n value: PaletteEntryDescription | readonly ElementToolEntryDescription[],\n): LabeledAction[] {\n const list: readonly ElementToolEntryDescription[] = Array.isArray(value)\n ? value\n : [value as PaletteEntryDescription];\n return list.map((entry, i) =>\n labeled(Array.isArray(value) ? `${kind}#${i}` : kind, entry, {\n kind: 'triggerNodeCreation',\n elementTypeId: kind,\n ...(entry.properties ? { args: { customProperties: entry.properties } } : {}),\n }),\n );\n}\n\nfunction linkEntries(kind: string, list: readonly LinkToolEntryDescription[]): LabeledAction[] {\n return list.map((entry, i) => {\n const args = {\n ...(entry.value === undefined ? {} : { value: entry.value }),\n ...(entry.dependum === undefined ? {} : { dependum: { kind: entry.dependum } }),\n };\n return labeled(`${kind}#${i}`, entry, {\n kind: 'triggerEdgeCreation',\n elementTypeId: kind,\n ...(Object.keys(args).length > 0 ? { args } : {}),\n });\n });\n}\n\nfunction order(action: LabeledAction): number {\n return action.order ?? Number.POSITIVE_INFINITY;\n}\n\nfunction labeled(\n id: string,\n entry: PaletteEntryDescription,\n action: LabeledAction['actions'][number],\n): LabeledAction {\n return {\n id,\n label: entry.label,\n actions: [action],\n ...(entry.group === undefined ? {} : { group: entry.group }),\n ...(entry.section === undefined ? {} : { section: entry.section }),\n ...(entry.order === undefined ? {} : { order: entry.order }),\n };\n}\n\n/**\n * A palette as GLSP context actions: one `LabeledAction` per entry, triggering the client's\n * creation tool with the entry's presets, sorted by `order`. Only the metamodel's kinds are\n * offered, in the metamodel's order where orders tie; kinds the palette hides (`false`) or\n * lacks are left out.\n */\nexport function contextActionsFor<EK extends string, LK extends string>(\n palette: AnyPaletteDescription,\n metamodel: Metamodel<EK, LK>,\n): Pick<SetContextActions, 'actions' | 'groups'> {\n const meta = metamodel as unknown as AnyMetamodel;\n const actions: LabeledAction[] = [];\n for (const kind of meta.elements.keys()) {\n const value = palette.elements[kind];\n if (value) actions.push(...elementEntries(kind, value));\n }\n for (const kind of meta.links.keys()) {\n const list = palette.links[kind];\n if (list) actions.push(...linkEntries(kind, list));\n }\n actions.sort((a, b) => (order(a) === order(b) ? 0 : order(a) < order(b) ? -1 : 1));\n return { actions, groups: palette.groups };\n}\n\n/**\n * A minimal palette for a metamodel with none of its own: one toolbar entry per visible kind\n * (declaration order, actors first), labelled from the kind's own `label`. Kinds generated for\n * an n-ary link (a hub, leg or end — `role` set) are hidden, as a hand-written palette would\n * hide them (`KAOS_PALETTE`'s `RefinementLinkHub: false`, for instance). The fallback\n * `createActionDispatcher` and `contributionFor` (`@istar-ts/glsp`) both use when no palette\n * was given.\n */\nexport function paletteFromMetamodel(metamodel: AnyMetamodel): AnyPaletteDescription {\n const elements: Record<string, PaletteEntryDescription | false> = {};\n let order = 0;\n for (const definition of metamodel.elements.values()) {\n elements[definition.kind] =\n definition.role !== undefined\n ? false\n : {\n label: definition.label,\n order: order++,\n section: definition.category === 'actor' ? 'actors' : 'elements',\n ...(definition.category === 'actor' ? { group: 'actors' } : {}),\n };\n }\n const links: Record<string, readonly LinkToolEntryDescription[] | false> = {};\n order = 0;\n for (const definition of metamodel.links.values()) {\n links[definition.kind] =\n definition.role !== undefined\n ? false\n : [{ label: definition.label, order: order++, section: 'elements' }];\n }\n return { elements, links, groups: { actors: { label: 'Actor' } } };\n}\n","import { DIAGNOSTIC_SEVERITIES } from '@istar-ts/core';\nimport type { DiagnosticSeverity, GoalDiagnostic } from '@istar-ts/core';\nimport type { Marker } from './actions';\n\n/** A `GoalDiagnostic` as a GLSP marker: `kind` is its severity, `label` its message. */\nexport function diagnosticToMarker(diagnostic: GoalDiagnostic): Marker {\n const { elementId, key, severity, message, source, code } = diagnostic;\n return {\n label: message,\n description: source === undefined ? message : `${message} (${source})`,\n elementId,\n kind: severity,\n ...(key === undefined ? {} : { key }),\n ...(source === undefined ? {} : { source }),\n ...(code === undefined ? {} : { code }),\n };\n}\n\n/**\n * A GLSP marker as a `GoalDiagnostic`. A `kind` that is no `DiagnosticSeverity` reads as\n * `info`; `range` and `data` are not carried by markers.\n */\nexport function markerToDiagnostic(marker: Marker): GoalDiagnostic {\n const { elementId, kind, label, key, source, code } = marker;\n const severity = (DIAGNOSTIC_SEVERITIES as readonly string[]).includes(kind)\n ? (kind as DiagnosticSeverity)\n : 'info';\n return {\n elementId,\n severity,\n message: label,\n ...(key === undefined ? {} : { key }),\n ...(source === undefined ? {} : { source }),\n ...(code === undefined ? {} : { code }),\n };\n}\n","/**\n * The dispatcher: the server side of the protocol over a `ModelStore`. Operations run as one\n * store transaction each and are rejected, model untouched, with `GoalDiagnostic`s; requests\n * are answered from the model, its metamodel and the palette; store changes reach subscribers\n * as `ModelSourceChangedAction`s, whoever made them.\n */\nimport {\n FILE_METAMODEL_KEY,\n MetamodelError,\n ModelOperationError,\n PistarParseError,\n TOP_LEVEL_KEYS,\n canLink,\n connectResultToDiagnostic,\n dependencyEnds,\n hostMetamodelOf,\n inheritMetamodel,\n inheritSourceLayout,\n metamodelOf,\n parsePistar,\n toPistarObject,\n validateModel,\n validateModelProperties,\n withFileMetamodel,\n} from '@istar-ts/core';\nimport type {\n AnyIstarModel,\n AnyMetamodel,\n AnyPaletteDescription,\n ConnectResult,\n CustomProperties,\n ElementKind,\n Extra,\n GoalDiagnostic,\n IstarLink,\n IstarModel,\n LinkCheck,\n LinkKind,\n ModelChangeEvent,\n ModelStore,\n PistarFile,\n PropertySchema,\n PropertyShape,\n} from '@istar-ts/core';\nimport type {\n CheckEdgeResultAction,\n DirtyStateChangeReason,\n IstarAction,\n IstarOperation,\n RequestCheckEdgeAction,\n RequestContextActions,\n RequestMarkersAction,\n RequestModelAction,\n RequestTypeHintsAction,\n SaveModelAction,\n SetContextActions,\n SetMarkersAction,\n SetModelAction,\n SetTypeHintsAction,\n} from './actions';\nimport { isOperation, isRequestAction } from './actions';\nimport { contextActionsFor, paletteFromMetamodel, typeHintsFor } from './hints';\nimport { diagnosticToMarker } from './markers';\n\n/** The response a request is answered with; `never` for other actions. */\nexport type ResponseFor<A> = A extends RequestModelAction\n ? SetModelAction\n : A extends RequestTypeHintsAction\n ? SetTypeHintsAction\n : A extends RequestCheckEdgeAction\n ? CheckEdgeResultAction\n : A extends RequestContextActions\n ? SetContextActions\n : A extends RequestMarkersAction\n ? SetMarkersAction\n : never;\n\n/**\n * What dispatching an action did. Plain JSON, like the actions.\n *\n * A rejection (`ok: false`) left the model untouched: the same model object, no undo step. Its\n * diagnostics say why (an unknown element, a link `canLink` refuses, a guard, a property schema).\n */\nexport type ActionResult<R = never> =\n | {\n readonly ok: true;\n /** Ids of the elements, then links, the action added, in model order. */\n readonly createdIds: readonly string[];\n /** A request's answer. */\n readonly response?: R;\n /** Non-error diagnostics from guards, for an operation that was applied anyway. */\n readonly diagnostics?: readonly GoalDiagnostic[];\n }\n | { readonly ok: false; readonly diagnostics: readonly GoalDiagnostic[] };\n\nexport type ActionListener<EK extends string = ElementKind, LK extends string = LinkKind> = (\n action: IstarAction<EK, LK>,\n) => void;\n\n/**\n * Sends actions and hears what the other side sends back. Implemented in-process by\n * `createActionDispatcher`; a transport implements it over a message port.\n */\n/** `dispatch`'s second argument. */\nexport interface DispatchOptions {\n /**\n * Echoed back as `origin` on every `ModelSourceChangedAction` and `SetDirtyStateAction` this\n * dispatch causes (each change of a compound, both events of an undo or redo), so a listener\n * can tell which surface or client made a change without tracking it itself. Carried through\n * `createRemoteDispatcher`/`connectDispatcher` and by `createMirrorStore`'s dispatcher, so it\n * survives a round trip to a remote host. Optional: a change with no origin (a host's direct\n * `store.load`, for instance) has none.\n */\n readonly origin?: string;\n}\n\nexport interface ActionDispatcher<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * For a **local** dispatcher (`createActionDispatcher`), an operation, `glspUndo`/`glspRedo`,\n * and the guards and postGuards around them, are applied to the store and every listener\n * (`subscribe`, the store's own) is notified synchronously, before this call's promise is\n * created to resolve — only `saveModel` awaits. Code that needs to see the result of an action\n * before its own next statement (not just before `await dispatch(...)` resolves) can rely on\n * this for a local dispatcher; it does **not** hold across a `createRemoteDispatcher`/\n * `connectDispatcher` transport or a `createMirrorStore` mirror, where a change always arrives\n * after a message round trip. Use `origin` ({@link DispatchOptions}) instead where that\n * portability matters — it is carried through both.\n */\n dispatch<A extends IstarAction<EK, LK>>(\n action: A,\n options?: DispatchOptions,\n ): Promise<ActionResult<ResponseFor<A>>>;\n /**\n * Hears the actions the dispatcher sends: `ModelSourceChangedAction` after every model change,\n * `SetDirtyStateAction` when the dirty state flips, and the notifications dispatched to it.\n * Returns an unsubscribe function.\n */\n subscribe(listener: ActionListener<EK, LK>): () => void;\n}\n\n/**\n * A host's rule, run before each operation is applied (and before each operation of a compound\n * one, against the model as the previous ones left it). Diagnostics of severity `error` reject\n * the operation; others are returned with the result.\n */\nexport type ActionGuard<EK extends string = ElementKind, LK extends string = LinkKind> = (\n operation: IstarOperation<EK, LK>,\n model: IstarModel<EK, LK>,\n) => readonly GoalDiagnostic[] | void;\n\n/**\n * A host's rule, run after each operation is applied (and after each operation of a compound\n * one, plus once more on the compound's own result), inside the operation's transaction. Sees\n * the model as the operation leaves it (`modelAfter`) and as it was before (`modelBefore`), so\n * it can check things a pre-guard can't without re-applying the operation itself (goal-controller's\n * edgeV2 engine check is the motivating case). Diagnostics of severity `error` roll the\n * transaction back: the model is untouched and there is no undo entry. Others are returned with\n * the result, merged with pre-guards' warnings.\n */\nexport type ActionPostGuard<EK extends string = ElementKind, LK extends string = LinkKind> = (\n operation: IstarOperation<EK, LK>,\n modelAfter: IstarModel<EK, LK>,\n modelBefore: IstarModel<EK, LK>,\n) => readonly GoalDiagnostic[] | void;\n\nexport interface ActionDispatcherOptions<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> {\n readonly guards?: readonly ActionGuard<EK, LK>[];\n /** Run after each operation is applied; see `ActionPostGuard`. */\n readonly postGuards?: readonly ActionPostGuard<EK, LK>[];\n /**\n * What `RequestContextActions` offers: a fixed description, or a function evaluated on each\n * request (so a host can track a registry or extensions that change after this dispatcher was\n * created — a plain `AnyPaletteDescription` is read once, at creation). Default: derived from\n * the model's current metamodel (`paletteFromMetamodel`), the same fallback `contributionFor`\n * (`@istar-ts/glsp`) uses — not iStar 2.0's palette regardless of dialect.\n */\n readonly palette?: AnyPaletteDescription | (() => AnyPaletteDescription);\n /**\n * Property schemas an operation must not break: an operation that adds an issue\n * (`validateModelProperties`) is rejected. Their issues are also markers.\n */\n readonly schemas?: readonly PropertySchema<PropertyShape, string>[];\n /** The host's diagnostics (e.g. a `DiagnosticsStore`'s `getAll`), reported as markers. */\n readonly diagnostics?: () => readonly GoalDiagnostic[];\n /** Writes the file for `SaveModelAction`; without it, saving is rejected. */\n readonly save?: (file: PistarFile, action: SaveModelAction) => void | Promise<void>;\n /** `ModelSourceChangedAction.sourceModelName`, e.g. the file name. Default `''`. */\n readonly sourceModelName?: string;\n /**\n * Attach the new model to every `sourceModelChanged` as `newRoot` (piStar JSON), so a mirror\n * on the other end of a transport (`createMirrorStore`) follows without a `requestModel` round\n * trip. Costs a `toPistarObject` per change (0.3 ms on the largest fixture). Default false.\n */\n readonly sendModel?: boolean;\n}\n\nexport interface StoreActionDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends ActionDispatcher<EK, LK> {\n /** True while the model differs from the one last saved (or loaded, or given at creation). */\n isDirty(): boolean;\n /** Stops listening to the store. */\n dispose(): void;\n}\n\n/** Thrown inside a transaction to roll it back and reject the action. */\nclass Rejection extends Error {\n readonly diagnostics: readonly GoalDiagnostic[];\n constructor(diagnostics: readonly GoalDiagnostic[]) {\n super(diagnostics.map((d) => d.message).join('; '));\n this.diagnostics = diagnostics;\n }\n}\n\nfunction reject(message: string, elementId = '', code?: string): never {\n throw new Rejection([\n { elementId, severity: 'error', message, ...(code === undefined ? {} : { code }) },\n ]);\n}\n\nfunction rejectCheck(\n check: Extract<LinkCheck, { ok: false }>,\n endpoints: { readonly source: string; readonly target: string },\n): never {\n throw new Rejection([connectResultToDiagnostic(check as ConnectResult, endpoints)!]);\n}\n\nfunction metaOf(model: AnyIstarModel): AnyMetamodel {\n return metamodelOf(model) as unknown as AnyMetamodel;\n}\n\n/**\n * Keys `istar.updateModelExtra`'s `set`/`remove` must not touch: every key core models itself\n * (`TOP_LEVEL_KEYS`, which includes `tool`), and `\"metamodel\"` (`istar.setFileMetamodel`'s own).\n */\nconst RESERVED_EXTRA_KEYS: ReadonlySet<string> = new Set([...TOP_LEVEL_KEYS, FILE_METAMODEL_KEY]);\n\n/** A model with `links` changed, as the core operations derive one. */\nfunction withLinks(model: AnyIstarModel, links: ReadonlyMap<string, IstarLink<string>>) {\n return inheritMetamodel(model, inheritSourceLayout(model, { ...model, links }));\n}\n\nfunction createdIds(before: AnyIstarModel, after: AnyIstarModel): string[] {\n const ids: string[] = [];\n for (const id of after.elements.keys()) if (!before.elements.has(id)) ids.push(id);\n for (const id of after.links.keys()) if (!before.links.has(id)) ids.push(id);\n return ids;\n}\n\nfunction issueKey(d: { readonly id: string; readonly key: string; readonly message: string }) {\n return `${d.id}\\u0000${d.key}\\u0000${d.message}`;\n}\n\nfunction linkIssueDiagnostics(model: AnyIstarModel): GoalDiagnostic[] {\n return validateModel(model).map((issue) => ({\n elementId: issue.linkId,\n severity: 'error',\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * A dispatcher over `store`, in-process. Hand it to a transport to serve remote clients.\n */\nexport function createActionDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n>(\n store: ModelStore<EK, LK>,\n options: ActionDispatcherOptions<EK, LK> = {},\n): StoreActionDispatcher<EK, LK> {\n const s = store as unknown as ModelStore<string, string>;\n const guards = (options.guards ?? []) as readonly ActionGuard<string, string>[];\n const postGuards = (options.postGuards ?? []) as readonly ActionPostGuard<string, string>[];\n const resolvePalette = (meta: AnyMetamodel): AnyPaletteDescription => {\n const option = options.palette;\n if (typeof option === 'function') return option();\n return option ?? paletteFromMetamodel(meta);\n };\n const sourceModelName = options.sourceModelName ?? '';\n const listeners = new Set<ActionListener<string, string>>();\n\n let saved: AnyIstarModel = s.getModel();\n let dirty = false;\n /**\n * The origin of the dispatch currently applying synchronously (set by `dispatch`, around the\n * synchronous part of `run`): what the store's subscription below echoes on\n * `sourceModelChanged`/`setDirtyState`. `undefined` for a change not caused by a dispatch (a\n * host's direct `store.load`) or once `run`'s synchronous part has returned.\n */\n let currentOrigin: string | undefined;\n\n const emit = (action: IstarAction<string, string>): void => {\n for (const listener of listeners) listener(action);\n };\n\n const updateDirty = (reason: DirtyStateChangeReason, origin: string | undefined): void => {\n const next = s.getModel() !== saved;\n if (next === dirty) return;\n dirty = next;\n emit({\n kind: 'setDirtyState',\n isDirty: next,\n reason,\n ...(origin === undefined ? {} : { origin }),\n });\n };\n\n const REASONS: Record<ModelChangeEvent['source'], DirtyStateChangeReason> = {\n edit: 'operation',\n undo: 'undo',\n redo: 'redo',\n load: 'external',\n };\n const unsubscribe = s.subscribe((event) => {\n // A load opens a file: the new model is the saved one.\n if (event.source === 'load') saved = event.model;\n emit({\n kind: 'sourceModelChanged',\n sourceModelName,\n source: event.source,\n changes: event.changes,\n ...(options.sendModel ? { newRoot: toPistarObject(event.model) } : {}),\n ...(options.sendModel ? { canUndo: s.canUndo(), canRedo: s.canRedo() } : {}),\n ...(currentOrigin === undefined ? {} : { origin: currentOrigin }),\n });\n updateDirty(REASONS[event.source], currentOrigin);\n });\n\n // -------------------------------------------------------------------------------------------\n // Operations\n\n const requireElement = (id: string) =>\n s.getModel().elements.get(id) ?? reject(`unknown element \"${id}\"`, id, 'unknown-element');\n\n const runGuards = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]) => {\n const errors: GoalDiagnostic[] = [];\n for (const guard of guards) {\n for (const d of guard(operation, s.getModel()) ?? []) {\n (d.severity === 'error' ? errors : warnings).push(d);\n }\n }\n if (errors.length > 0) throw new Rejection(errors);\n };\n\n const runPostGuards = (\n operation: IstarOperation<string, string>,\n before: AnyIstarModel,\n warnings: GoalDiagnostic[],\n ) => {\n const errors: GoalDiagnostic[] = [];\n for (const guard of postGuards) {\n for (const d of guard(operation, s.getModel(), before) ?? []) {\n (d.severity === 'error' ? errors : warnings).push(d);\n }\n }\n if (errors.length > 0) throw new Rejection(errors);\n };\n\n const apply = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]): void => {\n runGuards(operation, warnings);\n const before = s.getModel();\n doApply(operation, warnings);\n runPostGuards(operation, before, warnings);\n };\n\n const doApply = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]): void => {\n const model = s.getModel();\n const meta = metaOf(model);\n switch (operation.kind) {\n case 'createNode': {\n const { elementTypeId: kind, containerId, args = {} } = operation;\n const definition =\n meta.elements.get(kind) ??\n reject(`unknown element kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n if (definition.role === 'hub') {\n reject(`a ${definition.label} is created with its link (createEdge)`, '', 'hub-kind');\n }\n const container = containerId === undefined ? undefined : requireElement(containerId);\n if (definition.category === 'node') {\n // piStar only adds an element where its kind may be: inside an actor, or on paper.\n if (container && definition.info?.canBeInnerElement === false) {\n reject(`a ${definition.label} cannot be inside an actor`, containerId, 'container');\n }\n if (!container && definition.info?.canBeOnPaper === false) {\n reject(`a ${definition.label} must be created inside an actor`, '', 'container');\n }\n }\n const location = operation.location ?? container ?? { x: 0, y: 0 };\n s.addElement({\n kind,\n x: location.x,\n y: location.y,\n ...(containerId === undefined ? {} : { parent: containerId }),\n ...(args.id === undefined ? {} : { id: args.id }),\n ...(args.name === undefined ? {} : { name: args.name }),\n ...(args.customProperties ? { customProperties: args.customProperties } : {}),\n });\n return;\n }\n case 'createEdge': {\n const { elementTypeId: kind, sourceElementId: source, targetElementId: target } = operation;\n const args = operation.args ?? {};\n const definition =\n meta.links.get(kind) ??\n reject(`unknown link kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n if (definition.category === 'dependency') {\n const dependum = args.dependum ?? {};\n const dependumKind =\n dependum.kind ??\n [...meta.elements.values()].find(\n (d) => d.category === 'node' && d.role !== 'hub' && d.info?.canBeDependum !== false,\n )?.kind ??\n reject(`${meta.name} has no kind that can be a dependum`, '', 'unknown-kind');\n const result = s.addDependency({\n depender: source,\n dependee: target,\n linkKind: kind,\n dependum: {\n kind: dependumKind,\n ...(dependum.id === undefined ? {} : { id: dependum.id }),\n ...(dependum.name === undefined ? {} : { name: dependum.name }),\n ...(dependum.location ? { x: dependum.location.x, y: dependum.location.y } : {}),\n ...(dependum.customProperties ? { customProperties: dependum.customProperties } : {}),\n },\n ...(args.linkIds ? { linkIds: args.linkIds } : {}),\n });\n if (!result.ok) rejectCheck(result, { source, target });\n return;\n }\n const values = definition.info.possibleLabels;\n if (args.value !== undefined && values && !values.includes(args.value)) {\n reject(\n `\"${args.value}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n source,\n 'invalid-value',\n );\n }\n const result = s.connect({\n kind,\n source,\n target,\n ...(args.id === undefined ? {} : { id: args.id }),\n ...(args.value === undefined ? {} : { label: args.value }),\n ...(args.name === undefined ? {} : { name: args.name }),\n ...(args.customProperties ? { customProperties: args.customProperties } : {}),\n ...(args.legId === undefined ? {} : { legId: args.legId }),\n ...(args.endId === undefined ? {} : { endId: args.endId }),\n });\n if (!result.ok) rejectCheck(result, { source, target });\n return;\n }\n case 'deleteElement': {\n const elements: string[] = [];\n const links: string[] = [];\n for (const id of operation.elementIds) {\n if (model.elements.has(id)) elements.push(id);\n else if (model.links.has(id)) links.push(id);\n else reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n }\n if (elements.length > 0) s.removeElements(elements);\n // Removing elements may already have taken some of the links with them.\n for (const id of links) if (s.getModel().links.has(id)) s.disconnect(id);\n return;\n }\n case 'changeBounds': {\n for (const { elementId, newPosition, newSize } of operation.newBounds) {\n requireElement(elementId);\n if (newPosition) s.moveElement(elementId, newPosition.x, newPosition.y);\n if (newSize) {\n s.updateElement(elementId, {\n display: { width: newSize.width, height: newSize.height },\n });\n }\n }\n return;\n }\n case 'changeContainer': {\n const { elementId, targetContainerId, location } = operation;\n s.nestElement(elementId, targetContainerId);\n if (location) s.moveElement(elementId, location.x, location.y);\n return;\n }\n case 'reconnectEdge':\n reconnect(operation.edgeElementId, operation.sourceElementId, operation.targetElementId);\n return;\n case 'applyLabelEdit': {\n const hash = operation.labelId.indexOf('#');\n const id = hash < 0 ? operation.labelId : operation.labelId.slice(0, hash);\n const key = hash < 0 ? undefined : operation.labelId.slice(hash + 1);\n if (key === undefined) {\n if (model.elements.has(id)) s.updateElement(id, { name: operation.text });\n // A link's name is optional; an empty text removes it, matching what piStar writes\n // for a link whose name was cleared (fileManager.js only writes `name` when truthy).\n else if (model.links.has(id)) {\n s.updateLink(id, { name: operation.text === '' ? null : operation.text });\n } else reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n } else {\n setProperties(id, { [key]: operation.text });\n }\n return;\n }\n case 'compound':\n for (const child of operation.operationList) apply(child, warnings);\n return;\n case 'istar.addLeg': {\n const { hubId, sourceElementId: source } = operation;\n const result = s.addLeg(hubId, source, operation.args?.id ? { id: operation.args.id } : {});\n if (!result.ok) rejectCheck(result, { source, target: hubId });\n return;\n }\n case 'istar.removeLeg':\n s.removeLeg(operation.legId);\n return;\n case 'istar.setCollapsed': {\n const element = requireElement(operation.elementId);\n if (meta.elements.get(element.kind)?.category !== 'actor') {\n reject(`\"${element.id}\" is not an actor`, element.id, 'not-an-actor');\n }\n s.setCollapsed(element.id, operation.collapsed);\n return;\n }\n case 'istar.updateDiagram': {\n const { name, width, height, customProperties } = operation.diagram;\n s.updateDiagram({\n ...(name === undefined ? {} : { name }),\n ...(width === undefined ? {} : { width }),\n ...(height === undefined ? {} : { height }),\n ...(customProperties === undefined ? {} : { customProperties }),\n });\n return;\n }\n case 'istar.updateProperties':\n setProperties(operation.elementId, operation.properties);\n return;\n case 'istar.updateDisplay':\n requireElement(operation.elementId);\n s.updateElement(operation.elementId, { display: operation.patch });\n return;\n case 'istar.updateLinkDisplay':\n if (!model.links.has(operation.linkId)) {\n reject(`unknown link \"${operation.linkId}\"`, operation.linkId, 'unknown-element');\n }\n s.updateLink(operation.linkId, { display: operation.patch });\n return;\n case 'istar.setLinkValue': {\n const { linkId, value } = operation;\n const link =\n model.links.get(linkId) ?? reject(`unknown link \"${linkId}\"`, linkId, 'unknown-element');\n const definition = meta.links.get(link.kind);\n const values = definition?.info.possibleLabels;\n if (value !== null && values && !values.includes(value)) {\n reject(\n `\"${value}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n linkId,\n 'invalid-value',\n );\n }\n s.updateLink(linkId, { label: value });\n return;\n }\n case 'istar.changeLinkKind': {\n const { linkIds, elementTypeId: kind } = operation;\n if (linkIds.length === 0) return;\n const ids = new Set(linkIds);\n const links = [...ids].map(\n (id) => model.links.get(id) ?? reject(`unknown link \"${id}\"`, id, 'unknown-element'),\n );\n const definition =\n meta.links.get(kind) ??\n reject(`unknown link kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n const toChange = links.filter((link) => link.kind !== kind);\n if (toChange.length === 0) return;\n const remaining = new Map(model.links);\n for (const id of ids) remaining.delete(id);\n const without = withLinks(model, remaining);\n const values = definition.info.possibleLabels;\n for (const link of toChange) {\n const check = canLink(without, link.source, link.target, kind);\n if (!check.ok) rejectCheck(check, { source: link.source, target: link.target });\n if (link.label != null && values && !values.includes(link.label)) {\n reject(\n `\"${link.label}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n link.id,\n 'invalid-value',\n );\n }\n }\n const next = new Map(model.links);\n for (const link of toChange) next.set(link.id, { ...link, kind });\n s.replace(withLinks(model, next));\n return;\n }\n case 'istar.setFileMetamodel': {\n let next: AnyIstarModel;\n try {\n next = withFileMetamodel(model, operation.block);\n } catch (error) {\n if (error instanceof MetamodelError) reject(error.message, '', 'invalid-metamodel');\n throw error;\n }\n s.replace(next);\n return;\n }\n case 'istar.updateModelExtra': {\n const { set, remove, tool } = operation;\n for (const key of [...Object.keys(set ?? {}), ...(remove ?? [])]) {\n if (!RESERVED_EXTRA_KEYS.has(key)) continue;\n if (key === 'tool') {\n reject(\n `\"tool\" is a modelled field: set it with this operation's own \"tool\"`,\n '',\n 'reserved-key',\n );\n }\n if (key === FILE_METAMODEL_KEY) {\n reject(\n `\"${key}\" is set with istar.setFileMetamodel, not updateModelExtra`,\n '',\n 'reserved-key',\n );\n }\n reject(\n `\"${key}\" is modelled by the file itself and cannot be an extra key`,\n '',\n 'reserved-key',\n );\n }\n let withTool: AnyIstarModel = model;\n if (tool === null) {\n const { tool: _tool, ...rest } = withTool;\n withTool = rest;\n } else if (tool !== undefined) {\n withTool = { ...withTool, tool };\n }\n const extra: Record<string, unknown> = { ...withTool.extra };\n if (set) for (const [key, value] of Object.entries(set)) extra[key] = value;\n if (remove) for (const key of remove) delete extra[key];\n const { extra: _extra, ...rest } = withTool;\n const next: AnyIstarModel = {\n ...rest,\n ...(Object.keys(extra).length > 0 ? { extra: extra as Extra } : {}),\n };\n s.replace(inheritMetamodel(model, inheritSourceLayout(model, next)));\n return;\n }\n case 'istar.replaceModel': {\n const host = hostMetamodelOf(model) ?? meta;\n let next: AnyIstarModel;\n try {\n next = parsePistar(operation.model, {\n metamodel: host,\n fileMetamodel: operation.fileMetamodel ?? false,\n });\n } catch (error) {\n if (error instanceof PistarParseError) reject(error.message, '', 'parse-error');\n throw error;\n }\n s.replace(next);\n return;\n }\n default:\n reject(`unknown operation \"${(operation as { kind: string }).kind}\"`, '', 'unknown-action');\n }\n };\n\n /** Sets (or, with `null`, removes) custom properties of an element or link. */\n const setProperties = (id: string, properties: Readonly<Record<string, string | null>>) => {\n const model = s.getModel();\n const owner = model.elements.get(id) ?? model.links.get(id);\n if (!owner) reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n const next: Record<string, string> = { ...owner.customProperties };\n for (const [key, value] of Object.entries(properties)) {\n if (value === null) delete next[key];\n else if (typeof value === 'string') next[key] = value;\n else reject(`the value of \"${key}\" must be a string or null`, id, 'invalid-value');\n }\n // Removing the last property keeps an empty object, as piStar's exports do\n // (\"customProperties\": {}); an owner that never had the key and ends up with none stays without it.\n if (Object.keys(next).length === 0 && owner.customProperties === undefined) return;\n const customProperties: CustomProperties = next;\n if (model.elements.has(id)) s.updateElement(id, { customProperties });\n else s.updateLink(id, { customProperties });\n };\n\n /**\n * Gives a link new ends, checked with `canLink` against the model without it. The link keeps\n * its place in the model (and the file), its id and everything else it carries.\n */\n const reconnect = (id: string, source: string, target: string): void => {\n const model = s.getModel();\n const meta = metaOf(model);\n const link = model.links.get(id) ?? reject(`unknown link \"${id}\"`, id, 'unknown-element');\n if (link.source === source && link.target === target) return;\n const definition = meta.links.get(link.kind);\n const others = new Map(model.links);\n others.delete(id);\n const without = withLinks(model, others);\n let check: LinkCheck;\n if (definition?.category === 'dependency') {\n // A dependency's link keeps its dependum end; the check is depender → dependee.\n const dependumAtTarget = model.elements.get(link.target)?.isDependum === true;\n const dependumId = dependumAtTarget ? link.target : link.source;\n if ((dependumAtTarget ? target : source) !== dependumId) {\n reject('a dependency link keeps its dependum', id, 'dependum-endpoint');\n }\n const ends = dependencyEnds(model, dependumId);\n const depender = dependumAtTarget ? source : ends.depender;\n const dependee = dependumAtTarget ? ends.dependee : target;\n if (depender === undefined || dependee === undefined) {\n reject('the dependency is incomplete', id, 'dependum-endpoint');\n }\n check = canLink(without, depender, dependee, link.kind);\n if (!check.ok) rejectCheck(check, { source: depender, target: dependee });\n } else {\n // An n-ary link's end stays on its hub, and a leg can't leave a hub without legs.\n if (definition?.role === 'end' && source !== link.source) {\n reject('the end of an n-ary link stays on its hub', id, 'hub-target');\n }\n if (definition?.role === 'leg' && target !== link.target) {\n const legs = [...model.links.values()].filter(\n (l) => l.target === link.target && l.kind === link.kind,\n );\n if (legs.length === 1) {\n reject('the last leg of an n-ary link cannot leave its hub', id, 'hub-target');\n }\n }\n check = canLink(without, source, target, link.kind);\n if (!check.ok) rejectCheck(check, { source, target });\n }\n s.replace(withLinks(model, new Map(model.links).set(id, { ...link, source, target })));\n };\n\n const runOperation = (operation: IstarOperation<string, string>): ActionResult => {\n const before = s.getModel();\n const warnings: GoalDiagnostic[] = [];\n s.transaction(() => {\n apply(operation, warnings);\n const schemas = options.schemas;\n if (!schemas || s.getModel() === before) return;\n const known = new Set(validateModelProperties(before, schemas).map(issueKey));\n const added = validateModelProperties(s.getModel(), schemas).filter(\n (issue) => !known.has(issueKey(issue)),\n );\n if (added.length > 0) {\n throw new Rejection(\n added.map((issue) => ({\n elementId: issue.id,\n key: issue.key,\n severity: 'error',\n message: issue.message,\n code: 'invalid-property',\n })),\n );\n }\n });\n return {\n ok: true,\n createdIds: createdIds(before, s.getModel()),\n ...(warnings.length > 0 ? { diagnostics: warnings } : {}),\n };\n };\n\n // -------------------------------------------------------------------------------------------\n // Requests\n\n const checkEdge = (action: RequestCheckEdgeAction): CheckEdgeResultAction => {\n const { edgeType, sourceElementId: source, targetElementId: target } = action;\n const model = s.getModel();\n const meta = metaOf(model);\n const answer = (check: LinkCheck): CheckEdgeResultAction => ({\n kind: 'checkEdgeTargetResult',\n responseId: action.requestId,\n isValid: check.ok,\n edgeType,\n sourceElementId: source,\n ...(target === undefined ? {} : { targetElementId: target }),\n ...(check.ok ? {} : { reason: check.reason, code: check.code }),\n });\n if (target !== undefined) {\n const check = canLink(model, source, target, edgeType);\n // `createEdge` retries reversed where piStar does (Needed-By, Qualification).\n if (!check.ok && meta.links.get(edgeType)?.info.tryReversedWhenAdding) {\n const reversed = canLink(model, target, source, edgeType);\n if (reversed.ok) return answer(reversed);\n }\n return answer(check);\n }\n // No target yet: can the source start such a link at all?\n const element = model.elements.get(source);\n if (!element) {\n return answer({\n ok: false,\n code: 'unknown-element',\n reason: `unknown source element \"${source}\"`,\n });\n }\n const hint = typeHintsFor(meta).edgeHints.find((h) => h.elementTypeId === edgeType);\n if (!hint) {\n return answer({\n ok: false,\n code: 'unknown-link-kind',\n reason: `unknown link kind \"${edgeType}\"`,\n });\n }\n if (hint.sourceElementTypeIds && !hint.sourceElementTypeIds.includes(element.kind)) {\n return answer({\n ok: false,\n code: 'invalid-source',\n reason: `a ${meta.elements.get(element.kind)?.label ?? element.kind} cannot be the source of a ${meta.links.get(edgeType)?.label ?? edgeType} link`,\n });\n }\n return answer({ ok: true });\n };\n\n const markers = (action: RequestMarkersAction): SetMarkersAction => {\n const model = s.getModel();\n const diagnostics: GoalDiagnostic[] = linkIssueDiagnostics(model);\n if (options.schemas) {\n for (const issue of validateModelProperties(model, options.schemas)) {\n diagnostics.push({\n elementId: issue.id,\n key: issue.key,\n severity: 'error',\n message: issue.message,\n code: 'invalid-property',\n });\n }\n }\n diagnostics.push(...(options.diagnostics?.() ?? []));\n const ids = action.elementsIDs.filter((id) => model.elements.has(id) || model.links.has(id));\n const wanted = new Set(ids);\n return {\n kind: 'setMarkers',\n responseId: action.requestId,\n markers: diagnostics\n .filter((d) => wanted.size === 0 || wanted.has(d.elementId))\n .map(diagnosticToMarker),\n ...(action.reason === undefined ? {} : { reason: action.reason }),\n };\n };\n\n const respond = (action: IstarAction<string, string>) => {\n const model = s.getModel();\n switch (action.kind) {\n case 'requestModel':\n return { kind: 'setModel', responseId: action.requestId, newRoot: toPistarObject(model) };\n case 'requestTypeHints':\n return {\n kind: 'setTypeHints',\n responseId: action.requestId,\n ...typeHintsFor(metaOf(model)),\n };\n case 'requestCheckEdge':\n return checkEdge(action);\n case 'requestContextActions': {\n const meta = metaOf(model);\n return {\n kind: 'setContextActions',\n responseId: action.requestId,\n ...contextActionsFor(resolvePalette(meta), meta),\n };\n }\n case 'requestMarkers':\n return markers(action);\n default:\n return undefined;\n }\n };\n\n // -------------------------------------------------------------------------------------------\n\n const run = async (\n action: IstarAction<string, string>,\n origin: string | undefined,\n ): Promise<ActionResult<unknown>> => {\n if (isOperation(action)) return runOperation(action);\n if (isRequestAction(action)) return { ok: true, createdIds: [], response: respond(action) };\n switch (action.kind) {\n case 'glspUndo':\n s.undo();\n return { ok: true, createdIds: [] };\n case 'glspRedo':\n s.redo();\n return { ok: true, createdIds: [] };\n case 'saveModel': {\n if (!options.save) reject('this host does not save models', '', 'no-save-handler');\n const model = s.getModel();\n await options.save(toPistarObject(model, { saveDate: new Date() }), action);\n saved = model;\n updateDirty('save', origin);\n return { ok: true, createdIds: [] };\n }\n case 'sourceModelChanged':\n case 'setDirtyState':\n case 'triggerNodeCreation':\n case 'triggerEdgeCreation':\n case 'deleteMarkers':\n emit(action);\n return { ok: true, createdIds: [] };\n default:\n return reject(\n `\"${action.kind}\" is not an action this dispatcher handles`,\n '',\n 'unknown-action',\n );\n }\n };\n\n return {\n async dispatch(action, dispatchOptions) {\n const origin = dispatchOptions?.origin;\n // `run`'s synchronous part (an operation, undo, redo, their guards) applies and notifies\n // listeners before this call returns to its caller below, still inside this `try`: see\n // `ActionDispatcher.dispatch`'s doc comment. `currentOrigin` is reset right after, before\n // any `await`, so it can't leak into an unrelated dispatch's own synchronous part.\n currentOrigin = origin;\n let pending: Promise<ActionResult<unknown>>;\n try {\n pending = run(action as IstarAction<string, string>, origin);\n } finally {\n currentOrigin = undefined;\n }\n try {\n return (await pending) as ActionResult<never>;\n } catch (error) {\n if (error instanceof Rejection) return { ok: false, diagnostics: error.diagnostics };\n if (error instanceof ModelOperationError) {\n return { ok: false, diagnostics: [error.toDiagnostic()] };\n }\n throw error;\n }\n },\n subscribe(listener) {\n const l = listener as ActionListener<string, string>;\n listeners.add(l);\n return () => listeners.delete(l);\n },\n isDirty: () => s.getModel() !== saved,\n dispose: unsubscribe,\n };\n}\n","/**\n * Host extensions (#175): what a host application gives an agent beyond the model's metamodel —\n * context the model should read (free-text help, notation, pooled values) and extra tools\n * (lookups, external validators, edits of its own). Opaque data plus handler functions: nothing\n * here, nor in the packages that serve them, knows any host's domain.\n *\n * Defined once, a tool or provider works on every backend: `@istar-ts/glsp`'s MCP launchers\n * (`mcp: { hostTools, context }`) register them as session-scoped server-mcp handlers next to\n * the istar tools, `@istar-ts/agent`'s action backend (`createActionToolRegistry`'s and\n * `createActionChangeSet`'s `hostTools`) lists the tools next to the action tools, and\n * `runAgent`'s `context` splices the providers into the system prompt. A tool reaches the model\n * only through the `dispatcher` it is handed, so the host's guards and schemas apply and the\n * session keeps one undo stack.\n */\nimport type { AnyIstarModel, GoalDiagnostic } from '@istar-ts/core';\nimport { isRequestAction } from './actions';\nimport type { ActionDispatcher, ActionResult } from './dispatcher';\n\n/** A host's knowledge for the model: a system-prompt section and/or an MCP resource. */\nexport interface HostContextProvider {\n /**\n * `^[a-zA-Z0-9_-]{1,64}$`: the MCP resource's name (and its tool's, when the server lists\n * resources as tools), and the section's heading unless `title` is set.\n */\n readonly name: string;\n readonly title?: string;\n /** What the resource holds, for an MCP client's catalog. Default: the title. */\n readonly description?: string;\n /** The text: fixed, or computed from the model each time it is read. */\n readonly text: string | ((model: AnyIstarModel) => string | Promise<string>);\n /** Also a section of `runAgent`'s system prompt. Default true. */\n readonly prompt?: boolean;\n /** Also an MCP resource of every diagram session. Default true. */\n readonly resource?: boolean;\n}\n\n/** What a host tool's handler is given. */\nexport interface HostToolContext {\n /** The model as it is now: the live one, or a Propose-mode run's scratch copy. */\n getModel(): AnyIstarModel;\n /**\n * The session's dispatcher, the only way a tool edits the model. A read-only tool's refuses\n * everything but requests (`requestModel`, `requestMarkers`, ...), with a `read-only-tool`\n * diagnostic.\n */\n readonly dispatcher: ActionDispatcher<string, string>;\n readonly signal?: AbortSignal;\n}\n\n/**\n * What a host tool answers, in `ActionResult`'s shape: `content` (any JSON value) for the model\n * to read, or a refusal with typed diagnostics it can repair against. A refused dispatch's\n * `ActionResult` is one already: `if (!result.ok) return result;`.\n */\nexport type HostToolResult =\n | { readonly ok: true; readonly content: unknown }\n | { readonly ok: false; readonly diagnostics: readonly GoalDiagnostic[] };\n\n/** A tool of the host's own, served next to the istar tools. */\nexport interface HostTool {\n /** `^[a-zA-Z0-9_-]{1,64}$`, distinct from every other tool's. */\n readonly name: string;\n readonly title?: string;\n /** What the model reads about the tool. */\n readonly description: string;\n /**\n * JSON Schema of the arguments: an object schema (`{ type: 'object', properties, required }`).\n * Over MCP the server validates calls against it (it needs `zod` 4.2 or later, for\n * `z.fromJSONSchema`), with the session's `sessionId` added.\n */\n readonly inputSchema: { readonly [key: string]: unknown };\n /**\n * True for a tool that only reads (MCP's `readOnlyHint`): Propose mode runs it straight away\n * and never makes it a review step, and its `dispatcher` takes requests only.\n */\n readonly readOnly?: boolean;\n handler(\n args: { readonly [key: string]: unknown },\n context: HostToolContext,\n ): HostToolResult | Promise<HostToolResult>;\n}\n\n/** `dispatcher`, refusing anything but requests: what a read-only host tool is handed. */\nexport function readOnlyDispatcher(\n dispatcher: ActionDispatcher<string, string>,\n tool: string,\n): ActionDispatcher<string, string> {\n return {\n dispatch: (action) =>\n isRequestAction(action)\n ? dispatcher.dispatch(action)\n : Promise.resolve({\n ok: false,\n diagnostics: [\n {\n elementId: '',\n severity: 'error',\n code: 'read-only-tool',\n message: `\"${tool}\" is read-only: it cannot dispatch ${action.kind}`,\n },\n ],\n } as ActionResult<never>),\n subscribe: (listener) => dispatcher.subscribe(listener),\n };\n}\n\n/** The context a call of `tool` gets: `dispatcher` as is, or read-only for a read-only tool. */\nexport function hostToolContext(\n tool: HostTool,\n dispatcher: ActionDispatcher<string, string>,\n getModel: () => AnyIstarModel,\n signal?: AbortSignal,\n): HostToolContext {\n return {\n getModel,\n dispatcher: tool.readOnly ? readOnlyDispatcher(dispatcher, tool.name) : dispatcher,\n ...(signal ? { signal } : {}),\n };\n}\n\n/** A provider's text for `model`. */\nexport function contextText(provider: HostContextProvider, model: AnyIstarModel): Promise<string> {\n const { text } = provider;\n return Promise.resolve(typeof text === 'string' ? text : text(model));\n}\n","/**\n * A built-in context provider (#240): what an agent needs to know about a model's own\n * vocabulary — its element and link kinds, containment, link rules and value sets — derived\n * only from the `Metamodel`, so it works unchanged for iStar 2.0, KAOS, NFR, an\n * `extendMetamodel` result or a file metamodel (pistarExt). No dialect names in this file.\n *\n * `metamodelContextProvider` is the `HostContextProvider` every launcher and agent session\n * includes by default (opt-out: `metamodelContext: false`); a host's own providers are appended\n * after it.\n */\nimport { effectiveLinkKind } from '@istar-ts/core';\nimport type { AnyIstarModel, AnyMetamodel, PropertySchema, PropertyShape } from '@istar-ts/core';\nimport { metamodelOf } from '@istar-ts/core';\nimport { isHub, ofCategory, union } from './kind-selectors';\nimport type { HostContextProvider } from './host';\n\nexport interface MetamodelPropertyContext {\n readonly key: string;\n readonly type: string;\n readonly values?: readonly string[];\n readonly optional?: boolean;\n readonly description?: string;\n}\n\nexport interface MetamodelElementContext {\n readonly kind: string;\n readonly label: string;\n readonly description?: string;\n readonly category: 'actor' | 'node';\n readonly canBeOnPaper?: boolean;\n readonly canBeInnerElement?: boolean;\n readonly properties?: readonly MetamodelPropertyContext[];\n}\n\nexport interface MetamodelLinkContext {\n readonly kind: string;\n readonly label: string;\n readonly description?: string;\n readonly category: 'actor' | 'node' | 'dependency';\n readonly sources: readonly string[];\n readonly targets: readonly string[];\n /** `'n'` for a link joining several sources at a hub (see `Metamodel`'s `arity`). */\n readonly arity?: 'n';\n /** The link's declared value set (e.g. a Contribution link's make/help/hurt/break). */\n readonly values?: readonly string[];\n readonly properties?: readonly MetamodelPropertyContext[];\n}\n\n/** A `Metamodel`, described for an LLM: JSON-serializable, derived only from the metamodel. */\nexport interface MetamodelContext {\n readonly framework: string;\n readonly elements: readonly MetamodelElementContext[];\n readonly links: readonly MetamodelLinkContext[];\n}\n\nexport interface MetamodelContextOptions {\n /**\n * Typed custom-property schemas (`@istar-ts/core`'s `defineProperties`), keyed by kind, e.g.\n * a dialect's own or a contribution's (`IstarGlspContribution.schemas`). Properties a kind has\n * no schema for are left out: `customProperties` values stay strings the metamodel itself\n * knows nothing about.\n */\n readonly schemas?: readonly PropertySchema<PropertyShape, string>[];\n}\n\nfunction propertiesOf(\n kind: string,\n byKind: ReadonlyMap<string, readonly PropertySchema<PropertyShape, string>[]>,\n): readonly MetamodelPropertyContext[] | undefined {\n const schemas = byKind.get(kind);\n if (!schemas || schemas.length === 0) return undefined;\n const properties: MetamodelPropertyContext[] = [];\n for (const schema of schemas) {\n for (const [key, field] of Object.entries(schema.shape)) {\n properties.push({\n key,\n type: field.type,\n ...(field.values ? { values: field.values } : {}),\n ...(field.options.optional ? { optional: true } : {}),\n ...(field.options.description ? { description: field.options.description } : {}),\n });\n }\n }\n return properties;\n}\n\n/**\n * `metamodel`, as a typed, JSON-serializable description: every element and link kind a\n * modeller declares directly (kinds generated for an n-ary link's hub, leg or end are left out,\n * as a hand-written palette hides them too), its containment, and each link kind's source and\n * target kinds in words, resolved the same way `canLink` does (`union`/`ofCategory`).\n */\nexport function metamodelContext(\n metamodel: AnyMetamodel,\n options: MetamodelContextOptions = {},\n): MetamodelContext {\n const schemasByKind = new Map<string, PropertySchema<PropertyShape, string>[]>();\n for (const schema of options.schemas ?? []) {\n const list = schemasByKind.get(schema.kind) ?? [];\n list.push(schema);\n schemasByKind.set(schema.kind, list);\n }\n\n const elements: MetamodelElementContext[] = [];\n for (const definition of metamodel.elements.values()) {\n if (isHub(definition)) continue;\n elements.push({\n kind: definition.kind,\n label: definition.label,\n ...(definition.description !== undefined ? { description: definition.description } : {}),\n category: definition.category,\n ...(definition.info\n ? {\n canBeOnPaper: definition.info.canBeOnPaper,\n canBeInnerElement: definition.info.canBeInnerElement,\n }\n : {}),\n ...(propertiesOf(definition.kind, schemasByKind)\n ? { properties: propertiesOf(definition.kind, schemasByKind) }\n : {}),\n });\n }\n\n const links: MetamodelLinkContext[] = [];\n for (const definition of metamodel.links.values()) {\n if (definition.role !== undefined) continue;\n const rules = metamodel.links.get(effectiveLinkKind(metamodel, definition.kind))?.rules;\n const builtIn =\n definition.category === 'dependency'\n ? ofCategory(metamodel)\n : ofCategory(metamodel, definition.category as 'actor' | 'node');\n links.push({\n kind: definition.kind,\n label: definition.label,\n ...(definition.description !== undefined ? { description: definition.description } : {}),\n category: definition.category,\n sources: rules ? union(metamodel, rules.sources) : builtIn,\n targets: rules ? union(metamodel, rules.targets) : builtIn,\n ...(definition.arity === 'n' ? { arity: definition.arity } : {}),\n ...(definition.info.possibleLabels ? { values: definition.info.possibleLabels } : {}),\n ...(propertiesOf(definition.kind, schemasByKind)\n ? { properties: propertiesOf(definition.kind, schemasByKind) }\n : {}),\n });\n }\n\n return { framework: metamodel.framework, elements, links };\n}\n\nfunction propertiesLine(properties: readonly MetamodelPropertyContext[] | undefined): string[] {\n if (!properties || properties.length === 0) return [];\n const parts = properties.map((p) => {\n const bits = [p.type, ...(p.values ? [`values: ${p.values.join('/')}`] : [])];\n return `${p.key} (${bits.join(', ')})${p.optional ? '?' : ''}`;\n });\n return [` properties: ${parts.join(', ')}`];\n}\n\nfunction flags(element: MetamodelElementContext): string {\n const bits: string[] = [];\n if (element.canBeOnPaper) bits.push('on paper');\n if (element.canBeInnerElement) bits.push('inner');\n return bits.length > 0 ? ` [${bits.join(', ')}]` : '';\n}\n\nfunction elementLine(element: MetamodelElementContext): string[] {\n const description = element.description ? ` — ${element.description}` : '';\n return [\n `- ${element.kind} (${element.label})${flags(element)}${description}`,\n ...propertiesLine(element.properties),\n ];\n}\n\nfunction linkLine(link: MetamodelLinkContext): string[] {\n const arity = link.arity === 'n' ? ' [n-ary, via a hub]' : '';\n const values = link.values ? `; values: ${link.values.join(', ')}` : '';\n const description = link.description ? ` — ${link.description}` : '';\n return [\n `- ${link.kind} (${link.label})${arity}: ${link.category} link, ` +\n `${link.sources.join(', ')} → ${link.targets.join(', ')}${values}${description}`,\n ...propertiesLine(link.properties),\n ];\n}\n\n/**\n * `context`, rendered as compact, deterministic markdown for an LLM: one section each for actor\n * kinds, node kinds and link kinds, in the metamodel's own declaration order.\n */\nexport function metamodelContextText(context: MetamodelContext): string {\n const actors = context.elements.filter((e) => e.category === 'actor');\n const nodes = context.elements.filter((e) => e.category === 'node');\n const sections = [`# ${context.framework} metamodel`];\n if (actors.length > 0) {\n sections.push(['## Actor kinds', ...actors.flatMap(elementLine)].join('\\n'));\n }\n if (nodes.length > 0) {\n sections.push(['## Node kinds', ...nodes.flatMap(elementLine)].join('\\n'));\n }\n if (context.links.length > 0) {\n sections.push(['## Link kinds', ...context.links.flatMap(linkLine)].join('\\n'));\n }\n return sections.join('\\n\\n');\n}\n\n/**\n * The built-in `HostContextProvider` (#240): its text is always read from the model at hand\n * (`metamodelOf(model)`), so one instance works for every dialect a host serves. `options`\n * (`schemas`, mainly from a dialect's `IstarGlspContribution`) are fixed at creation time.\n */\nexport function metamodelContextProvider(\n options: MetamodelContextOptions = {},\n): HostContextProvider {\n return {\n name: 'metamodel',\n title: \"This model's language\",\n text: (model: AnyIstarModel) =>\n metamodelContextText(metamodelContext(metamodelOf(model) as AnyMetamodel, options)),\n };\n}\n","/**\n * A mirror store: a read-only `ModelStore` in this process whose model follows a dispatcher that\n * lives elsewhere (a worker, a server, the other end of a `createRemoteDispatcher` port), so a\n * canvas and an inspector written against `ModelStore` can render it. Edits never touch the\n * mirror: they are dispatched to the remote, and come back as the remote's `sourceModelChanged`.\n *\n * How the model travels: an initial `requestModel`, then one update per `sourceModelChanged`.\n * A notification that carries the new model (`newRoot`, a dispatcher created with `sendModel`)\n * is applied as it arrives; one without it is answered with a `requestModel`, in order. Either\n * way the update is a whole piStar file, re-parsed (2 ms for the largest fixture, 237 ids), and\n * then shared with the previous model: an element, link or diagram equal to the one it replaces\n * keeps the old object, so whatever is memoised on identity only redoes what changed.\n */\nimport {\n FILE_METAMODEL_KEY,\n ModelOperationError,\n canLink,\n createEmptyModel,\n inheritMetamodel,\n inheritSourceLayout,\n metamodelOf,\n parsePistar,\n} from '@istar-ts/core';\nimport type {\n AnyIstarModel,\n AnyMetamodel,\n ElementKind,\n LinkKind,\n Metamodel,\n ModelChange,\n ModelChangeEvent,\n ModelListener,\n ModelStore,\n ParsePistarOptions,\n PistarFile,\n} from '@istar-ts/core';\nimport type { ActionDispatcher, ActionResult } from './dispatcher';\n\nexport interface MirrorStoreOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * The metamodel the remote's files are read with (`parsePistar`'s `metamodel`), and of the\n * empty model shown until the first one arrives. Default iStar 2.0.\n */\n readonly metamodel?: Metamodel<EK, LK>;\n /** `parsePistar`'s `fileMetamodel`: apply the file's own `\"metamodel\"` block. Default false. */\n readonly fileMetamodel?: boolean;\n /**\n * How many undo steps the remote keeps, for `canUndo` estimate (see `MirrorStore`). Only used\n * when the dispatcher doesn't send exact values. Default 100, a `ModelStore`'s default.\n */\n readonly historyLimit?: number;\n /** Hears a failed update (a transport fault, a file that doesn't parse). Default: ignored. */\n readonly onError?: (error: unknown) => void;\n}\n\n/**\n * A `ModelStore` whose model is the remote's. Reading (`getModel`, `subscribe`, `canLink`) works\n * as on any store; every mutation (`addElement` … `replace`, `load`, `transaction`,\n * `clearHistory`) throws a `ModelOperationError`: dispatch the edit to the remote instead.\n *\n * Undo is the remote's, one stack for all its clients: `undo`/`redo` dispatch `glspUndo` /\n * `glspRedo` to it. `canUndo`/`canRedo` are exact when the dispatcher sends them with each\n * change (a dispatcher created with `sendModel`), or an estimate counted from the notifications\n * heard since the mirror connected (the remote doesn't publish its stack's depth when not sending\n * them): edits made before then are not counted.\n */\nexport interface MirrorStore<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends ModelStore<EK, LK> {\n /** Resolves once the remote's model is shown; rejects if the first `requestModel` fails. */\n readonly ready: Promise<void>;\n /**\n * The remote, wrapped so that `dispatch` resolves only once the mirror shows what the action\n * did: give this to `IstarProvider` as `dispatcher`. (With a `sendModel` remote, the remote\n * itself already has that order, since a change's notification arrives before its result.)\n */\n readonly dispatcher: ActionDispatcher<EK, LK>;\n /** Resolves once every change heard so far is shown. */\n synced(): Promise<void>;\n /** Stops following the remote (the remote itself stays open). */\n dispose(): void;\n}\n\ntype Source = ModelChangeEvent['source'];\n\n/** Deep equality of JSON values (what parsed models are made of). */\nfunction equal(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const key of ka) {\n if (!equal((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * `next`, with every element, link and the diagram that equals `previous`'s kept as\n * `previous`'s object; `previous` itself when nothing differs (in content, order or metamodel).\n */\nfunction share(previous: AnyIstarModel, next: AnyIstarModel): AnyIstarModel {\n let same =\n previous.elements.size === next.elements.size &&\n previous.links.size === next.links.size &&\n metamodelOf(previous) === metamodelOf(next);\n const shareMap = <T>(\n from: ReadonlyMap<string, T>,\n to: ReadonlyMap<string, T>,\n ): Map<string, T> => {\n const order = from.keys();\n const out = new Map<string, T>();\n for (const [id, value] of to) {\n const old = from.get(id);\n const keep = old !== undefined && equal(old, value);\n if (!keep || order.next().value !== id) same = false;\n out.set(id, keep ? old : value);\n }\n return out;\n };\n const elements = shareMap(previous.elements, next.elements);\n const links = shareMap(previous.links, next.links);\n const diagram = equal(previous.diagram, next.diagram) ? previous.diagram : next.diagram;\n const { elements: _e, links: _l, diagram: _d, ...rest } = next;\n const { elements: _pe, links: _pl, diagram: _pd, ...previousRest } = previous;\n if (same && equal(rest, previousRest)) return previous;\n const shared: AnyIstarModel = {\n ...rest,\n elements,\n links,\n ...(diagram === undefined ? {} : { diagram }),\n };\n return inheritMetamodel(next, inheritSourceLayout(next, shared));\n}\n\nfunction readOnly(): never {\n throw new ModelOperationError(\n 'a mirror store is read-only: dispatch the edit through its remote dispatcher',\n );\n}\n\nconst parseWith = parsePistar as (\n file: PistarFile,\n options: ParsePistarOptions<string, string>,\n) => AnyIstarModel;\n\n/**\n * A mirror of `remote`'s model (see `MirrorStore`). Shows an empty model until `ready`.\n *\n * Order: changes are shown in the order the remote sends them, whoever made them, and a\n * `dispatch` through `mirror.dispatcher` resolves after its change is shown, so code that\n * selects a created id or rolls back a rejected one sees the model it expects. A rejected\n * action sends no notification: the mirror stays as it was.\n */\nexport function createMirrorStore<EK extends string = ElementKind, LK extends string = LinkKind>(\n remote: ActionDispatcher<EK, LK>,\n options: MirrorStoreOptions<EK, LK> = {},\n): MirrorStore<EK, LK> {\n const r = remote as unknown as ActionDispatcher<string, string>;\n const metamodel = options.metamodel as unknown as AnyMetamodel | undefined;\n const limit = options.historyLimit ?? 100;\n const onError = options.onError ?? (() => {});\n const listeners = new Set<ModelListener<string, string>>();\n let model: AnyIstarModel = metamodel\n ? createEmptyModel(undefined, { metamodel })\n : (createEmptyModel() as AnyIstarModel);\n /** The last file's `\"metamodel\"` block, as JSON; `undefined` before the first file. */\n let block: string | undefined;\n let undoDepth = 0;\n let redoDepth = 0;\n /** How many pushed models (`newRoot`) were applied: a response asked for before one is stale. */\n let pushed = 0;\n let requests = 0;\n let tail: Promise<void> = Promise.resolve();\n let disposed = false;\n\n const parse = (file: PistarFile): AnyIstarModel => {\n const nextBlock = JSON.stringify((file as Record<string, unknown>)[FILE_METAMODEL_KEY] ?? null);\n if (nextBlock === block) {\n // The same file metamodel: read with the current model's metamodel, so `metamodelOf` keeps\n // its identity (a registry memoised on it isn't rebuilt on every change).\n return inheritMetamodel(model, parseWith(file, { metamodel: metamodelOf(model) }));\n }\n const parsed = parseWith(file, {\n ...(metamodel ? { metamodel } : {}),\n ...(options.fileMetamodel ? { fileMetamodel: true } : {}),\n });\n block = nextBlock;\n return parsed;\n };\n\n const apply = (file: PistarFile, source: Source, changes: readonly ModelChange[]): void => {\n const previous = model;\n const next = share(previous, parse(file));\n if (next === previous) return;\n model = next;\n const event: ModelChangeEvent<string, string> = { model, previous, changes, source };\n for (const listener of listeners) listener(event);\n };\n\n /** Counts the remote's undo stack from what it reports (see `MirrorStore`). */\n const track = (\n source: Source,\n exact?: { readonly canUndo: boolean; readonly canRedo: boolean },\n ): void => {\n if (exact) {\n undoDepth = exact.canUndo ? 1 : 0;\n redoDepth = exact.canRedo ? 1 : 0;\n } else if (source === 'edit') {\n undoDepth = Math.min(undoDepth + 1, limit);\n redoDepth = 0;\n } else if (source === 'undo') {\n undoDepth = Math.max(undoDepth - 1, 0);\n redoDepth++;\n } else if (source === 'redo') {\n undoDepth = Math.min(undoDepth + 1, limit);\n redoDepth = Math.max(redoDepth - 1, 0);\n } else {\n undoDepth = 0;\n redoDepth = 0;\n }\n };\n\n /**\n * Asks for the model now (so the remote answers in order) and shows it once every earlier\n * update is shown. Dropped if a pushed model arrived meanwhile: that one is at least as new.\n */\n const refresh = (source: Source, changes: readonly ModelChange[]): Promise<void> => {\n const seen = pushed;\n const sent = r\n .dispatch({ kind: 'requestModel', requestId: `mirror-${++requests}` })\n .then((result: ActionResult<{ readonly newRoot: PistarFile }>) => ({ result }))\n .catch((error: unknown) => ({ error }));\n const step = tail.then(async () => {\n const answer = await sent;\n if (disposed || pushed !== seen) return;\n if ('error' in answer) throw answer.error;\n const { result } = answer;\n if (!result.ok) {\n throw new Error(result.diagnostics[0]?.message ?? 'requestModel was rejected');\n }\n if (!result.response) throw new Error('requestModel was answered without a model');\n apply(result.response.newRoot, source, changes);\n });\n tail = step.catch(onError);\n return step;\n };\n\n const unsubscribe = r.subscribe((action) => {\n if (disposed || action.kind !== 'sourceModelChanged') return;\n track(\n action.source,\n action.canUndo !== undefined && action.canRedo !== undefined\n ? { canUndo: action.canUndo, canRedo: action.canRedo }\n : undefined,\n );\n if (action.newRoot) {\n pushed++;\n try {\n apply(action.newRoot, action.source, action.changes);\n } catch (error) {\n onError(error);\n }\n } else {\n void refresh(action.source, action.changes).catch(() => {});\n }\n });\n\n const ready = refresh('load', []);\n // `ready` rejects for whoever awaits it; unawaited, the failure only reaches `onError`.\n ready.catch(() => {});\n\n const send = (kind: 'glspUndo' | 'glspRedo'): void => {\n void r.dispatch({ kind }).catch(onError);\n };\n\n const dispatcher: ActionDispatcher<string, string> = {\n async dispatch(action, options) {\n const result = await r.dispatch(action, options);\n await tail;\n return result;\n },\n subscribe: (listener) => r.subscribe(listener),\n };\n\n const store: MirrorStore<string, string> = {\n ready,\n dispatcher,\n synced: () => tail,\n dispose() {\n disposed = true;\n unsubscribe();\n },\n\n getModel: () => model,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n canLink: (source, target, kind) => canLink(model, source, target, kind),\n\n addElement: readOnly,\n updateElement: readOnly,\n moveElement: readOnly,\n nestElement: readOnly,\n removeElement: readOnly,\n removeElements: readOnly,\n setCollapsed: readOnly,\n connect: readOnly,\n addDependency: readOnly,\n addLeg: readOnly,\n removeLeg: readOnly,\n updateLink: readOnly,\n disconnect: readOnly,\n updateDiagram: readOnly,\n replace: readOnly,\n load: readOnly,\n transaction: readOnly,\n clearHistory: readOnly,\n\n undo() {\n if (undoDepth === 0) return false;\n send('glspUndo');\n return true;\n },\n redo() {\n if (redoDepth === 0) return false;\n send('glspRedo');\n return true;\n },\n canUndo: () => undoDepth > 0,\n canRedo: () => redoDepth > 0,\n };\n return store as unknown as MirrorStore<EK, LK>;\n}\n","/**\n * A transport for `ActionDispatcher` over a `MessagePort`-like object, framed as JSON-RPC 2.0:\n * a dispatch is a request (`method = action.kind`, `params = action`), answered with the\n * `ActionResult` as `result`; `dispatcher.subscribe` events go server to client as notifications\n * (no `id`). A rejection (`ActionResult` with `ok: false`) is a normal result, not a JSON-RPC\n * error — only a transport or protocol fault (a malformed frame, an unhandled exception) is.\n *\n * `connectDispatcher` serves a dispatcher on one end; `createRemoteDispatcher` is the\n * `ActionDispatcher` implementation for the other end. No `vscode-jsonrpc`.\n */\nimport type { ElementKind, LinkKind } from '@istar-ts/core';\nimport type { ActionDispatcher, ActionListener, ActionResult, DispatchOptions } from './dispatcher';\nimport type { IstarAction } from './actions';\n\nconst JSONRPC_VERSION = '2.0';\n\n/** An id a JSON-RPC request carries and its response answers back. */\nexport type JsonRpcId = string | number;\n\nexport interface JsonRpcRequest {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly method: string;\n readonly params?: unknown;\n /** The dispatch's `origin` (`DispatchOptions.origin`), carried to the server's `dispatch`. */\n readonly origin?: string;\n}\n\n/** A subscriber event, sent with no `id`: it expects no response. */\nexport interface JsonRpcNotification {\n readonly jsonrpc: '2.0';\n readonly method: string;\n readonly params?: unknown;\n}\n\nexport interface JsonRpcSuccess {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly result: unknown;\n}\n\nexport interface JsonRpcErrorObject {\n readonly code: number;\n readonly message: string;\n readonly data?: unknown;\n}\n\nexport interface JsonRpcError {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly error: JsonRpcErrorObject;\n}\n\n/** The envelope `connectDispatcher`/`createRemoteDispatcher` exchange over the port. */\nexport type ActionMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\n/**\n * Structurally what a DOM `MessagePort`, a worker's `self`, or any two-way `postMessage` channel\n * gives us: enough to send and receive `ActionMessage`s, nothing DOM-specific. Generic over the\n * event type `onmessage` is handed (`MessageEvent` for a real port, inferred at the call site),\n * so a real `MessagePort` or `Worker` fits without a cast: `strictFunctionTypes` checks a\n * property-typed handler's parameter invariantly, so pinning it to a narrower `{ data: unknown }`\n * here would reject `MessagePort`'s own, wider `onmessage` type.\n */\nexport interface MessagePortLike<\n E extends { readonly data: unknown } = { readonly data: unknown },\n> {\n postMessage(data: unknown): void;\n onmessage: ((ev: E) => unknown) | null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isJsonRpcId(value: unknown): value is JsonRpcId {\n return typeof value === 'string' || typeof value === 'number';\n}\n\nfunction errorMessage(id: JsonRpcId, code: number, message: string): JsonRpcError {\n return { jsonrpc: JSONRPC_VERSION, id, error: { code, message } };\n}\n\n/**\n * Serves `dispatcher` on `port`: every well-formed request is answered with the\n * `ActionResult` as `result`; `dispatcher.subscribe` events are pushed as notifications.\n * A malformed request answers `-32600` (invalid request) or `-32601` (no usable `method`); an\n * exception `dispatch` itself doesn't catch answers `-32603` (internal error). Returns a\n * disposer that stops forwarding subscriber events and detaches the port's `onmessage`.\n */\nexport function connectDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n E extends { readonly data: unknown } = { readonly data: unknown },\n>(port: MessagePortLike<E>, dispatcher: ActionDispatcher<EK, LK>): () => void {\n const unsubscribe = dispatcher.subscribe((action) => {\n port.postMessage({ jsonrpc: JSONRPC_VERSION, method: action.kind, params: action });\n });\n\n port.onmessage = (ev: E) => {\n const message = ev.data;\n if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;\n const { id, method, params, origin } = message;\n const hasId = isJsonRpcId(id);\n const dispatchOptions: DispatchOptions | undefined =\n typeof origin === 'string' ? { origin } : undefined;\n\n if (typeof method !== 'string' || method.length === 0) {\n if (hasId) port.postMessage(errorMessage(id, -32601, 'method not found'));\n return;\n }\n if (!isRecord(params) || params.kind !== method) {\n if (hasId) port.postMessage(errorMessage(id, -32600, 'invalid request'));\n return;\n }\n\n const action = params as unknown as IstarAction<EK, LK>;\n if (!hasId) {\n // A notification from the client: dispatch it, no response expected.\n void dispatcher.dispatch(action, dispatchOptions);\n return;\n }\n dispatcher.dispatch(action, dispatchOptions).then(\n (result: ActionResult<unknown>) => {\n port.postMessage({ jsonrpc: JSONRPC_VERSION, id, result });\n },\n (error: unknown) => {\n const text = error instanceof Error ? error.message : 'internal error';\n port.postMessage(errorMessage(id, -32603, text));\n },\n );\n };\n\n return () => {\n unsubscribe();\n port.onmessage = null;\n };\n}\n\n/**\n * The `ActionDispatcher` for the other end of a `connectDispatcher` port: `dispatch` sends a\n * request and resolves with the `ActionResult` it is answered with (a JSON-RPC `error` rejects\n * the promise instead — a transport fault, not an `ActionResult`); `subscribe` hears the\n * notifications the server pushes.\n */\nexport function createRemoteDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n E extends { readonly data: unknown } = { readonly data: unknown },\n>(port: MessagePortLike<E>): ActionDispatcher<EK, LK> {\n let nextId = 0;\n const pending = new Map<\n JsonRpcId,\n { resolve: (result: ActionResult<unknown>) => void; reject: (error: Error) => void }\n >();\n const listeners = new Set<ActionListener<EK, LK>>();\n\n port.onmessage = (ev: E) => {\n const message = ev.data;\n if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;\n const { id, method, params, result, error } = message;\n\n if (isJsonRpcId(id)) {\n const waiting = pending.get(id);\n if (!waiting) return;\n pending.delete(id);\n if (isRecord(error)) {\n waiting.reject(new Error(`JSON-RPC error ${String(error.code)}: ${String(error.message)}`));\n } else {\n waiting.resolve(result as ActionResult<unknown>);\n }\n return;\n }\n\n if (typeof method === 'string' && isRecord(params)) {\n const action = params as unknown as IstarAction<EK, LK>;\n for (const listener of listeners) listener(action);\n }\n };\n\n return {\n dispatch(action, dispatchOptions) {\n const id = nextId++;\n return new Promise((resolve, reject) => {\n pending.set(id, { resolve: resolve as (result: ActionResult<unknown>) => void, reject });\n port.postMessage({\n jsonrpc: JSONRPC_VERSION,\n id,\n method: action.kind,\n params: action,\n ...(dispatchOptions?.origin === undefined ? {} : { origin: dispatchOptions.origin }),\n });\n });\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","/** Version of the action protocol this package speaks. */\nexport const ACTIONS_PROTOCOL_VERSION: string = '0.0.0';\n\nexport * from './actions';\nexport * from './created-ids';\nexport * from './dispatcher';\nexport * from './hints';\nexport * from './host';\nexport * from './markers';\nexport * from './metamodel-context';\nexport * from './mirror';\nexport * from './transport';\n"],"mappings":";;;AA4nBA,MAAM,sBAAyD;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,oBAA2D;CAC/D;CACA;CACA;CACA;CACA;AACF;;;;;AAMA,MAAM,yBAKQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAuC,IAAI,IAAI,mBAAmB;AACxE,MAAM,gBAAqC,IAAI,IAAI,iBAAiB;;;;;;;AAQpE,MAAa,uBAST;CACF,YAAY;CACZ,UAAU;CACV,eAAe;AACjB;;AAGA,SAAgB,YACd,QACkC;CAClC,OAAO,gBAAgB,IAAI,OAAO,IAAI;AACxC;;AAGA,SAAgB,gBAAgB,QAA8C;CAC5E,OAAO,cAAc,IAAI,OAAO,IAAI;AACtC;;;;;;AClsBA,SAAS,gBACP,WACA,OACqC;CACrC,QAAQ,UAAU,MAAlB;EACE,KAAK,cACH,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;EACjC,KAAK,cAAc;GACjB,MAAM,aAAA,GAAYA,eAAAA,YAAAA,CAAY,KAAK;GACnC,MAAM,aAAa,UAAU,MAAM,IAAI,UAAU,aAAa;GAC9D,IAAI,YAAY,aAAa,cAAc,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;GAC1E,IAAI,YAAY,SAAS,CAAC,YAAY,WAAW,OAAO,SAAS,GAE/D,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;GAEjC,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;EACjC;EACA,KAAK,gBACH,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;EACjC,KAAK,YAAY;GACf,IAAI,WAAW;GACf,IAAI,QAAQ;GACZ,KAAK,MAAM,SAAS,UAAU,eAAuC;IACnE,MAAM,SAAS,gBAAgB,OAAO,KAAK;IAC3C,YAAY,OAAO;IACnB,SAAS,OAAO;GAClB;GACA,OAAO;IAAE;IAAU;GAAM;EAC3B;EACA,SACE,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;CACnC;AACF;AAEA,SAAS,YACP,WACA,OACA,WACS;CACT,MAAM,aAAa,MAAM,SAAS,IAAI,UAAU,eAAe,CAAC,EAAE;CAClE,OAAO,eAAe,KAAA,KAAa,UAAU,SAAS,IAAI,UAAU,CAAC,EAAE,SAAS;AAClF;;;;AAKA,SAAS,eACP,WACA,YACA,SACA,OACW;CACX,QAAQ,UAAU,MAAlB;EACE,KAAK,cAAc;GACjB,MAAM,KAAK,WAAW,MAAM;GAC5B,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,cAAc;GACjB,MAAM,aAAA,GAAYA,eAAAA,YAAAA,CAAY,KAAK;GACnC,MAAM,aAAa,UAAU,MAAM,IAAI,UAAU,aAAa;GAC9D,IAAI,YAAY,aAAa,cAAc;IACzC,MAAM,aAAa,WAAW,MAAM;IACpC,MAAM,WAAW,CAAC,QAAQ,MAAM,GAAG,QAAQ,MAAM,CAAC;IAClD,IAAI,eAAe,KAAA,KAAa,SAAS,OAAO,KAAA,KAAa,SAAS,OAAO,KAAA,GAC3E,OAAO;IAET,OAAO;KACL,GAAG;KACH,MAAM;MACJ,GAAG,UAAU;MACb,UAAU;OAAE,GAAG,UAAU,MAAM;OAAU,IAAI;MAAW;MACxD,SAAS;KACX;IACF;GACF;GACA,IAAI,YAAY,SAAS,CAAC,YAAY,WAAW,OAAO,SAAS,GAAG;IAClE,MAAM,QAAQ,WAAW,MAAM;IAC/B,MAAM,QAAQ,QAAQ,MAAM;IAC5B,MAAM,QAAQ,QAAQ,MAAM;IAC5B,OAAO,UAAU,KAAA,KAAa,UAAU,KAAA,KAAa,UAAU,KAAA,IAC3D,YACA;KAAE,GAAG;KAAW,MAAM;MAAE,GAAG,UAAU;MAAM,IAAI;MAAO;MAAO;KAAM;IAAE;GAC3E;GACA,MAAM,KAAK,QAAQ,MAAM;GACzB,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,gBAAgB;GACnB,MAAM,KAAK,QAAQ,MAAM;GACzB,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,YACH,OAAO;GACL,GAAG;GACH,eAAgB,UAAU,cAAuC,KAAK,UACpE,eAAe,OAAO,YAAY,SAAS,KAAK,CAClD;EACF;EACF,SACE,OAAO;CACX;AACF;;AAGA,SAAgB,iBACd,WACA,YACA,OACW;CACX,MAAM,SAAS,gBAAgB,WAAW,KAAK;CAC/C,MAAM,aAAa,WAAW,MAAM,GAAG,OAAO,QAAQ;CACtD,MAAM,UAAU,WAAW,MAAM,OAAO,UAAU,OAAO,WAAW,OAAO,KAAK;CAChF,OAAO,eAAe,WAAW,CAAC,GAAG,UAAU,GAAG,CAAC,GAAG,OAAO,GAAG,KAAK;AACvE;;;;;;;;;ACtHA,SAAgB,MAAM,YAA4C;CAChE,OAAO,WAAW,SAAS;AAC7B;;AAGA,SAAgB,SAAS,WAAyB,UAA4B;CAC5E,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GAOjD,IALgB,MAAM,UAAU,IAC5B,WAAW,SAAS,WACpB,aAAa,OACb,aAAa,WAAW,aAAA,GACxBC,eAAAA,mBAAAA,CAAmB,WAAW,WAAW,MAAM,QAAQ,GAC9C,MAAM,KAAK,WAAW,IAAI;CAGzC,IAAI,aAAaC,eAAAA,eAAe,MAAM,KAAK,GAAG,UAAU,MAAM,KAAK,CAAC;MAC/D,IAAI,UAAU,MAAM,IAAI,QAAQ,GAC9B;OAAA,MAAM,QAAQ,UAAU,MAAM,KAAK,GACtC,KAAA,GAAIC,eAAAA,gBAAAA,CAAgB,WAAW,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI;CAAA;CAGnE,OAAO;AACT;AAEA,SAAgB,MAAM,WAAyB,WAAwC;CACrF,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,SAAS,aAAa,SAAS,WAAW,QAAQ,CAAC,CAAC,CAAC;AACpF;;AAGA,SAAgB,WAAW,WAAyB,UAAuC;CACzF,OAAO,CAAC,GAAG,UAAU,SAAS,OAAO,CAAC,CAAC,CACpC,QAAQ,MAAM,CAAC,MAAM,CAAC,MAAM,aAAa,KAAA,KAAa,EAAE,aAAa,SAAS,CAAC,CAC/E,KAAK,MAAM,EAAE,IAAI;AACtB;;;;;;;;;;;;;;;;ACbA,SAAgB,aACd,WACsD;CACtD,MAAM,OAAO;CACb,MAAM,QAAQ,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CACtC,QAAQ,MAAM,EAAE,aAAa,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,sBAAsB,KAAK,CAAC,CACxF,KAAK,MAAM,EAAE,IAAI;CA4BpB,OAAO;EAAE,YA3BU,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,MAAqB;GACvE,MAAM,MAAM,MAAM,CAAC;GACnB,OAAO;IACL,eAAe,EAAE;IACjB,gBAAgB;IAChB,WAAW;IACX,WAAW,CAAC;IACZ,cAAc,CAAC,OAAO,EAAE,aAAa,UAAU,EAAE,MAAM,sBAAsB;IAC7E,GAAI,EAAE,aAAa,UAAU,EAAE,2BAA2B,MAAM,IAAI,CAAC;GACvE;EACF,CAiBkB;EAAG,WAhBH,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,MAAoB;GAClE,MAAM,QAAQ,KAAK,MAAM,KAAA,GAAIC,eAAAA,kBAAAA,CAAkB,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE;GAC/D,MAAM,UAAU,EAAE,aAAa,eAAe,WAAW,IAAI,IAAI,WAAW,MAAM,EAAE,QAAQ;GAC5F,MAAM,UAAU,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;GAErD,MAAM,MAAM,EAAE,OAAO;GACrB,OAAO;IACL,eAAe,EAAE;IACjB,gBAAgB;IAChB,WAAW;IACX,UAAU;IACV,sBAAsB,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;IAC3D,sBAAsB,QAAQ,KAAA,IAAY,UAAU,CAAC,GAAG,SAAS,GAAG;IACpE,SAAS;GACX;EACF,CAC6B;CAAE;AACjC;AAEA,SAAS,eACP,MACA,OACiB;CAIjB,QAHqD,MAAM,QAAQ,KAAK,IACpE,QACA,CAAC,KAAgC,EAAA,CACzB,KAAK,OAAO,MACtB,QAAQ,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,MAAM,MAAM,OAAO;EAC3D,MAAM;EACN,eAAe;EACf,GAAI,MAAM,aAAa,EAAE,MAAM,EAAE,kBAAkB,MAAM,WAAW,EAAE,IAAI,CAAC;CAC7E,CAAC,CACH;AACF;AAEA,SAAS,YAAY,MAAc,MAA4D;CAC7F,OAAO,KAAK,KAAK,OAAO,MAAM;EAC5B,MAAM,OAAO;GACX,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;GAC1D,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,SAAS,EAAE;EAC/E;EACA,OAAO,QAAQ,GAAG,KAAK,GAAG,KAAK,OAAO;GACpC,MAAM;GACN,eAAe;GACf,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;EACjD,CAAC;CACH,CAAC;AACH;AAEA,SAAS,MAAM,QAA+B;CAC5C,OAAO,OAAO,SAAS,OAAO;AAChC;AAEA,SAAS,QACP,IACA,OACA,QACe;CACf,OAAO;EACL;EACA,OAAO,MAAM;EACb,SAAS,CAAC,MAAM;EAChB,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;EAC1D,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;EAChE,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;CAC5D;AACF;;;;;;;AAQA,SAAgB,kBACd,SACA,WAC+C;CAC/C,MAAM,OAAO;CACb,MAAM,UAA2B,CAAC;CAClC,KAAK,MAAM,QAAQ,KAAK,SAAS,KAAK,GAAG;EACvC,MAAM,QAAQ,QAAQ,SAAS;EAC/B,IAAI,OAAO,QAAQ,KAAK,GAAG,eAAe,MAAM,KAAK,CAAC;CACxD;CACA,KAAK,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAG;EACpC,MAAM,OAAO,QAAQ,MAAM;EAC3B,IAAI,MAAM,QAAQ,KAAK,GAAG,YAAY,MAAM,IAAI,CAAC;CACnD;CACA,QAAQ,MAAM,GAAG,MAAO,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAE;CACjF,OAAO;EAAE;EAAS,QAAQ,QAAQ;CAAO;AAC3C;;;;;;;;;AAUA,SAAgB,qBAAqB,WAAgD;CACnF,MAAM,WAA4D,CAAC;CACnE,IAAI,QAAQ;CACZ,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GACjD,SAAS,WAAW,QAClB,WAAW,SAAS,KAAA,IAChB,QACA;EACE,OAAO,WAAW;EAClB,OAAO;EACP,SAAS,WAAW,aAAa,UAAU,WAAW;EACtD,GAAI,WAAW,aAAa,UAAU,EAAE,OAAO,SAAS,IAAI,CAAC;CAC/D;CAER,MAAM,QAAqE,CAAC;CAC5E,QAAQ;CACR,KAAK,MAAM,cAAc,UAAU,MAAM,OAAO,GAC9C,MAAM,WAAW,QACf,WAAW,SAAS,KAAA,IAChB,QACA,CAAC;EAAE,OAAO,WAAW;EAAO,OAAO;EAAS,SAAS;CAAW,CAAC;CAEzE,OAAO;EAAE;EAAU;EAAO,QAAQ,EAAE,QAAQ,EAAE,OAAO,QAAQ,EAAE;CAAE;AACnE;;;;ACvKA,SAAgB,mBAAmB,YAAoC;CACrE,MAAM,EAAE,WAAW,KAAK,UAAU,SAAS,QAAQ,SAAS;CAC5D,OAAO;EACL,OAAO;EACP,aAAa,WAAW,KAAA,IAAY,UAAU,GAAG,QAAQ,IAAI,OAAO;EACpE;EACA,MAAM;EACN,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EACnC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;AACF;;;;;AAMA,SAAgB,mBAAmB,QAAgC;CACjE,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,QAAQ,SAAS;CAItD,OAAO;EACL;EACA,UALgBC,eAAAA,sBAA4C,SAAS,IAAI,IACtE,OACD;EAIF,SAAS;EACT,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EACnC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;AACF;;;;;;;;;;AC+KA,IAAM,YAAN,cAAwB,MAAM;CAC5B;CACA,YAAY,aAAwC;EAClD,MAAM,YAAY,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;EAClD,KAAK,cAAc;CACrB;AACF;AAEA,SAAS,OAAO,SAAiB,YAAY,IAAI,MAAsB;CACrE,MAAM,IAAI,UAAU,CAClB;EAAE;EAAW,UAAU;EAAS;EAAS,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CAAG,CACnF,CAAC;AACH;AAEA,SAAS,YACP,OACA,WACO;CACP,MAAM,IAAI,UAAU,EAAA,GAACC,eAAAA,0BAAAA,CAA0B,OAAwB,SAAS,CAAE,CAAC;AACrF;AAEA,SAAS,OAAO,OAAoC;CAClD,QAAA,GAAOC,eAAAA,YAAAA,CAAY,KAAK;AAC1B;;;;;AAMA,MAAM,sCAA2C,IAAI,IAAI,CAAC,GAAGC,eAAAA,gBAAgBC,eAAAA,kBAAkB,CAAC;;AAGhG,SAAS,UAAU,OAAsB,OAA+C;CACtF,QAAA,GAAOC,eAAAA,iBAAAA,CAAiB,QAAA,GAAOC,eAAAA,oBAAAA,CAAoB,OAAO;EAAE,GAAG;EAAO;CAAM,CAAC,CAAC;AAChF;AAEA,SAAS,WAAW,QAAuB,OAAgC;CACzE,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,MAAM,MAAM,SAAS,KAAK,GAAG,IAAI,CAAC,OAAO,SAAS,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE;CACjF,KAAK,MAAM,MAAM,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE;CAC3E,OAAO;AACT;AAEA,SAAS,SAAS,GAA4E;CAC5F,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,IAAI,QAAQ,EAAE;AACzC;AAEA,SAAS,qBAAqB,OAAwC;CACpE,QAAA,GAAOC,eAAAA,cAAAA,CAAc,KAAK,CAAC,CAAC,KAAK,WAAW;EAC1C,WAAW,MAAM;EACjB,UAAU;EACV,SAAS,MAAM;EACf,MAAM,MAAM;CACd,EAAE;AACJ;;;;AAKA,SAAgB,uBAId,OACA,UAA2C,CAAC,GACb;CAC/B,MAAM,IAAI;CACV,MAAM,SAAU,QAAQ,UAAU,CAAC;CACnC,MAAM,aAAc,QAAQ,cAAc,CAAC;CAC3C,MAAM,kBAAkB,SAA8C;EACpE,MAAM,SAAS,QAAQ;EACvB,IAAI,OAAO,WAAW,YAAY,OAAO,OAAO;EAChD,OAAO,UAAU,qBAAqB,IAAI;CAC5C;CACA,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,4BAAY,IAAI,IAAoC;CAE1D,IAAI,QAAuB,EAAE,SAAS;CACtC,IAAI,QAAQ;;;;;;;CAOZ,IAAI;CAEJ,MAAM,QAAQ,WAA8C;EAC1D,KAAK,MAAM,YAAY,WAAW,SAAS,MAAM;CACnD;CAEA,MAAM,eAAe,QAAgC,WAAqC;EACxF,MAAM,OAAO,EAAE,SAAS,MAAM;EAC9B,IAAI,SAAS,OAAO;EACpB,QAAQ;EACR,KAAK;GACH,MAAM;GACN,SAAS;GACT;GACA,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAC3C,CAAC;CACH;CAEA,MAAM,UAAsE;EAC1E,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;CACR;CACA,MAAM,cAAc,EAAE,WAAW,UAAU;EAEzC,IAAI,MAAM,WAAW,QAAQ,QAAQ,MAAM;EAC3C,KAAK;GACH,MAAM;GACN;GACA,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,GAAI,QAAQ,YAAY,EAAE,UAAA,GAASC,eAAAA,eAAAA,CAAe,MAAM,KAAK,EAAE,IAAI,CAAC;GACpE,GAAI,QAAQ,YAAY;IAAE,SAAS,EAAE,QAAQ;IAAG,SAAS,EAAE,QAAQ;GAAE,IAAI,CAAC;GAC1E,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,cAAc;EACjE,CAAC;EACD,YAAY,QAAQ,MAAM,SAAS,aAAa;CAClD,CAAC;CAKD,MAAM,kBAAkB,OACtB,EAAE,SAAS,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,OAAO,oBAAoB,GAAG,IAAI,IAAI,iBAAiB;CAE1F,MAAM,aAAa,WAA2C,aAA+B;EAC3F,MAAM,SAA2B,CAAC;EAClC,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,KAAK,MAAM,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,GACjD,CAAC,EAAE,aAAa,UAAU,SAAS,SAAA,CAAU,KAAK,CAAC;EAGvD,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,UAAU,MAAM;CACnD;CAEA,MAAM,iBACJ,WACA,QACA,aACG;EACH,MAAM,SAA2B,CAAC;EAClC,KAAK,MAAM,SAAS,YAClB,KAAK,MAAM,KAAK,MAAM,WAAW,EAAE,SAAS,GAAG,MAAM,KAAK,CAAC,GACzD,CAAC,EAAE,aAAa,UAAU,SAAS,SAAA,CAAU,KAAK,CAAC;EAGvD,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,UAAU,MAAM;CACnD;CAEA,MAAM,SAAS,WAA2C,aAAqC;EAC7F,UAAU,WAAW,QAAQ;EAC7B,MAAM,SAAS,EAAE,SAAS;EAC1B,QAAQ,WAAW,QAAQ;EAC3B,cAAc,WAAW,QAAQ,QAAQ;CAC3C;CAEA,MAAM,WAAW,WAA2C,aAAqC;EAC/F,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,QAAQ,UAAU,MAAlB;GACE,KAAK,cAAc;IACjB,MAAM,EAAE,eAAe,MAAM,aAAa,OAAO,CAAC,MAAM;IACxD,MAAM,aACJ,KAAK,SAAS,IAAI,IAAI,KACtB,OAAO,yBAAyB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC7E,IAAI,WAAW,SAAS,OACtB,OAAO,KAAK,WAAW,MAAM,yCAAyC,IAAI,UAAU;IAEtF,MAAM,YAAY,gBAAgB,KAAA,IAAY,KAAA,IAAY,eAAe,WAAW;IACpF,IAAI,WAAW,aAAa,QAAQ;KAElC,IAAI,aAAa,WAAW,MAAM,sBAAsB,OACtD,OAAO,KAAK,WAAW,MAAM,6BAA6B,aAAa,WAAW;KAEpF,IAAI,CAAC,aAAa,WAAW,MAAM,iBAAiB,OAClD,OAAO,KAAK,WAAW,MAAM,mCAAmC,IAAI,WAAW;IAEnF;IACA,MAAM,WAAW,UAAU,YAAY,aAAa;KAAE,GAAG;KAAG,GAAG;IAAE;IACjE,EAAE,WAAW;KACX;KACA,GAAG,SAAS;KACZ,GAAG,SAAS;KACZ,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,YAAY;KAC3D,GAAI,KAAK,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG;KAC/C,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;KACrD,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;IAC7E,CAAC;IACD;GACF;GACA,KAAK,cAAc;IACjB,MAAM,EAAE,eAAe,MAAM,iBAAiB,QAAQ,iBAAiB,WAAW;IAClF,MAAM,OAAO,UAAU,QAAQ,CAAC;IAChC,MAAM,aACJ,KAAK,MAAM,IAAI,IAAI,KACnB,OAAO,sBAAsB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC1E,IAAI,WAAW,aAAa,cAAc;KACxC,MAAM,WAAW,KAAK,YAAY,CAAC;KACnC,MAAM,eACJ,SAAS,QACT,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,MACzB,MAAM,EAAE,aAAa,UAAU,EAAE,SAAS,SAAS,EAAE,MAAM,kBAAkB,KAChF,CAAC,EAAE,QACH,OAAO,GAAG,KAAK,KAAK,sCAAsC,IAAI,cAAc;KAC9E,MAAM,SAAS,EAAE,cAAc;MAC7B,UAAU;MACV,UAAU;MACV,UAAU;MACV,UAAU;OACR,MAAM;OACN,GAAI,SAAS,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG;OACvD,GAAI,SAAS,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,SAAS,KAAK;OAC7D,GAAI,SAAS,WAAW;QAAE,GAAG,SAAS,SAAS;QAAG,GAAG,SAAS,SAAS;OAAE,IAAI,CAAC;OAC9E,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,SAAS,iBAAiB,IAAI,CAAC;MACrF;MACA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;KAClD,CAAC;KACD,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;MAAE;MAAQ;KAAO,CAAC;KACtD;IACF;IACA,MAAM,SAAS,WAAW,KAAK;IAC/B,IAAI,KAAK,UAAU,KAAA,KAAa,UAAU,CAAC,OAAO,SAAS,KAAK,KAAK,GACnE,OACE,IAAI,KAAK,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IACnF,QACA,eACF;IAEF,MAAM,SAAS,EAAE,QAAQ;KACvB;KACA;KACA;KACA,GAAI,KAAK,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG;KAC/C,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;KACxD,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;KACrD,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;KAC3E,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;KACxD,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;IAC1D,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;KAAE;KAAQ;IAAO,CAAC;IACtD;GACF;GACA,KAAK,iBAAiB;IACpB,MAAM,WAAqB,CAAC;IAC5B,MAAM,QAAkB,CAAC;IACzB,KAAK,MAAM,MAAM,UAAU,YACzB,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,SAAS,KAAK,EAAE;SACvC,IAAI,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,KAAK,EAAE;SACtC,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;IAEtE,IAAI,SAAS,SAAS,GAAG,EAAE,eAAe,QAAQ;IAElD,KAAK,MAAM,MAAM,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE;IACvE;GACF;GACA,KAAK;IACH,KAAK,MAAM,EAAE,WAAW,aAAa,aAAa,UAAU,WAAW;KACrE,eAAe,SAAS;KACxB,IAAI,aAAa,EAAE,YAAY,WAAW,YAAY,GAAG,YAAY,CAAC;KACtE,IAAI,SACF,EAAE,cAAc,WAAW,EACzB,SAAS;MAAE,OAAO,QAAQ;MAAO,QAAQ,QAAQ;KAAO,EAC1D,CAAC;IAEL;IACA;GAEF,KAAK,mBAAmB;IACtB,MAAM,EAAE,WAAW,mBAAmB,aAAa;IACnD,EAAE,YAAY,WAAW,iBAAiB;IAC1C,IAAI,UAAU,EAAE,YAAY,WAAW,SAAS,GAAG,SAAS,CAAC;IAC7D;GACF;GACA,KAAK;IACH,UAAU,UAAU,eAAe,UAAU,iBAAiB,UAAU,eAAe;IACvF;GACF,KAAK,kBAAkB;IACrB,MAAM,OAAO,UAAU,QAAQ,QAAQ,GAAG;IAC1C,MAAM,KAAK,OAAO,IAAI,UAAU,UAAU,UAAU,QAAQ,MAAM,GAAG,IAAI;IACzE,MAAM,MAAM,OAAO,IAAI,KAAA,IAAY,UAAU,QAAQ,MAAM,OAAO,CAAC;IACnE,IAAI,QAAQ,KAAA,GAAW;KACrB,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,EAAE,cAAc,IAAI,EAAE,MAAM,UAAU,KAAK,CAAC;UAGnE,IAAI,MAAM,MAAM,IAAI,EAAE,GACzB,EAAE,WAAW,IAAI,EAAE,MAAM,UAAU,SAAS,KAAK,OAAO,UAAU,KAAK,CAAC;UACnE,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;IACxE,OACE,cAAc,IAAI,GAAG,MAAM,UAAU,KAAK,CAAC;IAE7C;GACF;GACA,KAAK;IACH,KAAK,MAAM,SAAS,UAAU,eAAe,MAAM,OAAO,QAAQ;IAClE;GACF,KAAK,gBAAgB;IACnB,MAAM,EAAE,OAAO,iBAAiB,WAAW;IAC3C,MAAM,SAAS,EAAE,OAAO,OAAO,QAAQ,UAAU,MAAM,KAAK,EAAE,IAAI,UAAU,KAAK,GAAG,IAAI,CAAC,CAAC;IAC1F,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;KAAE;KAAQ,QAAQ;IAAM,CAAC;IAC7D;GACF;GACA,KAAK;IACH,EAAE,UAAU,UAAU,KAAK;IAC3B;GACF,KAAK,sBAAsB;IACzB,MAAM,UAAU,eAAe,UAAU,SAAS;IAClD,IAAI,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,aAAa,SAChD,OAAO,IAAI,QAAQ,GAAG,oBAAoB,QAAQ,IAAI,cAAc;IAEtE,EAAE,aAAa,QAAQ,IAAI,UAAU,SAAS;IAC9C;GACF;GACA,KAAK,uBAAuB;IAC1B,MAAM,EAAE,MAAM,OAAO,QAAQ,qBAAqB,UAAU;IAC5D,EAAE,cAAc;KACd,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;KACrC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;KACvC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;KACzC,GAAI,qBAAqB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB;IAC/D,CAAC;IACD;GACF;GACA,KAAK;IACH,cAAc,UAAU,WAAW,UAAU,UAAU;IACvD;GACF,KAAK;IACH,eAAe,UAAU,SAAS;IAClC,EAAE,cAAc,UAAU,WAAW,EAAE,SAAS,UAAU,MAAM,CAAC;IACjE;GACF,KAAK;IACH,IAAI,CAAC,MAAM,MAAM,IAAI,UAAU,MAAM,GACnC,OAAO,iBAAiB,UAAU,OAAO,IAAI,UAAU,QAAQ,iBAAiB;IAElF,EAAE,WAAW,UAAU,QAAQ,EAAE,SAAS,UAAU,MAAM,CAAC;IAC3D;GACF,KAAK,sBAAsB;IACzB,MAAM,EAAE,QAAQ,UAAU;IAC1B,MAAM,OACJ,MAAM,MAAM,IAAI,MAAM,KAAK,OAAO,iBAAiB,OAAO,IAAI,QAAQ,iBAAiB;IACzF,MAAM,aAAa,KAAK,MAAM,IAAI,KAAK,IAAI;IAC3C,MAAM,SAAS,YAAY,KAAK;IAChC,IAAI,UAAU,QAAQ,UAAU,CAAC,OAAO,SAAS,KAAK,GACpD,OACE,IAAI,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IAC9E,QACA,eACF;IAEF,EAAE,WAAW,QAAQ,EAAE,OAAO,MAAM,CAAC;IACrC;GACF;GACA,KAAK,wBAAwB;IAC3B,MAAM,EAAE,SAAS,eAAe,SAAS;IACzC,IAAI,QAAQ,WAAW,GAAG;IAC1B,MAAM,MAAM,IAAI,IAAI,OAAO;IAC3B,MAAM,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,KACpB,OAAO,MAAM,MAAM,IAAI,EAAE,KAAK,OAAO,iBAAiB,GAAG,IAAI,IAAI,iBAAiB,CACrF;IACA,MAAM,aACJ,KAAK,MAAM,IAAI,IAAI,KACnB,OAAO,sBAAsB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC1E,MAAM,WAAW,MAAM,QAAQ,SAAS,KAAK,SAAS,IAAI;IAC1D,IAAI,SAAS,WAAW,GAAG;IAC3B,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK;IACrC,KAAK,MAAM,MAAM,KAAK,UAAU,OAAO,EAAE;IACzC,MAAM,UAAU,UAAU,OAAO,SAAS;IAC1C,MAAM,SAAS,WAAW,KAAK;IAC/B,KAAK,MAAM,QAAQ,UAAU;KAC3B,MAAM,SAAA,GAAQC,eAAAA,QAAAA,CAAQ,SAAS,KAAK,QAAQ,KAAK,QAAQ,IAAI;KAC7D,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;MAAE,QAAQ,KAAK;MAAQ,QAAQ,KAAK;KAAO,CAAC;KAC9E,IAAI,KAAK,SAAS,QAAQ,UAAU,CAAC,OAAO,SAAS,KAAK,KAAK,GAC7D,OACE,IAAI,KAAK,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IACnF,KAAK,IACL,eACF;IAEJ;IACA,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;IAChC,KAAK,MAAM,QAAQ,UAAU,KAAK,IAAI,KAAK,IAAI;KAAE,GAAG;KAAM;IAAK,CAAC;IAChE,EAAE,QAAQ,UAAU,OAAO,IAAI,CAAC;IAChC;GACF;GACA,KAAK,0BAA0B;IAC7B,IAAI;IACJ,IAAI;KACF,QAAA,GAAOC,eAAAA,kBAAAA,CAAkB,OAAO,UAAU,KAAK;IACjD,SAAS,OAAO;KACd,IAAI,iBAAiBC,eAAAA,gBAAgB,OAAO,MAAM,SAAS,IAAI,mBAAmB;KAClF,MAAM;IACR;IACA,EAAE,QAAQ,IAAI;IACd;GACF;GACA,KAAK,0BAA0B;IAC7B,MAAM,EAAE,KAAK,QAAQ,SAAS;IAC9B,KAAK,MAAM,OAAO,CAAC,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,GAAI,UAAU,CAAC,CAAE,GAAG;KAChE,IAAI,CAAC,oBAAoB,IAAI,GAAG,GAAG;KACnC,IAAI,QAAQ,QACV,OACE,uEACA,IACA,cACF;KAEF,IAAI,QAAQP,eAAAA,oBACV,OACE,IAAI,IAAI,6DACR,IACA,cACF;KAEF,OACE,IAAI,IAAI,8DACR,IACA,cACF;IACF;IACA,IAAI,WAA0B;IAC9B,IAAI,SAAS,MAAM;KACjB,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;KACjC,WAAW;IACb,OAAO,IAAI,SAAS,KAAA,GAClB,WAAW;KAAE,GAAG;KAAU;IAAK;IAEjC,MAAM,QAAiC,EAAE,GAAG,SAAS,MAAM;IAC3D,IAAI,KAAK,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAAG,MAAM,OAAO;IACtE,IAAI,QAAQ,KAAK,MAAM,OAAO,QAAQ,OAAO,MAAM;IACnD,MAAM,EAAE,OAAO,QAAQ,GAAG,SAAS;IACnC,MAAM,OAAsB;KAC1B,GAAG;KACH,GAAI,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,EAAS,MAAe,IAAI,CAAC;IACnE;IACA,EAAE,SAAA,GAAQC,eAAAA,iBAAAA,CAAiB,QAAA,GAAOC,eAAAA,oBAAAA,CAAoB,OAAO,IAAI,CAAC,CAAC;IACnE;GACF;GACA,KAAK,sBAAsB;IACzB,MAAM,QAAA,GAAOM,eAAAA,gBAAAA,CAAgB,KAAK,KAAK;IACvC,IAAI;IACJ,IAAI;KACF,QAAA,GAAOC,eAAAA,YAAAA,CAAY,UAAU,OAAO;MAClC,WAAW;MACX,eAAe,UAAU,iBAAiB;KAC5C,CAAC;IACH,SAAS,OAAO;KACd,IAAI,iBAAiBC,eAAAA,kBAAkB,OAAO,MAAM,SAAS,IAAI,aAAa;KAC9E,MAAM;IACR;IACA,EAAE,QAAQ,IAAI;IACd;GACF;GACA,SACE,OAAO,sBAAuB,UAA+B,KAAK,IAAI,IAAI,gBAAgB;EAC9F;CACF;;CAGA,MAAM,iBAAiB,IAAY,eAAwD;EACzF,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,QAAQ,MAAM,SAAS,IAAI,EAAE,KAAK,MAAM,MAAM,IAAI,EAAE;EAC1D,IAAI,CAAC,OAAO,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;EAC3E,MAAM,OAA+B,EAAE,GAAG,MAAM,iBAAiB;EACjE,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,GAClD,IAAI,UAAU,MAAM,OAAO,KAAK;OAC3B,IAAI,OAAO,UAAU,UAAU,KAAK,OAAO;OAC3C,OAAO,iBAAiB,IAAI,6BAA6B,IAAI,eAAe;EAInF,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,KAAK,MAAM,qBAAqB,KAAA,GAAW;EAC5E,MAAM,mBAAqC;EAC3C,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,EAAE,cAAc,IAAI,EAAE,iBAAiB,CAAC;OAC/D,EAAE,WAAW,IAAI,EAAE,iBAAiB,CAAC;CAC5C;;;;;CAMA,MAAM,aAAa,IAAY,QAAgB,WAAyB;EACtE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,MAAM,OAAO,MAAM,MAAM,IAAI,EAAE,KAAK,OAAO,iBAAiB,GAAG,IAAI,IAAI,iBAAiB;EACxF,IAAI,KAAK,WAAW,UAAU,KAAK,WAAW,QAAQ;EACtD,MAAM,aAAa,KAAK,MAAM,IAAI,KAAK,IAAI;EAC3C,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK;EAClC,OAAO,OAAO,EAAE;EAChB,MAAM,UAAU,UAAU,OAAO,MAAM;EACvC,IAAI;EACJ,IAAI,YAAY,aAAa,cAAc;GAEzC,MAAM,mBAAmB,MAAM,SAAS,IAAI,KAAK,MAAM,CAAC,EAAE,eAAe;GACzE,MAAM,aAAa,mBAAmB,KAAK,SAAS,KAAK;GACzD,KAAK,mBAAmB,SAAS,YAAY,YAC3C,OAAO,wCAAwC,IAAI,mBAAmB;GAExE,MAAM,QAAA,GAAOC,eAAAA,eAAAA,CAAe,OAAO,UAAU;GAC7C,MAAM,WAAW,mBAAmB,SAAS,KAAK;GAClD,MAAM,WAAW,mBAAmB,KAAK,WAAW;GACpD,IAAI,aAAa,KAAA,KAAa,aAAa,KAAA,GACzC,OAAO,gCAAgC,IAAI,mBAAmB;GAEhE,SAAA,GAAQN,eAAAA,QAAAA,CAAQ,SAAS,UAAU,UAAU,KAAK,IAAI;GACtD,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;IAAE,QAAQ;IAAU,QAAQ;GAAS,CAAC;EAC1E,OAAO;GAEL,IAAI,YAAY,SAAS,SAAS,WAAW,KAAK,QAChD,OAAO,6CAA6C,IAAI,YAAY;GAEtE,IAAI,YAAY,SAAS,SAAS,WAAW,KAAK,QACnC;QAAA,CAAC,GAAG,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,QACpC,MAAM,EAAE,WAAW,KAAK,UAAU,EAAE,SAAS,KAAK,IAE9C,CAAC,CAAC,WAAW,GAClB,OAAO,sDAAsD,IAAI,YAAY;GAAA;GAGjF,SAAA,GAAQA,eAAAA,QAAAA,CAAQ,SAAS,QAAQ,QAAQ,KAAK,IAAI;GAClD,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;IAAE;IAAQ;GAAO,CAAC;EACtD;EACA,EAAE,QAAQ,UAAU,OAAO,IAAI,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI;GAAE,GAAG;GAAM;GAAQ;EAAO,CAAC,CAAC,CAAC;CACvF;CAEA,MAAM,gBAAgB,cAA4D;EAChF,MAAM,SAAS,EAAE,SAAS;EAC1B,MAAM,WAA6B,CAAC;EACpC,EAAE,kBAAkB;GAClB,MAAM,WAAW,QAAQ;GACzB,MAAM,UAAU,QAAQ;GACxB,IAAI,CAAC,WAAW,EAAE,SAAS,MAAM,QAAQ;GACzC,MAAM,QAAQ,IAAI,KAAA,GAAIO,eAAAA,wBAAAA,CAAwB,QAAQ,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC;GAC5E,MAAM,SAAA,GAAQA,eAAAA,wBAAAA,CAAwB,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC,QAC1D,UAAU,CAAC,MAAM,IAAI,SAAS,KAAK,CAAC,CACvC;GACA,IAAI,MAAM,SAAS,GACjB,MAAM,IAAI,UACR,MAAM,KAAK,WAAW;IACpB,WAAW,MAAM;IACjB,KAAK,MAAM;IACX,UAAU;IACV,SAAS,MAAM;IACf,MAAM;GACR,EAAE,CACJ;EAEJ,CAAC;EACD,OAAO;GACL,IAAI;GACJ,YAAY,WAAW,QAAQ,EAAE,SAAS,CAAC;GAC3C,GAAI,SAAS,SAAS,IAAI,EAAE,aAAa,SAAS,IAAI,CAAC;EACzD;CACF;CAKA,MAAM,aAAa,WAA0D;EAC3E,MAAM,EAAE,UAAU,iBAAiB,QAAQ,iBAAiB,WAAW;EACvE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,MAAM,UAAU,WAA6C;GAC3D,MAAM;GACN,YAAY,OAAO;GACnB,SAAS,MAAM;GACf;GACA,iBAAiB;GACjB,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,OAAO;GAC1D,GAAI,MAAM,KAAK,CAAC,IAAI;IAAE,QAAQ,MAAM;IAAQ,MAAM,MAAM;GAAK;EAC/D;EACA,IAAI,WAAW,KAAA,GAAW;GACxB,MAAM,SAAA,GAAQP,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,QAAQ;GAErD,IAAI,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,uBAAuB;IACrE,MAAM,YAAA,GAAWA,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,QAAQ;IACxD,IAAI,SAAS,IAAI,OAAO,OAAO,QAAQ;GACzC;GACA,OAAO,OAAO,KAAK;EACrB;EAEA,MAAM,UAAU,MAAM,SAAS,IAAI,MAAM;EACzC,IAAI,CAAC,SACH,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,2BAA2B,OAAO;EAC5C,CAAC;EAEH,MAAM,OAAO,aAAa,IAAI,CAAC,CAAC,UAAU,MAAM,MAAM,EAAE,kBAAkB,QAAQ;EAClF,IAAI,CAAC,MACH,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,sBAAsB,SAAS;EACzC,CAAC;EAEH,IAAI,KAAK,wBAAwB,CAAC,KAAK,qBAAqB,SAAS,QAAQ,IAAI,GAC/E,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,KAAK,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,SAAS,QAAQ,KAAK,6BAA6B,KAAK,MAAM,IAAI,QAAQ,CAAC,EAAE,SAAS,SAAS;EAC/I,CAAC;EAEH,OAAO,OAAO,EAAE,IAAI,KAAK,CAAC;CAC5B;CAEA,MAAM,WAAW,WAAmD;EAClE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,cAAgC,qBAAqB,KAAK;EAChE,IAAI,QAAQ,SACV,KAAK,MAAM,UAAA,GAASO,eAAAA,wBAAAA,CAAwB,OAAO,QAAQ,OAAO,GAChE,YAAY,KAAK;GACf,WAAW,MAAM;GACjB,KAAK,MAAM;GACX,UAAU;GACV,SAAS,MAAM;GACf,MAAM;EACR,CAAC;EAGL,YAAY,KAAK,GAAI,QAAQ,cAAc,KAAK,CAAC,CAAE;EACnD,MAAM,MAAM,OAAO,YAAY,QAAQ,OAAO,MAAM,SAAS,IAAI,EAAE,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC;EAC3F,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,OAAO;GACL,MAAM;GACN,YAAY,OAAO;GACnB,SAAS,YACN,QAAQ,MAAM,OAAO,SAAS,KAAK,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,CAC3D,IAAI,kBAAkB;GACzB,GAAI,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,OAAO,OAAO;EACjE;CACF;CAEA,MAAM,WAAW,WAAwC;EACvD,MAAM,QAAQ,EAAE,SAAS;EACzB,QAAQ,OAAO,MAAf;GACE,KAAK,gBACH,OAAO;IAAE,MAAM;IAAY,YAAY,OAAO;IAAW,UAAA,GAASR,eAAAA,eAAAA,CAAe,KAAK;GAAE;GAC1F,KAAK,oBACH,OAAO;IACL,MAAM;IACN,YAAY,OAAO;IACnB,GAAG,aAAa,OAAO,KAAK,CAAC;GAC/B;GACF,KAAK,oBACH,OAAO,UAAU,MAAM;GACzB,KAAK,yBAAyB;IAC5B,MAAM,OAAO,OAAO,KAAK;IACzB,OAAO;KACL,MAAM;KACN,YAAY,OAAO;KACnB,GAAG,kBAAkB,eAAe,IAAI,GAAG,IAAI;IACjD;GACF;GACA,KAAK,kBACH,OAAO,QAAQ,MAAM;GACvB,SACE;EACJ;CACF;CAIA,MAAM,MAAM,OACV,QACA,WACmC;EACnC,IAAI,YAAY,MAAM,GAAG,OAAO,aAAa,MAAM;EACnD,IAAI,gBAAgB,MAAM,GAAG,OAAO;GAAE,IAAI;GAAM,YAAY,CAAC;GAAG,UAAU,QAAQ,MAAM;EAAE;EAC1F,QAAQ,OAAO,MAAf;GACE,KAAK;IACH,EAAE,KAAK;IACP,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,KAAK;IACH,EAAE,KAAK;IACP,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,KAAK,aAAa;IAChB,IAAI,CAAC,QAAQ,MAAM,OAAO,kCAAkC,IAAI,iBAAiB;IACjF,MAAM,QAAQ,EAAE,SAAS;IACzB,MAAM,QAAQ,MAAA,GAAKA,eAAAA,eAAAA,CAAe,OAAO,EAAE,0BAAU,IAAI,KAAK,EAAE,CAAC,GAAG,MAAM;IAC1E,QAAQ;IACR,YAAY,QAAQ,MAAM;IAC1B,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC;GACA,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,MAAM;IACX,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,SACE,OAAO,OACL,IAAI,OAAO,KAAK,6CAChB,IACA,gBACF;EACJ;CACF;CAEA,OAAO;EACL,MAAM,SAAS,QAAQ,iBAAiB;GACtC,MAAM,SAAS,iBAAiB;GAKhC,gBAAgB;GAChB,IAAI;GACJ,IAAI;IACF,UAAU,IAAI,QAAuC,MAAM;GAC7D,UAAU;IACR,gBAAgB,KAAA;GAClB;GACA,IAAI;IACF,OAAQ,MAAM;GAChB,SAAS,OAAO;IACd,IAAI,iBAAiB,WAAW,OAAO;KAAE,IAAI;KAAO,aAAa,MAAM;IAAY;IACnF,IAAI,iBAAiBS,eAAAA,qBACnB,OAAO;KAAE,IAAI;KAAO,aAAa,CAAC,MAAM,aAAa,CAAC;IAAE;IAE1D,MAAM;GACR;EACF;EACA,UAAU,UAAU;GAClB,MAAM,IAAI;GACV,UAAU,IAAI,CAAC;GACf,aAAa,UAAU,OAAO,CAAC;EACjC;EACA,eAAe,EAAE,SAAS,MAAM;EAChC,SAAS;CACX;AACF;;;;AC/1BA,SAAgB,mBACd,YACA,MACkC;CAClC,OAAO;EACL,WAAW,WACT,gBAAgB,MAAM,IAClB,WAAW,SAAS,MAAM,IAC1B,QAAQ,QAAQ;GACd,IAAI;GACJ,aAAa,CACX;IACE,WAAW;IACX,UAAU;IACV,MAAM;IACN,SAAS,IAAI,KAAK,qCAAqC,OAAO;GAChE,CACF;EACF,CAAwB;EAC9B,YAAY,aAAa,WAAW,UAAU,QAAQ;CACxD;AACF;;AAGA,SAAgB,gBACd,MACA,YACA,UACA,QACiB;CACjB,OAAO;EACL;EACA,YAAY,KAAK,WAAW,mBAAmB,YAAY,KAAK,IAAI,IAAI;EACxE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;CAC7B;AACF;;AAGA,SAAgB,YAAY,UAA+B,OAAuC;CAChG,MAAM,EAAE,SAAS;CACjB,OAAO,QAAQ,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK,KAAK,CAAC;AACtE;;;;;;;;;;;;;AC3DA,SAAS,aACP,MACA,QACiD;CACjD,MAAM,UAAU,OAAO,IAAI,IAAI;CAC/B,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,OAAO,KAAA;CAC7C,MAAM,aAAyC,CAAC;CAChD,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,KAAK,GACpD,WAAW,KAAK;EACd;EACA,MAAM,MAAM;EACZ,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;EAC/C,GAAI,MAAM,QAAQ,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;EACnD,GAAI,MAAM,QAAQ,cAAc,EAAE,aAAa,MAAM,QAAQ,YAAY,IAAI,CAAC;CAChF,CAAC;CAGL,OAAO;AACT;;;;;;;AAQA,SAAgB,iBACd,WACA,UAAmC,CAAC,GAClB;CAClB,MAAM,gCAAgB,IAAI,IAAqD;CAC/E,KAAK,MAAM,UAAU,QAAQ,WAAW,CAAC,GAAG;EAC1C,MAAM,OAAO,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC;EAChD,KAAK,KAAK,MAAM;EAChB,cAAc,IAAI,OAAO,MAAM,IAAI;CACrC;CAEA,MAAM,WAAsC,CAAC;CAC7C,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GAAG;EACpD,IAAI,MAAM,UAAU,GAAG;EACvB,SAAS,KAAK;GACZ,MAAM,WAAW;GACjB,OAAO,WAAW;GAClB,GAAI,WAAW,gBAAgB,KAAA,IAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;GACtF,UAAU,WAAW;GACrB,GAAI,WAAW,OACX;IACE,cAAc,WAAW,KAAK;IAC9B,mBAAmB,WAAW,KAAK;GACrC,IACA,CAAC;GACL,GAAI,aAAa,WAAW,MAAM,aAAa,IAC3C,EAAE,YAAY,aAAa,WAAW,MAAM,aAAa,EAAE,IAC3D,CAAC;EACP,CAAC;CACH;CAEA,MAAM,QAAgC,CAAC;CACvC,KAAK,MAAM,cAAc,UAAU,MAAM,OAAO,GAAG;EACjD,IAAI,WAAW,SAAS,KAAA,GAAW;EACnC,MAAM,QAAQ,UAAU,MAAM,KAAA,GAAIC,eAAAA,kBAAAA,CAAkB,WAAW,WAAW,IAAI,CAAC,CAAC,EAAE;EAClF,MAAM,UACJ,WAAW,aAAa,eACpB,WAAW,SAAS,IACpB,WAAW,WAAW,WAAW,QAA4B;EACnE,MAAM,KAAK;GACT,MAAM,WAAW;GACjB,OAAO,WAAW;GAClB,GAAI,WAAW,gBAAgB,KAAA,IAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;GACtF,UAAU,WAAW;GACrB,SAAS,QAAQ,MAAM,WAAW,MAAM,OAAO,IAAI;GACnD,SAAS,QAAQ,MAAM,WAAW,MAAM,OAAO,IAAI;GACnD,GAAI,WAAW,UAAU,MAAM,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;GAC9D,GAAI,WAAW,KAAK,iBAAiB,EAAE,QAAQ,WAAW,KAAK,eAAe,IAAI,CAAC;GACnF,GAAI,aAAa,WAAW,MAAM,aAAa,IAC3C,EAAE,YAAY,aAAa,WAAW,MAAM,aAAa,EAAE,IAC3D,CAAC;EACP,CAAC;CACH;CAEA,OAAO;EAAE,WAAW,UAAU;EAAW;EAAU;CAAM;AAC3D;AAEA,SAAS,eAAe,YAAuE;CAC7F,IAAI,CAAC,cAAc,WAAW,WAAW,GAAG,OAAO,CAAC;CAKpD,OAAO,CAAC,iBAJM,WAAW,KAAK,MAAM;EAClC,MAAM,OAAO,CAAC,EAAE,MAAM,GAAI,EAAE,SAAS,CAAC,WAAW,EAAE,OAAO,KAAK,GAAG,GAAG,IAAI,CAAC,CAAE;EAC5E,OAAO,GAAG,EAAE,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,WAAW,MAAM;CAC5D,CAC6B,CAAC,CAAC,KAAK,IAAI,GAAG;AAC7C;AAEA,SAAS,MAAM,SAA0C;CACvD,MAAM,OAAiB,CAAC;CACxB,IAAI,QAAQ,cAAc,KAAK,KAAK,UAAU;CAC9C,IAAI,QAAQ,mBAAmB,KAAK,KAAK,OAAO;CAChD,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE,KAAK;AACrD;AAEA,SAAS,YAAY,SAA4C;CAC/D,MAAM,cAAc,QAAQ,cAAc,MAAM,QAAQ,gBAAgB;CACxE,OAAO,CACL,KAAK,QAAQ,KAAK,IAAI,QAAQ,MAAM,GAAG,MAAM,OAAO,IAAI,eACxD,GAAG,eAAe,QAAQ,UAAU,CACtC;AACF;AAEA,SAAS,SAAS,MAAsC;CACtD,MAAM,QAAQ,KAAK,UAAU,MAAM,wBAAwB;CAC3D,MAAM,SAAS,KAAK,SAAS,aAAa,KAAK,OAAO,KAAK,IAAI,MAAM;CACrE,MAAM,cAAc,KAAK,cAAc,MAAM,KAAK,gBAAgB;CAClE,OAAO,CACL,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG,MAAM,IAAI,KAAK,SAAS,SACpD,KAAK,QAAQ,KAAK,IAAI,EAAE,KAAK,KAAK,QAAQ,KAAK,IAAI,IAAI,SAAS,eACrE,GAAG,eAAe,KAAK,UAAU,CACnC;AACF;;;;;AAMA,SAAgB,qBAAqB,SAAmC;CACtE,MAAM,SAAS,QAAQ,SAAS,QAAQ,MAAM,EAAE,aAAa,OAAO;CACpE,MAAM,QAAQ,QAAQ,SAAS,QAAQ,MAAM,EAAE,aAAa,MAAM;CAClE,MAAM,WAAW,CAAC,KAAK,QAAQ,UAAU,WAAW;CACpD,IAAI,OAAO,SAAS,GAClB,SAAS,KAAK,CAAC,kBAAkB,GAAG,OAAO,QAAQ,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAE7E,IAAI,MAAM,SAAS,GACjB,SAAS,KAAK,CAAC,iBAAiB,GAAG,MAAM,QAAQ,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAE3E,IAAI,QAAQ,MAAM,SAAS,GACzB,SAAS,KAAK,CAAC,iBAAiB,GAAG,QAAQ,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAEhF,OAAO,SAAS,KAAK,MAAM;AAC7B;;;;;;AAOA,SAAgB,yBACd,UAAmC,CAAC,GACf;CACrB,OAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO,UACL,qBAAqB,kBAAA,GAAiBC,eAAAA,YAAAA,CAAY,KAAK,GAAmB,OAAO,CAAC;CACtF;AACF;;;;;;;;;;;;;;;;;ACnIA,SAAS,MAAM,GAAY,GAAqB;CAC9C,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM,OAAO;CACvF,IAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,GAAG,OAAO;CAClD,MAAM,KAAK,OAAO,KAAK,CAAC;CACxB,MAAM,KAAK,OAAO,KAAK,CAAC;CACxB,IAAI,GAAG,WAAW,GAAG,QAAQ,OAAO;CACpC,KAAK,MAAM,OAAO,IAChB,IAAI,CAAC,MAAO,EAA8B,MAAO,EAA8B,IAAI,GACjF,OAAO;CAGX,OAAO;AACT;;;;;AAMA,SAAS,MAAM,UAAyB,MAAoC;CAC1E,IAAI,OACF,SAAS,SAAS,SAAS,KAAK,SAAS,QACzC,SAAS,MAAM,SAAS,KAAK,MAAM,SAAA,GACnCC,eAAAA,YAAAA,CAAY,QAAQ,OAAA,GAAMA,eAAAA,YAAAA,CAAY,IAAI;CAC5C,MAAM,YACJ,MACA,OACmB;EACnB,MAAM,QAAQ,KAAK,KAAK;EACxB,MAAM,sBAAM,IAAI,IAAe;EAC/B,KAAK,MAAM,CAAC,IAAI,UAAU,IAAI;GAC5B,MAAM,MAAM,KAAK,IAAI,EAAE;GACvB,MAAM,OAAO,QAAQ,KAAA,KAAa,MAAM,KAAK,KAAK;GAClD,IAAI,CAAC,QAAQ,MAAM,KAAK,CAAC,CAAC,UAAU,IAAI,OAAO;GAC/C,IAAI,IAAI,IAAI,OAAO,MAAM,KAAK;EAChC;EACA,OAAO;CACT;CACA,MAAM,WAAW,SAAS,SAAS,UAAU,KAAK,QAAQ;CAC1D,MAAM,QAAQ,SAAS,SAAS,OAAO,KAAK,KAAK;CACjD,MAAM,UAAU,MAAM,SAAS,SAAS,KAAK,OAAO,IAAI,SAAS,UAAU,KAAK;CAChF,MAAM,EAAE,UAAU,IAAI,OAAO,IAAI,SAAS,IAAI,GAAG,SAAS;CAC1D,MAAM,EAAE,UAAU,KAAK,OAAO,KAAK,SAAS,KAAK,GAAG,iBAAiB;CACrE,IAAI,QAAQ,MAAM,MAAM,YAAY,GAAG,OAAO;CAC9C,MAAM,SAAwB;EAC5B,GAAG;EACH;EACA;EACA,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;CAC7C;CACA,QAAA,GAAOC,eAAAA,iBAAAA,CAAiB,OAAA,GAAMC,eAAAA,oBAAAA,CAAoB,MAAM,MAAM,CAAC;AACjE;AAEA,SAAS,WAAkB;CACzB,MAAM,IAAIC,eAAAA,oBACR,8EACF;AACF;AAEA,MAAM,YAAYC,eAAAA;;;;;;;;;AAalB,SAAgB,kBACd,QACA,UAAsC,CAAC,GAClB;CACrB,MAAM,IAAI;CACV,MAAM,YAAY,QAAQ;CAC1B,MAAM,QAAQ,QAAQ,gBAAgB;CACtC,MAAM,UAAU,QAAQ,kBAAkB,CAAC;CAC3C,MAAM,4BAAY,IAAI,IAAmC;CACzD,IAAI,QAAuB,aAAA,GACvBC,eAAAA,iBAAAA,CAAiB,KAAA,GAAW,EAAE,UAAU,CAAC,KAAA,GACxCA,eAAAA,iBAAAA,CAAiB;;CAEtB,IAAI;CACJ,IAAI,YAAY;CAChB,IAAI,YAAY;;CAEhB,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI,OAAsB,QAAQ,QAAQ;CAC1C,IAAI,WAAW;CAEf,MAAM,SAAS,SAAoC;EACjD,MAAM,YAAY,KAAK,UAAW,KAAiCC,eAAAA,uBAAuB,IAAI;EAC9F,IAAI,cAAc,OAGhB,QAAA,GAAOL,eAAAA,iBAAAA,CAAiB,OAAO,UAAU,MAAM,EAAE,YAAA,GAAWD,eAAAA,YAAAA,CAAY,KAAK,EAAE,CAAC,CAAC;EAEnF,MAAM,SAAS,UAAU,MAAM;GAC7B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;GACjC,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACzD,CAAC;EACD,QAAQ;EACR,OAAO;CACT;CAEA,MAAM,SAAS,MAAkB,QAAgB,YAA0C;EACzF,MAAM,WAAW;EACjB,MAAM,OAAO,MAAM,UAAU,MAAM,IAAI,CAAC;EACxC,IAAI,SAAS,UAAU;EACvB,QAAQ;EACR,MAAM,QAA0C;GAAE;GAAO;GAAU;GAAS;EAAO;EACnF,KAAK,MAAM,YAAY,WAAW,SAAS,KAAK;CAClD;;CAGA,MAAM,SACJ,QACA,UACS;EACT,IAAI,OAAO;GACT,YAAY,MAAM,UAAU,IAAI;GAChC,YAAY,MAAM,UAAU,IAAI;EAClC,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,KAAK;GACzC,YAAY;EACd,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,CAAC;GACrC;EACF,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,KAAK;GACzC,YAAY,KAAK,IAAI,YAAY,GAAG,CAAC;EACvC,OAAO;GACL,YAAY;GACZ,YAAY;EACd;CACF;;;;;CAMA,MAAM,WAAW,QAAgB,YAAmD;EAClF,MAAM,OAAO;EACb,MAAM,OAAO,EACV,SAAS;GAAE,MAAM;GAAgB,WAAW,UAAU,EAAE;EAAW,CAAC,CAAC,CACrE,MAAM,YAA4D,EAAE,OAAO,EAAE,CAAC,CAC9E,OAAO,WAAoB,EAAE,MAAM,EAAE;EACxC,MAAM,OAAO,KAAK,KAAK,YAAY;GACjC,MAAM,SAAS,MAAM;GACrB,IAAI,YAAY,WAAW,MAAM;GACjC,IAAI,WAAW,QAAQ,MAAM,OAAO;GACpC,MAAM,EAAE,WAAW;GACnB,IAAI,CAAC,OAAO,IACV,MAAM,IAAI,MAAM,OAAO,YAAY,EAAE,EAAE,WAAW,2BAA2B;GAE/E,IAAI,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,2CAA2C;GACjF,MAAM,OAAO,SAAS,SAAS,QAAQ,OAAO;EAChD,CAAC;EACD,OAAO,KAAK,MAAM,OAAO;EACzB,OAAO;CACT;CAEA,MAAM,cAAc,EAAE,WAAW,WAAW;EAC1C,IAAI,YAAY,OAAO,SAAS,sBAAsB;EACtD,MACE,OAAO,QACP,OAAO,YAAY,KAAA,KAAa,OAAO,YAAY,KAAA,IAC/C;GAAE,SAAS,OAAO;GAAS,SAAS,OAAO;EAAQ,IACnD,KAAA,CACN;EACA,IAAI,OAAO,SAAS;GAClB;GACA,IAAI;IACF,MAAM,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO;GACrD,SAAS,OAAO;IACd,QAAQ,KAAK;GACf;EACF,OACE,QAAa,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;CAE9D,CAAC;CAED,MAAM,QAAQ,QAAQ,QAAQ,CAAC,CAAC;CAEhC,MAAM,YAAY,CAAC,CAAC;CAEpB,MAAM,QAAQ,SAAwC;EACpD,EAAO,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO;CACzC;CA2DA,OAAO;EA/CL;EACA,YAAA;GAVA,MAAM,SAAS,QAAQ,SAAS;IAC9B,MAAM,SAAS,MAAM,EAAE,SAAS,QAAQ,OAAO;IAC/C,MAAM;IACN,OAAO;GACT;GACA,YAAY,aAAa,EAAE,UAAU,QAAQ;EAKpC;EACT,cAAc;EACd,UAAU;GACR,WAAW;GACX,YAAY;EACd;EAEA,gBAAgB;EAChB,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;EACA,UAAU,QAAQ,QAAQ,UAAA,GAASO,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,IAAI;EAEtE,YAAY;EACZ,eAAe;EACf,aAAa;EACb,aAAa;EACb,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,SAAS;EACT,eAAe;EACf,QAAQ;EACR,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,eAAe;EACf,SAAS;EACT,MAAM;EACN,aAAa;EACb,cAAc;EAEd,OAAO;GACL,IAAI,cAAc,GAAG,OAAO;GAC5B,KAAK,UAAU;GACf,OAAO;EACT;EACA,OAAO;GACL,IAAI,cAAc,GAAG,OAAO;GAC5B,KAAK,UAAU;GACf,OAAO;EACT;EACA,eAAe,YAAY;EAC3B,eAAe,YAAY;CAElB;AACb;;;ACrUA,MAAM,kBAAkB;AAyDxB,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,YAAY,OAAoC;CACvD,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACvD;AAEA,SAAS,aAAa,IAAe,MAAc,SAA+B;CAChF,OAAO;EAAE,SAAS;EAAiB;EAAI,OAAO;GAAE;GAAM;EAAQ;CAAE;AAClE;;;;;;;;AASA,SAAgB,kBAId,MAA0B,YAAkD;CAC5E,MAAM,cAAc,WAAW,WAAW,WAAW;EACnD,KAAK,YAAY;GAAE,SAAS;GAAiB,QAAQ,OAAO;GAAM,QAAQ;EAAO,CAAC;CACpF,CAAC;CAED,KAAK,aAAa,OAAU;EAC1B,MAAM,UAAU,GAAG;EACnB,IAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,YAAY,iBAAiB;EAC/D,MAAM,EAAE,IAAI,QAAQ,QAAQ,WAAW;EACvC,MAAM,QAAQ,YAAY,EAAE;EAC5B,MAAM,kBACJ,OAAO,WAAW,WAAW,EAAE,OAAO,IAAI,KAAA;EAE5C,IAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;GACrD,IAAI,OAAO,KAAK,YAAY,aAAa,IAAI,QAAQ,kBAAkB,CAAC;GACxE;EACF;EACA,IAAI,CAAC,SAAS,MAAM,KAAK,OAAO,SAAS,QAAQ;GAC/C,IAAI,OAAO,KAAK,YAAY,aAAa,IAAI,QAAQ,iBAAiB,CAAC;GACvE;EACF;EAEA,MAAM,SAAS;EACf,IAAI,CAAC,OAAO;GAEV,WAAgB,SAAS,QAAQ,eAAe;GAChD;EACF;EACA,WAAW,SAAS,QAAQ,eAAe,CAAC,CAAC,MAC1C,WAAkC;GACjC,KAAK,YAAY;IAAE,SAAS;IAAiB;IAAI;GAAO,CAAC;EAC3D,IACC,UAAmB;GAClB,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU;GACtD,KAAK,YAAY,aAAa,IAAI,QAAQ,IAAI,CAAC;EACjD,CACF;CACF;CAEA,aAAa;EACX,YAAY;EACZ,KAAK,YAAY;CACnB;AACF;;;;;;;AAQA,SAAgB,uBAId,MAAoD;CACpD,IAAI,SAAS;CACb,MAAM,0BAAU,IAAI,IAGlB;CACF,MAAM,4BAAY,IAAI,IAA4B;CAElD,KAAK,aAAa,OAAU;EAC1B,MAAM,UAAU,GAAG;EACnB,IAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,YAAY,iBAAiB;EAC/D,MAAM,EAAE,IAAI,QAAQ,QAAQ,QAAQ,UAAU;EAE9C,IAAI,YAAY,EAAE,GAAG;GACnB,MAAM,UAAU,QAAQ,IAAI,EAAE;GAC9B,IAAI,CAAC,SAAS;GACd,QAAQ,OAAO,EAAE;GACjB,IAAI,SAAS,KAAK,GAChB,QAAQ,uBAAO,IAAI,MAAM,kBAAkB,OAAO,MAAM,IAAI,EAAE,IAAI,OAAO,MAAM,OAAO,GAAG,CAAC;QAE1F,QAAQ,QAAQ,MAA+B;GAEjD;EACF;EAEA,IAAI,OAAO,WAAW,YAAY,SAAS,MAAM,GAAG;GAClD,MAAM,SAAS;GACf,KAAK,MAAM,YAAY,WAAW,SAAS,MAAM;EACnD;CACF;CAEA,OAAO;EACL,SAAS,QAAQ,iBAAiB;GAChC,MAAM,KAAK;GACX,OAAO,IAAI,SAAS,SAAS,WAAW;IACtC,QAAQ,IAAI,IAAI;KAAW;KAAoD;IAAO,CAAC;IACvF,KAAK,YAAY;KACf,SAAS;KACT;KACA,QAAQ,OAAO;KACf,QAAQ;KACR,GAAI,iBAAiB,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,gBAAgB,OAAO;IACpF,CAAC;GACH,CAAC;EACH;EACA,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;;;;ACtMA,MAAa,2BAAmC"}
1
+ {"version":3,"file":"index.cjs","names":["metamodelOf","elementBehavesLike","LINK_SELECTOR","linkBehavesLike","effectiveLinkKind","DIAGNOSTIC_SEVERITIES","connectResultToDiagnostic","metamodelOf","TOP_LEVEL_KEYS","FILE_METAMODEL_KEY","inheritMetamodel","inheritSourceLayout","validateModel","toPistarObject","canLink","withFileMetamodel","MetamodelError","hostMetamodelOf","parsePistar","PistarParseError","dependencyEnds","validateModelProperties","ModelOperationError","effectiveLinkKind","metamodelOf","metamodelOf","inheritMetamodel","inheritSourceLayout","ModelOperationError","parsePistar","createEmptyModel","FILE_METAMODEL_KEY","canLink"],"sources":["../src/actions.ts","../src/created-ids.ts","../src/kind-selectors.ts","../src/hints.ts","../src/markers.ts","../src/dispatcher.ts","../src/host.ts","../src/metamodel-context.ts","../src/mirror.ts","../src/transport.ts","../src/index.ts"],"sourcesContent":["/**\n * The action vocabulary: a subset of GLSP's action protocol\n * (https://eclipse.dev/glsp/documentation/protocol/), with GLSP's interface names and `kind`\n * strings where the concept is the same, and iStar extras under `istar.*`.\n *\n * Every action is plain JSON (no Maps, functions or class instances), so a dispatcher can sit\n * on the other side of a `postMessage` or a socket. Requests carry `requestId`; their response\n * carries it back as `responseId`, as in GLSP.\n *\n * Where a shape differs from GLSP's: `args` of the create operations are structured (a name,\n * custom properties, ids) rather than GLSP's flat `Args`; `newSize` of `ElementAndBounds` is\n * optional; `ChangeContainerOperation.targetContainerId` is `null` to take an element out of\n * its actor; `SetModelAction.newRoot` is the piStar file, not a GModel; operations need not\n * carry GLSP's `isOperation: true` (the dispatcher knows them by `kind`).\n */\nimport type {\n CustomProperties,\n DiagnosticSeverity,\n ElementKind,\n FileMetamodel,\n LinkKind,\n ModelChange,\n PistarFile,\n} from '@istar-ts/core';\n\n/** GLSP's custom arguments: a flat map of primitives. */\nexport type Args = Readonly<Record<string, string | number | boolean>>;\n\n/** A value that survives a JSON round trip, for `istar.updateModelExtra`'s `set`. */\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface Dimension {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface Action {\n readonly kind: string;\n}\n\nexport interface RequestAction extends Action {\n readonly requestId: string;\n /** Milliseconds the sender is willing to wait (GLSP); the in-process dispatcher ignores it. */\n readonly timeout?: number;\n}\n\nexport interface ResponseAction extends Action {\n /** The `requestId` of the request this answers. */\n readonly responseId: string;\n}\n\n/** An action that edits the model, as one undo step. */\nexport interface Operation extends Action {\n /** GLSP's operation marker. Optional here: the dispatcher knows operations by `kind`. */\n readonly isOperation?: true;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Operations (GLSP)\n\nexport interface CreateNodeArgs {\n /** Default: the kind's label (\"Goal\"), as in piStar. */\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n /** The new element's id. Default: a fresh UUID. Lets a compound operation refer to it. */\n readonly id?: string;\n}\n\nexport interface CreateNodeOperation<EK extends string = ElementKind> extends Operation {\n readonly kind: 'createNode';\n /** The element kind, e.g. `istar.Goal`. */\n readonly elementTypeId: EK;\n /** Default: the container's position, or the origin. */\n readonly location?: Point;\n /** The actor to create the element in. */\n readonly containerId?: string;\n readonly args?: CreateNodeArgs;\n}\n\n/** The dependum a dependency creates between its depender and dependee. */\nexport interface DependumArgs<EK extends string = ElementKind> {\n /** Default: the metamodel's first node kind that can be a dependum. */\n readonly kind?: EK;\n readonly name?: string;\n readonly id?: string;\n /** Default: midway between depender and dependee, as in piStar. */\n readonly location?: Point;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface CreateEdgeArgs<EK extends string = ElementKind> {\n /** A contribution's value (the link's `label`), e.g. `help`. */\n readonly value?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n /**\n * The new link's id: for an n-ary kind whose target is not yet a hub, the new hub's; for an\n * n-ary kind whose target already is a hub, the new leg's (same as `legId` there). Default: a\n * fresh UUID.\n */\n readonly id?: string;\n /** For a dependency kind: the dependum to create. */\n readonly dependum?: DependumArgs<EK>;\n /** For a dependency kind: the ids of its two links. */\n readonly linkIds?: readonly [string, string];\n /**\n * The id of the leg it creates: for a target that is not yet a hub, the new leg from source;\n * for a target that already is a hub, the new leg instead of `id`.\n */\n readonly legId?: string;\n /** For an n-ary kind whose target is not yet a hub: the id of the end it creates. */\n readonly endId?: string;\n}\n\n/**\n * Adds a link. With a dependency kind, adds the dependum and its two links (as `addDependency`\n * does), source being the depender and target the dependee. With an n-ary kind, adds a leg when\n * the target is one of the kind's hubs, else a new hub with a leg and an end.\n */\nexport interface CreateEdgeOperation<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends Operation {\n readonly kind: 'createEdge';\n /** The link kind, e.g. `istar.ContributionLink`. */\n readonly elementTypeId: LK;\n readonly sourceElementId: string;\n readonly targetElementId: string;\n readonly args?: CreateEdgeArgs<EK>;\n}\n\n/** Removes elements and links, with everything that depends on them (as the store does). */\nexport interface DeleteElementOperation extends Operation {\n readonly kind: 'deleteElement';\n /** Element and link ids. */\n readonly elementIds: readonly string[];\n}\n\nexport interface ElementAndBounds {\n readonly elementId: string;\n /** Moving an actor moves its inner elements with it. */\n readonly newPosition?: Point;\n /** Written to the element's `display` (`width`, `height`). */\n readonly newSize?: Dimension;\n}\n\nexport interface ChangeBoundsOperation extends Operation {\n readonly kind: 'changeBounds';\n readonly newBounds: readonly ElementAndBounds[];\n}\n\n/** Moves an inner element into another actor, or out of any actor with `null` (`nestElement`). */\nexport interface ChangeContainerOperation extends Operation {\n readonly kind: 'changeContainer';\n readonly elementId: string;\n readonly targetContainerId: string | null;\n /** The element's new position, if it moves too. */\n readonly location?: Point;\n}\n\n/**\n * Gives a link new ends, keeping its id, kind and properties. A dependency's link keeps its\n * dependum end; an n-ary link's leg keeps its hub (or moves to another hub of the kind), its end\n * keeps the hub.\n */\nexport interface ReconnectEdgeOperation extends Operation {\n readonly kind: 'reconnectEdge';\n readonly edgeElementId: string;\n readonly sourceElementId: string;\n readonly targetElementId: string;\n readonly args?: Args;\n}\n\n/**\n * Sets an element's or link's name (`labelId` = its id), or one of its custom properties\n * (`labelId` = `\"<id>#<key>\"`). An element's name is written as-is (`text`, including `\"\"`, as\n * piStar always keeps the key); a link's name is removed from the file when `text` is `\"\"`, as\n * piStar does for a link whose name was cleared (`fileManager.js` only writes `name` when it is\n * truthy).\n */\nexport interface ApplyLabelEditOperation extends Operation {\n readonly kind: 'applyLabelEdit';\n readonly labelId: string;\n readonly text: string;\n}\n\n/** Applies its operations in order, as one undo step; if one is rejected, none is applied. */\nexport interface CompoundOperation<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends Operation {\n readonly kind: 'compound';\n readonly operationList: readonly IstarOperation<EK, LK>[];\n}\n\n// ---------------------------------------------------------------------------------------------\n// Operations (iStar)\n\n/** Adds a leg from `sourceElementId` to the hub of an n-ary link (`store.addLeg`). */\nexport interface AddLegOperation extends Operation {\n readonly kind: 'istar.addLeg';\n readonly hubId: string;\n readonly sourceElementId: string;\n readonly args?: { readonly id?: string };\n}\n\n/** Removes a leg of an n-ary link; the last one takes the hub and end with it. */\nexport interface RemoveLegOperation extends Operation {\n readonly kind: 'istar.removeLeg';\n readonly legId: string;\n}\n\nexport interface SetCollapsedOperation extends Operation {\n readonly kind: 'istar.setCollapsed';\n /** An actor. */\n readonly elementId: string;\n readonly collapsed: boolean;\n}\n\nexport interface DiagramPatch {\n readonly name?: string;\n readonly width?: number;\n readonly height?: number;\n /** Replaces the diagram's custom properties. */\n readonly customProperties?: CustomProperties;\n}\n\nexport interface UpdateDiagramOperation extends Operation {\n readonly kind: 'istar.updateDiagram';\n readonly diagram: DiagramPatch;\n}\n\n/**\n * Sets custom properties of an element or link: each key is set to its value, or removed when\n * the value is `null`; other keys are kept. Values are strings, as piStar stores them.\n */\nexport interface UpdatePropertiesOperation extends Operation {\n readonly kind: 'istar.updateProperties';\n /** An element or link id. */\n readonly elementId: string;\n readonly properties: Readonly<Record<string, string | null>>;\n}\n\n/**\n * Merges into an element's `display` (colour, the auto-grown height from a label fit): a key set\n * to `undefined` is removed, the rest is written as-is. Same semantics as `ElementPatch.display`\n * (`@istar-ts/core`), which this forwards to.\n */\nexport interface UpdateDisplayOperation extends Operation {\n readonly kind: 'istar.updateDisplay';\n readonly elementId: string;\n readonly patch: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Sets an existing link's contribution value (`label` in the save file), e.g. a Contribution\n * link's make/help/hurt/break. `null` clears it. Rejected when the link's kind has no\n * `possibleLabels`, or `value` is not one of them (as `createEdge.args.value` is checked at\n * creation).\n */\nexport interface SetLinkValueOperation extends Operation {\n readonly kind: 'istar.setLinkValue';\n readonly linkId: string;\n readonly value: string | null;\n}\n\n/**\n * Merges into a link's `display` (its bend points, `vertices`): a key set to `undefined` is\n * removed, the rest is written as-is. Same semantics as `LinkPatch.display` (`@istar-ts/core`),\n * which this forwards to. GLSP's counterpart is `changeRoutingPoints`.\n */\nexport interface UpdateLinkDisplayOperation extends Operation {\n readonly kind: 'istar.updateLinkDisplay';\n readonly linkId: string;\n readonly patch: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Changes the kind of a set of links: each listed link's id, source, target, order in the file,\n * name, value, custom properties and display are kept; other links are untouched. One undo step\n * for the whole set, all or nothing. A link whose kind is already `elementTypeId` is a no-op;\n * an empty `linkIds` is a no-op too. Rejected (model untouched) if `canLink` refuses any listed\n * link's new kind for its unchanged source and target (e.g. a mixed-refinement rule), or if the\n * link keeps a `value` the new kind's `possibleLabels` disallows.\n */\nexport interface ChangeLinkKindOperation<LK extends string = LinkKind> extends Operation {\n readonly kind: 'istar.changeLinkKind';\n readonly linkIds: readonly string[];\n /** The links' new kind, e.g. `istar.OrRefinementLink`. */\n readonly elementTypeId: LK;\n}\n\n/**\n * Sets (or, with `null` or an empty block, removes) the model file's own `\"metamodel\"` block:\n * custom element kinds, groupers, link kinds with their rules and line style (`withFileMetamodel`\n * in `@istar-ts/core`). One undo step; undo restores the previous block exactly. Rejected (model\n * untouched) if the block is malformed, collides with the host's kinds, or drops a kind an\n * element or link still uses. A host's dialect-specific checks (e.g. goal-controller's own\n * validation of the block) run as an `ActionGuard` on this operation's kind, so their refusal\n * also comes back as diagnostics.\n */\nexport interface SetFileMetamodelOperation extends Operation {\n readonly kind: 'istar.setFileMetamodel';\n readonly block: FileMetamodel | null;\n}\n\n/**\n * Sets, removes or reads back the model's own top-level keys that core keeps in `model.extra`\n * (e.g. a dialect's `metamodelVersion`): `set`'s keys are written (other extra keys and their\n * order are kept; a new key is appended where `toPistar` would place it), `remove`'s keys are\n * deleted. `tool` sets (or, with `null`, removes) the model's own `tool` field in the same undo\n * step — `set`/`remove` reject it, and every key core models itself (`actors`, `orphans`,\n * `dependencies`, `links`, `display`, `istar`, `saveDate`, `diagram`), and `\"metamodel\"` (use\n * `istar.setFileMetamodel` for that one). One undo step.\n */\nexport interface UpdateModelExtraOperation extends Operation {\n readonly kind: 'istar.updateModelExtra';\n readonly set?: Readonly<Record<string, JsonValue>>;\n readonly remove?: readonly string[];\n readonly tool?: string | null;\n}\n\n/**\n * Replaces the whole model from a piStar save file, as one undo step: ids, order and extra keys\n * come from `model`, so a parse → `toPistar` round trip is byte-identical to it. Parsed with\n * `parsePistar` under the dispatcher's own metamodel (`fileMetamodel` as in `parsePistar`); a\n * parse error rejects with a typed diagnostic, the model untouched. Pre-guards and postGuards\n * run against this operation, the model before and the model after, like any other operation.\n */\nexport interface ReplaceModelOperation extends Operation {\n readonly kind: 'istar.replaceModel';\n readonly model: PistarFile;\n readonly fileMetamodel?: boolean;\n}\n\n/** Every operation, keyed by `kind`. */\nexport type IstarOperation<EK extends string = ElementKind, LK extends string = LinkKind> =\n | CreateNodeOperation<EK>\n | CreateEdgeOperation<EK, LK>\n | DeleteElementOperation\n | ChangeBoundsOperation\n | ChangeContainerOperation\n | ReconnectEdgeOperation\n | ApplyLabelEditOperation\n | CompoundOperation<EK, LK>\n | AddLegOperation\n | RemoveLegOperation\n | SetCollapsedOperation\n | UpdateDiagramOperation\n | UpdatePropertiesOperation\n | UpdateDisplayOperation\n | SetLinkValueOperation\n | UpdateLinkDisplayOperation\n | ChangeLinkKindOperation<LK>\n | SetFileMetamodelOperation\n | UpdateModelExtraOperation\n | ReplaceModelOperation;\n\n// ---------------------------------------------------------------------------------------------\n// Model\n\nexport interface RequestModelAction extends RequestAction {\n readonly kind: 'requestModel';\n readonly options?: Args;\n}\n\nexport interface SetModelAction extends ResponseAction {\n readonly kind: 'setModel';\n /** The model as a piStar save file (`toPistarObject`). */\n readonly newRoot: PistarFile;\n}\n\n/**\n * The model changed: sent to subscribers after every edit, undo, redo or load, whoever caused\n * it. `source` and `changes` are iStar extras (the store's `ModelChangeEvent`).\n */\nexport interface ModelSourceChangedAction extends Action {\n readonly kind: 'sourceModelChanged';\n /** The dispatcher's `sourceModelName` option. */\n readonly sourceModelName: string;\n readonly source: 'edit' | 'undo' | 'redo' | 'load';\n /** What an edit did; empty for undo, redo and load. */\n readonly changes: readonly ModelChange[];\n /**\n * The new model as a piStar save file (`toPistarObject`), when the dispatcher was created with\n * `sendModel`: what a mirror (`createMirrorStore`) follows without asking for it. An iStar\n * extra.\n */\n readonly newRoot?: PistarFile;\n /**\n * Whether undo is possible, from the remote store after this change (when the dispatcher was\n * created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.\n */\n readonly canUndo?: boolean;\n /**\n * Whether redo is possible, from the remote store after this change (when the dispatcher was\n * created with `sendModel`). An iStar extra; a mirror uses this to know the exact state.\n */\n readonly canRedo?: boolean;\n /**\n * The `origin` the causing `dispatch` was given, echoed back; absent for a change with none\n * (a host's direct `store.load`, for instance). See `ActionDispatcher.dispatch`.\n */\n readonly origin?: string;\n}\n\n/** Saves the model through the host's `save` callback. */\nexport interface SaveModelAction extends Action {\n readonly kind: 'saveModel';\n readonly fileUri?: string;\n}\n\nexport type DirtyStateChangeReason = 'operation' | 'undo' | 'redo' | 'save' | 'external';\n\n/** Sent to subscribers when the model starts or stops differing from the last saved one. */\nexport interface SetDirtyStateAction extends Action {\n readonly kind: 'setDirtyState';\n readonly isDirty: boolean;\n readonly reason?: DirtyStateChangeReason;\n /** The `origin` of the dispatch that caused this dirty-state change, echoed back; see `ModelSourceChangedAction.origin`. */\n readonly origin?: string;\n}\n\nexport interface UndoAction extends Action {\n readonly kind: 'glspUndo';\n}\n\nexport interface RedoAction extends Action {\n readonly kind: 'glspRedo';\n}\n\n// ---------------------------------------------------------------------------------------------\n// Type hints and edge checks\n\nexport interface TypeHint {\n readonly elementTypeId: string;\n readonly repositionable: boolean;\n readonly deletable: boolean;\n}\n\nexport interface ShapeTypeHint extends TypeHint {\n readonly resizable: boolean;\n /** Can move into or out of an actor. */\n readonly reparentable: boolean;\n /** For an actor: the node kinds it can contain. */\n readonly containableElementTypeIds?: readonly string[];\n}\n\nexport interface EdgeTypeHint extends TypeHint {\n readonly routable: boolean;\n /** Element kinds that may be the source; absent when any may. */\n readonly sourceElementTypeIds?: readonly string[];\n /** Element kinds that may be the target; absent when any may. */\n readonly targetElementTypeIds?: readonly string[];\n /** Always true for iStar: kinds alone don't decide (same actor, uniqueness…); ask `requestCheckEdge`. */\n readonly dynamic?: boolean;\n}\n\nexport interface RequestTypeHintsAction extends RequestAction {\n readonly kind: 'requestTypeHints';\n}\n\nexport interface SetTypeHintsAction extends ResponseAction {\n readonly kind: 'setTypeHints';\n readonly shapeHints: readonly ShapeTypeHint[];\n readonly edgeHints: readonly EdgeTypeHint[];\n}\n\n/** Would a link of `edgeType` from source to target be accepted (`canLink`)? */\nexport interface RequestCheckEdgeAction extends RequestAction {\n readonly kind: 'requestCheckEdge';\n readonly edgeType: string;\n readonly sourceElementId: string;\n /** Absent: is the source an acceptable source at all? */\n readonly targetElementId?: string;\n}\n\nexport interface CheckEdgeResultAction extends ResponseAction {\n readonly kind: 'checkEdgeTargetResult';\n readonly isValid: boolean;\n readonly edgeType: string;\n readonly sourceElementId: string;\n readonly targetElementId?: string;\n /** iStar extra: why not, when `isValid` is false. */\n readonly reason?: string;\n /** iStar extra: the constraint that failed (`ConstraintCode`). */\n readonly code?: string;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Context actions (the palette)\n\nexport interface EditorContext {\n readonly selectedElementIds: readonly string[];\n /** Where the user is about to create something, in model coordinates. */\n readonly lastMousePosition?: Point;\n readonly args?: Args;\n}\n\n/** GLSP's context ids. The dispatcher answers every context with the palette. */\nexport type ContextId = 'tool-palette' | 'context-menu' | 'command-palette' | (string & {});\n\nexport interface RequestContextActions extends RequestAction {\n readonly kind: 'requestContextActions';\n readonly contextId: ContextId;\n readonly editorContext: EditorContext;\n}\n\n/** One palette entry: the trigger action(s) a click sends, with the palette's data. */\nexport interface LabeledAction {\n readonly label: string;\n readonly actions: readonly IstarAction[];\n readonly icon?: string;\n /** iStar extras, from the `PaletteDescription` entry. */\n readonly id?: string;\n readonly group?: string;\n readonly section?: string;\n readonly order?: number;\n}\n\nexport interface SetContextActions extends ResponseAction {\n readonly kind: 'setContextActions';\n /** Sorted by `order`. */\n readonly actions: readonly LabeledAction[];\n /** iStar extra: labels of the entries' `group`s (the palette's dropdown buttons). */\n readonly groups?: Readonly<Record<string, { readonly label: string }>>;\n readonly args?: Args;\n}\n\n/** Arms the client's node creation tool; the client then sends a `CreateNodeOperation`. */\nexport interface TriggerNodeCreationAction extends Action {\n readonly kind: 'triggerNodeCreation';\n readonly elementTypeId: string;\n /** Presets for the operation's `args`. */\n readonly args?: { readonly customProperties?: CustomProperties };\n}\n\n/** Arms the client's edge creation tool; the client then sends a `CreateEdgeOperation`. */\nexport interface TriggerEdgeCreationAction extends Action {\n readonly kind: 'triggerEdgeCreation';\n readonly elementTypeId: string;\n /** Presets for the operation's `args`: a contribution's value, a dependency's dependum kind. */\n readonly args?: { readonly value?: string; readonly dependum?: { readonly kind: string } };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Markers\n\n/** GLSP's validation marker; `kind` is a `DiagnosticSeverity`. */\nexport interface Marker {\n /** Short text (the diagnostic's message). */\n readonly label: string;\n /** Full text (the message, with its source when it has one). */\n readonly description: string;\n readonly elementId: string;\n readonly kind: DiagnosticSeverity | (string & {});\n /** iStar extras, kept so a marker converts back to the same `GoalDiagnostic`. */\n readonly key?: string;\n readonly source?: string;\n readonly code?: string;\n}\n\n/**\n * Markers of the model: link constraint violations (`validateModel`), property issues (the\n * dispatcher's `schemas`) and the host's `diagnostics`.\n */\nexport interface RequestMarkersAction extends RequestAction {\n readonly kind: 'requestMarkers';\n /**\n * Elements to report on (GLSP's spelling). Empty, or naming no element or link of the model\n * (a GLSP client sends its root's id), means the whole model.\n */\n readonly elementsIDs: readonly string[];\n readonly reason?: string;\n}\n\nexport interface SetMarkersAction extends ResponseAction {\n readonly kind: 'setMarkers';\n readonly markers: readonly Marker[];\n readonly reason?: string;\n}\n\nexport interface DeleteMarkersAction extends Action {\n readonly kind: 'deleteMarkers';\n readonly markers: readonly Marker[];\n}\n\n// ---------------------------------------------------------------------------------------------\n// Unions\n\nexport type IstarRequestAction =\n | RequestModelAction\n | RequestTypeHintsAction\n | RequestCheckEdgeAction\n | RequestContextActions\n | RequestMarkersAction;\n\nexport type IstarResponseAction =\n | SetModelAction\n | SetTypeHintsAction\n | CheckEdgeResultAction\n | SetContextActions\n | SetMarkersAction;\n\n/**\n * Actions the dispatcher does not act on: it passes them to its subscribers (a server telling\n * its clients), and sends the first two itself.\n */\nexport type IstarNotificationAction =\n | ModelSourceChangedAction\n | SetDirtyStateAction\n | TriggerNodeCreationAction\n | TriggerEdgeCreationAction\n | DeleteMarkersAction;\n\n/** Every action of the protocol, keyed by `kind`. */\nexport type IstarAction<EK extends string = ElementKind, LK extends string = LinkKind> =\n | IstarOperation<EK, LK>\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarRequestAction\n | IstarResponseAction\n | IstarNotificationAction;\n\nconst OPERATION_KIND_LIST: readonly IstarOperation['kind'][] = [\n 'createNode',\n 'createEdge',\n 'deleteElement',\n 'changeBounds',\n 'changeContainer',\n 'reconnectEdge',\n 'applyLabelEdit',\n 'compound',\n 'istar.addLeg',\n 'istar.removeLeg',\n 'istar.setCollapsed',\n 'istar.updateDiagram',\n 'istar.updateProperties',\n 'istar.updateDisplay',\n 'istar.setLinkValue',\n 'istar.updateLinkDisplay',\n 'istar.changeLinkKind',\n 'istar.setFileMetamodel',\n 'istar.updateModelExtra',\n 'istar.replaceModel',\n];\n\nconst REQUEST_KIND_LIST: readonly IstarRequestAction['kind'][] = [\n 'requestModel',\n 'requestTypeHints',\n 'requestCheckEdge',\n 'requestContextActions',\n 'requestMarkers',\n];\n\n/**\n * The other actions the dispatcher accepts: `glspUndo`/`glspRedo`/`saveModel` (acted on), then\n * the notifications it only re-emits to subscribers (`IstarNotificationAction`'s kinds).\n */\nconst NOTIFICATION_KIND_LIST: readonly (\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarNotificationAction\n)['kind'][] = [\n 'glspUndo',\n 'glspRedo',\n 'saveModel',\n 'sourceModelChanged',\n 'setDirtyState',\n 'triggerNodeCreation',\n 'triggerEdgeCreation',\n 'deleteMarkers',\n];\n\nconst OPERATION_KINDS: ReadonlySet<string> = new Set(OPERATION_KIND_LIST);\nconst REQUEST_KINDS: ReadonlySet<string> = new Set(REQUEST_KIND_LIST);\n\n/**\n * The action kinds `createActionDispatcher` accepts, grouped the way it treats them: `operations`\n * edit the model as one undo step, `requests` get a response action, `notifications` (plus\n * `glspUndo`/`glspRedo`/`saveModel`) are acted on or re-emitted as is. Derived from the same\n * lists `isOperation`/`isRequestAction` use, so it can't drift from the dispatcher.\n */\nexport const HANDLED_ACTION_KINDS: {\n readonly operations: readonly IstarOperation['kind'][];\n readonly requests: readonly IstarRequestAction['kind'][];\n readonly notifications: readonly (\n | UndoAction\n | RedoAction\n | SaveModelAction\n | IstarNotificationAction\n )['kind'][];\n} = {\n operations: OPERATION_KIND_LIST,\n requests: REQUEST_KIND_LIST,\n notifications: NOTIFICATION_KIND_LIST,\n};\n\n/** True for the operations (actions that edit the model). */\nexport function isOperation<EK extends string, LK extends string>(\n action: IstarAction<EK, LK>,\n): action is IstarOperation<EK, LK> {\n return OPERATION_KINDS.has(action.kind);\n}\n\n/** True for the requests (actions answered with a response action). */\nexport function isRequestAction(action: Action): action is IstarRequestAction {\n return REQUEST_KINDS.has(action.kind);\n}\n","/**\n * An accepted operation with the ids it created injected back as explicit ids, so dispatching it\n * again against the same model state creates the same ids. The playground's protocol lab replay\n * (#46) and agent Propose mode (#155, whose apply must reproduce the scratch run's ids for later\n * steps that name them) need it, and so does `@istar-ts/glsp`'s grouping of an MCP tool call\n * (#223), which applies a draft's operations again on the store as one `compound`.\n */\nimport type { IstarOperation } from './actions';\nimport { type AnyIstarModel, type AnyMetamodel, metamodelOf } from '@istar-ts/core';\n\ntype Operation = IstarOperation<string, string>;\n\n/** How many new element ids, then new link ids, `operation` creates, mirroring the dispatcher's\n * `createdIds` diff (`dispatcher.ts`) and `connect`/`addDependency`/`addLeg`\n * (`packages/core/src/operations.ts`). */\nfunction countCreatedIds(\n operation: Operation,\n model: AnyIstarModel,\n): { elements: number; links: number } {\n switch (operation.kind) {\n case 'createNode':\n return { elements: 1, links: 0 };\n case 'createEdge': {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const definition = metamodel.links.get(operation.elementTypeId);\n if (definition?.category === 'dependency') return { elements: 1, links: 2 };\n if (definition?.parts && !targetIsHub(operation, model, metamodel)) {\n // A new hub: hub (element) + leg + end (links).\n return { elements: 1, links: 2 };\n }\n return { elements: 0, links: 1 };\n }\n case 'istar.addLeg':\n return { elements: 0, links: 1 };\n case 'compound': {\n let elements = 0;\n let links = 0;\n for (const child of operation.operationList as readonly Operation[]) {\n const counts = countCreatedIds(child, model);\n elements += counts.elements;\n links += counts.links;\n }\n return { elements, links };\n }\n default:\n return { elements: 0, links: 0 };\n }\n}\n\nfunction targetIsHub(\n operation: Extract<Operation, { kind: 'createEdge' }>,\n model: AnyIstarModel,\n metamodel: AnyMetamodel,\n): boolean {\n const targetKind = model.elements.get(operation.targetElementId)?.kind;\n return targetKind !== undefined && metamodel.elements.get(targetKind)?.role === 'hub';\n}\n\n/** `operation` with ids from `elementIds`/`linkIds` (consumed in model order) injected as the\n * explicit ids its creates take, so a dispatcher that applies it against the same model state\n * creates the same ids. */\nfunction withCreatedIds(\n operation: Operation,\n elementIds: string[],\n linkIds: string[],\n model: AnyIstarModel,\n): Operation {\n switch (operation.kind) {\n case 'createNode': {\n const id = elementIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'createEdge': {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const definition = metamodel.links.get(operation.elementTypeId);\n if (definition?.category === 'dependency') {\n const dependumId = elementIds.shift();\n const linkIds2 = [linkIds.shift(), linkIds.shift()] as const;\n if (dependumId === undefined || linkIds2[0] === undefined || linkIds2[1] === undefined) {\n return operation;\n }\n return {\n ...operation,\n args: {\n ...operation.args,\n dependum: { ...operation.args?.dependum, id: dependumId },\n linkIds: linkIds2 as readonly [string, string],\n },\n };\n }\n if (definition?.parts && !targetIsHub(operation, model, metamodel)) {\n const hubId = elementIds.shift();\n const legId = linkIds.shift();\n const endId = linkIds.shift();\n return hubId === undefined || legId === undefined || endId === undefined\n ? operation\n : { ...operation, args: { ...operation.args, id: hubId, legId, endId } };\n }\n const id = linkIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'istar.addLeg': {\n const id = linkIds.shift();\n return id === undefined ? operation : { ...operation, args: { ...operation.args, id } };\n }\n case 'compound':\n return {\n ...operation,\n operationList: (operation.operationList as readonly Operation[]).map((child) =>\n withCreatedIds(child, elementIds, linkIds, model),\n ),\n };\n default:\n return operation;\n }\n}\n\n/** `operation`, with `createdIds` (an accepted result's) injected as explicit ids. */\nexport function injectCreatedIds(\n operation: Operation,\n createdIds: readonly string[],\n model: AnyIstarModel,\n): Operation {\n const counts = countCreatedIds(operation, model);\n const elementIds = createdIds.slice(0, counts.elements);\n const linkIds = createdIds.slice(counts.elements, counts.elements + counts.links);\n return withCreatedIds(operation, [...elementIds], [...linkIds], model);\n}\n","/**\n * Internal: which element and link kinds a rule selector matches, the same way `canLink` does.\n * Shared by `hints.ts` (GLSP type hints) and `metamodel-context.ts` (#240), not part of this\n * package's public API — `index.ts` doesn't re-export this module.\n */\nimport { LINK_SELECTOR, elementBehavesLike, linkBehavesLike } from '@istar-ts/core';\nimport type { AnyMetamodel, ElementKindDefinition } from '@istar-ts/core';\n\n/** A generated kind (a hub, leg or end) that an n-ary link's declaration adds on its own. */\nexport function isHub(definition: ElementKindDefinition): boolean {\n return definition.role === 'hub';\n}\n\n/** Element kinds a rule selector matches, as `canLink` matches elements against it. */\nexport function matching(metamodel: AnyMetamodel, selector: string): string[] {\n const kinds: string[] = [];\n for (const definition of metamodel.elements.values()) {\n // A hub is only matched by its own kind's name: categories never include it.\n const matches = isHub(definition)\n ? definition.kind === selector\n : selector === '*' ||\n selector === definition.category ||\n elementBehavesLike(metamodel, definition.kind, selector);\n if (matches) kinds.push(definition.kind);\n }\n // Link targets: `link` matches every link kind, a link kind itself and the kinds behaving like it.\n if (selector === LINK_SELECTOR) kinds.push(...metamodel.links.keys());\n else if (metamodel.links.has(selector)) {\n for (const kind of metamodel.links.keys()) {\n if (linkBehavesLike(metamodel, kind, selector)) kinds.push(kind);\n }\n }\n return kinds;\n}\n\nexport function union(metamodel: AnyMetamodel, selectors: readonly string[]): string[] {\n return [...new Set(selectors.flatMap((selector) => matching(metamodel, selector)))];\n}\n\n/** Kinds of a category, without hubs. */\nexport function ofCategory(metamodel: AnyMetamodel, category?: 'actor' | 'node'): string[] {\n return [...metamodel.elements.values()]\n .filter((d) => !isHub(d) && (category === undefined || d.category === category))\n .map((d) => d.kind);\n}\n","/**\n * What a client can know before it asks: type hints from the metamodel, and the palette as\n * GLSP context actions. Both are derived from data (`Metamodel`, `PaletteDescription`), so they\n * work for any root or extension.\n */\nimport { effectiveLinkKind } from '@istar-ts/core';\nimport type {\n AnyMetamodel,\n AnyPaletteDescription,\n ElementToolEntryDescription,\n LinkToolEntryDescription,\n Metamodel,\n PaletteEntryDescription,\n} from '@istar-ts/core';\nimport type {\n EdgeTypeHint,\n LabeledAction,\n SetContextActions,\n SetTypeHintsAction,\n ShapeTypeHint,\n} from './actions';\nimport { isHub, ofCategory, union } from './kind-selectors';\n\n/**\n * GLSP type hints of a metamodel. Shapes: every element kind (hubs can't be resized or\n * reparented; actors contain the node kinds that can be inner elements). Edges: every link kind,\n * its sources and targets from its rules, or by category for kinds with built-in rules (iStar\n * 2.0's), plus an n-ary kind's hub (`createEdge` onto a hub adds a leg to that link, #108). Edge\n * hints are `repositionable` (their ends can be reconnected) and `dynamic`: `canLink` checks more\n * than kinds.\n */\nexport function typeHintsFor<EK extends string, LK extends string>(\n metamodel: Metamodel<EK, LK>,\n): Pick<SetTypeHintsAction, 'shapeHints' | 'edgeHints'> {\n const meta = metamodel as unknown as AnyMetamodel;\n const inner = [...meta.elements.values()]\n .filter((d) => d.category === 'node' && !isHub(d) && d.info?.canBeInnerElement !== false)\n .map((d) => d.kind);\n const shapeHints = [...meta.elements.values()].map((d): ShapeTypeHint => {\n const hub = isHub(d);\n return {\n elementTypeId: d.kind,\n repositionable: true,\n deletable: true,\n resizable: !hub,\n reparentable: !hub && d.category === 'node' && d.info?.canBeInnerElement !== false,\n ...(d.category === 'actor' ? { containableElementTypeIds: inner } : {}),\n };\n });\n const edgeHints = [...meta.links.values()].map((d): EdgeTypeHint => {\n const rules = meta.links.get(effectiveLinkKind(meta, d.kind))?.rules;\n const builtIn = d.category === 'dependency' ? ofCategory(meta) : ofCategory(meta, d.category);\n const targets = rules ? union(meta, rules.targets) : builtIn;\n // An n-ary kind's `createEdge` onto its hub adds a leg to that link (#108).\n const hub = d.parts?.hub;\n return {\n elementTypeId: d.kind,\n repositionable: true,\n deletable: true,\n routable: true,\n sourceElementTypeIds: rules ? union(meta, rules.sources) : builtIn,\n targetElementTypeIds: hub === undefined ? targets : [...targets, hub],\n dynamic: true,\n };\n });\n return { shapeHints, edgeHints };\n}\n\nfunction elementEntries(\n kind: string,\n value: PaletteEntryDescription | readonly ElementToolEntryDescription[],\n): LabeledAction[] {\n const list: readonly ElementToolEntryDescription[] = Array.isArray(value)\n ? value\n : [value as PaletteEntryDescription];\n return list.map((entry, i) =>\n labeled(Array.isArray(value) ? `${kind}#${i}` : kind, entry, {\n kind: 'triggerNodeCreation',\n elementTypeId: kind,\n ...(entry.properties ? { args: { customProperties: entry.properties } } : {}),\n }),\n );\n}\n\nfunction linkEntries(kind: string, list: readonly LinkToolEntryDescription[]): LabeledAction[] {\n return list.map((entry, i) => {\n const args = {\n ...(entry.value === undefined ? {} : { value: entry.value }),\n ...(entry.dependum === undefined ? {} : { dependum: { kind: entry.dependum } }),\n };\n return labeled(`${kind}#${i}`, entry, {\n kind: 'triggerEdgeCreation',\n elementTypeId: kind,\n ...(Object.keys(args).length > 0 ? { args } : {}),\n });\n });\n}\n\nfunction order(action: LabeledAction): number {\n return action.order ?? Number.POSITIVE_INFINITY;\n}\n\nfunction labeled(\n id: string,\n entry: PaletteEntryDescription,\n action: LabeledAction['actions'][number],\n): LabeledAction {\n return {\n id,\n label: entry.label,\n actions: [action],\n ...(entry.group === undefined ? {} : { group: entry.group }),\n ...(entry.section === undefined ? {} : { section: entry.section }),\n ...(entry.order === undefined ? {} : { order: entry.order }),\n };\n}\n\n/**\n * A palette as GLSP context actions: one `LabeledAction` per entry, triggering the client's\n * creation tool with the entry's presets, sorted by `order`. Only the metamodel's kinds are\n * offered, in the metamodel's order where orders tie; kinds the palette hides (`false`) or\n * lacks are left out.\n */\nexport function contextActionsFor<EK extends string, LK extends string>(\n palette: AnyPaletteDescription,\n metamodel: Metamodel<EK, LK>,\n): Pick<SetContextActions, 'actions' | 'groups'> {\n const meta = metamodel as unknown as AnyMetamodel;\n const actions: LabeledAction[] = [];\n for (const kind of meta.elements.keys()) {\n const value = palette.elements[kind];\n if (value) actions.push(...elementEntries(kind, value));\n }\n for (const kind of meta.links.keys()) {\n const list = palette.links[kind];\n if (list) actions.push(...linkEntries(kind, list));\n }\n actions.sort((a, b) => (order(a) === order(b) ? 0 : order(a) < order(b) ? -1 : 1));\n return { actions, groups: palette.groups };\n}\n\n/**\n * A minimal palette for a metamodel with none of its own: one toolbar entry per visible kind\n * (declaration order, actors first), labelled from the kind's own `label`. Kinds generated for\n * an n-ary link (a hub, leg or end — `role` set) are hidden, as a hand-written palette would\n * hide them (`KAOS_PALETTE`'s `RefinementLinkHub: false`, for instance). The fallback\n * `createActionDispatcher` and `contributionFor` (`@istar-ts/glsp`) both use when no palette\n * was given.\n */\nexport function paletteFromMetamodel(metamodel: AnyMetamodel): AnyPaletteDescription {\n const elements: Record<string, PaletteEntryDescription | false> = {};\n let order = 0;\n for (const definition of metamodel.elements.values()) {\n elements[definition.kind] =\n definition.role !== undefined\n ? false\n : {\n label: definition.label,\n order: order++,\n section: definition.category === 'actor' ? 'actors' : 'elements',\n ...(definition.category === 'actor' ? { group: 'actors' } : {}),\n };\n }\n const links: Record<string, readonly LinkToolEntryDescription[] | false> = {};\n order = 0;\n for (const definition of metamodel.links.values()) {\n links[definition.kind] =\n definition.role !== undefined\n ? false\n : [{ label: definition.label, order: order++, section: 'elements' }];\n }\n return { elements, links, groups: { actors: { label: 'Actor' } } };\n}\n","import { DIAGNOSTIC_SEVERITIES } from '@istar-ts/core';\nimport type { DiagnosticSeverity, GoalDiagnostic } from '@istar-ts/core';\nimport type { Marker } from './actions';\n\n/** A `GoalDiagnostic` as a GLSP marker: `kind` is its severity, `label` its message. */\nexport function diagnosticToMarker(diagnostic: GoalDiagnostic): Marker {\n const { elementId, key, severity, message, source, code } = diagnostic;\n return {\n label: message,\n description: source === undefined ? message : `${message} (${source})`,\n elementId,\n kind: severity,\n ...(key === undefined ? {} : { key }),\n ...(source === undefined ? {} : { source }),\n ...(code === undefined ? {} : { code }),\n };\n}\n\n/**\n * A GLSP marker as a `GoalDiagnostic`. A `kind` that is no `DiagnosticSeverity` reads as\n * `info`; `range` and `data` are not carried by markers.\n */\nexport function markerToDiagnostic(marker: Marker): GoalDiagnostic {\n const { elementId, kind, label, key, source, code } = marker;\n const severity = (DIAGNOSTIC_SEVERITIES as readonly string[]).includes(kind)\n ? (kind as DiagnosticSeverity)\n : 'info';\n return {\n elementId,\n severity,\n message: label,\n ...(key === undefined ? {} : { key }),\n ...(source === undefined ? {} : { source }),\n ...(code === undefined ? {} : { code }),\n };\n}\n","/**\n * The dispatcher: the server side of the protocol over a `ModelStore`. Operations run as one\n * store transaction each and are rejected, model untouched, with `GoalDiagnostic`s; requests\n * are answered from the model, its metamodel and the palette; store changes reach subscribers\n * as `ModelSourceChangedAction`s, whoever made them.\n */\nimport {\n FILE_METAMODEL_KEY,\n MetamodelError,\n ModelOperationError,\n PistarParseError,\n TOP_LEVEL_KEYS,\n canLink,\n connectResultToDiagnostic,\n dependencyEnds,\n hostMetamodelOf,\n inheritMetamodel,\n inheritSourceLayout,\n metamodelOf,\n parsePistar,\n toPistarObject,\n validateModel,\n validateModelProperties,\n withFileMetamodel,\n} from '@istar-ts/core';\nimport type {\n AnyIstarModel,\n AnyMetamodel,\n AnyPaletteDescription,\n ConnectResult,\n CustomProperties,\n ElementKind,\n Extra,\n GoalDiagnostic,\n IstarLink,\n IstarModel,\n LinkCheck,\n LinkKind,\n ModelChangeEvent,\n ModelStore,\n PistarFile,\n PropertySchema,\n PropertyShape,\n} from '@istar-ts/core';\nimport type {\n CheckEdgeResultAction,\n DirtyStateChangeReason,\n IstarAction,\n IstarOperation,\n RequestCheckEdgeAction,\n RequestContextActions,\n RequestMarkersAction,\n RequestModelAction,\n RequestTypeHintsAction,\n SaveModelAction,\n SetContextActions,\n SetMarkersAction,\n SetModelAction,\n SetTypeHintsAction,\n} from './actions';\nimport { isOperation, isRequestAction } from './actions';\nimport { contextActionsFor, paletteFromMetamodel, typeHintsFor } from './hints';\nimport { diagnosticToMarker } from './markers';\n\n/** The response a request is answered with; `never` for other actions. */\nexport type ResponseFor<A> = A extends RequestModelAction\n ? SetModelAction\n : A extends RequestTypeHintsAction\n ? SetTypeHintsAction\n : A extends RequestCheckEdgeAction\n ? CheckEdgeResultAction\n : A extends RequestContextActions\n ? SetContextActions\n : A extends RequestMarkersAction\n ? SetMarkersAction\n : never;\n\n/**\n * What dispatching an action did. Plain JSON, like the actions.\n *\n * A rejection (`ok: false`) left the model untouched: the same model object, no undo step. Its\n * diagnostics say why (an unknown element, a link `canLink` refuses, a guard, a property schema).\n */\nexport type ActionResult<R = never> =\n | {\n readonly ok: true;\n /** Ids of the elements, then links, the action added, in model order. */\n readonly createdIds: readonly string[];\n /** A request's answer. */\n readonly response?: R;\n /** Non-error diagnostics from guards, for an operation that was applied anyway. */\n readonly diagnostics?: readonly GoalDiagnostic[];\n }\n | { readonly ok: false; readonly diagnostics: readonly GoalDiagnostic[] };\n\nexport type ActionListener<EK extends string = ElementKind, LK extends string = LinkKind> = (\n action: IstarAction<EK, LK>,\n) => void;\n\n/**\n * Sends actions and hears what the other side sends back. Implemented in-process by\n * `createActionDispatcher`; a transport implements it over a message port.\n */\n/** `dispatch`'s second argument. */\nexport interface DispatchOptions {\n /**\n * Echoed back as `origin` on every `ModelSourceChangedAction` and `SetDirtyStateAction` this\n * dispatch causes (each change of a compound, both events of an undo or redo), so a listener\n * can tell which surface or client made a change without tracking it itself. Carried through\n * `createRemoteDispatcher`/`connectDispatcher` and by `createMirrorStore`'s dispatcher, so it\n * survives a round trip to a remote host. Optional: a change with no origin (a host's direct\n * `store.load`, for instance) has none.\n */\n readonly origin?: string;\n}\n\nexport interface ActionDispatcher<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * For a **local** dispatcher (`createActionDispatcher`), an operation, `glspUndo`/`glspRedo`,\n * and the guards and postGuards around them, are applied to the store and every listener\n * (`subscribe`, the store's own) is notified synchronously, before this call's promise is\n * created to resolve — only `saveModel` awaits. Code that needs to see the result of an action\n * before its own next statement (not just before `await dispatch(...)` resolves) can rely on\n * this for a local dispatcher; it does **not** hold across a `createRemoteDispatcher`/\n * `connectDispatcher` transport or a `createMirrorStore` mirror, where a change always arrives\n * after a message round trip. Use `origin` ({@link DispatchOptions}) instead where that\n * portability matters — it is carried through both.\n */\n dispatch<A extends IstarAction<EK, LK>>(\n action: A,\n options?: DispatchOptions,\n ): Promise<ActionResult<ResponseFor<A>>>;\n /**\n * Hears the actions the dispatcher sends: `ModelSourceChangedAction` after every model change,\n * `SetDirtyStateAction` when the dirty state flips, and the notifications dispatched to it.\n * Returns an unsubscribe function.\n */\n subscribe(listener: ActionListener<EK, LK>): () => void;\n}\n\n/**\n * A host's rule, run before each operation is applied (and before each operation of a compound\n * one, against the model as the previous ones left it). Diagnostics of severity `error` reject\n * the operation; others are returned with the result.\n */\nexport type ActionGuard<EK extends string = ElementKind, LK extends string = LinkKind> = (\n operation: IstarOperation<EK, LK>,\n model: IstarModel<EK, LK>,\n) => readonly GoalDiagnostic[] | void;\n\n/**\n * A host's rule, run after each operation is applied (and after each operation of a compound\n * one, plus once more on the compound's own result), inside the operation's transaction. Sees\n * the model as the operation leaves it (`modelAfter`) and as it was before (`modelBefore`), so\n * it can check things a pre-guard can't without re-applying the operation itself (goal-controller's\n * edgeV2 engine check is the motivating case). Diagnostics of severity `error` roll the\n * transaction back: the model is untouched and there is no undo entry. Others are returned with\n * the result, merged with pre-guards' warnings.\n */\nexport type ActionPostGuard<EK extends string = ElementKind, LK extends string = LinkKind> = (\n operation: IstarOperation<EK, LK>,\n modelAfter: IstarModel<EK, LK>,\n modelBefore: IstarModel<EK, LK>,\n) => readonly GoalDiagnostic[] | void;\n\nexport interface ActionDispatcherOptions<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> {\n readonly guards?: readonly ActionGuard<EK, LK>[];\n /** Run after each operation is applied; see `ActionPostGuard`. */\n readonly postGuards?: readonly ActionPostGuard<EK, LK>[];\n /**\n * What `RequestContextActions` offers: a fixed description, or a function evaluated on each\n * request (so a host can track a registry or extensions that change after this dispatcher was\n * created — a plain `AnyPaletteDescription` is read once, at creation). Default: derived from\n * the model's current metamodel (`paletteFromMetamodel`), the same fallback `contributionFor`\n * (`@istar-ts/glsp`) uses — not iStar 2.0's palette regardless of dialect.\n */\n readonly palette?: AnyPaletteDescription | (() => AnyPaletteDescription);\n /**\n * Property schemas an operation must not break: an operation that adds an issue\n * (`validateModelProperties`) is rejected. Their issues are also markers.\n */\n readonly schemas?: readonly PropertySchema<PropertyShape, string>[];\n /** The host's diagnostics (e.g. a `DiagnosticsStore`'s `getAll`), reported as markers. */\n readonly diagnostics?: () => readonly GoalDiagnostic[];\n /** Writes the file for `SaveModelAction`; without it, saving is rejected. */\n readonly save?: (file: PistarFile, action: SaveModelAction) => void | Promise<void>;\n /** `ModelSourceChangedAction.sourceModelName`, e.g. the file name. Default `''`. */\n readonly sourceModelName?: string;\n /**\n * Attach the new model to every `sourceModelChanged` as `newRoot` (piStar JSON), so a mirror\n * on the other end of a transport (`createMirrorStore`) follows without a `requestModel` round\n * trip. Costs a `toPistarObject` per change (0.3 ms on the largest fixture). Default false.\n */\n readonly sendModel?: boolean;\n}\n\nexport interface StoreActionDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends ActionDispatcher<EK, LK> {\n /** True while the model differs from the one last saved (or loaded, or given at creation). */\n isDirty(): boolean;\n /** Stops listening to the store. */\n dispose(): void;\n}\n\n/** Thrown inside a transaction to roll it back and reject the action. */\nclass Rejection extends Error {\n readonly diagnostics: readonly GoalDiagnostic[];\n constructor(diagnostics: readonly GoalDiagnostic[]) {\n super(diagnostics.map((d) => d.message).join('; '));\n this.diagnostics = diagnostics;\n }\n}\n\nfunction reject(message: string, elementId = '', code?: string): never {\n throw new Rejection([\n { elementId, severity: 'error', message, ...(code === undefined ? {} : { code }) },\n ]);\n}\n\nfunction rejectCheck(\n check: Extract<LinkCheck, { ok: false }>,\n endpoints: { readonly source: string; readonly target: string },\n): never {\n throw new Rejection([connectResultToDiagnostic(check as ConnectResult, endpoints)!]);\n}\n\nfunction metaOf(model: AnyIstarModel): AnyMetamodel {\n return metamodelOf(model) as unknown as AnyMetamodel;\n}\n\n/**\n * Keys `istar.updateModelExtra`'s `set`/`remove` must not touch: every key core models itself\n * (`TOP_LEVEL_KEYS`, which includes `tool`), and `\"metamodel\"` (`istar.setFileMetamodel`'s own).\n */\nconst RESERVED_EXTRA_KEYS: ReadonlySet<string> = new Set([...TOP_LEVEL_KEYS, FILE_METAMODEL_KEY]);\n\n/** A model with `links` changed, as the core operations derive one. */\nfunction withLinks(model: AnyIstarModel, links: ReadonlyMap<string, IstarLink<string>>) {\n return inheritMetamodel(model, inheritSourceLayout(model, { ...model, links }));\n}\n\nfunction createdIds(before: AnyIstarModel, after: AnyIstarModel): string[] {\n const ids: string[] = [];\n for (const id of after.elements.keys()) if (!before.elements.has(id)) ids.push(id);\n for (const id of after.links.keys()) if (!before.links.has(id)) ids.push(id);\n return ids;\n}\n\nfunction issueKey(d: { readonly id: string; readonly key: string; readonly message: string }) {\n return `${d.id}\\u0000${d.key}\\u0000${d.message}`;\n}\n\nfunction linkIssueDiagnostics(model: AnyIstarModel): GoalDiagnostic[] {\n return validateModel(model).map((issue) => ({\n elementId: issue.linkId,\n severity: 'error',\n message: issue.message,\n code: issue.code,\n }));\n}\n\n/**\n * A dispatcher over `store`, in-process. Hand it to a transport to serve remote clients.\n */\nexport function createActionDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n>(\n store: ModelStore<EK, LK>,\n options: ActionDispatcherOptions<EK, LK> = {},\n): StoreActionDispatcher<EK, LK> {\n const s = store as unknown as ModelStore<string, string>;\n const guards = (options.guards ?? []) as readonly ActionGuard<string, string>[];\n const postGuards = (options.postGuards ?? []) as readonly ActionPostGuard<string, string>[];\n const resolvePalette = (meta: AnyMetamodel): AnyPaletteDescription => {\n const option = options.palette;\n if (typeof option === 'function') return option();\n return option ?? paletteFromMetamodel(meta);\n };\n const sourceModelName = options.sourceModelName ?? '';\n const listeners = new Set<ActionListener<string, string>>();\n\n let saved: AnyIstarModel = s.getModel();\n let dirty = false;\n /**\n * The origin of the dispatch currently applying synchronously (set by `dispatch`, around the\n * synchronous part of `run`): what the store's subscription below echoes on\n * `sourceModelChanged`/`setDirtyState`. `undefined` for a change not caused by a dispatch (a\n * host's direct `store.load`) or once `run`'s synchronous part has returned.\n */\n let currentOrigin: string | undefined;\n\n const emit = (action: IstarAction<string, string>): void => {\n for (const listener of listeners) listener(action);\n };\n\n const updateDirty = (reason: DirtyStateChangeReason, origin: string | undefined): void => {\n const next = s.getModel() !== saved;\n if (next === dirty) return;\n dirty = next;\n emit({\n kind: 'setDirtyState',\n isDirty: next,\n reason,\n ...(origin === undefined ? {} : { origin }),\n });\n };\n\n const REASONS: Record<ModelChangeEvent['source'], DirtyStateChangeReason> = {\n edit: 'operation',\n undo: 'undo',\n redo: 'redo',\n load: 'external',\n };\n const unsubscribe = s.subscribe((event) => {\n // A load opens a file: the new model is the saved one.\n if (event.source === 'load') saved = event.model;\n emit({\n kind: 'sourceModelChanged',\n sourceModelName,\n source: event.source,\n changes: event.changes,\n ...(options.sendModel ? { newRoot: toPistarObject(event.model) } : {}),\n ...(options.sendModel ? { canUndo: s.canUndo(), canRedo: s.canRedo() } : {}),\n ...(currentOrigin === undefined ? {} : { origin: currentOrigin }),\n });\n updateDirty(REASONS[event.source], currentOrigin);\n });\n\n // -------------------------------------------------------------------------------------------\n // Operations\n\n const requireElement = (id: string) =>\n s.getModel().elements.get(id) ?? reject(`unknown element \"${id}\"`, id, 'unknown-element');\n\n const runGuards = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]) => {\n const errors: GoalDiagnostic[] = [];\n for (const guard of guards) {\n for (const d of guard(operation, s.getModel()) ?? []) {\n (d.severity === 'error' ? errors : warnings).push(d);\n }\n }\n if (errors.length > 0) throw new Rejection(errors);\n };\n\n const runPostGuards = (\n operation: IstarOperation<string, string>,\n before: AnyIstarModel,\n warnings: GoalDiagnostic[],\n ) => {\n const errors: GoalDiagnostic[] = [];\n for (const guard of postGuards) {\n for (const d of guard(operation, s.getModel(), before) ?? []) {\n (d.severity === 'error' ? errors : warnings).push(d);\n }\n }\n if (errors.length > 0) throw new Rejection(errors);\n };\n\n const apply = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]): void => {\n runGuards(operation, warnings);\n const before = s.getModel();\n doApply(operation, warnings);\n runPostGuards(operation, before, warnings);\n };\n\n const doApply = (operation: IstarOperation<string, string>, warnings: GoalDiagnostic[]): void => {\n const model = s.getModel();\n const meta = metaOf(model);\n switch (operation.kind) {\n case 'createNode': {\n const { elementTypeId: kind, containerId, args = {} } = operation;\n const definition =\n meta.elements.get(kind) ??\n reject(`unknown element kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n if (definition.role === 'hub') {\n reject(`a ${definition.label} is created with its link (createEdge)`, '', 'hub-kind');\n }\n const container = containerId === undefined ? undefined : requireElement(containerId);\n if (definition.category === 'node') {\n // piStar only adds an element where its kind may be: inside an actor, or on paper.\n if (container && definition.info?.canBeInnerElement === false) {\n reject(`a ${definition.label} cannot be inside an actor`, containerId, 'container');\n }\n if (!container && definition.info?.canBeOnPaper === false) {\n reject(`a ${definition.label} must be created inside an actor`, '', 'container');\n }\n }\n const location = operation.location ?? container ?? { x: 0, y: 0 };\n s.addElement({\n kind,\n x: location.x,\n y: location.y,\n ...(containerId === undefined ? {} : { parent: containerId }),\n ...(args.id === undefined ? {} : { id: args.id }),\n ...(args.name === undefined ? {} : { name: args.name }),\n ...(args.customProperties ? { customProperties: args.customProperties } : {}),\n });\n return;\n }\n case 'createEdge': {\n const { elementTypeId: kind, sourceElementId: source, targetElementId: target } = operation;\n const args = operation.args ?? {};\n const definition =\n meta.links.get(kind) ??\n reject(`unknown link kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n if (definition.category === 'dependency') {\n const dependum = args.dependum ?? {};\n const dependumKind =\n dependum.kind ??\n [...meta.elements.values()].find(\n (d) => d.category === 'node' && d.role !== 'hub' && d.info?.canBeDependum !== false,\n )?.kind ??\n reject(`${meta.name} has no kind that can be a dependum`, '', 'unknown-kind');\n const result = s.addDependency({\n depender: source,\n dependee: target,\n linkKind: kind,\n dependum: {\n kind: dependumKind,\n ...(dependum.id === undefined ? {} : { id: dependum.id }),\n ...(dependum.name === undefined ? {} : { name: dependum.name }),\n ...(dependum.location ? { x: dependum.location.x, y: dependum.location.y } : {}),\n ...(dependum.customProperties ? { customProperties: dependum.customProperties } : {}),\n },\n ...(args.linkIds ? { linkIds: args.linkIds } : {}),\n });\n if (!result.ok) rejectCheck(result, { source, target });\n return;\n }\n const values = definition.info.possibleLabels;\n if (args.value !== undefined && values && !values.includes(args.value)) {\n reject(\n `\"${args.value}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n source,\n 'invalid-value',\n );\n }\n const result = s.connect({\n kind,\n source,\n target,\n ...(args.id === undefined ? {} : { id: args.id }),\n ...(args.value === undefined ? {} : { label: args.value }),\n ...(args.name === undefined ? {} : { name: args.name }),\n ...(args.customProperties ? { customProperties: args.customProperties } : {}),\n ...(args.legId === undefined ? {} : { legId: args.legId }),\n ...(args.endId === undefined ? {} : { endId: args.endId }),\n });\n if (!result.ok) rejectCheck(result, { source, target });\n return;\n }\n case 'deleteElement': {\n const elements: string[] = [];\n const links: string[] = [];\n for (const id of operation.elementIds) {\n if (model.elements.has(id)) elements.push(id);\n else if (model.links.has(id)) links.push(id);\n else reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n }\n if (elements.length > 0) s.removeElements(elements);\n // Removing elements may already have taken some of the links with them.\n for (const id of links) if (s.getModel().links.has(id)) s.disconnect(id);\n return;\n }\n case 'changeBounds': {\n for (const { elementId, newPosition, newSize } of operation.newBounds) {\n requireElement(elementId);\n if (newPosition) s.moveElement(elementId, newPosition.x, newPosition.y);\n if (newSize) {\n s.updateElement(elementId, {\n display: { width: newSize.width, height: newSize.height },\n });\n }\n }\n return;\n }\n case 'changeContainer': {\n const { elementId, targetContainerId, location } = operation;\n s.nestElement(elementId, targetContainerId);\n if (location) s.moveElement(elementId, location.x, location.y);\n return;\n }\n case 'reconnectEdge':\n reconnect(operation.edgeElementId, operation.sourceElementId, operation.targetElementId);\n return;\n case 'applyLabelEdit': {\n const hash = operation.labelId.indexOf('#');\n const id = hash < 0 ? operation.labelId : operation.labelId.slice(0, hash);\n const key = hash < 0 ? undefined : operation.labelId.slice(hash + 1);\n if (key === undefined) {\n if (model.elements.has(id)) s.updateElement(id, { name: operation.text });\n // A link's name is optional; an empty text removes it, matching what piStar writes\n // for a link whose name was cleared (fileManager.js only writes `name` when truthy).\n else if (model.links.has(id)) {\n s.updateLink(id, { name: operation.text === '' ? null : operation.text });\n } else reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n } else {\n setProperties(id, { [key]: operation.text });\n }\n return;\n }\n case 'compound':\n for (const child of operation.operationList) apply(child, warnings);\n return;\n case 'istar.addLeg': {\n const { hubId, sourceElementId: source } = operation;\n const result = s.addLeg(hubId, source, operation.args?.id ? { id: operation.args.id } : {});\n if (!result.ok) rejectCheck(result, { source, target: hubId });\n return;\n }\n case 'istar.removeLeg':\n s.removeLeg(operation.legId);\n return;\n case 'istar.setCollapsed': {\n const element = requireElement(operation.elementId);\n if (meta.elements.get(element.kind)?.category !== 'actor') {\n reject(`\"${element.id}\" is not an actor`, element.id, 'not-an-actor');\n }\n s.setCollapsed(element.id, operation.collapsed);\n return;\n }\n case 'istar.updateDiagram': {\n const { name, width, height, customProperties } = operation.diagram;\n s.updateDiagram({\n ...(name === undefined ? {} : { name }),\n ...(width === undefined ? {} : { width }),\n ...(height === undefined ? {} : { height }),\n ...(customProperties === undefined ? {} : { customProperties }),\n });\n return;\n }\n case 'istar.updateProperties':\n setProperties(operation.elementId, operation.properties);\n return;\n case 'istar.updateDisplay':\n requireElement(operation.elementId);\n s.updateElement(operation.elementId, { display: operation.patch });\n return;\n case 'istar.updateLinkDisplay':\n if (!model.links.has(operation.linkId)) {\n reject(`unknown link \"${operation.linkId}\"`, operation.linkId, 'unknown-element');\n }\n s.updateLink(operation.linkId, { display: operation.patch });\n return;\n case 'istar.setLinkValue': {\n const { linkId, value } = operation;\n const link =\n model.links.get(linkId) ?? reject(`unknown link \"${linkId}\"`, linkId, 'unknown-element');\n const definition = meta.links.get(link.kind);\n const values = definition?.info.possibleLabels;\n if (value !== null && values && !values.includes(value)) {\n reject(\n `\"${value}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n linkId,\n 'invalid-value',\n );\n }\n s.updateLink(linkId, { label: value });\n return;\n }\n case 'istar.changeLinkKind': {\n const { linkIds, elementTypeId: kind } = operation;\n if (linkIds.length === 0) return;\n const ids = new Set(linkIds);\n const links = [...ids].map(\n (id) => model.links.get(id) ?? reject(`unknown link \"${id}\"`, id, 'unknown-element'),\n );\n const definition =\n meta.links.get(kind) ??\n reject(`unknown link kind \"${kind}\" in ${meta.name}`, '', 'unknown-kind');\n const toChange = links.filter((link) => link.kind !== kind);\n if (toChange.length === 0) return;\n const remaining = new Map(model.links);\n for (const id of ids) remaining.delete(id);\n const without = withLinks(model, remaining);\n const values = definition.info.possibleLabels;\n for (const link of toChange) {\n const check = canLink(without, link.source, link.target, kind);\n if (!check.ok) rejectCheck(check, { source: link.source, target: link.target });\n if (link.label != null && values && !values.includes(link.label)) {\n reject(\n `\"${link.label}\" is not a value of a ${definition.label} link (${values.join(', ')})`,\n link.id,\n 'invalid-value',\n );\n }\n }\n const next = new Map(model.links);\n for (const link of toChange) next.set(link.id, { ...link, kind });\n s.replace(withLinks(model, next));\n return;\n }\n case 'istar.setFileMetamodel': {\n let next: AnyIstarModel;\n try {\n next = withFileMetamodel(model, operation.block);\n } catch (error) {\n if (error instanceof MetamodelError) reject(error.message, '', 'invalid-metamodel');\n throw error;\n }\n s.replace(next);\n return;\n }\n case 'istar.updateModelExtra': {\n const { set, remove, tool } = operation;\n for (const key of [...Object.keys(set ?? {}), ...(remove ?? [])]) {\n if (!RESERVED_EXTRA_KEYS.has(key)) continue;\n if (key === 'tool') {\n reject(\n `\"tool\" is a modelled field: set it with this operation's own \"tool\"`,\n '',\n 'reserved-key',\n );\n }\n if (key === FILE_METAMODEL_KEY) {\n reject(\n `\"${key}\" is set with istar.setFileMetamodel, not updateModelExtra`,\n '',\n 'reserved-key',\n );\n }\n reject(\n `\"${key}\" is modelled by the file itself and cannot be an extra key`,\n '',\n 'reserved-key',\n );\n }\n let withTool: AnyIstarModel = model;\n if (tool === null) {\n const { tool: _tool, ...rest } = withTool;\n withTool = rest;\n } else if (tool !== undefined) {\n withTool = { ...withTool, tool };\n }\n const extra: Record<string, unknown> = { ...withTool.extra };\n if (set) for (const [key, value] of Object.entries(set)) extra[key] = value;\n if (remove) for (const key of remove) delete extra[key];\n const { extra: _extra, ...rest } = withTool;\n const next: AnyIstarModel = {\n ...rest,\n ...(Object.keys(extra).length > 0 ? { extra: extra as Extra } : {}),\n };\n s.replace(inheritMetamodel(model, inheritSourceLayout(model, next)));\n return;\n }\n case 'istar.replaceModel': {\n const host = hostMetamodelOf(model) ?? meta;\n let next: AnyIstarModel;\n try {\n next = parsePistar(operation.model, {\n metamodel: host,\n fileMetamodel: operation.fileMetamodel ?? false,\n });\n } catch (error) {\n if (error instanceof PistarParseError) reject(error.message, '', 'parse-error');\n throw error;\n }\n s.replace(next);\n return;\n }\n default:\n reject(`unknown operation \"${(operation as { kind: string }).kind}\"`, '', 'unknown-action');\n }\n };\n\n /** Sets (or, with `null`, removes) custom properties of an element or link. */\n const setProperties = (id: string, properties: Readonly<Record<string, string | null>>) => {\n const model = s.getModel();\n const owner = model.elements.get(id) ?? model.links.get(id);\n if (!owner) reject(`unknown element or link \"${id}\"`, id, 'unknown-element');\n const next: Record<string, string> = { ...owner.customProperties };\n for (const [key, value] of Object.entries(properties)) {\n if (value === null) delete next[key];\n else if (typeof value === 'string') next[key] = value;\n else reject(`the value of \"${key}\" must be a string or null`, id, 'invalid-value');\n }\n // Removing the last property keeps an empty object, as piStar's exports do\n // (\"customProperties\": {}); an owner that never had the key and ends up with none stays without it.\n if (Object.keys(next).length === 0 && owner.customProperties === undefined) return;\n const customProperties: CustomProperties = next;\n if (model.elements.has(id)) s.updateElement(id, { customProperties });\n else s.updateLink(id, { customProperties });\n };\n\n /**\n * Gives a link new ends, checked with `canLink` against the model without it. The link keeps\n * its place in the model (and the file), its id and everything else it carries.\n */\n const reconnect = (id: string, source: string, target: string): void => {\n const model = s.getModel();\n const meta = metaOf(model);\n const link = model.links.get(id) ?? reject(`unknown link \"${id}\"`, id, 'unknown-element');\n if (link.source === source && link.target === target) return;\n const definition = meta.links.get(link.kind);\n const others = new Map(model.links);\n others.delete(id);\n const without = withLinks(model, others);\n let check: LinkCheck;\n if (definition?.category === 'dependency') {\n // A dependency's link keeps its dependum end; the check is depender → dependee.\n const dependumAtTarget = model.elements.get(link.target)?.isDependum === true;\n const dependumId = dependumAtTarget ? link.target : link.source;\n if ((dependumAtTarget ? target : source) !== dependumId) {\n reject('a dependency link keeps its dependum', id, 'dependum-endpoint');\n }\n const ends = dependencyEnds(model, dependumId);\n const depender = dependumAtTarget ? source : ends.depender;\n const dependee = dependumAtTarget ? ends.dependee : target;\n if (depender === undefined || dependee === undefined) {\n reject('the dependency is incomplete', id, 'dependum-endpoint');\n }\n check = canLink(without, depender, dependee, link.kind);\n if (!check.ok) rejectCheck(check, { source: depender, target: dependee });\n } else {\n // An n-ary link's end stays on its hub, and a leg can't leave a hub without legs.\n if (definition?.role === 'end' && source !== link.source) {\n reject('the end of an n-ary link stays on its hub', id, 'hub-target');\n }\n if (definition?.role === 'leg' && target !== link.target) {\n const legs = [...model.links.values()].filter(\n (l) => l.target === link.target && l.kind === link.kind,\n );\n if (legs.length === 1) {\n reject('the last leg of an n-ary link cannot leave its hub', id, 'hub-target');\n }\n }\n check = canLink(without, source, target, link.kind);\n if (!check.ok) rejectCheck(check, { source, target });\n }\n s.replace(withLinks(model, new Map(model.links).set(id, { ...link, source, target })));\n };\n\n const runOperation = (operation: IstarOperation<string, string>): ActionResult => {\n const before = s.getModel();\n const warnings: GoalDiagnostic[] = [];\n s.transaction(() => {\n apply(operation, warnings);\n const schemas = options.schemas;\n if (!schemas || s.getModel() === before) return;\n const known = new Set(validateModelProperties(before, schemas).map(issueKey));\n const added = validateModelProperties(s.getModel(), schemas).filter(\n (issue) => !known.has(issueKey(issue)),\n );\n if (added.length > 0) {\n throw new Rejection(\n added.map((issue) => ({\n elementId: issue.id,\n key: issue.key,\n severity: 'error',\n message: issue.message,\n code: 'invalid-property',\n })),\n );\n }\n });\n return {\n ok: true,\n createdIds: createdIds(before, s.getModel()),\n ...(warnings.length > 0 ? { diagnostics: warnings } : {}),\n };\n };\n\n // -------------------------------------------------------------------------------------------\n // Requests\n\n const checkEdge = (action: RequestCheckEdgeAction): CheckEdgeResultAction => {\n const { edgeType, sourceElementId: source, targetElementId: target } = action;\n const model = s.getModel();\n const meta = metaOf(model);\n const answer = (check: LinkCheck): CheckEdgeResultAction => ({\n kind: 'checkEdgeTargetResult',\n responseId: action.requestId,\n isValid: check.ok,\n edgeType,\n sourceElementId: source,\n ...(target === undefined ? {} : { targetElementId: target }),\n ...(check.ok ? {} : { reason: check.reason, code: check.code }),\n });\n if (target !== undefined) {\n const check = canLink(model, source, target, edgeType);\n // `createEdge` retries reversed where piStar does (Needed-By, Qualification).\n if (!check.ok && meta.links.get(edgeType)?.info.tryReversedWhenAdding) {\n const reversed = canLink(model, target, source, edgeType);\n if (reversed.ok) return answer(reversed);\n }\n return answer(check);\n }\n // No target yet: can the source start such a link at all?\n const element = model.elements.get(source);\n if (!element) {\n return answer({\n ok: false,\n code: 'unknown-element',\n reason: `unknown source element \"${source}\"`,\n });\n }\n const hint = typeHintsFor(meta).edgeHints.find((h) => h.elementTypeId === edgeType);\n if (!hint) {\n return answer({\n ok: false,\n code: 'unknown-link-kind',\n reason: `unknown link kind \"${edgeType}\"`,\n });\n }\n if (hint.sourceElementTypeIds && !hint.sourceElementTypeIds.includes(element.kind)) {\n return answer({\n ok: false,\n code: 'invalid-source',\n reason: `a ${meta.elements.get(element.kind)?.label ?? element.kind} cannot be the source of a ${meta.links.get(edgeType)?.label ?? edgeType} link`,\n });\n }\n return answer({ ok: true });\n };\n\n const markers = (action: RequestMarkersAction): SetMarkersAction => {\n const model = s.getModel();\n const diagnostics: GoalDiagnostic[] = linkIssueDiagnostics(model);\n if (options.schemas) {\n for (const issue of validateModelProperties(model, options.schemas)) {\n diagnostics.push({\n elementId: issue.id,\n key: issue.key,\n severity: 'error',\n message: issue.message,\n code: 'invalid-property',\n });\n }\n }\n diagnostics.push(...(options.diagnostics?.() ?? []));\n const ids = action.elementsIDs.filter((id) => model.elements.has(id) || model.links.has(id));\n const wanted = new Set(ids);\n return {\n kind: 'setMarkers',\n responseId: action.requestId,\n markers: diagnostics\n .filter((d) => wanted.size === 0 || wanted.has(d.elementId))\n .map(diagnosticToMarker),\n ...(action.reason === undefined ? {} : { reason: action.reason }),\n };\n };\n\n const respond = (action: IstarAction<string, string>) => {\n const model = s.getModel();\n switch (action.kind) {\n case 'requestModel':\n return { kind: 'setModel', responseId: action.requestId, newRoot: toPistarObject(model) };\n case 'requestTypeHints':\n return {\n kind: 'setTypeHints',\n responseId: action.requestId,\n ...typeHintsFor(metaOf(model)),\n };\n case 'requestCheckEdge':\n return checkEdge(action);\n case 'requestContextActions': {\n const meta = metaOf(model);\n return {\n kind: 'setContextActions',\n responseId: action.requestId,\n ...contextActionsFor(resolvePalette(meta), meta),\n };\n }\n case 'requestMarkers':\n return markers(action);\n default:\n return undefined;\n }\n };\n\n // -------------------------------------------------------------------------------------------\n\n const run = async (\n action: IstarAction<string, string>,\n origin: string | undefined,\n ): Promise<ActionResult<unknown>> => {\n if (isOperation(action)) return runOperation(action);\n if (isRequestAction(action)) return { ok: true, createdIds: [], response: respond(action) };\n switch (action.kind) {\n case 'glspUndo':\n s.undo();\n return { ok: true, createdIds: [] };\n case 'glspRedo':\n s.redo();\n return { ok: true, createdIds: [] };\n case 'saveModel': {\n if (!options.save) reject('this host does not save models', '', 'no-save-handler');\n const model = s.getModel();\n await options.save(toPistarObject(model, { saveDate: new Date() }), action);\n saved = model;\n updateDirty('save', origin);\n return { ok: true, createdIds: [] };\n }\n case 'sourceModelChanged':\n case 'setDirtyState':\n case 'triggerNodeCreation':\n case 'triggerEdgeCreation':\n case 'deleteMarkers':\n emit(action);\n return { ok: true, createdIds: [] };\n default:\n return reject(\n `\"${action.kind}\" is not an action this dispatcher handles`,\n '',\n 'unknown-action',\n );\n }\n };\n\n return {\n async dispatch(action, dispatchOptions) {\n const origin = dispatchOptions?.origin;\n // `run`'s synchronous part (an operation, undo, redo, their guards) applies and notifies\n // listeners before this call returns to its caller below, still inside this `try`: see\n // `ActionDispatcher.dispatch`'s doc comment. `currentOrigin` is reset right after, before\n // any `await`, so it can't leak into an unrelated dispatch's own synchronous part.\n currentOrigin = origin;\n let pending: Promise<ActionResult<unknown>>;\n try {\n pending = run(action as IstarAction<string, string>, origin);\n } finally {\n currentOrigin = undefined;\n }\n try {\n return (await pending) as ActionResult<never>;\n } catch (error) {\n if (error instanceof Rejection) return { ok: false, diagnostics: error.diagnostics };\n if (error instanceof ModelOperationError) {\n return { ok: false, diagnostics: [error.toDiagnostic()] };\n }\n throw error;\n }\n },\n subscribe(listener) {\n const l = listener as ActionListener<string, string>;\n listeners.add(l);\n return () => listeners.delete(l);\n },\n isDirty: () => s.getModel() !== saved,\n dispose: unsubscribe,\n };\n}\n","/**\n * Host extensions (#175): what a host application gives an agent beyond the model's metamodel —\n * context the model should read (free-text help, notation, pooled values) and extra tools\n * (lookups, external validators, edits of its own). Opaque data plus handler functions: nothing\n * here, nor in the packages that serve them, knows any host's domain.\n *\n * Defined once, a tool or provider works on every backend: `@istar-ts/glsp`'s MCP launchers\n * (`mcp: { hostTools, context }`) register them as session-scoped server-mcp handlers next to\n * the istar tools, `@istar-ts/agent`'s action backend (`createActionToolRegistry`'s and\n * `createActionChangeSet`'s `hostTools`) lists the tools next to the action tools, and\n * `runAgent`'s `context` splices the providers into the system prompt. A tool reaches the model\n * only through the `dispatcher` it is handed, so the host's guards and schemas apply and the\n * session keeps one undo stack.\n */\nimport type { AnyIstarModel, GoalDiagnostic } from '@istar-ts/core';\nimport { isRequestAction } from './actions';\nimport type { ActionDispatcher, ActionResult } from './dispatcher';\n\n/** A host's knowledge for the model: a system-prompt section and/or an MCP resource. */\nexport interface HostContextProvider {\n /**\n * `^[a-zA-Z0-9_-]{1,64}$`: the MCP resource's name (and its tool's, when the server lists\n * resources as tools), and the section's heading unless `title` is set.\n */\n readonly name: string;\n readonly title?: string;\n /** What the resource holds, for an MCP client's catalog. Default: the title. */\n readonly description?: string;\n /** The text: fixed, or computed from the model each time it is read. */\n readonly text: string | ((model: AnyIstarModel) => string | Promise<string>);\n /** Also a section of `runAgent`'s system prompt. Default true. */\n readonly prompt?: boolean;\n /** Also an MCP resource of every diagram session. Default true. */\n readonly resource?: boolean;\n}\n\n/** What a host tool's handler is given. */\nexport interface HostToolContext {\n /** The model as it is now: the live one, or a Propose-mode run's scratch copy. */\n getModel(): AnyIstarModel;\n /**\n * The session's dispatcher, the only way a tool edits the model. A read-only tool's refuses\n * everything but requests (`requestModel`, `requestMarkers`, ...), with a `read-only-tool`\n * diagnostic.\n */\n readonly dispatcher: ActionDispatcher<string, string>;\n readonly signal?: AbortSignal;\n}\n\n/**\n * What a host tool answers, in `ActionResult`'s shape: `content` (any JSON value) for the model\n * to read, or a refusal with typed diagnostics it can repair against. A refused dispatch's\n * `ActionResult` is one already: `if (!result.ok) return result;`.\n */\nexport type HostToolResult =\n | { readonly ok: true; readonly content: unknown }\n | { readonly ok: false; readonly diagnostics: readonly GoalDiagnostic[] };\n\n/** A tool of the host's own, served next to the istar tools. */\nexport interface HostTool {\n /** `^[a-zA-Z0-9_-]{1,64}$`, distinct from every other tool's. */\n readonly name: string;\n readonly title?: string;\n /** What the model reads about the tool. */\n readonly description: string;\n /**\n * JSON Schema of the arguments: an object schema (`{ type: 'object', properties, required }`).\n * Over MCP the server validates calls against it (it needs `zod` 4.2 or later, for\n * `z.fromJSONSchema`), with the session's `sessionId` added.\n */\n readonly inputSchema: { readonly [key: string]: unknown };\n /**\n * True for a tool that only reads (MCP's `readOnlyHint`): Propose mode runs it straight away\n * and never makes it a review step, and its `dispatcher` takes requests only.\n */\n readonly readOnly?: boolean;\n handler(\n args: { readonly [key: string]: unknown },\n context: HostToolContext,\n ): HostToolResult | Promise<HostToolResult>;\n}\n\n/** `dispatcher`, refusing anything but requests: what a read-only host tool is handed. */\nexport function readOnlyDispatcher(\n dispatcher: ActionDispatcher<string, string>,\n tool: string,\n): ActionDispatcher<string, string> {\n return {\n dispatch: (action) =>\n isRequestAction(action)\n ? dispatcher.dispatch(action)\n : Promise.resolve({\n ok: false,\n diagnostics: [\n {\n elementId: '',\n severity: 'error',\n code: 'read-only-tool',\n message: `\"${tool}\" is read-only: it cannot dispatch ${action.kind}`,\n },\n ],\n } as ActionResult<never>),\n subscribe: (listener) => dispatcher.subscribe(listener),\n };\n}\n\n/** The context a call of `tool` gets: `dispatcher` as is, or read-only for a read-only tool. */\nexport function hostToolContext(\n tool: HostTool,\n dispatcher: ActionDispatcher<string, string>,\n getModel: () => AnyIstarModel,\n signal?: AbortSignal,\n): HostToolContext {\n return {\n getModel,\n dispatcher: tool.readOnly ? readOnlyDispatcher(dispatcher, tool.name) : dispatcher,\n ...(signal ? { signal } : {}),\n };\n}\n\n/** A provider's text for `model`. */\nexport function contextText(provider: HostContextProvider, model: AnyIstarModel): Promise<string> {\n const { text } = provider;\n return Promise.resolve(typeof text === 'string' ? text : text(model));\n}\n","/**\n * A built-in context provider (#240): what an agent needs to know about a model's own\n * vocabulary — its element and link kinds, containment, link rules and value sets — derived\n * only from the `Metamodel`, so it works unchanged for iStar 2.0, KAOS, NFR, an\n * `extendMetamodel` result or a file metamodel (pistarExt). No dialect names in this file.\n *\n * `metamodelContextProvider` is the `HostContextProvider` every launcher and agent session\n * includes by default (opt-out: `metamodelContext: false`); a host's own providers are appended\n * after it.\n */\nimport { effectiveLinkKind } from '@istar-ts/core';\nimport type { AnyIstarModel, AnyMetamodel, PropertySchema, PropertyShape } from '@istar-ts/core';\nimport { metamodelOf } from '@istar-ts/core';\nimport { isHub, ofCategory, union } from './kind-selectors';\nimport type { HostContextProvider } from './host';\n\nexport interface MetamodelPropertyContext {\n readonly key: string;\n readonly type: string;\n readonly values?: readonly string[];\n readonly optional?: boolean;\n readonly description?: string;\n}\n\nexport interface MetamodelElementContext {\n readonly kind: string;\n readonly label: string;\n readonly description?: string;\n readonly category: 'actor' | 'node';\n readonly canBeOnPaper?: boolean;\n readonly canBeInnerElement?: boolean;\n readonly properties?: readonly MetamodelPropertyContext[];\n}\n\nexport interface MetamodelLinkContext {\n readonly kind: string;\n readonly label: string;\n readonly description?: string;\n readonly category: 'actor' | 'node' | 'dependency';\n readonly sources: readonly string[];\n readonly targets: readonly string[];\n /** `'n'` for a link joining several sources at a hub (see `Metamodel`'s `arity`). */\n readonly arity?: 'n';\n /** The link's declared value set (e.g. a Contribution link's make/help/hurt/break). */\n readonly values?: readonly string[];\n readonly properties?: readonly MetamodelPropertyContext[];\n}\n\n/** A `Metamodel`, described for an LLM: JSON-serializable, derived only from the metamodel. */\nexport interface MetamodelContext {\n readonly framework: string;\n readonly elements: readonly MetamodelElementContext[];\n readonly links: readonly MetamodelLinkContext[];\n}\n\nexport interface MetamodelContextOptions {\n /**\n * Typed custom-property schemas (`@istar-ts/core`'s `defineProperties`), keyed by kind, e.g.\n * a dialect's own or a contribution's (`IstarGlspContribution.schemas`). Properties a kind has\n * no schema for are left out: `customProperties` values stay strings the metamodel itself\n * knows nothing about.\n */\n readonly schemas?: readonly PropertySchema<PropertyShape, string>[];\n}\n\nfunction propertiesOf(\n kind: string,\n byKind: ReadonlyMap<string, readonly PropertySchema<PropertyShape, string>[]>,\n): readonly MetamodelPropertyContext[] | undefined {\n const schemas = byKind.get(kind);\n if (!schemas || schemas.length === 0) return undefined;\n const properties: MetamodelPropertyContext[] = [];\n for (const schema of schemas) {\n for (const [key, field] of Object.entries(schema.shape)) {\n properties.push({\n key,\n type: field.type,\n ...(field.values ? { values: field.values } : {}),\n ...(field.options.optional ? { optional: true } : {}),\n ...(field.options.description ? { description: field.options.description } : {}),\n });\n }\n }\n return properties;\n}\n\n/**\n * `metamodel`, as a typed, JSON-serializable description: every element and link kind a\n * modeller declares directly (kinds generated for an n-ary link's hub, leg or end are left out,\n * as a hand-written palette hides them too), its containment, and each link kind's source and\n * target kinds in words, resolved the same way `canLink` does (`union`/`ofCategory`).\n */\nexport function metamodelContext(\n metamodel: AnyMetamodel,\n options: MetamodelContextOptions = {},\n): MetamodelContext {\n const schemasByKind = new Map<string, PropertySchema<PropertyShape, string>[]>();\n for (const schema of options.schemas ?? []) {\n const list = schemasByKind.get(schema.kind) ?? [];\n list.push(schema);\n schemasByKind.set(schema.kind, list);\n }\n\n const elements: MetamodelElementContext[] = [];\n for (const definition of metamodel.elements.values()) {\n if (isHub(definition)) continue;\n elements.push({\n kind: definition.kind,\n label: definition.label,\n ...(definition.description !== undefined ? { description: definition.description } : {}),\n category: definition.category,\n ...(definition.info\n ? {\n canBeOnPaper: definition.info.canBeOnPaper,\n canBeInnerElement: definition.info.canBeInnerElement,\n }\n : {}),\n ...(propertiesOf(definition.kind, schemasByKind)\n ? { properties: propertiesOf(definition.kind, schemasByKind) }\n : {}),\n });\n }\n\n const links: MetamodelLinkContext[] = [];\n for (const definition of metamodel.links.values()) {\n if (definition.role !== undefined) continue;\n const rules = metamodel.links.get(effectiveLinkKind(metamodel, definition.kind))?.rules;\n const builtIn =\n definition.category === 'dependency'\n ? ofCategory(metamodel)\n : ofCategory(metamodel, definition.category as 'actor' | 'node');\n links.push({\n kind: definition.kind,\n label: definition.label,\n ...(definition.description !== undefined ? { description: definition.description } : {}),\n category: definition.category,\n sources: rules ? union(metamodel, rules.sources) : builtIn,\n targets: rules ? union(metamodel, rules.targets) : builtIn,\n ...(definition.arity === 'n' ? { arity: definition.arity } : {}),\n ...(definition.info.possibleLabels ? { values: definition.info.possibleLabels } : {}),\n ...(propertiesOf(definition.kind, schemasByKind)\n ? { properties: propertiesOf(definition.kind, schemasByKind) }\n : {}),\n });\n }\n\n return { framework: metamodel.framework, elements, links };\n}\n\nfunction propertiesLine(properties: readonly MetamodelPropertyContext[] | undefined): string[] {\n if (!properties || properties.length === 0) return [];\n const parts = properties.map((p) => {\n const bits = [p.type, ...(p.values ? [`values: ${p.values.join('/')}`] : [])];\n return `${p.key} (${bits.join(', ')})${p.optional ? '?' : ''}`;\n });\n return [` properties: ${parts.join(', ')}`];\n}\n\nfunction flags(element: MetamodelElementContext): string {\n const bits: string[] = [];\n if (element.canBeOnPaper) bits.push('on paper');\n if (element.canBeInnerElement) bits.push('inner');\n return bits.length > 0 ? ` [${bits.join(', ')}]` : '';\n}\n\nfunction elementLine(element: MetamodelElementContext): string[] {\n const description = element.description ? ` — ${element.description}` : '';\n return [\n `- ${element.kind} (${element.label})${flags(element)}${description}`,\n ...propertiesLine(element.properties),\n ];\n}\n\nfunction linkLine(link: MetamodelLinkContext): string[] {\n const arity = link.arity === 'n' ? ' [n-ary, via a hub]' : '';\n const values = link.values ? `; values: ${link.values.join(', ')}` : '';\n const description = link.description ? ` — ${link.description}` : '';\n return [\n `- ${link.kind} (${link.label})${arity}: ${link.category} link, ` +\n `${link.sources.join(', ')} → ${link.targets.join(', ')}${values}${description}`,\n ...propertiesLine(link.properties),\n ];\n}\n\n/**\n * `context`, rendered as compact, deterministic markdown for an LLM: one section each for actor\n * kinds, node kinds and link kinds, in the metamodel's own declaration order.\n */\nexport function metamodelContextText(context: MetamodelContext): string {\n const actors = context.elements.filter((e) => e.category === 'actor');\n const nodes = context.elements.filter((e) => e.category === 'node');\n const sections = [`# ${context.framework} metamodel`];\n if (actors.length > 0) {\n sections.push(['## Actor kinds', ...actors.flatMap(elementLine)].join('\\n'));\n }\n if (nodes.length > 0) {\n sections.push(['## Node kinds', ...nodes.flatMap(elementLine)].join('\\n'));\n }\n if (context.links.length > 0) {\n sections.push(['## Link kinds', ...context.links.flatMap(linkLine)].join('\\n'));\n }\n return sections.join('\\n\\n');\n}\n\n/**\n * The built-in `HostContextProvider` (#240): its text is always read from the model at hand\n * (`metamodelOf(model)`), so one instance works for every dialect a host serves. `options`\n * (`schemas`, mainly from a dialect's `IstarGlspContribution`) are fixed at creation time.\n */\nexport function metamodelContextProvider(\n options: MetamodelContextOptions = {},\n): HostContextProvider {\n return {\n name: 'metamodel',\n title: \"This model's language\",\n text: (model: AnyIstarModel) =>\n metamodelContextText(metamodelContext(metamodelOf(model) as AnyMetamodel, options)),\n };\n}\n","/**\n * A mirror store: a read-only `ModelStore` in this process whose model follows a dispatcher that\n * lives elsewhere (a worker, a server, the other end of a `createRemoteDispatcher` port), so a\n * canvas and an inspector written against `ModelStore` can render it. Edits never touch the\n * mirror: they are dispatched to the remote, and come back as the remote's `sourceModelChanged`.\n *\n * How the model travels: an initial `requestModel`, then one update per `sourceModelChanged`.\n * A notification that carries the new model (`newRoot`, a dispatcher created with `sendModel`)\n * is applied as it arrives; one without it is answered with a `requestModel`, in order. Either\n * way the update is a whole piStar file, re-parsed (2 ms for the largest fixture, 237 ids), and\n * then shared with the previous model: an element, link or diagram equal to the one it replaces\n * keeps the old object, so whatever is memoised on identity only redoes what changed.\n */\nimport {\n FILE_METAMODEL_KEY,\n ModelOperationError,\n canLink,\n createEmptyModel,\n inheritMetamodel,\n inheritSourceLayout,\n metamodelOf,\n parsePistar,\n} from '@istar-ts/core';\nimport type {\n AnyIstarModel,\n AnyMetamodel,\n ElementKind,\n IstarModel,\n LinkKind,\n Metamodel,\n ModelChange,\n ModelChangeEvent,\n ModelListener,\n ModelStore,\n ParsePistarOptions,\n PistarFile,\n} from '@istar-ts/core';\nimport type { ActionDispatcher, ActionResult } from './dispatcher';\n\nexport interface MirrorStoreOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * The metamodel the remote's files are read with (`parsePistar`'s `metamodel`), and of the\n * empty model shown until the first one arrives. Default iStar 2.0.\n */\n readonly metamodel?: Metamodel<EK, LK>;\n /** `parsePistar`'s `fileMetamodel`: apply the file's own `\"metamodel\"` block. Default false. */\n readonly fileMetamodel?: boolean;\n /**\n * How many undo steps the remote keeps, for `canUndo` estimate (see `MirrorStore`). Only used\n * when the dispatcher doesn't send exact values. Default 100, a `ModelStore`'s default.\n */\n readonly historyLimit?: number;\n /** Hears a failed update (a transport fault, a file that doesn't parse). Default: ignored. */\n readonly onError?: (error: unknown) => void;\n /**\n * Shown until the remote's first `requestModel` answers, instead of an empty model (a parsed\n * model, or a piStar file parsed the same way as a pushed one — see `metamodelFor`). Replaced\n * once the remote answers, unless its model is equal.\n */\n readonly initial?: IstarModel<EK, LK> | PistarFile;\n /**\n * The metamodel a pushed or re-requested file is read with, resolved per file (e.g. by its\n * `tool`, with `detectFramework`) instead of the fixed `metamodel`. Keeps the mirror itself\n * dialect-agnostic: a host whose remote may switch a mirror's root metamodel (an iStar mirror\n * shown a KAOS file after `store.replace`) passes this instead of `metamodel`. Default:\n * every file is read with `metamodel` (today's behaviour).\n */\n readonly metamodelFor?: (file: PistarFile) => Metamodel<EK, LK>;\n}\n\n/**\n * A `ModelStore` whose model is the remote's. Reading (`getModel`, `subscribe`, `canLink`) works\n * as on any store; every mutation (`addElement` … `replace`, `load`, `transaction`,\n * `clearHistory`) throws a `ModelOperationError`: dispatch the edit to the remote instead.\n *\n * Undo is the remote's, one stack for all its clients: `undo`/`redo` dispatch `glspUndo` /\n * `glspRedo` to it. `canUndo`/`canRedo` are exact when the dispatcher sends them with each\n * change (a dispatcher created with `sendModel`), or an estimate counted from the notifications\n * heard since the mirror connected (the remote doesn't publish its stack's depth when not sending\n * them): edits made before then are not counted.\n */\nexport interface MirrorStore<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n> extends ModelStore<EK, LK> {\n /** Resolves once the remote's model is shown; rejects if the first `requestModel` fails. */\n readonly ready: Promise<void>;\n /**\n * The remote, wrapped so that `dispatch` resolves only once the mirror shows what the action\n * did: give this to `IstarProvider` as `dispatcher`. (With a `sendModel` remote, the remote\n * itself already has that order, since a change's notification arrives before its result.)\n */\n readonly dispatcher: ActionDispatcher<EK, LK>;\n /** Resolves once every change heard so far is shown. */\n synced(): Promise<void>;\n /** Stops following the remote (the remote itself stays open). */\n dispose(): void;\n}\n\ntype Source = ModelChangeEvent['source'];\n\n/** Deep equality of JSON values (what parsed models are made of). */\nfunction equal(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n for (const key of ka) {\n if (!equal((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * `next`, with every element, link and the diagram that equals `previous`'s kept as\n * `previous`'s object; `previous` itself when nothing differs (in content, order or metamodel).\n */\nfunction share(previous: AnyIstarModel, next: AnyIstarModel): AnyIstarModel {\n let same =\n previous.elements.size === next.elements.size &&\n previous.links.size === next.links.size &&\n metamodelOf(previous) === metamodelOf(next);\n const shareMap = <T>(\n from: ReadonlyMap<string, T>,\n to: ReadonlyMap<string, T>,\n ): Map<string, T> => {\n const order = from.keys();\n const out = new Map<string, T>();\n for (const [id, value] of to) {\n const old = from.get(id);\n const keep = old !== undefined && equal(old, value);\n if (!keep || order.next().value !== id) same = false;\n out.set(id, keep ? old : value);\n }\n return out;\n };\n const elements = shareMap(previous.elements, next.elements);\n const links = shareMap(previous.links, next.links);\n const diagram = equal(previous.diagram, next.diagram) ? previous.diagram : next.diagram;\n const { elements: _e, links: _l, diagram: _d, ...rest } = next;\n const { elements: _pe, links: _pl, diagram: _pd, ...previousRest } = previous;\n if (same && equal(rest, previousRest)) return previous;\n const shared: AnyIstarModel = {\n ...rest,\n elements,\n links,\n ...(diagram === undefined ? {} : { diagram }),\n };\n return inheritMetamodel(next, inheritSourceLayout(next, shared));\n}\n\nfunction readOnly(): never {\n throw new ModelOperationError(\n 'a mirror store is read-only: dispatch the edit through its remote dispatcher',\n );\n}\n\nconst parseWith = parsePistar as (\n file: PistarFile,\n options: ParsePistarOptions<string, string>,\n) => AnyIstarModel;\n\n/**\n * A mirror of `remote`'s model (see `MirrorStore`). Shows an empty model until `ready`.\n *\n * Order: changes are shown in the order the remote sends them, whoever made them, and a\n * `dispatch` through `mirror.dispatcher` resolves after its change is shown, so code that\n * selects a created id or rolls back a rejected one sees the model it expects. A rejected\n * action sends no notification: the mirror stays as it was.\n */\nexport function createMirrorStore<EK extends string = ElementKind, LK extends string = LinkKind>(\n remote: ActionDispatcher<EK, LK>,\n options: MirrorStoreOptions<EK, LK> = {},\n): MirrorStore<EK, LK> {\n const r = remote as unknown as ActionDispatcher<string, string>;\n const metamodel = options.metamodel as unknown as AnyMetamodel | undefined;\n const metamodelFor = options.metamodelFor as unknown as\n | ((file: PistarFile) => AnyMetamodel)\n | undefined;\n const limit = options.historyLimit ?? 100;\n const onError = options.onError ?? (() => {});\n const listeners = new Set<ModelListener<string, string>>();\n const parseFile = (file: PistarFile): AnyIstarModel => {\n const base = metamodelFor ? metamodelFor(file) : metamodel;\n return parseWith(file, {\n ...(base ? { metamodel: base } : {}),\n ...(options.fileMetamodel ? { fileMetamodel: true } : {}),\n });\n };\n const initial = options.initial as unknown as AnyIstarModel | PistarFile | undefined;\n const initialModel: AnyIstarModel | undefined =\n initial === undefined\n ? undefined\n : initial.elements instanceof Map\n ? (initial as AnyIstarModel)\n : parseFile(initial as PistarFile);\n let model: AnyIstarModel =\n initialModel ??\n (metamodel\n ? createEmptyModel(undefined, { metamodel })\n : (createEmptyModel() as AnyIstarModel));\n /** The last file's `\"metamodel\"` block, as JSON; `undefined` before the first file. */\n let block: string | undefined;\n let undoDepth = 0;\n let redoDepth = 0;\n /** How many pushed models (`newRoot`) were applied: a response asked for before one is stale. */\n let pushed = 0;\n let requests = 0;\n let tail: Promise<void> = Promise.resolve();\n let disposed = false;\n\n const parse = (file: PistarFile): AnyIstarModel => {\n const nextBlock = JSON.stringify((file as Record<string, unknown>)[FILE_METAMODEL_KEY] ?? null);\n const root = metamodelFor?.(file);\n if (nextBlock === block && (!metamodelFor || root === metamodelOf(model))) {\n // The same file metamodel, and (with `metamodelFor`) the same root: read with the current\n // model's metamodel, so `metamodelOf` keeps its identity (a registry memoised on it isn't\n // rebuilt on every change).\n return inheritMetamodel(model, parseWith(file, { metamodel: metamodelOf(model) }));\n }\n const parsed = parseFile(file);\n block = nextBlock;\n return parsed;\n };\n\n const apply = (file: PistarFile, source: Source, changes: readonly ModelChange[]): void => {\n const previous = model;\n const next = share(previous, parse(file));\n if (next === previous) return;\n model = next;\n const event: ModelChangeEvent<string, string> = { model, previous, changes, source };\n for (const listener of listeners) listener(event);\n };\n\n /** Counts the remote's undo stack from what it reports (see `MirrorStore`). */\n const track = (\n source: Source,\n exact?: { readonly canUndo: boolean; readonly canRedo: boolean },\n ): void => {\n if (exact) {\n undoDepth = exact.canUndo ? 1 : 0;\n redoDepth = exact.canRedo ? 1 : 0;\n } else if (source === 'edit') {\n undoDepth = Math.min(undoDepth + 1, limit);\n redoDepth = 0;\n } else if (source === 'undo') {\n undoDepth = Math.max(undoDepth - 1, 0);\n redoDepth++;\n } else if (source === 'redo') {\n undoDepth = Math.min(undoDepth + 1, limit);\n redoDepth = Math.max(redoDepth - 1, 0);\n } else {\n undoDepth = 0;\n redoDepth = 0;\n }\n };\n\n /**\n * Asks for the model now (so the remote answers in order) and shows it once every earlier\n * update is shown. Dropped if a pushed model arrived meanwhile: that one is at least as new.\n */\n const refresh = (source: Source, changes: readonly ModelChange[]): Promise<void> => {\n const seen = pushed;\n const sent = r\n .dispatch({ kind: 'requestModel', requestId: `mirror-${++requests}` })\n .then((result: ActionResult<{ readonly newRoot: PistarFile }>) => ({ result }))\n .catch((error: unknown) => ({ error }));\n const step = tail.then(async () => {\n const answer = await sent;\n if (disposed || pushed !== seen) return;\n if ('error' in answer) throw answer.error;\n const { result } = answer;\n if (!result.ok) {\n throw new Error(result.diagnostics[0]?.message ?? 'requestModel was rejected');\n }\n if (!result.response) throw new Error('requestModel was answered without a model');\n apply(result.response.newRoot, source, changes);\n });\n tail = step.catch(onError);\n return step;\n };\n\n const unsubscribe = r.subscribe((action) => {\n if (disposed || action.kind !== 'sourceModelChanged') return;\n track(\n action.source,\n action.canUndo !== undefined && action.canRedo !== undefined\n ? { canUndo: action.canUndo, canRedo: action.canRedo }\n : undefined,\n );\n if (action.newRoot) {\n pushed++;\n try {\n apply(action.newRoot, action.source, action.changes);\n } catch (error) {\n onError(error);\n }\n } else {\n void refresh(action.source, action.changes).catch(() => {});\n }\n });\n\n const ready = refresh('load', []);\n // `ready` rejects for whoever awaits it; unawaited, the failure only reaches `onError`.\n ready.catch(() => {});\n\n const send = (kind: 'glspUndo' | 'glspRedo'): void => {\n void r.dispatch({ kind }).catch(onError);\n };\n\n const dispatcher: ActionDispatcher<string, string> = {\n async dispatch(action, options) {\n const result = await r.dispatch(action, options);\n await tail;\n return result;\n },\n subscribe: (listener) => r.subscribe(listener),\n };\n\n const store: MirrorStore<string, string> = {\n ready,\n dispatcher,\n synced: () => tail,\n dispose() {\n disposed = true;\n unsubscribe();\n },\n\n getModel: () => model,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n canLink: (source, target, kind) => canLink(model, source, target, kind),\n\n addElement: readOnly,\n updateElement: readOnly,\n moveElement: readOnly,\n nestElement: readOnly,\n removeElement: readOnly,\n removeElements: readOnly,\n setCollapsed: readOnly,\n connect: readOnly,\n addDependency: readOnly,\n addLeg: readOnly,\n removeLeg: readOnly,\n updateLink: readOnly,\n disconnect: readOnly,\n updateDiagram: readOnly,\n replace: readOnly,\n load: readOnly,\n transaction: readOnly,\n clearHistory: readOnly,\n\n undo() {\n if (undoDepth === 0) return false;\n send('glspUndo');\n return true;\n },\n redo() {\n if (redoDepth === 0) return false;\n send('glspRedo');\n return true;\n },\n canUndo: () => undoDepth > 0,\n canRedo: () => redoDepth > 0,\n };\n return store as unknown as MirrorStore<EK, LK>;\n}\n","/**\n * A transport for `ActionDispatcher` over a `MessagePort`-like object, framed as JSON-RPC 2.0:\n * a dispatch is a request (`method = action.kind`, `params = action`), answered with the\n * `ActionResult` as `result`; `dispatcher.subscribe` events go server to client as notifications\n * (no `id`). A rejection (`ActionResult` with `ok: false`) is a normal result, not a JSON-RPC\n * error — only a transport or protocol fault (a malformed frame, an unhandled exception) is.\n *\n * `connectDispatcher` serves a dispatcher on one end; `createRemoteDispatcher` is the\n * `ActionDispatcher` implementation for the other end. No `vscode-jsonrpc`.\n */\nimport type { ElementKind, LinkKind } from '@istar-ts/core';\nimport type {\n ActionDispatcher,\n ActionListener,\n ActionResult,\n DispatchOptions,\n StoreActionDispatcher,\n} from './dispatcher';\nimport type { IstarAction } from './actions';\n\nconst JSONRPC_VERSION = '2.0';\n\n/** An id a JSON-RPC request carries and its response answers back. */\nexport type JsonRpcId = string | number;\n\nexport interface JsonRpcRequest {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly method: string;\n readonly params?: unknown;\n /** The dispatch's `origin` (`DispatchOptions.origin`), carried to the server's `dispatch`. */\n readonly origin?: string;\n}\n\n/** A subscriber event, sent with no `id`: it expects no response. */\nexport interface JsonRpcNotification {\n readonly jsonrpc: '2.0';\n readonly method: string;\n readonly params?: unknown;\n}\n\nexport interface JsonRpcSuccess {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly result: unknown;\n}\n\nexport interface JsonRpcErrorObject {\n readonly code: number;\n readonly message: string;\n readonly data?: unknown;\n}\n\nexport interface JsonRpcError {\n readonly jsonrpc: '2.0';\n readonly id: JsonRpcId;\n readonly error: JsonRpcErrorObject;\n}\n\n/** The envelope `connectDispatcher`/`createRemoteDispatcher` exchange over the port. */\nexport type ActionMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\n/**\n * Structurally what a DOM `MessagePort`, a worker's `self`, or any two-way `postMessage` channel\n * gives us: enough to send and receive `ActionMessage`s, nothing DOM-specific. Generic over the\n * event type `onmessage` is handed (`MessageEvent` for a real port, inferred at the call site),\n * so a real `MessagePort` or `Worker` fits without a cast: `strictFunctionTypes` checks a\n * property-typed handler's parameter invariantly, so pinning it to a narrower `{ data: unknown }`\n * here would reject `MessagePort`'s own, wider `onmessage` type.\n */\nexport interface MessagePortLike<\n E extends { readonly data: unknown } = { readonly data: unknown },\n> {\n postMessage(data: unknown): void;\n onmessage: ((ev: E) => unknown) | null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isJsonRpcId(value: unknown): value is JsonRpcId {\n return typeof value === 'string' || typeof value === 'number';\n}\n\nfunction errorMessage(id: JsonRpcId, code: number, message: string): JsonRpcError {\n return { jsonrpc: JSONRPC_VERSION, id, error: { code, message } };\n}\n\n/**\n * Serves `dispatcher` on `port`: every well-formed request is answered with the\n * `ActionResult` as `result`; `dispatcher.subscribe` events are pushed as notifications.\n * A malformed request answers `-32600` (invalid request) or `-32601` (no usable `method`); an\n * exception `dispatch` itself doesn't catch answers `-32603` (internal error). Returns a\n * disposer that stops forwarding subscriber events and detaches the port's `onmessage`.\n */\nexport function connectDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n E extends { readonly data: unknown } = { readonly data: unknown },\n>(port: MessagePortLike<E>, dispatcher: ActionDispatcher<EK, LK>): () => void {\n const unsubscribe = dispatcher.subscribe((action) => {\n port.postMessage({ jsonrpc: JSONRPC_VERSION, method: action.kind, params: action });\n });\n\n port.onmessage = (ev: E) => {\n const message = ev.data;\n if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;\n const { id, method, params, origin } = message;\n const hasId = isJsonRpcId(id);\n const dispatchOptions: DispatchOptions | undefined =\n typeof origin === 'string' ? { origin } : undefined;\n\n if (typeof method !== 'string' || method.length === 0) {\n if (hasId) port.postMessage(errorMessage(id, -32601, 'method not found'));\n return;\n }\n if (!isRecord(params) || params.kind !== method) {\n if (hasId) port.postMessage(errorMessage(id, -32600, 'invalid request'));\n return;\n }\n\n const action = params as unknown as IstarAction<EK, LK>;\n if (!hasId) {\n // A notification from the client: dispatch it, no response expected.\n void dispatcher.dispatch(action, dispatchOptions);\n return;\n }\n dispatcher.dispatch(action, dispatchOptions).then(\n (result: ActionResult<unknown>) => {\n port.postMessage({ jsonrpc: JSONRPC_VERSION, id, result });\n },\n (error: unknown) => {\n const text = error instanceof Error ? error.message : 'internal error';\n port.postMessage(errorMessage(id, -32603, text));\n },\n );\n };\n\n return () => {\n unsubscribe();\n port.onmessage = null;\n };\n}\n\n/**\n * The `ActionDispatcher` for the other end of a `connectDispatcher` port: `dispatch` sends a\n * request and resolves with the `ActionResult` it is answered with (a JSON-RPC `error` rejects\n * the promise instead — a transport fault, not an `ActionResult`); `subscribe` hears the\n * notifications the server pushes.\n */\nexport function createRemoteDispatcher<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n E extends { readonly data: unknown } = { readonly data: unknown },\n>(port: MessagePortLike<E>): ActionDispatcher<EK, LK> {\n let nextId = 0;\n const pending = new Map<\n JsonRpcId,\n { resolve: (result: ActionResult<unknown>) => void; reject: (error: Error) => void }\n >();\n const listeners = new Set<ActionListener<EK, LK>>();\n\n port.onmessage = (ev: E) => {\n const message = ev.data;\n if (!isRecord(message) || message.jsonrpc !== JSONRPC_VERSION) return;\n const { id, method, params, result, error } = message;\n\n if (isJsonRpcId(id)) {\n const waiting = pending.get(id);\n if (!waiting) return;\n pending.delete(id);\n if (isRecord(error)) {\n waiting.reject(new Error(`JSON-RPC error ${String(error.code)}: ${String(error.message)}`));\n } else {\n waiting.resolve(result as ActionResult<unknown>);\n }\n return;\n }\n\n if (typeof method === 'string' && isRecord(params)) {\n const action = params as unknown as IstarAction<EK, LK>;\n for (const listener of listeners) listener(action);\n }\n };\n\n return {\n dispatch(action, dispatchOptions) {\n const id = nextId++;\n return new Promise((resolve, reject) => {\n pending.set(id, { resolve: resolve as (result: ActionResult<unknown>) => void, reject });\n port.postMessage({\n jsonrpc: JSONRPC_VERSION,\n id,\n method: action.kind,\n params: action,\n ...(dispatchOptions?.origin === undefined ? {} : { origin: dispatchOptions.origin }),\n });\n });\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\n/**\n * `dispatcher` as a `StoreActionDispatcher`, for a consumer that asks for its dirty state (a GLSP\n * session over a host's dispatcher, `@istar-ts/glsp`'s `IstarSharedModel`). A dispatcher that has\n * `isDirty` is returned as is (with a no-op `dispose` if it has none); one that doesn't (a\n * `createRemoteDispatcher`, a mirror's) is wrapped, its dirty state tracked from the\n * `setDirtyState` notifications it relays from then on: clean until the first one, since a remote\n * dispatcher doesn't publish the state it had before. `dispose` stops tracking and never disposes\n * the dispatcher itself, which stays its owner's (#249).\n */\nexport function withDirtyState<EK extends string = ElementKind, LK extends string = LinkKind>(\n dispatcher: ActionDispatcher<EK, LK> & { isDirty?(): boolean; dispose?(): void },\n): StoreActionDispatcher<EK, LK> {\n const own = dispatcher.isDirty;\n if (typeof own === 'function') {\n if (typeof dispatcher.dispose === 'function')\n return dispatcher as StoreActionDispatcher<EK, LK>;\n return {\n dispatch: (action, options) => dispatcher.dispatch(action, options),\n subscribe: (listener) => dispatcher.subscribe(listener),\n isDirty: () => own.call(dispatcher),\n dispose: () => undefined,\n };\n }\n let dirty = false;\n const unsubscribe = dispatcher.subscribe((action) => {\n if (action.kind === 'setDirtyState') dirty = action.isDirty;\n });\n return {\n dispatch: (action, options) => dispatcher.dispatch(action, options),\n subscribe: (listener) => dispatcher.subscribe(listener),\n isDirty: () => dirty,\n dispose: () => {\n unsubscribe();\n },\n };\n}\n","/** Version of the action protocol this package speaks. */\nexport const ACTIONS_PROTOCOL_VERSION: string = '0.0.0';\n\nexport * from './actions';\nexport * from './created-ids';\nexport * from './dispatcher';\nexport * from './hints';\nexport * from './host';\nexport * from './markers';\nexport * from './metamodel-context';\nexport * from './mirror';\nexport * from './transport';\n"],"mappings":";;;AA4nBA,MAAM,sBAAyD;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,oBAA2D;CAC/D;CACA;CACA;CACA;CACA;AACF;;;;;AAMA,MAAM,yBAKQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAuC,IAAI,IAAI,mBAAmB;AACxE,MAAM,gBAAqC,IAAI,IAAI,iBAAiB;;;;;;;AAQpE,MAAa,uBAST;CACF,YAAY;CACZ,UAAU;CACV,eAAe;AACjB;;AAGA,SAAgB,YACd,QACkC;CAClC,OAAO,gBAAgB,IAAI,OAAO,IAAI;AACxC;;AAGA,SAAgB,gBAAgB,QAA8C;CAC5E,OAAO,cAAc,IAAI,OAAO,IAAI;AACtC;;;;;;AClsBA,SAAS,gBACP,WACA,OACqC;CACrC,QAAQ,UAAU,MAAlB;EACE,KAAK,cACH,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;EACjC,KAAK,cAAc;GACjB,MAAM,aAAA,GAAYA,eAAAA,YAAAA,CAAY,KAAK;GACnC,MAAM,aAAa,UAAU,MAAM,IAAI,UAAU,aAAa;GAC9D,IAAI,YAAY,aAAa,cAAc,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;GAC1E,IAAI,YAAY,SAAS,CAAC,YAAY,WAAW,OAAO,SAAS,GAE/D,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;GAEjC,OAAO;IAAE,UAAU;IAAG,OAAO;GAAE;EACjC;EACA,KAAK,gBACH,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;EACjC,KAAK,YAAY;GACf,IAAI,WAAW;GACf,IAAI,QAAQ;GACZ,KAAK,MAAM,SAAS,UAAU,eAAuC;IACnE,MAAM,SAAS,gBAAgB,OAAO,KAAK;IAC3C,YAAY,OAAO;IACnB,SAAS,OAAO;GAClB;GACA,OAAO;IAAE;IAAU;GAAM;EAC3B;EACA,SACE,OAAO;GAAE,UAAU;GAAG,OAAO;EAAE;CACnC;AACF;AAEA,SAAS,YACP,WACA,OACA,WACS;CACT,MAAM,aAAa,MAAM,SAAS,IAAI,UAAU,eAAe,CAAC,EAAE;CAClE,OAAO,eAAe,KAAA,KAAa,UAAU,SAAS,IAAI,UAAU,CAAC,EAAE,SAAS;AAClF;;;;AAKA,SAAS,eACP,WACA,YACA,SACA,OACW;CACX,QAAQ,UAAU,MAAlB;EACE,KAAK,cAAc;GACjB,MAAM,KAAK,WAAW,MAAM;GAC5B,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,cAAc;GACjB,MAAM,aAAA,GAAYA,eAAAA,YAAAA,CAAY,KAAK;GACnC,MAAM,aAAa,UAAU,MAAM,IAAI,UAAU,aAAa;GAC9D,IAAI,YAAY,aAAa,cAAc;IACzC,MAAM,aAAa,WAAW,MAAM;IACpC,MAAM,WAAW,CAAC,QAAQ,MAAM,GAAG,QAAQ,MAAM,CAAC;IAClD,IAAI,eAAe,KAAA,KAAa,SAAS,OAAO,KAAA,KAAa,SAAS,OAAO,KAAA,GAC3E,OAAO;IAET,OAAO;KACL,GAAG;KACH,MAAM;MACJ,GAAG,UAAU;MACb,UAAU;OAAE,GAAG,UAAU,MAAM;OAAU,IAAI;MAAW;MACxD,SAAS;KACX;IACF;GACF;GACA,IAAI,YAAY,SAAS,CAAC,YAAY,WAAW,OAAO,SAAS,GAAG;IAClE,MAAM,QAAQ,WAAW,MAAM;IAC/B,MAAM,QAAQ,QAAQ,MAAM;IAC5B,MAAM,QAAQ,QAAQ,MAAM;IAC5B,OAAO,UAAU,KAAA,KAAa,UAAU,KAAA,KAAa,UAAU,KAAA,IAC3D,YACA;KAAE,GAAG;KAAW,MAAM;MAAE,GAAG,UAAU;MAAM,IAAI;MAAO;MAAO;KAAM;IAAE;GAC3E;GACA,MAAM,KAAK,QAAQ,MAAM;GACzB,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,gBAAgB;GACnB,MAAM,KAAK,QAAQ,MAAM;GACzB,OAAO,OAAO,KAAA,IAAY,YAAY;IAAE,GAAG;IAAW,MAAM;KAAE,GAAG,UAAU;KAAM;IAAG;GAAE;EACxF;EACA,KAAK,YACH,OAAO;GACL,GAAG;GACH,eAAgB,UAAU,cAAuC,KAAK,UACpE,eAAe,OAAO,YAAY,SAAS,KAAK,CAClD;EACF;EACF,SACE,OAAO;CACX;AACF;;AAGA,SAAgB,iBACd,WACA,YACA,OACW;CACX,MAAM,SAAS,gBAAgB,WAAW,KAAK;CAC/C,MAAM,aAAa,WAAW,MAAM,GAAG,OAAO,QAAQ;CACtD,MAAM,UAAU,WAAW,MAAM,OAAO,UAAU,OAAO,WAAW,OAAO,KAAK;CAChF,OAAO,eAAe,WAAW,CAAC,GAAG,UAAU,GAAG,CAAC,GAAG,OAAO,GAAG,KAAK;AACvE;;;;;;;;;ACtHA,SAAgB,MAAM,YAA4C;CAChE,OAAO,WAAW,SAAS;AAC7B;;AAGA,SAAgB,SAAS,WAAyB,UAA4B;CAC5E,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GAOjD,IALgB,MAAM,UAAU,IAC5B,WAAW,SAAS,WACpB,aAAa,OACb,aAAa,WAAW,aAAA,GACxBC,eAAAA,mBAAAA,CAAmB,WAAW,WAAW,MAAM,QAAQ,GAC9C,MAAM,KAAK,WAAW,IAAI;CAGzC,IAAI,aAAaC,eAAAA,eAAe,MAAM,KAAK,GAAG,UAAU,MAAM,KAAK,CAAC;MAC/D,IAAI,UAAU,MAAM,IAAI,QAAQ,GAC9B;OAAA,MAAM,QAAQ,UAAU,MAAM,KAAK,GACtC,KAAA,GAAIC,eAAAA,gBAAAA,CAAgB,WAAW,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI;CAAA;CAGnE,OAAO;AACT;AAEA,SAAgB,MAAM,WAAyB,WAAwC;CACrF,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,SAAS,aAAa,SAAS,WAAW,QAAQ,CAAC,CAAC,CAAC;AACpF;;AAGA,SAAgB,WAAW,WAAyB,UAAuC;CACzF,OAAO,CAAC,GAAG,UAAU,SAAS,OAAO,CAAC,CAAC,CACpC,QAAQ,MAAM,CAAC,MAAM,CAAC,MAAM,aAAa,KAAA,KAAa,EAAE,aAAa,SAAS,CAAC,CAC/E,KAAK,MAAM,EAAE,IAAI;AACtB;;;;;;;;;;;;;;;;ACbA,SAAgB,aACd,WACsD;CACtD,MAAM,OAAO;CACb,MAAM,QAAQ,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CACtC,QAAQ,MAAM,EAAE,aAAa,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,sBAAsB,KAAK,CAAC,CACxF,KAAK,MAAM,EAAE,IAAI;CA4BpB,OAAO;EAAE,YA3BU,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,MAAqB;GACvE,MAAM,MAAM,MAAM,CAAC;GACnB,OAAO;IACL,eAAe,EAAE;IACjB,gBAAgB;IAChB,WAAW;IACX,WAAW,CAAC;IACZ,cAAc,CAAC,OAAO,EAAE,aAAa,UAAU,EAAE,MAAM,sBAAsB;IAC7E,GAAI,EAAE,aAAa,UAAU,EAAE,2BAA2B,MAAM,IAAI,CAAC;GACvE;EACF,CAiBkB;EAAG,WAhBH,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,MAAoB;GAClE,MAAM,QAAQ,KAAK,MAAM,KAAA,GAAIC,eAAAA,kBAAAA,CAAkB,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE;GAC/D,MAAM,UAAU,EAAE,aAAa,eAAe,WAAW,IAAI,IAAI,WAAW,MAAM,EAAE,QAAQ;GAC5F,MAAM,UAAU,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;GAErD,MAAM,MAAM,EAAE,OAAO;GACrB,OAAO;IACL,eAAe,EAAE;IACjB,gBAAgB;IAChB,WAAW;IACX,UAAU;IACV,sBAAsB,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;IAC3D,sBAAsB,QAAQ,KAAA,IAAY,UAAU,CAAC,GAAG,SAAS,GAAG;IACpE,SAAS;GACX;EACF,CAC6B;CAAE;AACjC;AAEA,SAAS,eACP,MACA,OACiB;CAIjB,QAHqD,MAAM,QAAQ,KAAK,IACpE,QACA,CAAC,KAAgC,EAAA,CACzB,KAAK,OAAO,MACtB,QAAQ,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,MAAM,MAAM,OAAO;EAC3D,MAAM;EACN,eAAe;EACf,GAAI,MAAM,aAAa,EAAE,MAAM,EAAE,kBAAkB,MAAM,WAAW,EAAE,IAAI,CAAC;CAC7E,CAAC,CACH;AACF;AAEA,SAAS,YAAY,MAAc,MAA4D;CAC7F,OAAO,KAAK,KAAK,OAAO,MAAM;EAC5B,MAAM,OAAO;GACX,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;GAC1D,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,SAAS,EAAE;EAC/E;EACA,OAAO,QAAQ,GAAG,KAAK,GAAG,KAAK,OAAO;GACpC,MAAM;GACN,eAAe;GACf,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;EACjD,CAAC;CACH,CAAC;AACH;AAEA,SAAS,MAAM,QAA+B;CAC5C,OAAO,OAAO,SAAS,OAAO;AAChC;AAEA,SAAS,QACP,IACA,OACA,QACe;CACf,OAAO;EACL;EACA,OAAO,MAAM;EACb,SAAS,CAAC,MAAM;EAChB,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;EAC1D,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;EAChE,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;CAC5D;AACF;;;;;;;AAQA,SAAgB,kBACd,SACA,WAC+C;CAC/C,MAAM,OAAO;CACb,MAAM,UAA2B,CAAC;CAClC,KAAK,MAAM,QAAQ,KAAK,SAAS,KAAK,GAAG;EACvC,MAAM,QAAQ,QAAQ,SAAS;EAC/B,IAAI,OAAO,QAAQ,KAAK,GAAG,eAAe,MAAM,KAAK,CAAC;CACxD;CACA,KAAK,MAAM,QAAQ,KAAK,MAAM,KAAK,GAAG;EACpC,MAAM,OAAO,QAAQ,MAAM;EAC3B,IAAI,MAAM,QAAQ,KAAK,GAAG,YAAY,MAAM,IAAI,CAAC;CACnD;CACA,QAAQ,MAAM,GAAG,MAAO,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAE;CACjF,OAAO;EAAE;EAAS,QAAQ,QAAQ;CAAO;AAC3C;;;;;;;;;AAUA,SAAgB,qBAAqB,WAAgD;CACnF,MAAM,WAA4D,CAAC;CACnE,IAAI,QAAQ;CACZ,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GACjD,SAAS,WAAW,QAClB,WAAW,SAAS,KAAA,IAChB,QACA;EACE,OAAO,WAAW;EAClB,OAAO;EACP,SAAS,WAAW,aAAa,UAAU,WAAW;EACtD,GAAI,WAAW,aAAa,UAAU,EAAE,OAAO,SAAS,IAAI,CAAC;CAC/D;CAER,MAAM,QAAqE,CAAC;CAC5E,QAAQ;CACR,KAAK,MAAM,cAAc,UAAU,MAAM,OAAO,GAC9C,MAAM,WAAW,QACf,WAAW,SAAS,KAAA,IAChB,QACA,CAAC;EAAE,OAAO,WAAW;EAAO,OAAO;EAAS,SAAS;CAAW,CAAC;CAEzE,OAAO;EAAE;EAAU;EAAO,QAAQ,EAAE,QAAQ,EAAE,OAAO,QAAQ,EAAE;CAAE;AACnE;;;;ACvKA,SAAgB,mBAAmB,YAAoC;CACrE,MAAM,EAAE,WAAW,KAAK,UAAU,SAAS,QAAQ,SAAS;CAC5D,OAAO;EACL,OAAO;EACP,aAAa,WAAW,KAAA,IAAY,UAAU,GAAG,QAAQ,IAAI,OAAO;EACpE;EACA,MAAM;EACN,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EACnC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;AACF;;;;;AAMA,SAAgB,mBAAmB,QAAgC;CACjE,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,QAAQ,SAAS;CAItD,OAAO;EACL;EACA,UALgBC,eAAAA,sBAA4C,SAAS,IAAI,IACtE,OACD;EAIF,SAAS;EACT,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;EACnC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EACzC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;AACF;;;;;;;;;;AC+KA,IAAM,YAAN,cAAwB,MAAM;CAC5B;CACA,YAAY,aAAwC;EAClD,MAAM,YAAY,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;EAClD,KAAK,cAAc;CACrB;AACF;AAEA,SAAS,OAAO,SAAiB,YAAY,IAAI,MAAsB;CACrE,MAAM,IAAI,UAAU,CAClB;EAAE;EAAW,UAAU;EAAS;EAAS,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CAAG,CACnF,CAAC;AACH;AAEA,SAAS,YACP,OACA,WACO;CACP,MAAM,IAAI,UAAU,EAAA,GAACC,eAAAA,0BAAAA,CAA0B,OAAwB,SAAS,CAAE,CAAC;AACrF;AAEA,SAAS,OAAO,OAAoC;CAClD,QAAA,GAAOC,eAAAA,YAAAA,CAAY,KAAK;AAC1B;;;;;AAMA,MAAM,sCAA2C,IAAI,IAAI,CAAC,GAAGC,eAAAA,gBAAgBC,eAAAA,kBAAkB,CAAC;;AAGhG,SAAS,UAAU,OAAsB,OAA+C;CACtF,QAAA,GAAOC,eAAAA,iBAAAA,CAAiB,QAAA,GAAOC,eAAAA,oBAAAA,CAAoB,OAAO;EAAE,GAAG;EAAO;CAAM,CAAC,CAAC;AAChF;AAEA,SAAS,WAAW,QAAuB,OAAgC;CACzE,MAAM,MAAgB,CAAC;CACvB,KAAK,MAAM,MAAM,MAAM,SAAS,KAAK,GAAG,IAAI,CAAC,OAAO,SAAS,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE;CACjF,KAAK,MAAM,MAAM,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE;CAC3E,OAAO;AACT;AAEA,SAAS,SAAS,GAA4E;CAC5F,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,IAAI,QAAQ,EAAE;AACzC;AAEA,SAAS,qBAAqB,OAAwC;CACpE,QAAA,GAAOC,eAAAA,cAAAA,CAAc,KAAK,CAAC,CAAC,KAAK,WAAW;EAC1C,WAAW,MAAM;EACjB,UAAU;EACV,SAAS,MAAM;EACf,MAAM,MAAM;CACd,EAAE;AACJ;;;;AAKA,SAAgB,uBAId,OACA,UAA2C,CAAC,GACb;CAC/B,MAAM,IAAI;CACV,MAAM,SAAU,QAAQ,UAAU,CAAC;CACnC,MAAM,aAAc,QAAQ,cAAc,CAAC;CAC3C,MAAM,kBAAkB,SAA8C;EACpE,MAAM,SAAS,QAAQ;EACvB,IAAI,OAAO,WAAW,YAAY,OAAO,OAAO;EAChD,OAAO,UAAU,qBAAqB,IAAI;CAC5C;CACA,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,4BAAY,IAAI,IAAoC;CAE1D,IAAI,QAAuB,EAAE,SAAS;CACtC,IAAI,QAAQ;;;;;;;CAOZ,IAAI;CAEJ,MAAM,QAAQ,WAA8C;EAC1D,KAAK,MAAM,YAAY,WAAW,SAAS,MAAM;CACnD;CAEA,MAAM,eAAe,QAAgC,WAAqC;EACxF,MAAM,OAAO,EAAE,SAAS,MAAM;EAC9B,IAAI,SAAS,OAAO;EACpB,QAAQ;EACR,KAAK;GACH,MAAM;GACN,SAAS;GACT;GACA,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAC3C,CAAC;CACH;CAEA,MAAM,UAAsE;EAC1E,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;CACR;CACA,MAAM,cAAc,EAAE,WAAW,UAAU;EAEzC,IAAI,MAAM,WAAW,QAAQ,QAAQ,MAAM;EAC3C,KAAK;GACH,MAAM;GACN;GACA,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,GAAI,QAAQ,YAAY,EAAE,UAAA,GAASC,eAAAA,eAAAA,CAAe,MAAM,KAAK,EAAE,IAAI,CAAC;GACpE,GAAI,QAAQ,YAAY;IAAE,SAAS,EAAE,QAAQ;IAAG,SAAS,EAAE,QAAQ;GAAE,IAAI,CAAC;GAC1E,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,cAAc;EACjE,CAAC;EACD,YAAY,QAAQ,MAAM,SAAS,aAAa;CAClD,CAAC;CAKD,MAAM,kBAAkB,OACtB,EAAE,SAAS,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,OAAO,oBAAoB,GAAG,IAAI,IAAI,iBAAiB;CAE1F,MAAM,aAAa,WAA2C,aAA+B;EAC3F,MAAM,SAA2B,CAAC;EAClC,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,KAAK,MAAM,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,GACjD,CAAC,EAAE,aAAa,UAAU,SAAS,SAAA,CAAU,KAAK,CAAC;EAGvD,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,UAAU,MAAM;CACnD;CAEA,MAAM,iBACJ,WACA,QACA,aACG;EACH,MAAM,SAA2B,CAAC;EAClC,KAAK,MAAM,SAAS,YAClB,KAAK,MAAM,KAAK,MAAM,WAAW,EAAE,SAAS,GAAG,MAAM,KAAK,CAAC,GACzD,CAAC,EAAE,aAAa,UAAU,SAAS,SAAA,CAAU,KAAK,CAAC;EAGvD,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,UAAU,MAAM;CACnD;CAEA,MAAM,SAAS,WAA2C,aAAqC;EAC7F,UAAU,WAAW,QAAQ;EAC7B,MAAM,SAAS,EAAE,SAAS;EAC1B,QAAQ,WAAW,QAAQ;EAC3B,cAAc,WAAW,QAAQ,QAAQ;CAC3C;CAEA,MAAM,WAAW,WAA2C,aAAqC;EAC/F,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,QAAQ,UAAU,MAAlB;GACE,KAAK,cAAc;IACjB,MAAM,EAAE,eAAe,MAAM,aAAa,OAAO,CAAC,MAAM;IACxD,MAAM,aACJ,KAAK,SAAS,IAAI,IAAI,KACtB,OAAO,yBAAyB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC7E,IAAI,WAAW,SAAS,OACtB,OAAO,KAAK,WAAW,MAAM,yCAAyC,IAAI,UAAU;IAEtF,MAAM,YAAY,gBAAgB,KAAA,IAAY,KAAA,IAAY,eAAe,WAAW;IACpF,IAAI,WAAW,aAAa,QAAQ;KAElC,IAAI,aAAa,WAAW,MAAM,sBAAsB,OACtD,OAAO,KAAK,WAAW,MAAM,6BAA6B,aAAa,WAAW;KAEpF,IAAI,CAAC,aAAa,WAAW,MAAM,iBAAiB,OAClD,OAAO,KAAK,WAAW,MAAM,mCAAmC,IAAI,WAAW;IAEnF;IACA,MAAM,WAAW,UAAU,YAAY,aAAa;KAAE,GAAG;KAAG,GAAG;IAAE;IACjE,EAAE,WAAW;KACX;KACA,GAAG,SAAS;KACZ,GAAG,SAAS;KACZ,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,YAAY;KAC3D,GAAI,KAAK,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG;KAC/C,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;KACrD,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;IAC7E,CAAC;IACD;GACF;GACA,KAAK,cAAc;IACjB,MAAM,EAAE,eAAe,MAAM,iBAAiB,QAAQ,iBAAiB,WAAW;IAClF,MAAM,OAAO,UAAU,QAAQ,CAAC;IAChC,MAAM,aACJ,KAAK,MAAM,IAAI,IAAI,KACnB,OAAO,sBAAsB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC1E,IAAI,WAAW,aAAa,cAAc;KACxC,MAAM,WAAW,KAAK,YAAY,CAAC;KACnC,MAAM,eACJ,SAAS,QACT,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,MACzB,MAAM,EAAE,aAAa,UAAU,EAAE,SAAS,SAAS,EAAE,MAAM,kBAAkB,KAChF,CAAC,EAAE,QACH,OAAO,GAAG,KAAK,KAAK,sCAAsC,IAAI,cAAc;KAC9E,MAAM,SAAS,EAAE,cAAc;MAC7B,UAAU;MACV,UAAU;MACV,UAAU;MACV,UAAU;OACR,MAAM;OACN,GAAI,SAAS,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG;OACvD,GAAI,SAAS,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,SAAS,KAAK;OAC7D,GAAI,SAAS,WAAW;QAAE,GAAG,SAAS,SAAS;QAAG,GAAG,SAAS,SAAS;OAAE,IAAI,CAAC;OAC9E,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,SAAS,iBAAiB,IAAI,CAAC;MACrF;MACA,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;KAClD,CAAC;KACD,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;MAAE;MAAQ;KAAO,CAAC;KACtD;IACF;IACA,MAAM,SAAS,WAAW,KAAK;IAC/B,IAAI,KAAK,UAAU,KAAA,KAAa,UAAU,CAAC,OAAO,SAAS,KAAK,KAAK,GACnE,OACE,IAAI,KAAK,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IACnF,QACA,eACF;IAEF,MAAM,SAAS,EAAE,QAAQ;KACvB;KACA;KACA;KACA,GAAI,KAAK,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG;KAC/C,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;KACxD,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;KACrD,GAAI,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;KAC3E,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;KACxD,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;IAC1D,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;KAAE;KAAQ;IAAO,CAAC;IACtD;GACF;GACA,KAAK,iBAAiB;IACpB,MAAM,WAAqB,CAAC;IAC5B,MAAM,QAAkB,CAAC;IACzB,KAAK,MAAM,MAAM,UAAU,YACzB,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,SAAS,KAAK,EAAE;SACvC,IAAI,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,KAAK,EAAE;SACtC,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;IAEtE,IAAI,SAAS,SAAS,GAAG,EAAE,eAAe,QAAQ;IAElD,KAAK,MAAM,MAAM,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE;IACvE;GACF;GACA,KAAK;IACH,KAAK,MAAM,EAAE,WAAW,aAAa,aAAa,UAAU,WAAW;KACrE,eAAe,SAAS;KACxB,IAAI,aAAa,EAAE,YAAY,WAAW,YAAY,GAAG,YAAY,CAAC;KACtE,IAAI,SACF,EAAE,cAAc,WAAW,EACzB,SAAS;MAAE,OAAO,QAAQ;MAAO,QAAQ,QAAQ;KAAO,EAC1D,CAAC;IAEL;IACA;GAEF,KAAK,mBAAmB;IACtB,MAAM,EAAE,WAAW,mBAAmB,aAAa;IACnD,EAAE,YAAY,WAAW,iBAAiB;IAC1C,IAAI,UAAU,EAAE,YAAY,WAAW,SAAS,GAAG,SAAS,CAAC;IAC7D;GACF;GACA,KAAK;IACH,UAAU,UAAU,eAAe,UAAU,iBAAiB,UAAU,eAAe;IACvF;GACF,KAAK,kBAAkB;IACrB,MAAM,OAAO,UAAU,QAAQ,QAAQ,GAAG;IAC1C,MAAM,KAAK,OAAO,IAAI,UAAU,UAAU,UAAU,QAAQ,MAAM,GAAG,IAAI;IACzE,MAAM,MAAM,OAAO,IAAI,KAAA,IAAY,UAAU,QAAQ,MAAM,OAAO,CAAC;IACnE,IAAI,QAAQ,KAAA,GAAW;KACrB,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,EAAE,cAAc,IAAI,EAAE,MAAM,UAAU,KAAK,CAAC;UAGnE,IAAI,MAAM,MAAM,IAAI,EAAE,GACzB,EAAE,WAAW,IAAI,EAAE,MAAM,UAAU,SAAS,KAAK,OAAO,UAAU,KAAK,CAAC;UACnE,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;IACxE,OACE,cAAc,IAAI,GAAG,MAAM,UAAU,KAAK,CAAC;IAE7C;GACF;GACA,KAAK;IACH,KAAK,MAAM,SAAS,UAAU,eAAe,MAAM,OAAO,QAAQ;IAClE;GACF,KAAK,gBAAgB;IACnB,MAAM,EAAE,OAAO,iBAAiB,WAAW;IAC3C,MAAM,SAAS,EAAE,OAAO,OAAO,QAAQ,UAAU,MAAM,KAAK,EAAE,IAAI,UAAU,KAAK,GAAG,IAAI,CAAC,CAAC;IAC1F,IAAI,CAAC,OAAO,IAAI,YAAY,QAAQ;KAAE;KAAQ,QAAQ;IAAM,CAAC;IAC7D;GACF;GACA,KAAK;IACH,EAAE,UAAU,UAAU,KAAK;IAC3B;GACF,KAAK,sBAAsB;IACzB,MAAM,UAAU,eAAe,UAAU,SAAS;IAClD,IAAI,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,aAAa,SAChD,OAAO,IAAI,QAAQ,GAAG,oBAAoB,QAAQ,IAAI,cAAc;IAEtE,EAAE,aAAa,QAAQ,IAAI,UAAU,SAAS;IAC9C;GACF;GACA,KAAK,uBAAuB;IAC1B,MAAM,EAAE,MAAM,OAAO,QAAQ,qBAAqB,UAAU;IAC5D,EAAE,cAAc;KACd,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;KACrC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;KACvC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;KACzC,GAAI,qBAAqB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB;IAC/D,CAAC;IACD;GACF;GACA,KAAK;IACH,cAAc,UAAU,WAAW,UAAU,UAAU;IACvD;GACF,KAAK;IACH,eAAe,UAAU,SAAS;IAClC,EAAE,cAAc,UAAU,WAAW,EAAE,SAAS,UAAU,MAAM,CAAC;IACjE;GACF,KAAK;IACH,IAAI,CAAC,MAAM,MAAM,IAAI,UAAU,MAAM,GACnC,OAAO,iBAAiB,UAAU,OAAO,IAAI,UAAU,QAAQ,iBAAiB;IAElF,EAAE,WAAW,UAAU,QAAQ,EAAE,SAAS,UAAU,MAAM,CAAC;IAC3D;GACF,KAAK,sBAAsB;IACzB,MAAM,EAAE,QAAQ,UAAU;IAC1B,MAAM,OACJ,MAAM,MAAM,IAAI,MAAM,KAAK,OAAO,iBAAiB,OAAO,IAAI,QAAQ,iBAAiB;IACzF,MAAM,aAAa,KAAK,MAAM,IAAI,KAAK,IAAI;IAC3C,MAAM,SAAS,YAAY,KAAK;IAChC,IAAI,UAAU,QAAQ,UAAU,CAAC,OAAO,SAAS,KAAK,GACpD,OACE,IAAI,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IAC9E,QACA,eACF;IAEF,EAAE,WAAW,QAAQ,EAAE,OAAO,MAAM,CAAC;IACrC;GACF;GACA,KAAK,wBAAwB;IAC3B,MAAM,EAAE,SAAS,eAAe,SAAS;IACzC,IAAI,QAAQ,WAAW,GAAG;IAC1B,MAAM,MAAM,IAAI,IAAI,OAAO;IAC3B,MAAM,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,KACpB,OAAO,MAAM,MAAM,IAAI,EAAE,KAAK,OAAO,iBAAiB,GAAG,IAAI,IAAI,iBAAiB,CACrF;IACA,MAAM,aACJ,KAAK,MAAM,IAAI,IAAI,KACnB,OAAO,sBAAsB,KAAK,OAAO,KAAK,QAAQ,IAAI,cAAc;IAC1E,MAAM,WAAW,MAAM,QAAQ,SAAS,KAAK,SAAS,IAAI;IAC1D,IAAI,SAAS,WAAW,GAAG;IAC3B,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK;IACrC,KAAK,MAAM,MAAM,KAAK,UAAU,OAAO,EAAE;IACzC,MAAM,UAAU,UAAU,OAAO,SAAS;IAC1C,MAAM,SAAS,WAAW,KAAK;IAC/B,KAAK,MAAM,QAAQ,UAAU;KAC3B,MAAM,SAAA,GAAQC,eAAAA,QAAAA,CAAQ,SAAS,KAAK,QAAQ,KAAK,QAAQ,IAAI;KAC7D,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;MAAE,QAAQ,KAAK;MAAQ,QAAQ,KAAK;KAAO,CAAC;KAC9E,IAAI,KAAK,SAAS,QAAQ,UAAU,CAAC,OAAO,SAAS,KAAK,KAAK,GAC7D,OACE,IAAI,KAAK,MAAM,wBAAwB,WAAW,MAAM,SAAS,OAAO,KAAK,IAAI,EAAE,IACnF,KAAK,IACL,eACF;IAEJ;IACA,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK;IAChC,KAAK,MAAM,QAAQ,UAAU,KAAK,IAAI,KAAK,IAAI;KAAE,GAAG;KAAM;IAAK,CAAC;IAChE,EAAE,QAAQ,UAAU,OAAO,IAAI,CAAC;IAChC;GACF;GACA,KAAK,0BAA0B;IAC7B,IAAI;IACJ,IAAI;KACF,QAAA,GAAOC,eAAAA,kBAAAA,CAAkB,OAAO,UAAU,KAAK;IACjD,SAAS,OAAO;KACd,IAAI,iBAAiBC,eAAAA,gBAAgB,OAAO,MAAM,SAAS,IAAI,mBAAmB;KAClF,MAAM;IACR;IACA,EAAE,QAAQ,IAAI;IACd;GACF;GACA,KAAK,0BAA0B;IAC7B,MAAM,EAAE,KAAK,QAAQ,SAAS;IAC9B,KAAK,MAAM,OAAO,CAAC,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,GAAI,UAAU,CAAC,CAAE,GAAG;KAChE,IAAI,CAAC,oBAAoB,IAAI,GAAG,GAAG;KACnC,IAAI,QAAQ,QACV,OACE,uEACA,IACA,cACF;KAEF,IAAI,QAAQP,eAAAA,oBACV,OACE,IAAI,IAAI,6DACR,IACA,cACF;KAEF,OACE,IAAI,IAAI,8DACR,IACA,cACF;IACF;IACA,IAAI,WAA0B;IAC9B,IAAI,SAAS,MAAM;KACjB,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;KACjC,WAAW;IACb,OAAO,IAAI,SAAS,KAAA,GAClB,WAAW;KAAE,GAAG;KAAU;IAAK;IAEjC,MAAM,QAAiC,EAAE,GAAG,SAAS,MAAM;IAC3D,IAAI,KAAK,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAAG,MAAM,OAAO;IACtE,IAAI,QAAQ,KAAK,MAAM,OAAO,QAAQ,OAAO,MAAM;IACnD,MAAM,EAAE,OAAO,QAAQ,GAAG,SAAS;IACnC,MAAM,OAAsB;KAC1B,GAAG;KACH,GAAI,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,EAAS,MAAe,IAAI,CAAC;IACnE;IACA,EAAE,SAAA,GAAQC,eAAAA,iBAAAA,CAAiB,QAAA,GAAOC,eAAAA,oBAAAA,CAAoB,OAAO,IAAI,CAAC,CAAC;IACnE;GACF;GACA,KAAK,sBAAsB;IACzB,MAAM,QAAA,GAAOM,eAAAA,gBAAAA,CAAgB,KAAK,KAAK;IACvC,IAAI;IACJ,IAAI;KACF,QAAA,GAAOC,eAAAA,YAAAA,CAAY,UAAU,OAAO;MAClC,WAAW;MACX,eAAe,UAAU,iBAAiB;KAC5C,CAAC;IACH,SAAS,OAAO;KACd,IAAI,iBAAiBC,eAAAA,kBAAkB,OAAO,MAAM,SAAS,IAAI,aAAa;KAC9E,MAAM;IACR;IACA,EAAE,QAAQ,IAAI;IACd;GACF;GACA,SACE,OAAO,sBAAuB,UAA+B,KAAK,IAAI,IAAI,gBAAgB;EAC9F;CACF;;CAGA,MAAM,iBAAiB,IAAY,eAAwD;EACzF,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,QAAQ,MAAM,SAAS,IAAI,EAAE,KAAK,MAAM,MAAM,IAAI,EAAE;EAC1D,IAAI,CAAC,OAAO,OAAO,4BAA4B,GAAG,IAAI,IAAI,iBAAiB;EAC3E,MAAM,OAA+B,EAAE,GAAG,MAAM,iBAAiB;EACjE,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,GAClD,IAAI,UAAU,MAAM,OAAO,KAAK;OAC3B,IAAI,OAAO,UAAU,UAAU,KAAK,OAAO;OAC3C,OAAO,iBAAiB,IAAI,6BAA6B,IAAI,eAAe;EAInF,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,KAAK,MAAM,qBAAqB,KAAA,GAAW;EAC5E,MAAM,mBAAqC;EAC3C,IAAI,MAAM,SAAS,IAAI,EAAE,GAAG,EAAE,cAAc,IAAI,EAAE,iBAAiB,CAAC;OAC/D,EAAE,WAAW,IAAI,EAAE,iBAAiB,CAAC;CAC5C;;;;;CAMA,MAAM,aAAa,IAAY,QAAgB,WAAyB;EACtE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,MAAM,OAAO,MAAM,MAAM,IAAI,EAAE,KAAK,OAAO,iBAAiB,GAAG,IAAI,IAAI,iBAAiB;EACxF,IAAI,KAAK,WAAW,UAAU,KAAK,WAAW,QAAQ;EACtD,MAAM,aAAa,KAAK,MAAM,IAAI,KAAK,IAAI;EAC3C,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK;EAClC,OAAO,OAAO,EAAE;EAChB,MAAM,UAAU,UAAU,OAAO,MAAM;EACvC,IAAI;EACJ,IAAI,YAAY,aAAa,cAAc;GAEzC,MAAM,mBAAmB,MAAM,SAAS,IAAI,KAAK,MAAM,CAAC,EAAE,eAAe;GACzE,MAAM,aAAa,mBAAmB,KAAK,SAAS,KAAK;GACzD,KAAK,mBAAmB,SAAS,YAAY,YAC3C,OAAO,wCAAwC,IAAI,mBAAmB;GAExE,MAAM,QAAA,GAAOC,eAAAA,eAAAA,CAAe,OAAO,UAAU;GAC7C,MAAM,WAAW,mBAAmB,SAAS,KAAK;GAClD,MAAM,WAAW,mBAAmB,KAAK,WAAW;GACpD,IAAI,aAAa,KAAA,KAAa,aAAa,KAAA,GACzC,OAAO,gCAAgC,IAAI,mBAAmB;GAEhE,SAAA,GAAQN,eAAAA,QAAAA,CAAQ,SAAS,UAAU,UAAU,KAAK,IAAI;GACtD,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;IAAE,QAAQ;IAAU,QAAQ;GAAS,CAAC;EAC1E,OAAO;GAEL,IAAI,YAAY,SAAS,SAAS,WAAW,KAAK,QAChD,OAAO,6CAA6C,IAAI,YAAY;GAEtE,IAAI,YAAY,SAAS,SAAS,WAAW,KAAK,QACnC;QAAA,CAAC,GAAG,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,QACpC,MAAM,EAAE,WAAW,KAAK,UAAU,EAAE,SAAS,KAAK,IAE9C,CAAC,CAAC,WAAW,GAClB,OAAO,sDAAsD,IAAI,YAAY;GAAA;GAGjF,SAAA,GAAQA,eAAAA,QAAAA,CAAQ,SAAS,QAAQ,QAAQ,KAAK,IAAI;GAClD,IAAI,CAAC,MAAM,IAAI,YAAY,OAAO;IAAE;IAAQ;GAAO,CAAC;EACtD;EACA,EAAE,QAAQ,UAAU,OAAO,IAAI,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI;GAAE,GAAG;GAAM;GAAQ;EAAO,CAAC,CAAC,CAAC;CACvF;CAEA,MAAM,gBAAgB,cAA4D;EAChF,MAAM,SAAS,EAAE,SAAS;EAC1B,MAAM,WAA6B,CAAC;EACpC,EAAE,kBAAkB;GAClB,MAAM,WAAW,QAAQ;GACzB,MAAM,UAAU,QAAQ;GACxB,IAAI,CAAC,WAAW,EAAE,SAAS,MAAM,QAAQ;GACzC,MAAM,QAAQ,IAAI,KAAA,GAAIO,eAAAA,wBAAAA,CAAwB,QAAQ,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC;GAC5E,MAAM,SAAA,GAAQA,eAAAA,wBAAAA,CAAwB,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC,QAC1D,UAAU,CAAC,MAAM,IAAI,SAAS,KAAK,CAAC,CACvC;GACA,IAAI,MAAM,SAAS,GACjB,MAAM,IAAI,UACR,MAAM,KAAK,WAAW;IACpB,WAAW,MAAM;IACjB,KAAK,MAAM;IACX,UAAU;IACV,SAAS,MAAM;IACf,MAAM;GACR,EAAE,CACJ;EAEJ,CAAC;EACD,OAAO;GACL,IAAI;GACJ,YAAY,WAAW,QAAQ,EAAE,SAAS,CAAC;GAC3C,GAAI,SAAS,SAAS,IAAI,EAAE,aAAa,SAAS,IAAI,CAAC;EACzD;CACF;CAKA,MAAM,aAAa,WAA0D;EAC3E,MAAM,EAAE,UAAU,iBAAiB,QAAQ,iBAAiB,WAAW;EACvE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,OAAO,OAAO,KAAK;EACzB,MAAM,UAAU,WAA6C;GAC3D,MAAM;GACN,YAAY,OAAO;GACnB,SAAS,MAAM;GACf;GACA,iBAAiB;GACjB,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,OAAO;GAC1D,GAAI,MAAM,KAAK,CAAC,IAAI;IAAE,QAAQ,MAAM;IAAQ,MAAM,MAAM;GAAK;EAC/D;EACA,IAAI,WAAW,KAAA,GAAW;GACxB,MAAM,SAAA,GAAQP,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,QAAQ;GAErD,IAAI,CAAC,MAAM,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,EAAE,KAAK,uBAAuB;IACrE,MAAM,YAAA,GAAWA,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,QAAQ;IACxD,IAAI,SAAS,IAAI,OAAO,OAAO,QAAQ;GACzC;GACA,OAAO,OAAO,KAAK;EACrB;EAEA,MAAM,UAAU,MAAM,SAAS,IAAI,MAAM;EACzC,IAAI,CAAC,SACH,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,2BAA2B,OAAO;EAC5C,CAAC;EAEH,MAAM,OAAO,aAAa,IAAI,CAAC,CAAC,UAAU,MAAM,MAAM,EAAE,kBAAkB,QAAQ;EAClF,IAAI,CAAC,MACH,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,sBAAsB,SAAS;EACzC,CAAC;EAEH,IAAI,KAAK,wBAAwB,CAAC,KAAK,qBAAqB,SAAS,QAAQ,IAAI,GAC/E,OAAO,OAAO;GACZ,IAAI;GACJ,MAAM;GACN,QAAQ,KAAK,KAAK,SAAS,IAAI,QAAQ,IAAI,CAAC,EAAE,SAAS,QAAQ,KAAK,6BAA6B,KAAK,MAAM,IAAI,QAAQ,CAAC,EAAE,SAAS,SAAS;EAC/I,CAAC;EAEH,OAAO,OAAO,EAAE,IAAI,KAAK,CAAC;CAC5B;CAEA,MAAM,WAAW,WAAmD;EAClE,MAAM,QAAQ,EAAE,SAAS;EACzB,MAAM,cAAgC,qBAAqB,KAAK;EAChE,IAAI,QAAQ,SACV,KAAK,MAAM,UAAA,GAASO,eAAAA,wBAAAA,CAAwB,OAAO,QAAQ,OAAO,GAChE,YAAY,KAAK;GACf,WAAW,MAAM;GACjB,KAAK,MAAM;GACX,UAAU;GACV,SAAS,MAAM;GACf,MAAM;EACR,CAAC;EAGL,YAAY,KAAK,GAAI,QAAQ,cAAc,KAAK,CAAC,CAAE;EACnD,MAAM,MAAM,OAAO,YAAY,QAAQ,OAAO,MAAM,SAAS,IAAI,EAAE,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC;EAC3F,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,OAAO;GACL,MAAM;GACN,YAAY,OAAO;GACnB,SAAS,YACN,QAAQ,MAAM,OAAO,SAAS,KAAK,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,CAC3D,IAAI,kBAAkB;GACzB,GAAI,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,OAAO,OAAO;EACjE;CACF;CAEA,MAAM,WAAW,WAAwC;EACvD,MAAM,QAAQ,EAAE,SAAS;EACzB,QAAQ,OAAO,MAAf;GACE,KAAK,gBACH,OAAO;IAAE,MAAM;IAAY,YAAY,OAAO;IAAW,UAAA,GAASR,eAAAA,eAAAA,CAAe,KAAK;GAAE;GAC1F,KAAK,oBACH,OAAO;IACL,MAAM;IACN,YAAY,OAAO;IACnB,GAAG,aAAa,OAAO,KAAK,CAAC;GAC/B;GACF,KAAK,oBACH,OAAO,UAAU,MAAM;GACzB,KAAK,yBAAyB;IAC5B,MAAM,OAAO,OAAO,KAAK;IACzB,OAAO;KACL,MAAM;KACN,YAAY,OAAO;KACnB,GAAG,kBAAkB,eAAe,IAAI,GAAG,IAAI;IACjD;GACF;GACA,KAAK,kBACH,OAAO,QAAQ,MAAM;GACvB,SACE;EACJ;CACF;CAIA,MAAM,MAAM,OACV,QACA,WACmC;EACnC,IAAI,YAAY,MAAM,GAAG,OAAO,aAAa,MAAM;EACnD,IAAI,gBAAgB,MAAM,GAAG,OAAO;GAAE,IAAI;GAAM,YAAY,CAAC;GAAG,UAAU,QAAQ,MAAM;EAAE;EAC1F,QAAQ,OAAO,MAAf;GACE,KAAK;IACH,EAAE,KAAK;IACP,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,KAAK;IACH,EAAE,KAAK;IACP,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,KAAK,aAAa;IAChB,IAAI,CAAC,QAAQ,MAAM,OAAO,kCAAkC,IAAI,iBAAiB;IACjF,MAAM,QAAQ,EAAE,SAAS;IACzB,MAAM,QAAQ,MAAA,GAAKA,eAAAA,eAAAA,CAAe,OAAO,EAAE,0BAAU,IAAI,KAAK,EAAE,CAAC,GAAG,MAAM;IAC1E,QAAQ;IACR,YAAY,QAAQ,MAAM;IAC1B,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC;GACA,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,MAAM;IACX,OAAO;KAAE,IAAI;KAAM,YAAY,CAAC;IAAE;GACpC,SACE,OAAO,OACL,IAAI,OAAO,KAAK,6CAChB,IACA,gBACF;EACJ;CACF;CAEA,OAAO;EACL,MAAM,SAAS,QAAQ,iBAAiB;GACtC,MAAM,SAAS,iBAAiB;GAKhC,gBAAgB;GAChB,IAAI;GACJ,IAAI;IACF,UAAU,IAAI,QAAuC,MAAM;GAC7D,UAAU;IACR,gBAAgB,KAAA;GAClB;GACA,IAAI;IACF,OAAQ,MAAM;GAChB,SAAS,OAAO;IACd,IAAI,iBAAiB,WAAW,OAAO;KAAE,IAAI;KAAO,aAAa,MAAM;IAAY;IACnF,IAAI,iBAAiBS,eAAAA,qBACnB,OAAO;KAAE,IAAI;KAAO,aAAa,CAAC,MAAM,aAAa,CAAC;IAAE;IAE1D,MAAM;GACR;EACF;EACA,UAAU,UAAU;GAClB,MAAM,IAAI;GACV,UAAU,IAAI,CAAC;GACf,aAAa,UAAU,OAAO,CAAC;EACjC;EACA,eAAe,EAAE,SAAS,MAAM;EAChC,SAAS;CACX;AACF;;;;AC/1BA,SAAgB,mBACd,YACA,MACkC;CAClC,OAAO;EACL,WAAW,WACT,gBAAgB,MAAM,IAClB,WAAW,SAAS,MAAM,IAC1B,QAAQ,QAAQ;GACd,IAAI;GACJ,aAAa,CACX;IACE,WAAW;IACX,UAAU;IACV,MAAM;IACN,SAAS,IAAI,KAAK,qCAAqC,OAAO;GAChE,CACF;EACF,CAAwB;EAC9B,YAAY,aAAa,WAAW,UAAU,QAAQ;CACxD;AACF;;AAGA,SAAgB,gBACd,MACA,YACA,UACA,QACiB;CACjB,OAAO;EACL;EACA,YAAY,KAAK,WAAW,mBAAmB,YAAY,KAAK,IAAI,IAAI;EACxE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;CAC7B;AACF;;AAGA,SAAgB,YAAY,UAA+B,OAAuC;CAChG,MAAM,EAAE,SAAS;CACjB,OAAO,QAAQ,QAAQ,OAAO,SAAS,WAAW,OAAO,KAAK,KAAK,CAAC;AACtE;;;;;;;;;;;;;AC3DA,SAAS,aACP,MACA,QACiD;CACjD,MAAM,UAAU,OAAO,IAAI,IAAI;CAC/B,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,OAAO,KAAA;CAC7C,MAAM,aAAyC,CAAC;CAChD,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,KAAK,GACpD,WAAW,KAAK;EACd;EACA,MAAM,MAAM;EACZ,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;EAC/C,GAAI,MAAM,QAAQ,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;EACnD,GAAI,MAAM,QAAQ,cAAc,EAAE,aAAa,MAAM,QAAQ,YAAY,IAAI,CAAC;CAChF,CAAC;CAGL,OAAO;AACT;;;;;;;AAQA,SAAgB,iBACd,WACA,UAAmC,CAAC,GAClB;CAClB,MAAM,gCAAgB,IAAI,IAAqD;CAC/E,KAAK,MAAM,UAAU,QAAQ,WAAW,CAAC,GAAG;EAC1C,MAAM,OAAO,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC;EAChD,KAAK,KAAK,MAAM;EAChB,cAAc,IAAI,OAAO,MAAM,IAAI;CACrC;CAEA,MAAM,WAAsC,CAAC;CAC7C,KAAK,MAAM,cAAc,UAAU,SAAS,OAAO,GAAG;EACpD,IAAI,MAAM,UAAU,GAAG;EACvB,SAAS,KAAK;GACZ,MAAM,WAAW;GACjB,OAAO,WAAW;GAClB,GAAI,WAAW,gBAAgB,KAAA,IAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;GACtF,UAAU,WAAW;GACrB,GAAI,WAAW,OACX;IACE,cAAc,WAAW,KAAK;IAC9B,mBAAmB,WAAW,KAAK;GACrC,IACA,CAAC;GACL,GAAI,aAAa,WAAW,MAAM,aAAa,IAC3C,EAAE,YAAY,aAAa,WAAW,MAAM,aAAa,EAAE,IAC3D,CAAC;EACP,CAAC;CACH;CAEA,MAAM,QAAgC,CAAC;CACvC,KAAK,MAAM,cAAc,UAAU,MAAM,OAAO,GAAG;EACjD,IAAI,WAAW,SAAS,KAAA,GAAW;EACnC,MAAM,QAAQ,UAAU,MAAM,KAAA,GAAIC,eAAAA,kBAAAA,CAAkB,WAAW,WAAW,IAAI,CAAC,CAAC,EAAE;EAClF,MAAM,UACJ,WAAW,aAAa,eACpB,WAAW,SAAS,IACpB,WAAW,WAAW,WAAW,QAA4B;EACnE,MAAM,KAAK;GACT,MAAM,WAAW;GACjB,OAAO,WAAW;GAClB,GAAI,WAAW,gBAAgB,KAAA,IAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;GACtF,UAAU,WAAW;GACrB,SAAS,QAAQ,MAAM,WAAW,MAAM,OAAO,IAAI;GACnD,SAAS,QAAQ,MAAM,WAAW,MAAM,OAAO,IAAI;GACnD,GAAI,WAAW,UAAU,MAAM,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;GAC9D,GAAI,WAAW,KAAK,iBAAiB,EAAE,QAAQ,WAAW,KAAK,eAAe,IAAI,CAAC;GACnF,GAAI,aAAa,WAAW,MAAM,aAAa,IAC3C,EAAE,YAAY,aAAa,WAAW,MAAM,aAAa,EAAE,IAC3D,CAAC;EACP,CAAC;CACH;CAEA,OAAO;EAAE,WAAW,UAAU;EAAW;EAAU;CAAM;AAC3D;AAEA,SAAS,eAAe,YAAuE;CAC7F,IAAI,CAAC,cAAc,WAAW,WAAW,GAAG,OAAO,CAAC;CAKpD,OAAO,CAAC,iBAJM,WAAW,KAAK,MAAM;EAClC,MAAM,OAAO,CAAC,EAAE,MAAM,GAAI,EAAE,SAAS,CAAC,WAAW,EAAE,OAAO,KAAK,GAAG,GAAG,IAAI,CAAC,CAAE;EAC5E,OAAO,GAAG,EAAE,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,WAAW,MAAM;CAC5D,CAC6B,CAAC,CAAC,KAAK,IAAI,GAAG;AAC7C;AAEA,SAAS,MAAM,SAA0C;CACvD,MAAM,OAAiB,CAAC;CACxB,IAAI,QAAQ,cAAc,KAAK,KAAK,UAAU;CAC9C,IAAI,QAAQ,mBAAmB,KAAK,KAAK,OAAO;CAChD,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE,KAAK;AACrD;AAEA,SAAS,YAAY,SAA4C;CAC/D,MAAM,cAAc,QAAQ,cAAc,MAAM,QAAQ,gBAAgB;CACxE,OAAO,CACL,KAAK,QAAQ,KAAK,IAAI,QAAQ,MAAM,GAAG,MAAM,OAAO,IAAI,eACxD,GAAG,eAAe,QAAQ,UAAU,CACtC;AACF;AAEA,SAAS,SAAS,MAAsC;CACtD,MAAM,QAAQ,KAAK,UAAU,MAAM,wBAAwB;CAC3D,MAAM,SAAS,KAAK,SAAS,aAAa,KAAK,OAAO,KAAK,IAAI,MAAM;CACrE,MAAM,cAAc,KAAK,cAAc,MAAM,KAAK,gBAAgB;CAClE,OAAO,CACL,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,GAAG,MAAM,IAAI,KAAK,SAAS,SACpD,KAAK,QAAQ,KAAK,IAAI,EAAE,KAAK,KAAK,QAAQ,KAAK,IAAI,IAAI,SAAS,eACrE,GAAG,eAAe,KAAK,UAAU,CACnC;AACF;;;;;AAMA,SAAgB,qBAAqB,SAAmC;CACtE,MAAM,SAAS,QAAQ,SAAS,QAAQ,MAAM,EAAE,aAAa,OAAO;CACpE,MAAM,QAAQ,QAAQ,SAAS,QAAQ,MAAM,EAAE,aAAa,MAAM;CAClE,MAAM,WAAW,CAAC,KAAK,QAAQ,UAAU,WAAW;CACpD,IAAI,OAAO,SAAS,GAClB,SAAS,KAAK,CAAC,kBAAkB,GAAG,OAAO,QAAQ,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAE7E,IAAI,MAAM,SAAS,GACjB,SAAS,KAAK,CAAC,iBAAiB,GAAG,MAAM,QAAQ,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAE3E,IAAI,QAAQ,MAAM,SAAS,GACzB,SAAS,KAAK,CAAC,iBAAiB,GAAG,QAAQ,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAEhF,OAAO,SAAS,KAAK,MAAM;AAC7B;;;;;;AAOA,SAAgB,yBACd,UAAmC,CAAC,GACf;CACrB,OAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO,UACL,qBAAqB,kBAAA,GAAiBC,eAAAA,YAAAA,CAAY,KAAK,GAAmB,OAAO,CAAC;CACtF;AACF;;;;;;;;;;;;;;;;;ACpHA,SAAS,MAAM,GAAY,GAAqB;CAC9C,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,MAAM,OAAO;CACvF,IAAI,MAAM,QAAQ,CAAC,MAAM,MAAM,QAAQ,CAAC,GAAG,OAAO;CAClD,MAAM,KAAK,OAAO,KAAK,CAAC;CACxB,MAAM,KAAK,OAAO,KAAK,CAAC;CACxB,IAAI,GAAG,WAAW,GAAG,QAAQ,OAAO;CACpC,KAAK,MAAM,OAAO,IAChB,IAAI,CAAC,MAAO,EAA8B,MAAO,EAA8B,IAAI,GACjF,OAAO;CAGX,OAAO;AACT;;;;;AAMA,SAAS,MAAM,UAAyB,MAAoC;CAC1E,IAAI,OACF,SAAS,SAAS,SAAS,KAAK,SAAS,QACzC,SAAS,MAAM,SAAS,KAAK,MAAM,SAAA,GACnCC,eAAAA,YAAAA,CAAY,QAAQ,OAAA,GAAMA,eAAAA,YAAAA,CAAY,IAAI;CAC5C,MAAM,YACJ,MACA,OACmB;EACnB,MAAM,QAAQ,KAAK,KAAK;EACxB,MAAM,sBAAM,IAAI,IAAe;EAC/B,KAAK,MAAM,CAAC,IAAI,UAAU,IAAI;GAC5B,MAAM,MAAM,KAAK,IAAI,EAAE;GACvB,MAAM,OAAO,QAAQ,KAAA,KAAa,MAAM,KAAK,KAAK;GAClD,IAAI,CAAC,QAAQ,MAAM,KAAK,CAAC,CAAC,UAAU,IAAI,OAAO;GAC/C,IAAI,IAAI,IAAI,OAAO,MAAM,KAAK;EAChC;EACA,OAAO;CACT;CACA,MAAM,WAAW,SAAS,SAAS,UAAU,KAAK,QAAQ;CAC1D,MAAM,QAAQ,SAAS,SAAS,OAAO,KAAK,KAAK;CACjD,MAAM,UAAU,MAAM,SAAS,SAAS,KAAK,OAAO,IAAI,SAAS,UAAU,KAAK;CAChF,MAAM,EAAE,UAAU,IAAI,OAAO,IAAI,SAAS,IAAI,GAAG,SAAS;CAC1D,MAAM,EAAE,UAAU,KAAK,OAAO,KAAK,SAAS,KAAK,GAAG,iBAAiB;CACrE,IAAI,QAAQ,MAAM,MAAM,YAAY,GAAG,OAAO;CAC9C,MAAM,SAAwB;EAC5B,GAAG;EACH;EACA;EACA,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;CAC7C;CACA,QAAA,GAAOC,eAAAA,iBAAAA,CAAiB,OAAA,GAAMC,eAAAA,oBAAAA,CAAoB,MAAM,MAAM,CAAC;AACjE;AAEA,SAAS,WAAkB;CACzB,MAAM,IAAIC,eAAAA,oBACR,8EACF;AACF;AAEA,MAAM,YAAYC,eAAAA;;;;;;;;;AAalB,SAAgB,kBACd,QACA,UAAsC,CAAC,GAClB;CACrB,MAAM,IAAI;CACV,MAAM,YAAY,QAAQ;CAC1B,MAAM,eAAe,QAAQ;CAG7B,MAAM,QAAQ,QAAQ,gBAAgB;CACtC,MAAM,UAAU,QAAQ,kBAAkB,CAAC;CAC3C,MAAM,4BAAY,IAAI,IAAmC;CACzD,MAAM,aAAa,SAAoC;EACrD,MAAM,OAAO,eAAe,aAAa,IAAI,IAAI;EACjD,OAAO,UAAU,MAAM;GACrB,GAAI,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;GAClC,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;EACzD,CAAC;CACH;CACA,MAAM,UAAU,QAAQ;CAOxB,IAAI,SALF,YAAY,KAAA,IACR,KAAA,IACA,QAAQ,oBAAoB,MACzB,UACD,UAAU,OAAqB,OAGpC,aAAA,GACGC,eAAAA,iBAAAA,CAAiB,KAAA,GAAW,EAAE,UAAU,CAAC,KAAA,GACxCA,eAAAA,iBAAAA,CAAiB;;CAExB,IAAI;CACJ,IAAI,YAAY;CAChB,IAAI,YAAY;;CAEhB,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI,OAAsB,QAAQ,QAAQ;CAC1C,IAAI,WAAW;CAEf,MAAM,SAAS,SAAoC;EACjD,MAAM,YAAY,KAAK,UAAW,KAAiCC,eAAAA,uBAAuB,IAAI;EAC9F,MAAM,OAAO,eAAe,IAAI;EAChC,IAAI,cAAc,UAAU,CAAC,gBAAgB,UAAA,GAASN,eAAAA,YAAAA,CAAY,KAAK,IAIrE,QAAA,GAAOC,eAAAA,iBAAAA,CAAiB,OAAO,UAAU,MAAM,EAAE,YAAA,GAAWD,eAAAA,YAAAA,CAAY,KAAK,EAAE,CAAC,CAAC;EAEnF,MAAM,SAAS,UAAU,IAAI;EAC7B,QAAQ;EACR,OAAO;CACT;CAEA,MAAM,SAAS,MAAkB,QAAgB,YAA0C;EACzF,MAAM,WAAW;EACjB,MAAM,OAAO,MAAM,UAAU,MAAM,IAAI,CAAC;EACxC,IAAI,SAAS,UAAU;EACvB,QAAQ;EACR,MAAM,QAA0C;GAAE;GAAO;GAAU;GAAS;EAAO;EACnF,KAAK,MAAM,YAAY,WAAW,SAAS,KAAK;CAClD;;CAGA,MAAM,SACJ,QACA,UACS;EACT,IAAI,OAAO;GACT,YAAY,MAAM,UAAU,IAAI;GAChC,YAAY,MAAM,UAAU,IAAI;EAClC,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,KAAK;GACzC,YAAY;EACd,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,CAAC;GACrC;EACF,OAAO,IAAI,WAAW,QAAQ;GAC5B,YAAY,KAAK,IAAI,YAAY,GAAG,KAAK;GACzC,YAAY,KAAK,IAAI,YAAY,GAAG,CAAC;EACvC,OAAO;GACL,YAAY;GACZ,YAAY;EACd;CACF;;;;;CAMA,MAAM,WAAW,QAAgB,YAAmD;EAClF,MAAM,OAAO;EACb,MAAM,OAAO,EACV,SAAS;GAAE,MAAM;GAAgB,WAAW,UAAU,EAAE;EAAW,CAAC,CAAC,CACrE,MAAM,YAA4D,EAAE,OAAO,EAAE,CAAC,CAC9E,OAAO,WAAoB,EAAE,MAAM,EAAE;EACxC,MAAM,OAAO,KAAK,KAAK,YAAY;GACjC,MAAM,SAAS,MAAM;GACrB,IAAI,YAAY,WAAW,MAAM;GACjC,IAAI,WAAW,QAAQ,MAAM,OAAO;GACpC,MAAM,EAAE,WAAW;GACnB,IAAI,CAAC,OAAO,IACV,MAAM,IAAI,MAAM,OAAO,YAAY,EAAE,EAAE,WAAW,2BAA2B;GAE/E,IAAI,CAAC,OAAO,UAAU,MAAM,IAAI,MAAM,2CAA2C;GACjF,MAAM,OAAO,SAAS,SAAS,QAAQ,OAAO;EAChD,CAAC;EACD,OAAO,KAAK,MAAM,OAAO;EACzB,OAAO;CACT;CAEA,MAAM,cAAc,EAAE,WAAW,WAAW;EAC1C,IAAI,YAAY,OAAO,SAAS,sBAAsB;EACtD,MACE,OAAO,QACP,OAAO,YAAY,KAAA,KAAa,OAAO,YAAY,KAAA,IAC/C;GAAE,SAAS,OAAO;GAAS,SAAS,OAAO;EAAQ,IACnD,KAAA,CACN;EACA,IAAI,OAAO,SAAS;GAClB;GACA,IAAI;IACF,MAAM,OAAO,SAAS,OAAO,QAAQ,OAAO,OAAO;GACrD,SAAS,OAAO;IACd,QAAQ,KAAK;GACf;EACF,OACE,QAAa,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;CAE9D,CAAC;CAED,MAAM,QAAQ,QAAQ,QAAQ,CAAC,CAAC;CAEhC,MAAM,YAAY,CAAC,CAAC;CAEpB,MAAM,QAAQ,SAAwC;EACpD,EAAO,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO;CACzC;CA2DA,OAAO;EA/CL;EACA,YAAA;GAVA,MAAM,SAAS,QAAQ,SAAS;IAC9B,MAAM,SAAS,MAAM,EAAE,SAAS,QAAQ,OAAO;IAC/C,MAAM;IACN,OAAO;GACT;GACA,YAAY,aAAa,EAAE,UAAU,QAAQ;EAKpC;EACT,cAAc;EACd,UAAU;GACR,WAAW;GACX,YAAY;EACd;EAEA,gBAAgB;EAChB,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;EACA,UAAU,QAAQ,QAAQ,UAAA,GAASO,eAAAA,QAAAA,CAAQ,OAAO,QAAQ,QAAQ,IAAI;EAEtE,YAAY;EACZ,eAAe;EACf,aAAa;EACb,aAAa;EACb,eAAe;EACf,gBAAgB;EAChB,cAAc;EACd,SAAS;EACT,eAAe;EACf,QAAQ;EACR,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,eAAe;EACf,SAAS;EACT,MAAM;EACN,aAAa;EACb,cAAc;EAEd,OAAO;GACL,IAAI,cAAc,GAAG,OAAO;GAC5B,KAAK,UAAU;GACf,OAAO;EACT;EACA,OAAO;GACL,IAAI,cAAc,GAAG,OAAO;GAC5B,KAAK,UAAU;GACf,OAAO;EACT;EACA,eAAe,YAAY;EAC3B,eAAe,YAAY;CAElB;AACb;;;AChWA,MAAM,kBAAkB;AAyDxB,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,YAAY,OAAoC;CACvD,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACvD;AAEA,SAAS,aAAa,IAAe,MAAc,SAA+B;CAChF,OAAO;EAAE,SAAS;EAAiB;EAAI,OAAO;GAAE;GAAM;EAAQ;CAAE;AAClE;;;;;;;;AASA,SAAgB,kBAId,MAA0B,YAAkD;CAC5E,MAAM,cAAc,WAAW,WAAW,WAAW;EACnD,KAAK,YAAY;GAAE,SAAS;GAAiB,QAAQ,OAAO;GAAM,QAAQ;EAAO,CAAC;CACpF,CAAC;CAED,KAAK,aAAa,OAAU;EAC1B,MAAM,UAAU,GAAG;EACnB,IAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,YAAY,iBAAiB;EAC/D,MAAM,EAAE,IAAI,QAAQ,QAAQ,WAAW;EACvC,MAAM,QAAQ,YAAY,EAAE;EAC5B,MAAM,kBACJ,OAAO,WAAW,WAAW,EAAE,OAAO,IAAI,KAAA;EAE5C,IAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;GACrD,IAAI,OAAO,KAAK,YAAY,aAAa,IAAI,QAAQ,kBAAkB,CAAC;GACxE;EACF;EACA,IAAI,CAAC,SAAS,MAAM,KAAK,OAAO,SAAS,QAAQ;GAC/C,IAAI,OAAO,KAAK,YAAY,aAAa,IAAI,QAAQ,iBAAiB,CAAC;GACvE;EACF;EAEA,MAAM,SAAS;EACf,IAAI,CAAC,OAAO;GAEV,WAAgB,SAAS,QAAQ,eAAe;GAChD;EACF;EACA,WAAW,SAAS,QAAQ,eAAe,CAAC,CAAC,MAC1C,WAAkC;GACjC,KAAK,YAAY;IAAE,SAAS;IAAiB;IAAI;GAAO,CAAC;EAC3D,IACC,UAAmB;GAClB,MAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU;GACtD,KAAK,YAAY,aAAa,IAAI,QAAQ,IAAI,CAAC;EACjD,CACF;CACF;CAEA,aAAa;EACX,YAAY;EACZ,KAAK,YAAY;CACnB;AACF;;;;;;;AAQA,SAAgB,uBAId,MAAoD;CACpD,IAAI,SAAS;CACb,MAAM,0BAAU,IAAI,IAGlB;CACF,MAAM,4BAAY,IAAI,IAA4B;CAElD,KAAK,aAAa,OAAU;EAC1B,MAAM,UAAU,GAAG;EACnB,IAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,YAAY,iBAAiB;EAC/D,MAAM,EAAE,IAAI,QAAQ,QAAQ,QAAQ,UAAU;EAE9C,IAAI,YAAY,EAAE,GAAG;GACnB,MAAM,UAAU,QAAQ,IAAI,EAAE;GAC9B,IAAI,CAAC,SAAS;GACd,QAAQ,OAAO,EAAE;GACjB,IAAI,SAAS,KAAK,GAChB,QAAQ,uBAAO,IAAI,MAAM,kBAAkB,OAAO,MAAM,IAAI,EAAE,IAAI,OAAO,MAAM,OAAO,GAAG,CAAC;QAE1F,QAAQ,QAAQ,MAA+B;GAEjD;EACF;EAEA,IAAI,OAAO,WAAW,YAAY,SAAS,MAAM,GAAG;GAClD,MAAM,SAAS;GACf,KAAK,MAAM,YAAY,WAAW,SAAS,MAAM;EACnD;CACF;CAEA,OAAO;EACL,SAAS,QAAQ,iBAAiB;GAChC,MAAM,KAAK;GACX,OAAO,IAAI,SAAS,SAAS,WAAW;IACtC,QAAQ,IAAI,IAAI;KAAW;KAAoD;IAAO,CAAC;IACvF,KAAK,YAAY;KACf,SAAS;KACT;KACA,QAAQ,OAAO;KACf,QAAQ;KACR,GAAI,iBAAiB,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,gBAAgB,OAAO;IACpF,CAAC;GACH,CAAC;EACH;EACA,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,aAAa,UAAU,OAAO,QAAQ;EACxC;CACF;AACF;;;;;;;;;;AAWA,SAAgB,eACd,YAC+B;CAC/B,MAAM,MAAM,WAAW;CACvB,IAAI,OAAO,QAAQ,YAAY;EAC7B,IAAI,OAAO,WAAW,YAAY,YAChC,OAAO;EACT,OAAO;GACL,WAAW,QAAQ,YAAY,WAAW,SAAS,QAAQ,OAAO;GAClE,YAAY,aAAa,WAAW,UAAU,QAAQ;GACtD,eAAe,IAAI,KAAK,UAAU;GAClC,eAAe,KAAA;EACjB;CACF;CACA,IAAI,QAAQ;CACZ,MAAM,cAAc,WAAW,WAAW,WAAW;EACnD,IAAI,OAAO,SAAS,iBAAiB,QAAQ,OAAO;CACtD,CAAC;CACD,OAAO;EACL,WAAW,QAAQ,YAAY,WAAW,SAAS,QAAQ,OAAO;EAClE,YAAY,aAAa,WAAW,UAAU,QAAQ;EACtD,eAAe;EACf,eAAe;GACb,YAAY;EACd;CACF;AACF;;;;ACjPA,MAAa,2BAAmC"}