@istar-ts/core 0.14.2 → 0.15.0-beta.0

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":["fail","isActorIn","ops.defaultIdGenerator","ops.addElement","ops.updateElement","ops.moveElement","ops.nestElement","ops.removeElement","ops.removeElements","ops.connect","ops.addLeg","ops.removeLeg","ops.addDependency","ops.updateLink","ops.disconnect","ops.updateDiagram","ops.ModelOperationError"],"sources":["../src/metamodel.ts","../src/metamodels.ts","../src/shared.ts","../src/model.ts","../src/constraints.ts","../src/file-metamodel.ts","../src/serialization.ts","../src/operations.ts","../src/store.ts","../src/properties.ts","../src/diagnostics.ts"],"sourcesContent":["/**\n * The iStar 2.0 metamodel, ported from piStar's `tool/language/metamodel.js`.\n *\n * Kind names carry the `istar.` prefix exactly as they appear in piStar save files.\n */\n\nexport const ISTAR_PREFIX = 'istar';\nexport const METAMODEL_VERSION = '0.2';\n\n/** Containers: elements that hold inner elements (piStar `metamodel.containers`). */\nexport const ACTOR_KINDS = ['istar.Actor', 'istar.Agent', 'istar.Role'] as const;\nexport type ActorKind = (typeof ACTOR_KINDS)[number];\n\n/** Intentional elements (piStar `metamodel.nodes`). */\nexport const NODE_KINDS = ['istar.Goal', 'istar.Quality', 'istar.Resource', 'istar.Task'] as const;\nexport type NodeKind = (typeof NODE_KINDS)[number];\n\nexport type ElementKind = ActorKind | NodeKind;\nexport const ELEMENT_KINDS: readonly ElementKind[] = [...ACTOR_KINDS, ...NODE_KINDS];\n\n/** Links between two containers (piStar `metamodel.containerLinks`). */\nexport const ACTOR_LINK_KINDS = ['istar.IsALink', 'istar.ParticipatesInLink'] as const;\nexport type ActorLinkKind = (typeof ACTOR_LINK_KINDS)[number];\n\n/** Links that connect two containers through a dependum (piStar `metamodel.dependencyLinks`). */\nexport const DEPENDENCY_LINK_KINDS = ['istar.DependencyLink'] as const;\nexport type DependencyLinkKind = (typeof DEPENDENCY_LINK_KINDS)[number];\n\n/** Links between two intentional elements (piStar `metamodel.nodeLinks`). */\nexport const NODE_LINK_KINDS = [\n 'istar.AndRefinementLink',\n 'istar.OrRefinementLink',\n 'istar.NeededByLink',\n 'istar.QualificationLink',\n 'istar.ContributionLink',\n] as const;\nexport type NodeLinkKind = (typeof NODE_LINK_KINDS)[number];\n\nexport type LinkKind = ActorLinkKind | DependencyLinkKind | NodeLinkKind;\nexport const LINK_KINDS: readonly LinkKind[] = [\n ...ACTOR_LINK_KINDS,\n ...DEPENDENCY_LINK_KINDS,\n ...NODE_LINK_KINDS,\n];\n\n/** Possible values of a Contribution link's `label`. */\nexport const CONTRIBUTION_LABELS = ['make', 'help', 'hurt', 'break'] as const;\nexport type ContributionLabel = (typeof CONTRIBUTION_LABELS)[number];\n\nexport interface NodeKindInfo {\n /** Can be added inside an actor. */\n readonly canBeInnerElement: boolean;\n /** Can be the dependum of a dependency. */\n readonly canBeDependum: boolean;\n /** Can be placed directly on the diagram, outside any actor. */\n readonly canBeOnPaper: boolean;\n}\n\nexport interface LinkKindInfo {\n /** Fixed text drawn on the link (e.g. \"is-a\"). */\n readonly label?: string;\n /** piStar retries with source and target swapped when the first attempt is invalid. */\n readonly tryReversedWhenAdding?: boolean;\n /** The link carries a user-selectable label, stored as `label` in the save file. */\n readonly changeableLabel?: boolean;\n readonly possibleLabels?: readonly string[];\n}\n\nconst innerNode: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: false,\n};\n\nexport const NODE_KIND_INFO: Readonly<Record<NodeKind, NodeKindInfo>> = {\n 'istar.Goal': innerNode,\n 'istar.Quality': innerNode,\n 'istar.Resource': innerNode,\n 'istar.Task': innerNode,\n};\n\nexport const LINK_KIND_INFO: Readonly<Record<LinkKind, LinkKindInfo>> = {\n 'istar.IsALink': { label: 'is-a' },\n 'istar.ParticipatesInLink': { label: 'participates-in' },\n 'istar.DependencyLink': {},\n 'istar.AndRefinementLink': {},\n 'istar.OrRefinementLink': {},\n 'istar.NeededByLink': { tryReversedWhenAdding: true },\n 'istar.QualificationLink': { tryReversedWhenAdding: true },\n 'istar.ContributionLink': { changeableLabel: true, possibleLabels: CONTRIBUTION_LABELS },\n};\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Default sizes of each element kind, from piStar's `shapes.js`. For actors this is the\n * initial boundary size; the collapsed actor symbol is a circle of radius 40.\n */\nexport const DEFAULT_ELEMENT_SIZE: Readonly<Record<ElementKind, Size>> = {\n 'istar.Actor': { width: 200, height: 120 },\n 'istar.Agent': { width: 200, height: 120 },\n 'istar.Role': { width: 200, height: 120 },\n 'istar.Goal': { width: 90, height: 35 },\n 'istar.Quality': { width: 90, height: 55 },\n 'istar.Resource': { width: 90, height: 35 },\n 'istar.Task': { width: 95, height: 36 },\n};\n\nconst actorKinds: ReadonlySet<string> = new Set(ACTOR_KINDS);\nconst nodeKinds: ReadonlySet<string> = new Set(NODE_KINDS);\nconst elementKinds: ReadonlySet<string> = new Set(ELEMENT_KINDS);\nconst linkKinds: ReadonlySet<string> = new Set(LINK_KINDS);\nconst actorLinkKinds: ReadonlySet<string> = new Set(ACTOR_LINK_KINDS);\nconst nodeLinkKinds: ReadonlySet<string> = new Set(NODE_LINK_KINDS);\n\nexport function isActorKind(kind: string): kind is ActorKind {\n return actorKinds.has(kind);\n}\nexport function isNodeKind(kind: string): kind is NodeKind {\n return nodeKinds.has(kind);\n}\nexport function isElementKind(kind: string): kind is ElementKind {\n return elementKinds.has(kind);\n}\nexport function isLinkKind(kind: string): kind is LinkKind {\n return linkKinds.has(kind);\n}\nexport function isActorLinkKind(kind: string): kind is ActorLinkKind {\n return actorLinkKinds.has(kind);\n}\nexport function isNodeLinkKind(kind: string): kind is NodeLinkKind {\n return nodeLinkKinds.has(kind);\n}\nexport function isDependencyLinkKind(kind: string): kind is DependencyLinkKind {\n return kind === 'istar.DependencyLink';\n}\nexport function isContributionLabel(value: string): value is ContributionLabel {\n return (CONTRIBUTION_LABELS as readonly string[]).includes(value);\n}\n\n/** `'istar.Goal'` → `'Goal'` */\nexport function shortKindName(kind: ElementKind | LinkKind): string {\n return kind.slice(ISTAR_PREFIX.length + 1);\n}\n","/**\n * Metamodels as values. A root metamodel (`defineMetamodel`) is a whole modelling language:\n * iStar 2.0 (`ISTAR_2_0`) is one, and other goal languages (KAOS, NFR, …) can be others.\n * Dialects of a root are built with `extendMetamodel`, which adds element kinds (e.g.\n * iStar4RationalAgents' Planning and Plan) and link kinds.\n *\n * The constants in `metamodel.ts` (`ELEMENT_KINDS`, `NODE_KIND_INFO`, …) describe iStar 2.0 and\n * stay as they are; this module declares `ISTAR_2_0` from them. Everything that accepts a\n * metamodel defaults to `ISTAR_2_0`, so code that never mentions one behaves exactly as before.\n *\n * Extensions follow piStar-ext (Gonçalves et al., iStar 2020): a new construct has a name, a\n * node-or-link category and, for links, the kinds it may connect. Two additions make them\n * usable as a library: `behavesLike` lets a new kind reuse an existing kind's link rules\n * (Planning behaves like a Task, so it can be refined and be a dependum), and kinds are\n * namespaced (`rationalAgents.Planning`), with the root's prefix (`istar.` for iStar 2.0)\n * reserved for the root.\n */\nimport type { LinkCheck, LinkRuleContext } from './constraints';\nimport type { ElementKind, LinkKind, LinkKindInfo, NodeKindInfo, Size } from './metamodel';\nimport {\n ACTOR_KINDS,\n ACTOR_LINK_KINDS,\n DEFAULT_ELEMENT_SIZE,\n DEPENDENCY_LINK_KINDS,\n ISTAR_PREFIX,\n LINK_KIND_INFO,\n NODE_KINDS,\n NODE_KIND_INFO,\n NODE_LINK_KINDS,\n} from './metamodel';\n\nexport type ElementCategory = 'actor' | 'node';\n\n/**\n * Presentation hints a kind may carry, as data (core never draws). `@istar-ts/react` uses them as\n * the defaults for the kind: a shape as SVG path data, the label's text box, a link's line.\n */\nexport interface KindShape {\n readonly path: string;\n readonly viewBox?: string;\n /** SVG `stroke-dasharray` of the outline, e.g. `'8,4'` for a dashed shape. */\n readonly dash?: string;\n /** Outline width, when it differs from the renderer's default. */\n readonly strokeWidth?: number;\n /**\n * Default fill (any CSS colour) of the kind's elements and palette icon, when the element has\n * no `display.backgroundColor`; absent: the renderer's node fill (DSM3's KAOS is grey, its\n * NFR white).\n */\n readonly fill?: string;\n}\nexport interface KindTextBox {\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n readonly left: number;\n}\nexport interface KindLine {\n readonly dash?: string;\n readonly marker?: string | false;\n readonly markerFilled?: boolean;\n}\nexport type LinkCategory = 'actor' | 'node' | 'dependency';\n\n/** A resolved element kind of a metamodel. */\nexport interface ElementKindDefinition<K extends string = string> {\n readonly kind: K;\n readonly category: ElementCategory;\n /** Human-readable name, e.g. \"Goal\" or \"Planning\". */\n readonly label: string;\n /** Default size; for actors the initial boundary size. */\n readonly size: Size;\n /** Containment rules (nodes only; actors have none). */\n readonly info?: NodeKindInfo;\n /** The kind whose link rules this kind follows (built-in kinds have none). */\n readonly behavesLike?: string;\n /** The `type` written in piStar files. Equal to `kind` unless declared otherwise. */\n readonly pistarType: string;\n /** Name of the extension that declared it; absent for iStar 2.0 kinds. */\n readonly extension?: string;\n /** Presentation hints (drawn by `@istar-ts/react`). */\n readonly shape?: KindShape;\n readonly textBox?: KindTextBox;\n /** `hub` for the kind generated for an n-ary link kind's hubs (see `LinkKindDeclaration.arity`). */\n readonly role?: 'hub';\n /** For a hub kind: the n-ary link kind it was generated for. */\n readonly of?: string;\n}\n\n/** The kinds generated for an n-ary link kind: its hub element kind, leg and end link kinds. */\nexport interface HubLinkParts {\n readonly hub: string;\n readonly leg: string;\n readonly end: string;\n}\n\n/**\n * The kinds an n-ary link kind `K` generates under the default names: its hub element kind\n * (`<K>Hub`), its leg (`<K>Start`) and its end (`<K>End`). A schema for one of them is declared\n * like any other: `defineProperties('kaos.RefinementLinkStart', { … })`.\n */\nexport type HubPartKind<K extends string> = `${K}Hub` | `${K}Start` | `${K}End`;\n\n/**\n * Declarative link rules, as piStar-ext's \"Create a new Construct\" dialog collects them:\n * which kinds may be the source and target. Entries are kind names (`istar.Goal`,\n * `rationalAgents.Plan`) or categories (`node`, `actor`, `*`). A kind name also matches kinds\n * that behave like it, so `istar.Task` accepts a Planning that behaves like a Task.\n *\n * A link may also target another link (NFR's Argument link points at a Contribution): `targets`\n * then holds `link` (any link) or link kind names. Sources are always elements.\n */\nexport interface LinkRules {\n readonly sources: readonly string[];\n /** Element selectors as for `sources`, plus `link` and link kind names. */\n readonly targets: readonly string[];\n /**\n * Source and target must belong to the same actor (iStar 2.0 Guide, page 14). Default true\n * for node links, ignored for actor links.\n */\n readonly sameActor?: boolean;\n /** Allow a dependum as source or target. Default false. */\n readonly allowDependum?: boolean;\n /** Allow a link from an element onto itself. Default false. */\n readonly allowSelf?: boolean;\n /**\n * At most one link `'kind'` of this kind, or `'any'` link at all, between the same two\n * elements (in either direction); `false` for no limit. Default `'kind'`.\n */\n readonly unique?: 'kind' | 'any' | false;\n}\n\n/** A resolved link kind of a metamodel. */\nexport interface LinkKindDefinition<K extends string = string> {\n readonly kind: K;\n readonly category: LinkCategory;\n readonly label: string;\n readonly info: LinkKindInfo;\n /** The link kind whose rules (and meaning, for other rules) this kind takes on. */\n readonly behavesLike?: string;\n /** Declarative rules, for link kinds that don't behave like another kind. */\n readonly rules?: LinkRules;\n /** An extra predicate, checked after the inherited or declarative rules pass. */\n readonly check?: (context: LinkRuleContext) => LinkCheck;\n readonly pistarType: string;\n readonly extension?: string;\n /** Presentation hint (drawn by `@istar-ts/react`). */\n readonly line?: KindLine;\n /** `'n'` for an n-ary link kind (several sources joined at a hub); absent means 1. */\n readonly arity?: 1 | 'n';\n /** For an n-ary kind: the kinds generated for it. */\n readonly parts?: HubLinkParts;\n /** For a generated kind: `leg` (a source → the hub) or `end` (the hub → the target). */\n readonly role?: 'leg' | 'end';\n /** For a generated kind: the n-ary link kind it was generated for. */\n readonly of?: string;\n}\n\n/**\n * How a root metamodel's files look, for models that don't come from a file (`createEmptyModel`)\n * and for writing them (`toPistar`). Files that were read keep their own layout.\n */\nexport interface MetamodelFileHints {\n /** The `tool` a new model records. Default: piStar's `pistar.2.1.0`. */\n readonly tool?: string;\n /** The `istar` version a new model records; only iStar 2.0 sets it (`'2.0'`). */\n readonly istar?: string;\n /** Extra top-level keys of a new model (its `extra`), e.g. `{ metamodelVersion: '1.0' }`. */\n readonly extra?: Readonly<Record<string, unknown>>;\n /** Top-level key order for models without a source layout. Default: piStar's. */\n readonly keys?: readonly string[];\n}\n\n/** A metamodel: the element and link kinds a model may use, and their rules. */\nexport interface Metamodel<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * The root's name (`istar-2.0`), followed by the names of the extensions applied, e.g.\n * `istar-2.0+rationalAgents`.\n */\n readonly name: string;\n /** The root metamodel's name, e.g. `istar-2.0`; extensions keep it. */\n readonly framework: string;\n /** The root's namespace (`istar`). Extensions may not declare kinds in it. */\n readonly prefix: string;\n /** How the root's files look (see `MetamodelFileHints`); extensions keep it. */\n readonly file: MetamodelFileHints;\n readonly extensions: readonly string[];\n /** In declaration order: the root's kinds first, then each extension's. */\n readonly elements: ReadonlyMap<EK, ElementKindDefinition<EK>>;\n readonly links: ReadonlyMap<LK, LinkKindDefinition<LK>>;\n /** `type` in piStar files → kind. */\n readonly elementsByPistarType: ReadonlyMap<string, EK>;\n readonly linksByPistarType: ReadonlyMap<string, LK>;\n}\n\n/** The kinds of a metamodel, as type-level unions. */\nexport type ElementKindOf<M> = M extends Metamodel<infer EK, string> ? EK : never;\nexport type LinkKindOf<M> = M extends Metamodel<string, infer LK> ? LK : never;\n\n/** A metamodel of any dialect, for code that handles every kind generically. */\nexport type AnyMetamodel = Metamodel<string, string>;\n\n// ---------------------------------------------------------------------------------------------\n// Declarations\n\nexport interface ElementKindDeclaration<K extends string = string> {\n /** Namespaced kind name, e.g. `rationalAgents.Planning`. */\n readonly kind: K;\n /** Default: the part after the namespace (\"Planning\"). */\n readonly label?: string;\n /** Required unless `behavesLike` is given (then it is the same category). */\n readonly category?: ElementCategory;\n /** An existing element kind whose link rules this kind follows, e.g. `istar.Task`. */\n readonly behavesLike?: string;\n /**\n * Containment rules for nodes. Default: those of `behavesLike`, else piStar-ext's (inner,\n * dependum) in an extension and DSM3's (inner, dependum, on paper) in a root.\n */\n readonly info?: Partial<NodeKindInfo>;\n /** Default: that of `behavesLike`, else piStar-ext's 90×55 for nodes and 200×120 for actors. */\n readonly size?: Size;\n /**\n * The `type` used in piStar files, when it differs from `kind`. piStar-ext saves its new\n * constructs as `istar.<Name>`, so `pistarType: 'istar.Planning'` reads its files.\n */\n readonly pistarType?: string;\n /** Presentation hints, kept as data for renderers (`@istar-ts/react` draws them). */\n readonly shape?: KindShape;\n readonly textBox?: KindTextBox;\n}\n\nexport interface LinkKindDeclaration<K extends string = string> {\n readonly kind: K;\n readonly label?: string;\n /** Default: that of `behavesLike`, else `node`. */\n readonly category?: LinkCategory;\n /** An existing link kind whose rules this kind takes on, e.g. `istar.OrRefinementLink`. */\n readonly behavesLike?: string;\n /**\n * Declarative rules; give these or `behavesLike`, not both. A root's link kind may give\n * neither when the library has built-in rules for it (iStar 2.0's links).\n */\n readonly rules?: LinkRules;\n /** An extra predicate, checked after the other rules pass. */\n readonly check?: (context: LinkRuleContext) => LinkCheck;\n /** Default: that of `behavesLike`, else none (no fixed label, no changeable value). */\n readonly info?: LinkKindInfo;\n readonly pistarType?: string;\n /** Presentation hint, kept as data for renderers (`@istar-ts/react` draws it). */\n readonly line?: KindLine;\n /**\n * `'n'` for a link with several sources, like KAOS's AND-refinement: in a model it is a hub\n * element joined to each source by a leg link and to the target by an end link, as DSM3-goals\n * draws and saves it. Declaring it generates three kinds, named after this one (`parts`):\n * `<kind>Hub`, `<kind>Start` and `<kind>End`, written as `<pistarType>Hub` etc. Needs `rules`\n * and the `node` category.\n */\n readonly arity?: 'n';\n /** Names of the generated kinds, when the defaults don't suit. */\n readonly parts?: Partial<HubLinkParts>;\n /** The hub's size. Default 20×20, as in DSM3-goals. */\n readonly hubSize?: Size;\n}\n\n/** A whole modelling language, turned into a `Metamodel` by `defineMetamodel`. */\nexport interface RootMetamodelDeclaration<EK extends string = string, LK extends string = string> {\n /** Identifies the language; the metamodel's `name` and `framework`, e.g. `istar-2.0`. */\n readonly name: string;\n /** The language's namespace, e.g. `istar`. Extensions may not declare kinds in it. */\n readonly prefix: string;\n readonly elements: readonly ElementKindDeclaration<EK>[];\n readonly links: readonly LinkKindDeclaration<LK>[];\n readonly file?: MetamodelFileHints;\n}\n\n/** A named set of new kinds, applied to a metamodel with `extendMetamodel`. */\nexport interface MetamodelExtension<NEK extends string = string, NLK extends string = string> {\n /** Identifies the extension, e.g. `rationalAgents`. */\n readonly name: string;\n readonly elements?: readonly ElementKindDeclaration<NEK>[];\n readonly links?: readonly LinkKindDeclaration<NLK>[];\n}\n\nexport class MetamodelError extends Error {\n override name = 'MetamodelError';\n}\n\n/**\n * Declares an extension, keeping its kind names as literal types (so `extendMetamodel` can\n * type the result). Identity at runtime.\n */\nexport function defineMetamodelExtension<\n const NEK extends string = never,\n const NLK extends string = never,\n>(extension: MetamodelExtension<NEK, NLK>): MetamodelExtension<NEK, NLK> {\n return extension;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Building kinds. `defineMetamodel` and `extendMetamodel` add kinds to a mutable table, one\n// declaration at a time, so `behavesLike` and rule selectors resolve against the kinds the\n// table already holds: the base metamodel's, then those declared earlier.\n\nconst KIND_NAME = /^[A-Za-z_][\\w-]*\\.[A-Za-z_][\\w-]*$/;\nconst PREFIX_NAME = /^[A-Za-z_][\\w-]*$/;\nconst CATEGORY_SELECTORS: ReadonlySet<string> = new Set(['node', 'actor', '*']);\n/** The `targets` selector for any link (see `LinkRules`). */\nexport const LINK_SELECTOR = 'link';\n\n/** piStar-ext's defaults for an extension's new nodes (tool/language/metamodel.js). */\nconst EXTENSION_NODE_INFO: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: false,\n};\n\n/** DSM3-goals' defaults for a root's nodes (istarcore metamodelManager). */\n/** A hub sits on the paper, outside any actor, and is never a dependum. */\nconst HUB_INFO: NodeKindInfo = {\n canBeInnerElement: false,\n canBeDependum: false,\n canBeOnPaper: true,\n};\n\n/** A circle filling the hub's box (DSM3-goals draws a circle of radius 10 in 20×20). */\nconst HUB_SHAPE: KindShape = {\n path: 'M 0 10 A 10 10 0 1 0 20 10 A 10 10 0 1 0 0 10 Z',\n viewBox: '0 0 20 20',\n};\n\nconst ROOT_NODE_INFO: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: true,\n};\n\ninterface KindTable {\n /** `extension \"x\"` or `metamodel \"x\"`, opening every error message. */\n readonly where: string;\n /** The namespace suggested in errors: the extension's name, or the root's prefix. */\n readonly namespace: string;\n /** The root's prefix, when the table builds an extension (a root may use any namespace). */\n readonly reserved?: string;\n /** Name of the extension being built; absent for a root. */\n readonly extension?: string;\n readonly elements: Map<string, ElementKindDefinition<string>>;\n readonly links: Map<string, LinkKindDefinition<string>>;\n readonly elementsByType: Map<string, string>;\n readonly linksByType: Map<string, string>;\n}\n\nfunction shortName(kind: string): string {\n const dot = kind.indexOf('.');\n return dot === -1 ? kind : kind.slice(dot + 1);\n}\n\nfunction claimName(table: KindTable, kind: string, what: string): void {\n const { where } = table;\n if (typeof kind !== 'string' || !KIND_NAME.test(kind)) {\n throw new MetamodelError(\n `${where}: ${what} kind ${JSON.stringify(kind)} must be namespaced, e.g. \"${table.namespace}.Name\"`,\n );\n }\n if (table.reserved !== undefined && kind.startsWith(`${table.reserved}.`)) {\n throw new MetamodelError(\n `${where}: ${what} kind \"${kind}\" uses the reserved \"${table.reserved}.\" prefix; ` +\n `name it \"${table.namespace}.${shortName(kind)}\" and set pistarType: \"${kind}\" to read files that use it`,\n );\n }\n if (table.elements.has(kind) || table.links.has(kind)) {\n throw new MetamodelError(`${where}: kind \"${kind}\" already exists`);\n }\n}\n\nfunction claimType(table: KindTable, type: string, kind: string): void {\n const { where } = table;\n if (typeof type !== 'string' || type === '') {\n throw new MetamodelError(`${where}: kind \"${kind}\" has an empty pistarType`);\n }\n if (\n table.elementsByType.has(type) ||\n table.linksByType.has(type) ||\n table.elements.has(type) ||\n table.links.has(type)\n ) {\n throw new MetamodelError(\n `${where}: pistarType \"${type}\" of kind \"${kind}\" is already used by another kind`,\n );\n }\n}\n\nfunction isCompleteNodeInfo(info: Partial<NodeKindInfo> | undefined): info is NodeKindInfo {\n return (\n info !== undefined &&\n typeof info.canBeInnerElement === 'boolean' &&\n typeof info.canBeDependum === 'boolean' &&\n typeof info.canBeOnPaper === 'boolean'\n );\n}\n\nfunction addElementKind(table: KindTable, declaration: ElementKindDeclaration<string>): void {\n const { where } = table;\n const { kind } = declaration;\n claimName(table, kind, 'element');\n let parent: ElementKindDefinition<string> | undefined;\n if (declaration.behavesLike !== undefined) {\n parent = table.elements.get(declaration.behavesLike);\n if (!parent) {\n throw new MetamodelError(\n `${where}: \"${kind}\" behaves like unknown element kind \"${declaration.behavesLike}\"`,\n );\n }\n }\n const category = declaration.category ?? parent?.category;\n if (category !== 'actor' && category !== 'node') {\n throw new MetamodelError(\n `${where}: element kind \"${kind}\" needs a category (\"node\" or \"actor\") or behavesLike`,\n );\n }\n if (parent && parent.category !== category) {\n throw new MetamodelError(\n `${where}: \"${kind}\" is a ${category} but behaves like \"${parent.kind}\", a ${parent.category}`,\n );\n }\n const type = declaration.pistarType ?? kind;\n claimType(table, type, kind);\n // A complete `info` is kept as given (iStar 2.0's `NODE_KIND_INFO` objects keep their identity).\n const info: NodeKindInfo = isCompleteNodeInfo(declaration.info)\n ? declaration.info\n : {\n ...(parent?.info ?? (table.extension === undefined ? ROOT_NODE_INFO : EXTENSION_NODE_INFO)),\n ...declaration.info,\n };\n const definition: ElementKindDefinition<string> = {\n kind,\n category,\n label: declaration.label ?? shortName(kind),\n size:\n declaration.size ??\n parent?.size ??\n (category === 'actor' ? { width: 200, height: 120 } : { width: 90, height: 55 }),\n ...(category === 'node' ? { info } : {}),\n ...(parent ? { behavesLike: parent.kind } : {}),\n pistarType: type,\n ...(table.extension !== undefined ? { extension: table.extension } : {}),\n ...(declaration.shape ? { shape: declaration.shape } : {}),\n ...(declaration.textBox ? { textBox: declaration.textBox } : {}),\n };\n table.elements.set(kind, definition);\n table.elementsByType.set(type, kind);\n}\n\nfunction addLinkKind(table: KindTable, declaration: LinkKindDeclaration<string>): void {\n const { where } = table;\n const { kind } = declaration;\n claimName(table, kind, 'link');\n const isRoot = table.extension === undefined;\n if (declaration.behavesLike !== undefined && declaration.rules !== undefined) {\n throw new MetamodelError(\n isRoot\n ? `${where}: link kind \"${kind}\" needs at most one of behavesLike or rules`\n : `${where}: link kind \"${kind}\" needs exactly one of behavesLike or rules`,\n );\n }\n // A root's link kind may give neither: its rules are then built in (iStar 2.0's links).\n if (!isRoot && declaration.behavesLike === undefined && declaration.rules === undefined) {\n throw new MetamodelError(\n `${where}: link kind \"${kind}\" needs exactly one of behavesLike or rules`,\n );\n }\n let parent: LinkKindDefinition<string> | undefined;\n if (declaration.behavesLike !== undefined) {\n parent = table.links.get(declaration.behavesLike);\n if (!parent) {\n throw new MetamodelError(\n `${where}: \"${kind}\" behaves like unknown link kind \"${declaration.behavesLike}\"`,\n );\n }\n }\n const category = declaration.category ?? parent?.category ?? 'node';\n if (category !== 'node' && category !== 'actor' && category !== 'dependency') {\n throw new MetamodelError(`${where}: link kind \"${kind}\" has an unknown category \"${category}\"`);\n }\n if (declaration.arity !== undefined) {\n if (declaration.arity !== 'n') {\n throw new MetamodelError(\n `${where}: link kind \"${kind}\" has an unknown arity ${JSON.stringify(declaration.arity)}`,\n );\n }\n if (!declaration.rules || category !== 'node') {\n throw new MetamodelError(\n `${where}: n-ary link kind \"${kind}\" needs rules and the \"node\" category`,\n );\n }\n }\n if (parent && parent.category !== category) {\n throw new MetamodelError(\n `${where}: \"${kind}\" is a ${category} link but behaves like \"${parent.kind}\", a ${parent.category} link`,\n );\n }\n if (category === 'dependency' && !parent && (!isRoot || declaration.rules !== undefined)) {\n throw new MetamodelError(\n `${where}: dependency link kind \"${kind}\" must behave like a dependency link (its dependum makes declarative rules ambiguous)`,\n );\n }\n if (declaration.rules) {\n for (const [side, selectors] of [\n ['sources', declaration.rules.sources],\n ['targets', declaration.rules.targets],\n ] as const) {\n if (!Array.isArray(selectors) || selectors.length === 0) {\n throw new MetamodelError(`${where}: link kind \"${kind}\" needs at least one of ${side}`);\n }\n for (const selector of selectors) {\n const known =\n CATEGORY_SELECTORS.has(selector) ||\n table.elements.has(selector) ||\n // Targets may also name links: any, an earlier kind, or this kind itself.\n (side === 'targets' &&\n (selector === LINK_SELECTOR || table.links.has(selector) || selector === kind));\n if (!known) {\n throw new MetamodelError(\n `${where}: ${side} of \"${kind}\" names unknown element kind \"${selector}\"`,\n );\n }\n }\n }\n }\n const type = declaration.pistarType ?? kind;\n claimType(table, type, kind);\n const definition: LinkKindDefinition<string> = {\n kind,\n category,\n label: declaration.label ?? shortName(kind),\n info: declaration.info ?? parent?.info ?? {},\n ...(parent ? { behavesLike: parent.kind } : {}),\n ...(declaration.rules ? { rules: declaration.rules } : {}),\n ...(declaration.check ? { check: declaration.check } : {}),\n pistarType: type,\n ...(table.extension !== undefined ? { extension: table.extension } : {}),\n ...(declaration.line ? { line: declaration.line } : {}),\n };\n if (declaration.arity !== 'n') {\n table.links.set(kind, definition);\n table.linksByType.set(type, kind);\n return;\n }\n const parts: HubLinkParts = {\n hub: declaration.parts?.hub ?? `${kind}Hub`,\n leg: declaration.parts?.leg ?? `${kind}Start`,\n end: declaration.parts?.end ?? `${kind}End`,\n };\n table.links.set(kind, { ...definition, arity: 'n', parts });\n table.linksByType.set(type, kind);\n addHubKinds(table, table.links.get(kind)!, parts, declaration.hubSize);\n}\n\n/**\n * Adds the kinds an n-ary link kind is made of, as DSM3-goals' `setupSplitLinks` generates them:\n * the hub (an element), the legs (each source → the hub, at most one per source) and the end\n * (the hub → the target).\n */\nfunction addHubKinds(\n table: KindTable,\n base: LinkKindDefinition<string>,\n parts: HubLinkParts,\n hubSize: Size | undefined,\n): void {\n const rules = base.rules!;\n // Generated kinds go through the usual checks; their errors name the kind they come from.\n const claim = (kind: string, type: string, what: string): void => {\n try {\n claimName(table, kind, what);\n claimType(table, type, kind);\n } catch (error) {\n if (!(error instanceof MetamodelError)) throw error;\n throw new MetamodelError(`${error.message} (generated for n-ary link kind \"${base.kind}\")`);\n }\n };\n const owner = table.extension !== undefined ? { extension: table.extension } : {};\n claim(parts.hub, `${base.pistarType}Hub`, 'element');\n table.elements.set(parts.hub, {\n kind: parts.hub,\n category: 'node',\n label: `${base.label} hub`,\n size: hubSize ?? { width: 20, height: 20 },\n info: HUB_INFO,\n pistarType: `${base.pistarType}Hub`,\n ...owner,\n shape: HUB_SHAPE,\n role: 'hub',\n of: base.kind,\n });\n table.elementsByType.set(`${base.pistarType}Hub`, parts.hub);\n // The base kind's same-actor rule is checked between a leg's source and the end's target\n // (`canLink`): the hub itself belongs to no actor.\n const common = {\n category: 'node' as const,\n ...owner,\n of: base.kind,\n };\n claim(parts.leg, `${base.pistarType}Start`, 'link');\n table.links.set(parts.leg, {\n ...common,\n kind: parts.leg,\n label: `${base.label} leg`,\n info: {},\n rules: {\n sources: rules.sources,\n targets: [parts.hub],\n sameActor: false,\n ...(rules.allowDependum !== undefined ? { allowDependum: rules.allowDependum } : {}),\n unique: 'kind',\n },\n pistarType: `${base.pistarType}Start`,\n role: 'leg',\n });\n table.linksByType.set(`${base.pistarType}Start`, parts.leg);\n claim(parts.end, `${base.pistarType}End`, 'link');\n table.links.set(parts.end, {\n ...common,\n kind: parts.end,\n label: `${base.label} end`,\n info: base.info,\n rules: {\n sources: [parts.hub],\n targets: rules.targets,\n sameActor: false,\n ...(rules.allowDependum !== undefined ? { allowDependum: rules.allowDependum } : {}),\n unique: 'kind',\n },\n pistarType: `${base.pistarType}End`,\n ...(base.line ? { line: base.line } : {}),\n role: 'end',\n });\n table.linksByType.set(`${base.pistarType}End`, parts.end);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Root metamodels\n\n/**\n * Builds a root metamodel: a modelling language of its own, such as iStar 2.0, KAOS or NFR.\n * Kinds are namespaced (any namespace; usually `prefix`), declared in order: `behavesLike` and\n * link rules refer to kinds declared before them. Extensions of the result may not use `prefix`.\n *\n * Throws `MetamodelError` on the same declaration errors as `extendMetamodel`.\n */\nexport function defineMetamodel<const EK extends string, const LK extends string>(\n declaration: RootMetamodelDeclaration<EK, LK>,\n): Metamodel<EK, LK> {\n const { name, prefix } = declaration;\n if (!name || typeof name !== 'string') {\n throw new MetamodelError('a root metamodel needs a name');\n }\n const where = `metamodel \"${name}\"`;\n if (typeof prefix !== 'string' || !PREFIX_NAME.test(prefix)) {\n throw new MetamodelError(\n `${where}: prefix ${JSON.stringify(prefix)} must be a name without dots, e.g. \"istar\"`,\n );\n }\n const table: KindTable = {\n where,\n namespace: prefix,\n elements: new Map(),\n links: new Map(),\n elementsByType: new Map(),\n linksByType: new Map(),\n };\n for (const element of declaration.elements) addElementKind(table, element);\n for (const link of declaration.links) addLinkKind(table, link);\n return {\n name,\n framework: name,\n prefix,\n file: declaration.file ?? {},\n extensions: [],\n elements: table.elements,\n links: table.links,\n elementsByPistarType: table.elementsByType,\n linksByPistarType: table.linksByType,\n } as unknown as Metamodel<EK, LK>;\n}\n\nconst ISTAR_LINK_LABELS: Readonly<Record<LinkKind, string>> = {\n 'istar.IsALink': 'Is-A',\n 'istar.ParticipatesInLink': 'Participates-In',\n 'istar.DependencyLink': 'Dependency',\n 'istar.AndRefinementLink': 'And-Refinement',\n 'istar.OrRefinementLink': 'Or-Refinement',\n 'istar.NeededByLink': 'Needed-By',\n 'istar.QualificationLink': 'Qualification',\n 'istar.ContributionLink': 'Contribution',\n};\n\nfunction istarLinks(\n kinds: readonly LinkKind[],\n category: LinkCategory,\n): LinkKindDeclaration<LinkKind>[] {\n // No rules: iStar 2.0's link rules are built in (`constraints.ts`).\n return kinds.map((kind) => ({\n kind,\n category,\n label: ISTAR_LINK_LABELS[kind],\n info: LINK_KIND_INFO[kind],\n }));\n}\n\n/** iStar 2.0's declaration, built from the constants in `metamodel.ts`. */\nexport const ISTAR_2_0_DECLARATION: RootMetamodelDeclaration<ElementKind, LinkKind> = {\n name: 'istar-2.0',\n prefix: ISTAR_PREFIX,\n elements: [\n ...ACTOR_KINDS.map((kind): ElementKindDeclaration<ElementKind> => ({\n kind,\n category: 'actor',\n size: DEFAULT_ELEMENT_SIZE[kind],\n })),\n ...NODE_KINDS.map((kind): ElementKindDeclaration<ElementKind> => ({\n kind,\n category: 'node',\n size: DEFAULT_ELEMENT_SIZE[kind],\n info: NODE_KIND_INFO[kind],\n })),\n ],\n links: [\n ...istarLinks(ACTOR_LINK_KINDS, 'actor'),\n ...istarLinks(DEPENDENCY_LINK_KINDS, 'dependency'),\n ...istarLinks(NODE_LINK_KINDS, 'node'),\n ],\n // `PISTAR_TOOL` and `ISTAR_VERSION` (model.ts), which can't be imported here without a cycle.\n file: { tool: 'pistar.2.1.0', istar: '2.0' },\n};\n\n/** iStar 2.0, as the piStar tool implements it. The default metamodel everywhere. */\nexport const ISTAR_2_0: Metamodel = defineMetamodel(ISTAR_2_0_DECLARATION);\n\n// ---------------------------------------------------------------------------------------------\n// Extensions\n\n/**\n * Returns a new metamodel with the extension's kinds added. `base` is not modified. The result\n * keeps `base`'s `framework`, `prefix` and `file`.\n *\n * Throws `MetamodelError` when a kind name isn't namespaced, uses the root's reserved prefix\n * (`istar.` for iStar 2.0), collides with an existing kind or piStar type, or refers to an\n * unknown kind.\n */\nexport function extendMetamodel<\n EK extends string,\n LK extends string,\n const NEK extends string = never,\n const NLK extends string = never,\n>(base: Metamodel<EK, LK>, extension: MetamodelExtension<NEK, NLK>): Metamodel<EK | NEK, LK | NLK> {\n if (!extension.name || typeof extension.name !== 'string') {\n throw new MetamodelError('an extension needs a name');\n }\n const where = `extension \"${extension.name}\"`;\n if (base.extensions.includes(extension.name)) {\n throw new MetamodelError(`${where} is already applied`);\n }\n const table: KindTable = {\n where,\n namespace: extension.name,\n reserved: base.prefix,\n extension: extension.name,\n elements: new Map<string, ElementKindDefinition<string>>(base.elements),\n links: new Map<string, LinkKindDefinition<string>>(base.links),\n elementsByType: new Map<string, string>(base.elementsByPistarType),\n linksByType: new Map<string, string>(base.linksByPistarType),\n };\n for (const element of extension.elements ?? []) addElementKind(table, element);\n for (const link of extension.links ?? []) addLinkKind(table, link);\n return {\n name: `${base.name}+${extension.name}`,\n framework: base.framework,\n prefix: base.prefix,\n file: base.file,\n extensions: [...base.extensions, extension.name],\n elements: table.elements,\n links: table.links,\n elementsByPistarType: table.elementsByType,\n linksByPistarType: table.linksByType,\n } as unknown as Metamodel<EK | NEK, LK | NLK>;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Queries. They accept any string so code handling models of unknown dialects can ask.\n\nexport function elementKindDefinition(\n metamodel: AnyMetamodel,\n kind: string,\n): ElementKindDefinition | undefined {\n return metamodel.elements.get(kind);\n}\n\nexport function linkKindDefinition(\n metamodel: AnyMetamodel,\n kind: string,\n): LinkKindDefinition | undefined {\n return metamodel.links.get(kind);\n}\n\n/** True for actor-category kinds (Actor, Agent, Role and extensions behaving like them). */\nexport function isActorKindIn(metamodel: AnyMetamodel, kind: string): boolean {\n return metamodel.elements.get(kind)?.category === 'actor';\n}\n\n/** True for node-category kinds (intentional elements, built-in or extended). */\nexport function isNodeKindIn(metamodel: AnyMetamodel, kind: string): boolean {\n return metamodel.elements.get(kind)?.category === 'node';\n}\n\n/**\n * The built-in (or rule-carrying) kind an element kind ultimately behaves like: `istar.Task`\n * for a Planning that behaves like a Task; the kind itself when it behaves like nothing.\n */\nexport function effectiveElementKind(metamodel: AnyMetamodel, kind: string): string {\n let current = metamodel.elements.get(kind);\n const seen = new Set<string>();\n while (current?.behavesLike !== undefined && !seen.has(current.kind)) {\n seen.add(current.kind);\n const next = metamodel.elements.get(current.behavesLike);\n if (!next) break;\n current = next;\n }\n return current?.kind ?? kind;\n}\n\n/** Like `effectiveElementKind`, for link kinds. */\nexport function effectiveLinkKind(metamodel: AnyMetamodel, kind: string): string {\n let current = metamodel.links.get(kind);\n const seen = new Set<string>();\n while (current?.behavesLike !== undefined && !seen.has(current.kind)) {\n seen.add(current.kind);\n const next = metamodel.links.get(current.behavesLike);\n if (!next) break;\n current = next;\n }\n return current?.kind ?? kind;\n}\n\n/** True when link `kind` is `ancestor` or (transitively) behaves like it. */\nexport function linkBehavesLike(metamodel: AnyMetamodel, kind: string, ancestor: string): boolean {\n let current: string | undefined = kind;\n const seen = new Set<string>();\n while (current !== undefined && !seen.has(current)) {\n if (current === ancestor) return true;\n seen.add(current);\n current = metamodel.links.get(current)?.behavesLike;\n }\n return false;\n}\n\n/** True when a link kind's rules let it target links (`link` or a link kind in `targets`). */\nexport function targetsLinks(metamodel: AnyMetamodel, kind: string): boolean {\n const root = metamodel.links.get(effectiveLinkKind(metamodel, kind));\n return (\n root?.rules?.targets.some(\n (selector) => selector === LINK_SELECTOR || metamodel.links.has(selector),\n ) ?? false\n );\n}\n\n/** True when `kind` is `ancestor` or (transitively) behaves like it. */\nexport function elementBehavesLike(\n metamodel: AnyMetamodel,\n kind: string,\n ancestor: string,\n): boolean {\n let current: string | undefined = kind;\n const seen = new Set<string>();\n while (current !== undefined && !seen.has(current)) {\n if (current === ancestor) return true;\n seen.add(current);\n current = metamodel.elements.get(current)?.behavesLike;\n }\n return false;\n}\n","/**\n * Registries the library keeps beside models (their metamodel, their file's layout) are\n * shared across every copy of `@istar-ts/core` loaded in a process. A bundle may load the\n * package twice, once as ESM and once as CommonJS (an application parsing with the ESM build\n * while a CommonJS dependency reads the model with the CJS build): a module-level WeakMap in\n * each copy would make a model parsed by one copy unknown to the other, so `metamodelOf`\n * would fall back to iStar 2.0 there. The registries live on `globalThis` under one symbol\n * instead, keyed by name, and every copy finds the same ones.\n */\nconst REGISTRIES: unique symbol = Symbol.for('@istar-ts/core/registries');\n\ntype Registries = Map<string, WeakMap<object, unknown>>;\n\n/** The WeakMap named `name`, the same object in every copy of the library in this process. */\nexport function sharedWeakMap<V>(name: string): WeakMap<object, V> {\n const host = globalThis as { [REGISTRIES]?: Registries };\n const registries = (host[REGISTRIES] ??= new Map());\n let map = registries.get(name);\n if (!map) registries.set(name, (map = new WeakMap()));\n return map as WeakMap<object, V>;\n}\n","import type { ActorKind, ElementKind, LinkKind, NodeKind, Size } from './metamodel';\nimport type { AnyMetamodel, Metamodel } from './metamodels';\nimport { ISTAR_2_0, isActorKindIn } from './metamodels';\nimport { sharedWeakMap } from './shared';\n\n/**\n * piStar stores every custom property value as a string (e.g. `\"initialValue\": \"false\"`).\n * Typed access is layered on top with property schemas (see `properties.ts`).\n */\nexport type CustomProperties = Readonly<Record<string, string>>;\n\n/** Arbitrary JSON keys the library does not interpret; kept so they survive a round trip. */\nexport type Extra = Readonly<Record<string, unknown>>;\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** Per-element entry of the save file's `display` section. */\nexport interface ElementDisplay {\n readonly backgroundColor?: string;\n readonly width?: number;\n readonly height?: number;\n /** Actors only. */\n readonly collapsed?: boolean;\n readonly [key: string]: unknown;\n}\n\n/** Per-link entry of the save file's `display` section. */\nexport interface LinkDisplay {\n readonly vertices?: readonly Point[];\n readonly [key: string]: unknown;\n}\n\n/**\n * An element of the model. `K` is the kind union: iStar 2.0's by default, wider for models of an\n * extended metamodel (see `extendMetamodel`).\n */\nexport interface IstarElement<K extends string = ElementKind> {\n readonly id: string;\n readonly kind: K;\n /** The element's label; `text` in the save file. */\n readonly name: string;\n /** Absolute diagram coordinates, as in the save file (children are not relative to actors). */\n readonly x: number;\n readonly y: number;\n /** Id of the containing actor, for inner elements. */\n readonly parent?: string;\n /** True when the element is the dependum of a dependency (lives in `dependencies`). */\n readonly isDependum?: boolean;\n /**\n * Depender/dependee recorded in the save file for a dependum. The dependency links are the\n * source of truth; this is only a fallback used when those links are missing.\n */\n readonly dependency?: { readonly source: string; readonly target: string };\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n readonly extra?: Extra;\n}\n\nexport type IstarActor = IstarElement<ActorKind>;\nexport type IstarNode = IstarElement<NodeKind>;\n\nexport interface IstarLink<K extends string = LinkKind> {\n readonly id: string;\n readonly kind: K;\n readonly source: string;\n readonly target: string;\n /** Contribution value (`make`/`help`/`hurt`/`break`), stored as `label` in the save file. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: LinkDisplay;\n readonly extra?: Extra;\n}\n\nexport interface Diagram {\n readonly width?: number;\n readonly height?: number;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly extra?: Extra;\n}\n\n/**\n * An immutable iStar model. Maps preserve insertion order, which is the order elements and\n * links are written back to disk.\n *\n * `EK`/`LK` are the element and link kind unions; they default to iStar 2.0's.\n */\nexport interface IstarModel<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly elements: ReadonlyMap<string, IstarElement<EK>>;\n readonly links: ReadonlyMap<string, IstarLink<LK>>;\n readonly diagram?: Diagram;\n readonly tool?: string;\n readonly istar?: string;\n readonly saveDate?: string;\n /** `display` entries whose id matches no element or link. */\n readonly extraDisplay?: Extra;\n /** Unknown top-level keys (e.g. `metamodelVersion`). */\n readonly extra?: Extra;\n}\n\n/** Tool identifier written by piStar 2.1.0, whose file format this library emulates. */\nexport const PISTAR_TOOL = 'pistar.2.1.0';\nexport const ISTAR_VERSION = '2.0';\n\n/**\n * DSM3-goals' file conventions, shared by its languages (KAOS, NFR; see `@istar-ts/dsm3-kaos`\n * and `@istar-ts/dsm3-nfr`): the `tool` its editors write, and the order of their top-level keys\n * (`fileManager.js`). Use them as a root's `file.tool` and `file.keys`.\n */\nexport const DSM3_TOOL = 'dsm3-goals';\nexport const DSM3_FILE_KEYS: readonly string[] = [\n 'actors',\n 'orphans',\n 'dependencies',\n 'links',\n 'display',\n 'tool',\n 'metamodelVersion',\n 'saveDate',\n 'diagram',\n];\n\nexport const DEFAULT_DIAGRAM: Diagram = { width: 2000, height: 1300 };\n\n/** A model of any dialect, for code that handles every kind generically. */\nexport type AnyIstarModel = IstarModel<string, string>;\n\n/**\n * The metamodel of each model that isn't iStar 2.0. Kept beside the model rather than in it,\n * so a model's shape (and `JSON.stringify`, deep equality, snapshots) is the same as before\n * metamodels existed. Operations and the store carry it to every model they derive.\n */\nconst metamodels = sharedWeakMap<AnyMetamodel>('metamodels');\n\n/**\n * Associates `metamodel` with `model` and returns the same model, typed for it. Use when a\n * model was built without the library's operations (e.g. with an object spread), which loses\n * the association.\n */\nexport function withMetamodel<EK extends string, LK extends string>(\n model: IstarModel<string, string>,\n metamodel: Metamodel<EK, LK>,\n): IstarModel<EK, LK> {\n if ((metamodel as unknown) === ISTAR_2_0) metamodels.delete(model);\n else metamodels.set(model, metamodel as unknown as AnyMetamodel);\n return model as unknown as IstarModel<EK, LK>;\n}\n\n/**\n * For models whose file declares part of their metamodel (see `withFileMetamodel`): the\n * metamodel the host supplied, without the file's kinds.\n */\nconst hostMetamodels = sharedWeakMap<AnyMetamodel>('hostMetamodels');\n\n/** @internal Records the host part of a model's metamodel (used by serialization). */\nexport function setHostMetamodel(model: object, metamodel: AnyMetamodel | undefined): void {\n if (metamodel) hostMetamodels.set(model, metamodel);\n else hostMetamodels.delete(model);\n}\n\n/** @internal The host part of a model's metamodel, if the file declares the rest. */\nexport function hostMetamodelOf(model: object): AnyMetamodel | undefined {\n return hostMetamodels.get(model);\n}\n\n/** Gives `to` the metamodel of `from` (used for every model an operation derives). */\nexport function inheritMetamodel<M extends IstarModel<string, string>>(\n from: IstarModel<string, string>,\n to: M,\n): M {\n if (from === to) return to;\n const metamodel = metamodels.get(from);\n if (metamodel) metamodels.set(to, metamodel);\n const host = hostMetamodels.get(from);\n if (host) hostMetamodels.set(to, host);\n return to;\n}\n\n// The iStar 2.0 overload comes last: TypeScript resolves function references (e.g.\n// `useIstarStore(createEmptyModel)`) against the last one, as before metamodels existed.\nexport function createEmptyModel<EK extends string, LK extends string>(\n diagram: Diagram | undefined,\n options: { metamodel: Metamodel<EK, LK> },\n): IstarModel<EK, LK>;\nexport function createEmptyModel(diagram?: Diagram): IstarModel;\nexport function createEmptyModel(\n diagram: Diagram = DEFAULT_DIAGRAM,\n options: { metamodel?: AnyMetamodel } = {},\n): AnyIstarModel {\n // The root metamodel's file hints say what a new file records: iStar 2.0 writes piStar's\n // `tool` and `istar: \"2.0\"`; other roots their own tool and top-level keys.\n const { file } = (options.metamodel ?? ISTAR_2_0) as AnyMetamodel;\n const model: AnyIstarModel = {\n elements: new Map(),\n links: new Map(),\n diagram,\n tool: file.tool ?? PISTAR_TOOL,\n ...(file.istar !== undefined ? { istar: file.istar } : {}),\n ...(file.extra !== undefined ? { extra: { ...file.extra } } : {}),\n };\n return options.metamodel ? withMetamodel(model, options.metamodel) : model;\n}\n\n/**\n * The metamodel a model was read or created with (see `parsePistar`, `createEmptyModel`), or\n * iStar 2.0. Constraints, operations and serialization use it unless given another one.\n */\nexport function metamodelOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): Metamodel<EK, LK> {\n return (metamodels.get(model) ?? ISTAR_2_0) as unknown as Metamodel<EK, LK>;\n}\n\n/**\n * True for iStar 2.0 actors (Actor, Agent, Role). One argument, so it is safe as an array\n * callback (`elements.filter(isActor)`). For extended actor kinds use `isActorIn(metamodel)`.\n */\nexport function isActor(element: IstarElement<string> | undefined): element is IstarActor {\n return element !== undefined && isActorKindIn(ISTAR_2_0, element.kind);\n}\n\n/** True for iStar 2.0 intentional elements. For extended kinds use `isNodeIn(metamodel)`. */\nexport function isNode(element: IstarElement<string> | undefined): element is IstarNode {\n return element !== undefined && !isActorKindIn(ISTAR_2_0, element.kind);\n}\n\n/**\n * A predicate for actor-category elements of `metamodel`, extended actor kinds included:\n * `elements.filter(isActorIn(metamodelOf(model)))`.\n */\nexport function isActorIn(\n metamodel: AnyMetamodel,\n): (element: IstarElement<string> | undefined) => boolean {\n return (element) => element !== undefined && isActorKindIn(metamodel, element.kind);\n}\n\n/** A predicate for node-category elements of `metamodel`, extended node kinds included. */\nexport function isNodeIn(\n metamodel: AnyMetamodel,\n): (element: IstarElement<string> | undefined) => boolean {\n return (element) =>\n element !== undefined && metamodel.elements.get(element.kind)?.category === 'node';\n}\n\n/** Inner elements of an actor, in model order. */\nexport function childrenOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n actorId: string,\n): IstarElement<EK>[] {\n const result: IstarElement<EK>[] = [];\n for (const element of model.elements.values()) {\n if (element.parent === actorId) result.push(element);\n }\n return result;\n}\n\n/**\n * Links that have the element as source or target. Given a link id, the links that target that\n * link (see `LinkRules`).\n */\nexport function linksOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n elementId: string,\n): IstarLink<LK>[] {\n const result: IstarLink<LK>[] = [];\n for (const link of model.links.values()) {\n if (link.source === elementId || link.target === elementId) result.push(link);\n }\n return result;\n}\n\n/** For a dependum, the two halves of its dependency: depender → dependum → dependee. */\nexport function dependencyLinksOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n dependumId: string,\n): { inbound?: IstarLink<LK>; outbound?: IstarLink<LK> } {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n let inbound: IstarLink<LK> | undefined;\n let outbound: IstarLink<LK> | undefined;\n for (const link of model.links.values()) {\n if (metamodel.links.get(link.kind)?.category !== 'dependency') continue;\n if (link.target === dependumId && !inbound) inbound = link;\n if (link.source === dependumId && !outbound) outbound = link;\n }\n return { inbound, outbound };\n}\n\n/** What a link points at: an element, or a link for kinds whose rules target links. */\nexport function linkTargetOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n link: IstarLink<LK>,\n): IstarElement<EK> | IstarLink<LK> | undefined {\n return model.elements.get(link.target) ?? model.links.get(link.target);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Hub links (n-ary link kinds, see `LinkKindDeclaration.arity`)\n\n/** An n-ary link as it lives in a model: its hub element, its legs (in link order), its end. */\nexport interface HubLink<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly hub: IstarElement<EK>;\n readonly legs: readonly IstarLink<LK>[];\n /** Absent only in an incomplete model (`validateModel` reports it). */\n readonly end?: IstarLink<LK>;\n}\n\n/** True when `element` is the hub of an n-ary link. */\nexport function isHubElement(\n metamodel: AnyMetamodel,\n element: IstarElement<string> | undefined,\n): boolean {\n return element !== undefined && metamodel.elements.get(element.kind)?.role === 'hub';\n}\n\n/** The n-ary link whose hub is `hubId`; `undefined` when it isn't a hub. */\nexport function hubLinkOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n hubId: string,\n): HubLink<EK, LK> | undefined {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const hub = model.elements.get(hubId);\n if (!hub || !isHubElement(metamodel, hub)) return undefined;\n const legs: IstarLink<LK>[] = [];\n let end: IstarLink<LK> | undefined;\n for (const link of model.links.values()) {\n const role = metamodel.links.get(link.kind)?.role;\n if (role === 'leg' && link.target === hubId) legs.push(link);\n else if (role === 'end' && link.source === hubId) end ??= link;\n }\n return { hub, legs, ...(end ? { end } : {}) };\n}\n\n/** The hub a leg or end link belongs to. */\nexport function hubOfLink<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n linkId: string,\n): IstarElement<EK> | undefined {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const link = model.links.get(linkId);\n const role = link && metamodel.links.get(link.kind)?.role;\n if (!link || !role) return undefined;\n const hub = model.elements.get(role === 'leg' ? link.target : link.source);\n return isHubElement(metamodel, hub) ? hub : undefined;\n}\n\n/** The centre of an element's box: its display size, else its kind's default size. */\nexport function elementCenter<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n element: IstarElement<EK>,\n): Point {\n const size = (metamodelOf(model) as AnyMetamodel).elements.get(element.kind)?.size;\n const width = element.display?.width ?? size?.width ?? 0;\n const height = element.display?.height ?? size?.height ?? 0;\n return { x: element.x + width / 2, y: element.y + height / 2 };\n}\n\n/**\n * Where a new hub goes: centred between the source and the target, as DSM3-goals places it.\n * Returns its top-left corner for a hub of `size`.\n */\nexport function defaultHubPosition<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n source: IstarElement<EK>,\n target: IstarElement<EK>,\n size: Size,\n): Point {\n const a = elementCenter(model, source);\n const b = elementCenter(model, target);\n return { x: (a.x + b.x) / 2 - size.width / 2, y: (a.y + b.y) / 2 - size.height / 2 };\n}\n","/**\n * iStar 2.0 link constraints, ported from piStar's `tool/language/constraints.js`.\n *\n * Each check runs in the same order as upstream so the reported reason is the one piStar\n * would show. Upstream messages embed HTML and illustrative images; here they are plain text.\n */\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, LinkKindDefinition, LinkRules, Metamodel } from './metamodels';\nimport {\n LINK_SELECTOR,\n effectiveElementKind,\n effectiveLinkKind,\n elementBehavesLike,\n linkBehavesLike,\n} from './metamodels';\nimport type { AnyIstarModel, IstarElement, IstarLink, IstarModel } from './model';\nimport { metamodelOf } from './model';\n\nexport type ConstraintCode =\n | 'unknown-element'\n | 'unknown-link-kind'\n | 'invalid-source'\n | 'invalid-target'\n | 'actor-types-differ'\n | 'self-link'\n | 'duplicate-link'\n | 'dependum-endpoint'\n | 'same-actor'\n | 'different-actors'\n | 'refined-depender'\n | 'contributed-depender'\n | 'depender-target'\n | 'mixed-refinement'\n | 'contribution-and-qualification'\n /** A link other than a leg towards the hub of an n-ary link. */\n | 'hub-target'\n /** `validateModel`: the hub of an n-ary link lacks its end or every leg. */\n | 'incomplete-hub';\n\nexport type LinkCheck = { ok: true } | { ok: false; reason: string; code: ConstraintCode };\n\nconst OK: LinkCheck = { ok: true };\n\nfunction fail(code: ConstraintCode, reason: string): LinkCheck {\n return { ok: false, code, reason };\n}\n\ntype ElementRef = string | { readonly id: string };\n\n/**\n * True for a link, as opposed to an element: the target of a link kind whose rules target links\n * (see `LinkRules`) may be either.\n */\nexport function isLinkRef<EK extends string, LK extends string>(\n value: IstarElement<EK> | IstarLink<LK>,\n): value is IstarLink<LK> {\n const candidate = value as { source?: unknown; target?: unknown };\n return typeof candidate.source === 'string' && typeof candidate.target === 'string';\n}\n\nexport interface CanLinkOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /** Default: the model's metamodel, or iStar 2.0. */\n readonly metamodel?: Metamodel<EK, LK>;\n}\n\n/**\n * Checks whether a link of `kind` may be added from `source` to `target` in `model`.\n *\n * For dependency links, `source` is the depender and `target` the dependee (an actor or one of\n * its inner elements); the dependum sits between them and is not part of the check.\n *\n * Extended kinds (see `extendMetamodel`) are checked with the rules of the kind they behave\n * like, or with their declarative rules, then with their extra predicate.\n *\n * `target` may be a link (or a link id) for kinds whose rules target links (`LinkRules`).\n *\n * For an n-ary kind (`arity: 'n'`), a `target` that is one of its hubs is checked as a new leg\n * of that hub; any other target, as a new link from `source` to `target`.\n */\nexport function canLink<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n source: string | IstarElement<EK>,\n target: string | IstarElement<EK> | IstarLink<LK>,\n kind: LK,\n options: CanLinkOptions<EK, LK> = {},\n): LinkCheck {\n const any = model as unknown as AnyIstarModel;\n const metamodel = (options.metamodel ?? metamodelOf(model)) as unknown as AnyMetamodel;\n const s = resolve(any, source);\n const t = resolve(any, target) ?? any.links.get(refId(target));\n if (!s) return fail('unknown-element', `unknown source element \"${refId(source)}\"`);\n if (!t) return fail('unknown-element', `unknown target element \"${refId(target)}\"`);\n let definition = metamodel.links.get(kind);\n if (!definition) return fail('unknown-link-kind', `unknown link kind \"${String(kind)}\"`);\n // Linking to one of the kind's own hubs adds a leg to it.\n if (definition.parts && !isLinkRef(t) && metamodel.elements.get(t.kind)?.of === definition.kind) {\n definition = metamodel.links.get(definition.parts.leg) ?? definition;\n }\n return checkWith(new Graph(any, metamodel), definition, s, t);\n}\n\n/** Runs the rule a link kind resolves to, then every extra predicate along its chain. */\nfunction checkWith(\n graph: Graph,\n definition: LinkKindDefinition,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n): LinkCheck {\n const chain: LinkKindDefinition[] = [];\n for (\n let current: LinkKindDefinition | undefined = definition;\n current && !chain.includes(current);\n current = current.behavesLike ? graph.metamodel.links.get(current.behavesLike) : undefined\n ) {\n chain.push(current);\n }\n const root = chain[chain.length - 1]!;\n const builtIn = CHECKS[root.kind as LinkKind];\n let result: LinkCheck;\n if (root.rules)\n result = declarativeCheck(graph, definition, root.rules, root.kind, source, target);\n else if (isLinkRef(target)) result = elementTargetOnly(definition);\n else if (builtIn) result = builtIn(graph, source, target);\n else result = fail('unknown-link-kind', `link kind \"${definition.kind}\" has no rules`);\n if (!result.ok) return result;\n if (definition.role !== undefined && !isLinkRef(target)) {\n const hubResult = hubCheck(graph, definition, source, target);\n if (!hubResult.ok) return hubResult;\n }\n const context = graph.context(definition.kind, source, target);\n for (const step of chain.toReversed()) {\n if (!step.check) continue;\n const extra = step.check(context);\n if (!extra.ok) return extra;\n }\n return OK;\n}\n\n/**\n * What a leg or end must also respect: an n-ary link has one end, and the base kind's same-actor\n * rule holds between each leg's source and the end's target (the hub belongs to no actor).\n */\nfunction hubCheck(\n graph: Graph,\n definition: LinkKindDefinition,\n source: IstarElement<string>,\n target: IstarElement<string>,\n): LinkCheck {\n const base = definition.of === undefined ? undefined : graph.metamodel.links.get(definition.of);\n if (!base) return OK;\n const roleOf = (link: IstarLink<string>): string | undefined =>\n graph.metamodel.links.get(link.kind)?.role;\n if (definition.role === 'end') {\n for (const link of graph.model.links.values()) {\n if (link.source === source.id && roleOf(link) === 'end') {\n return fail('duplicate-link', `the hub of a ${base.label} link has only one end`);\n }\n }\n return OK;\n }\n if (base.rules?.sameActor === false) return OK;\n for (const link of graph.model.links.values()) {\n if (link.source !== target.id || roleOf(link) !== 'end') continue;\n if (graph.model.elements.get(link.target)?.parent !== source.parent) {\n return fail(\n 'different-actors',\n `the sources and target of a ${base.label} link must pertain to the same actor`,\n );\n }\n }\n return OK;\n}\n\n/** The built-in (iStar 2.0) rules only know element targets. */\nfunction elementTargetOnly(definition: LinkKindDefinition): LinkCheck {\n const article = /^[aeiou]/i.test(definition.label) ? 'an' : 'a';\n return fail(\n 'invalid-target',\n `the target of ${article} ${definition.label} link must be an element, not a link`,\n );\n}\n\nfunction refId(ref: ElementRef): string {\n return typeof ref === 'string' ? ref : ref.id;\n}\n\nfunction resolve(model: AnyIstarModel, ref: ElementRef): IstarElement<string> | undefined {\n // Always look the element up so a stale object can't be checked against a newer model.\n return model.elements.get(refId(ref));\n}\n\n/**\n * What an extension's `check` predicate receives: the model, the endpoints, and the graph\n * queries the iStar 2.0 rules use.\n */\nexport interface LinkRuleContext {\n readonly model: AnyIstarModel;\n readonly metamodel: AnyMetamodel;\n /** The link kind being added. */\n readonly kind: string;\n readonly source: IstarElement<string>;\n /** An element, or a link for kinds whose rules target links (narrow with `isLinkRef`). */\n readonly target: IstarElement<string> | IstarLink<string>;\n /**\n * A link (optionally of `kind`, or a kind behaving like it) joins `a` and `b`, either way. Both\n * may be elements or links.\n */\n isThereLinkBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind?: string,\n ): boolean;\n /** `element` is the source of a link of `kind` (or a kind behaving like it). */\n isSourceOfType(element: IstarElement<string>, kind: string): boolean;\n /** `element` is the target of a link of `kind` (or a kind behaving like it). */\n isTargetOfType(element: IstarElement<string>, kind: string): boolean;\n}\n\n/**\n * The graph queries used by upstream constraints (`istar.isThereLinkBetween`, etc.). Link kinds\n * are compared by what they behave like, so an extension link behaving like an OR-refinement\n * counts as one for the iStar 2.0 rules (no mixing with AND, no refining a depender…).\n */\nclass Graph {\n constructor(\n readonly model: AnyIstarModel,\n readonly metamodel: AnyMetamodel,\n ) {}\n\n private matches(link: IstarLink<string>, kind: string): boolean {\n return link.kind === kind || effectiveLinkKind(this.metamodel, link.kind) === kind;\n }\n\n /**\n * True when a link (optionally of `kind`) already connects the two elements, in either\n * direction. Mirrors `istar.isThereLinkBetween`.\n */\n isThereLinkBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind?: string,\n ): boolean {\n for (const link of this.model.links.values()) {\n if (kind && !this.matches(link, kind)) continue;\n if (\n (link.source === a.id && link.target === b.id) ||\n (link.source === b.id && link.target === a.id)\n ) {\n return true;\n }\n }\n return false;\n }\n\n /** Like `isThereLinkBetween`, counting only links of exactly `kind`. */\n isThereLinkOfKindBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind: string,\n ): boolean {\n for (const link of this.model.links.values()) {\n if (link.kind !== kind) continue;\n if (\n (link.source === a.id && link.target === b.id) ||\n (link.source === b.id && link.target === a.id)\n ) {\n return true;\n }\n }\n return false;\n }\n\n isSourceOfType(element: IstarElement<string>, kind: string): boolean {\n for (const link of this.model.links.values()) {\n if (link.source === element.id && this.matches(link, kind)) return true;\n }\n return false;\n }\n\n isTargetOfType(element: IstarElement<string>, kind: string): boolean {\n for (const link of this.model.links.values()) {\n if (link.target === element.id && this.matches(link, kind)) return true;\n }\n return false;\n }\n\n /** The kind the iStar 2.0 rules see: built-in kinds as they are, extensions as what they behave like. */\n kindOf(element: IstarElement<string>): string {\n return effectiveElementKind(this.metamodel, element.kind);\n }\n\n isActor(element: IstarElement<string>): boolean {\n return this.metamodel.elements.get(element.kind)?.category === 'actor';\n }\n\n context(\n kind: string,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n ): LinkRuleContext {\n return {\n model: this.model,\n metamodel: this.metamodel,\n kind,\n source,\n target,\n isThereLinkBetween: (a, b, k) => this.isThereLinkBetween(a, b, k),\n isSourceOfType: (e, k) => this.isSourceOfType(e, k),\n isTargetOfType: (e, k) => this.isTargetOfType(e, k),\n };\n }\n}\n\ntype Check = (\n graph: Graph,\n source: IstarElement<string>,\n target: IstarElement<string>,\n) => LinkCheck;\n\nconst is = (graph: Graph, element: IstarElement<string>, ...shortNames: string[]): boolean => {\n const kind = graph.kindOf(element);\n return shortNames.some((name) => kind === `istar.${name}`);\n};\n\nconst isDependum = (element: IstarElement<string>): boolean => element.isDependum === true;\n\nconst isALink: Check = (graph, source, target) => {\n // Upstream evaluates the source-kind check after the type-equality check without guarding\n // on the previous result, so its message wins when both fail. Reproduced here.\n if (!is(graph, source, 'Actor', 'Role')) {\n return fail(\n 'invalid-source',\n 'the source of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n );\n }\n if (source.kind !== target.kind) {\n return fail(\n 'actor-types-differ',\n 'the source and target of Is-A links must be of the same type - Actor and Actor, or Role and Role (iStar 2.0 Guide, Page 6).',\n );\n }\n if (!is(graph, target, 'Actor', 'Role')) {\n return fail(\n 'invalid-target',\n 'the target of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make Is-A links from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\nconst participatesInLink: Check = (graph, source, target) => {\n if (!graph.isActor(source)) {\n return fail(\n 'invalid-source',\n 'the source of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n );\n }\n if (!graph.isActor(target)) {\n return fail(\n 'invalid-target',\n 'the target of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Participates-In link from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\n/** The actor an element belongs to: itself for actors, its parent for inner elements. */\nfunction owningActorId(graph: Graph, element: IstarElement<string>): string | undefined {\n return graph.isActor(element) ? element.id : element.parent;\n}\n\nconst dependencyLink: Check = (graph, source, target) => {\n if (source.id === target.id) {\n return fail('self-link', 'a Dependency link cannot link an element onto itself');\n }\n if (isDependum(source)) {\n return fail('dependum-endpoint', 'a Dependency link cannot start from a dependum');\n }\n if (isDependum(target)) {\n return fail('dependum-endpoint', 'a Dependency link cannot end in a dependum');\n }\n if (owningActorId(graph, source) === owningActorId(graph, target)) {\n return fail(\n 'same-actor',\n 'a Dependency link must involve two different actors (iStar 2.0 Guide, Page 14)',\n );\n }\n if (\n graph.isTargetOfType(source, 'istar.OrRefinementLink') ||\n graph.isTargetOfType(source, 'istar.AndRefinementLink')\n ) {\n return fail(\n 'refined-depender',\n 'a refined element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n );\n }\n if (graph.isTargetOfType(source, 'istar.ContributionLink')) {\n return fail(\n 'contributed-depender',\n 'a contributed element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n );\n }\n return OK;\n};\n\nfunction refinementLink(label: 'AND' | 'OR'): Check {\n const other = label === 'AND' ? 'istar.OrRefinementLink' : 'istar.AndRefinementLink';\n return (graph, source, target) => {\n if (!is(graph, source, 'Task', 'Goal')) {\n return fail(\n 'invalid-source',\n `the source of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n );\n }\n if (!is(graph, target, 'Task', 'Goal')) {\n return fail(\n 'invalid-target',\n `the target of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n `you cannot make an ${label}-refinement link from an element onto itself`,\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n `you cannot make an ${label}-refinement link with a dependum (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n `the source and target of an ${label}-refinement link must pertain to the same actor (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one refinement link between the same two elements',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot refine a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-element.',\n );\n }\n if (graph.isTargetOfType(target, other)) {\n const mix =\n label === 'AND'\n ? 'you cannot mix AND-refinements with OR-refinements targeting the same element (iStar 2.0 Guide, Page 10).'\n : 'you cannot mix OR-refinements with AND-refinements targeting the same element (iStar 2.0 Guide, Page 10).';\n return fail('mixed-refinement', mix);\n }\n return OK;\n };\n}\n\nconst neededByLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Needed-By link must be a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(graph, target, 'Task')) {\n return fail(\n 'invalid-target',\n 'the target of a Needed-By link must be a Task (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Needed-By link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Needed-By link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Needed-By link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Needed-By link between the same two elements',\n );\n }\n return OK;\n};\n\nconst contributionLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Goal', 'Quality', 'Task', 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Contribution link must be a Goal, a Quality, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(graph, target, 'Quality')) {\n return fail(\n 'invalid-target',\n 'the target of a Contribution link must be a Quality (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n 'you cannot make a Contribution link from an element onto itself (iStar 2.0 Guide, Page 15)',\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Contribution link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Contribution link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Contribution link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Contribution and Qualification links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot contribute to a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-quality.',\n );\n }\n return OK;\n};\n\nconst qualificationLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Quality')) {\n return fail(\n 'invalid-source',\n 'the source of a Qualification link must be a Quality (iStar 2.0 Guide, Table 1)',\n );\n }\n if (!is(graph, target, 'Goal', 'Task', 'Resource')) {\n return fail(\n 'invalid-target',\n 'the target of a Qualification link must be a Goal, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Qualification link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Qualification link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Qualification link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Qualification link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Qualification and Contribution links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n return OK;\n};\n\n/** The words used for a list of kind selectors in messages: \"a Goal or a Task\". */\nfunction describe(graph: Graph, selectors: readonly string[]): string {\n const names = selectors.map((selector) => {\n if (selector === '*') return 'any element';\n if (selector === 'node') return 'an intentional element';\n if (selector === 'actor') return 'an actor';\n if (selector === LINK_SELECTOR) return 'a link';\n const linkLabel = graph.metamodel.links.get(selector)?.label;\n if (linkLabel !== undefined) {\n return /^[aeiou]/i.test(linkLabel) ? `an ${linkLabel} link` : `a ${linkLabel} link`;\n }\n const label = graph.metamodel.elements.get(selector)?.label ?? selector;\n return /^[aeiou]/i.test(label) ? `an ${label}` : `a ${label}`;\n });\n return names.length <= 2\n ? names.join(' or ')\n : `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}`;\n}\n\nfunction matchesSelector(\n graph: Graph,\n element: IstarElement<string> | IstarLink<string>,\n selector: string,\n): boolean {\n // Links match `link` and link kinds (and what behaves like them); elements never do.\n if (isLinkRef(element)) {\n return selector === LINK_SELECTOR || linkBehavesLike(graph.metamodel, element.kind, selector);\n }\n if (selector === LINK_SELECTOR) return false;\n // A hub is only matched by its own kind's name: categories never include it.\n if (graph.metamodel.elements.get(element.kind)?.role === 'hub') {\n return element.kind === selector;\n }\n if (selector === '*') return true;\n const category = graph.metamodel.elements.get(element.kind)?.category;\n if (selector === 'node' || selector === 'actor') return category === selector;\n return elementBehavesLike(graph.metamodel, element.kind, selector);\n}\n\n/**\n * Declarative rules of an extension link kind, checked in the order of the iStar 2.0 node-link\n * rules (and of piStar-ext's generated `isValid`): source kind, target kind, self link,\n * dependum, same actor, duplicates. A link target skips the self, dependum and same-actor rules,\n * which are about elements.\n */\nfunction declarativeCheck(\n graph: Graph,\n definition: LinkKindDefinition,\n rules: LinkRules,\n rulesKind: string,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n): LinkCheck {\n const name = definition.label;\n const article = /^[aeiou]/i.test(name) ? 'an' : 'a';\n if (!rules.sources.some((selector) => matchesSelector(graph, source, selector))) {\n return fail(\n 'invalid-source',\n `the source of ${article} ${name} link must be ${describe(graph, rules.sources)}`,\n );\n }\n if (!rules.targets.some((selector) => matchesSelector(graph, target, selector))) {\n const targetKind = isLinkRef(target) ? undefined : graph.metamodel.elements.get(target.kind);\n const hubOf =\n targetKind?.role === 'hub' && targetKind.of !== undefined\n ? graph.metamodel.links.get(targetKind.of)\n : undefined;\n if (hubOf) {\n return fail(\n 'hub-target',\n `you cannot make ${article} ${name} link towards the hub of ${/^[aeiou]/i.test(hubOf.label) ? 'an' : 'a'} ${hubOf.label} link`,\n );\n }\n return fail(\n 'invalid-target',\n `the target of ${article} ${name} link must be ${describe(graph, rules.targets)}`,\n );\n }\n if (!rules.allowSelf && source.id === target.id) {\n return fail('self-link', `you cannot make ${article} ${name} link from an element onto itself`);\n }\n if (definition.category === 'node' && !isLinkRef(target)) {\n if (!rules.allowDependum && (isDependum(source) || isDependum(target))) {\n return fail('dependum-endpoint', `you cannot make ${article} ${name} link with a dependum`);\n }\n if (rules.sameActor !== false && source.parent !== target.parent) {\n return fail(\n 'different-actors',\n `the source and target of ${article} ${name} link must pertain to the same actor (iStar 2.0 Guide, Page 14)`,\n );\n }\n }\n const unique = rules.unique ?? 'kind';\n if (\n (unique === 'any' && graph.isThereLinkBetween(source, target)) ||\n (unique === 'kind' && graph.isThereLinkOfKindBetween(source, target, definition.kind)) ||\n // A kind inheriting these rules shares the limit with the kind that declares them.\n (unique === 'kind' &&\n rulesKind !== definition.kind &&\n graph.isThereLinkOfKindBetween(source, target, rulesKind))\n ) {\n return fail(\n 'duplicate-link',\n `there can only be one ${name} link between the same two elements`,\n );\n }\n return OK;\n}\n\nconst CHECKS: Partial<Readonly<Record<string, Check>>> = {\n 'istar.IsALink': isALink,\n 'istar.ParticipatesInLink': participatesInLink,\n 'istar.DependencyLink': dependencyLink,\n 'istar.AndRefinementLink': refinementLink('AND'),\n 'istar.OrRefinementLink': refinementLink('OR'),\n 'istar.NeededByLink': neededByLink,\n 'istar.ContributionLink': contributionLink,\n 'istar.QualificationLink': qualificationLink,\n};\n\nexport interface ModelIssue<LK extends string = LinkKind> {\n readonly linkId: string;\n readonly kind: LK;\n readonly source: string;\n readonly target: string;\n readonly code: ConstraintCode;\n readonly message: string;\n}\n\n/**\n * Re-validates every link of a model, the way piStar does when loading a file: dependencies\n * first (each checked before its own links are added), then the remaining links in file\n * order, each against the graph built so far, and last the links that target links. Invalid\n * links are reported, not removed. A hub without an end or legs is reported with code\n * `incomplete-hub`, the hub's id as `linkId` and the n-ary kind as `kind`.\n */\nexport function validateModel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n options: CanLinkOptions<EK, LK>,\n): ModelIssue<LK>[];\nexport function validateModel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): ModelIssue<LK>[];\n// 0.7.0's exact signature comes last, so `models.map(validateModel)` types as before.\nexport function validateModel(model: IstarModel): ModelIssue[];\nexport function validateModel<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n options?: CanLinkOptions<EK, LK>,\n): ModelIssue<LK>[] {\n // As an array callback the second argument is an index: ignore anything but options.\n const given = typeof options === 'object' && options !== null ? options.metamodel : undefined;\n const metamodel = (given ?? metamodelOf(model)) as unknown as AnyMetamodel;\n const any = model as unknown as AnyIstarModel;\n const issues: ModelIssue<LK>[] = [];\n const accepted = new Map<string, IstarLink<string>>();\n const view = (): AnyIstarModel => ({ ...any, links: accepted });\n const check = (source: string, target: string, kind: string): LinkCheck =>\n canLink(view(), source, target, kind, { metamodel });\n const isDependency = (link: IstarLink<string>): boolean =>\n metamodel.links.get(link.kind)?.category === 'dependency';\n\n const report = (\n linkId: string,\n kind: string,\n source: string,\n target: string,\n result: LinkCheck,\n ): void => {\n if (!result.ok) {\n issues.push({\n linkId,\n kind: kind as LK,\n source,\n target,\n code: result.code,\n message: result.reason,\n });\n }\n };\n\n const dependencyLinks = [...any.links.values()].filter(isDependency);\n for (const dependum of any.elements.values()) {\n if (!dependum.isDependum) continue;\n const inbound = dependencyLinks.find((l) => l.target === dependum.id);\n const outbound = dependencyLinks.find((l) => l.source === dependum.id);\n const depender = inbound?.source ?? dependum.dependency?.source;\n const dependee = outbound?.target ?? dependum.dependency?.target;\n const kind = inbound?.kind ?? outbound?.kind ?? 'istar.DependencyLink';\n if (depender !== undefined && dependee !== undefined) {\n report(inbound?.id ?? dependum.id, kind, depender, dependee, check(depender, dependee, kind));\n }\n if (inbound) accepted.set(inbound.id, inbound);\n if (outbound) accepted.set(outbound.id, outbound);\n }\n\n // Links that target links come second, so the links they point at are known whatever the\n // order (an Argument may be written before the Contribution it argues about).\n const rest = [...any.links.values()].filter((link) => !isDependency(link));\n const targetsLink = (link: IstarLink<string>): boolean =>\n !any.elements.has(link.target) && any.links.has(link.target);\n for (const link of [\n ...rest.filter((l) => !targetsLink(l)),\n ...rest.filter((l) => targetsLink(l)),\n ]) {\n if (any.elements.has(link.source) && (any.elements.has(link.target) || targetsLink(link))) {\n report(\n link.id,\n link.kind,\n link.source,\n link.target,\n check(link.source, link.target, link.kind),\n );\n } else {\n report(link.id, link.kind, link.source, link.target, {\n ok: false,\n code: 'unknown-element',\n reason: 'the link refers to an element that does not exist',\n });\n }\n accepted.set(link.id, link);\n }\n\n // Each hub needs an end and at least one leg.\n for (const hub of any.elements.values()) {\n const hubKind = metamodel.elements.get(hub.kind);\n if (hubKind?.role !== 'hub' || hubKind.of === undefined) continue;\n const base = metamodel.links.get(hubKind.of);\n const roleOf = (link: IstarLink<string>): string | undefined =>\n metamodel.links.get(link.kind)?.role;\n const legs = rest.filter((l) => l.target === hub.id && roleOf(l) === 'leg');\n const end = rest.find((l) => l.source === hub.id && roleOf(l) === 'end');\n if (legs.length > 0 && end) continue;\n const label = base?.label ?? hubKind.of;\n issues.push({\n linkId: hub.id,\n kind: hubKind.of as LK,\n source: legs[0]?.source ?? hub.id,\n target: end?.target ?? hub.id,\n code: 'incomplete-hub',\n message: end\n ? `the hub of a ${label} link needs at least one leg`\n : `the hub of a ${label} link needs an end`,\n });\n }\n return issues;\n}\n","/**\n * A model file's own metamodel: the top-level `\"metamodel\"` block, in which a file declares the\n * constructs it adds to iStar (as piStar-ext's \"Add new\" creates them), so they travel with the\n * model instead of living only in a tool's localStorage.\n *\n * The block has the shape `extendMetamodel` takes (`MetamodelExtension`), as JSON: no `check`\n * predicates, and presentation hints (`shape`, `textBox`, `line`) kept as data. Keys this\n * library doesn't know, in the block or in any entry, are left alone (hosts keep dialect data,\n * such as stereotypes, beside it) and are written back unchanged.\n */\nimport type { ElementKindDeclaration, LinkKindDeclaration, MetamodelExtension } from './metamodels';\nimport { MetamodelError } from './metamodels';\n\n/** The top-level key of the block in piStar JSON. */\nexport const FILE_METAMODEL_KEY = 'metamodel';\n\nexport interface FileElementKind extends Omit<ElementKindDeclaration<string>, 'info'> {\n readonly info?: {\n readonly canBeInnerElement?: boolean;\n readonly canBeDependum?: boolean;\n readonly canBeOnPaper?: boolean;\n };\n readonly [key: string]: unknown;\n}\n\nexport interface FileLinkKind extends Omit<LinkKindDeclaration<string>, 'check'> {\n readonly [key: string]: unknown;\n}\n\n/** The `\"metamodel\"` block of a model file. */\nexport interface FileMetamodel {\n /** Identifies the constructs' dialect, e.g. `iStar4RationalAgents`. */\n readonly name: string;\n readonly elements?: readonly FileElementKind[];\n readonly links?: readonly FileLinkKind[];\n readonly [key: string]: unknown;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction fail(path: string, message: string): never {\n throw new MetamodelError(`${path} ${message}`);\n}\n\nfunction optionalString(entry: Record<string, unknown>, key: string, path: string): void {\n if (entry[key] !== undefined && typeof entry[key] !== 'string') {\n fail(`${path}.${key}`, 'must be a string');\n }\n}\n\nfunction optionalBoolean(entry: Record<string, unknown>, key: string, path: string): void {\n if (entry[key] !== undefined && typeof entry[key] !== 'boolean') {\n fail(`${path}.${key}`, 'must be true or false');\n }\n}\n\nfunction checkSize(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { width, height }');\n for (const key of ['width', 'height']) {\n const n = value[key];\n if (typeof n !== 'number' || !Number.isFinite(n) || n <= 0) {\n fail(`${path}.${key}`, 'must be a positive number');\n }\n }\n}\n\nfunction checkShape(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { path, viewBox? }');\n if (typeof value.path !== 'string' || value.path.trim() === '') {\n fail(`${path}.path`, 'must be SVG path data');\n }\n optionalString(value, 'viewBox', path);\n}\n\nfunction checkTextBox(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { top, right, bottom, left }');\n for (const key of ['top', 'right', 'bottom', 'left']) {\n const n = value[key];\n if (typeof n !== 'number' || n < 0 || n >= 1) {\n fail(`${path}.${key}`, 'must be a fraction from 0 (inclusive) to 1 (exclusive)');\n }\n }\n}\n\nfunction checkLine(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { dash?, marker?, markerFilled? }');\n optionalString(value, 'dash', path);\n if (value.marker !== undefined && value.marker !== false && typeof value.marker !== 'string') {\n fail(`${path}.marker`, 'must be SVG path data or false');\n }\n optionalBoolean(value, 'markerFilled', path);\n}\n\nfunction checkStringList(value: unknown, path: string): void {\n if (!Array.isArray(value) || value.length === 0 || value.some((v) => typeof v !== 'string')) {\n fail(path, 'must be a non-empty list of kind names or categories');\n }\n}\n\nfunction checkRules(value: unknown, path: string): void {\n if (!isObject(value)) fail(path, 'must be an object { sources, targets, … }');\n checkStringList(value.sources, `${path}.sources`);\n checkStringList(value.targets, `${path}.targets`);\n for (const key of ['sameActor', 'allowDependum', 'allowSelf']) optionalBoolean(value, key, path);\n if (value.unique !== undefined && !['kind', 'any', false].includes(value.unique as never)) {\n fail(`${path}.unique`, 'must be \"kind\", \"any\" or false');\n }\n}\n\n/**\n * Checks that `value` is a well-formed `\"metamodel\"` block and returns it typed. Throws\n * `MetamodelError` naming the offending path (`metamodel.elements[1].kind must be a string`).\n * Whether its kinds fit a given metamodel (namespacing, collisions, `behavesLike` targets) is\n * checked when it is applied, by `extendMetamodel`.\n */\nexport function validateFileMetamodel(\n value: unknown,\n path: string = FILE_METAMODEL_KEY,\n): FileMetamodel {\n if (!isObject(value)) fail(path, 'must be an object { name, elements?, links? }');\n if (typeof value.name !== 'string' || value.name === '')\n fail(`${path}.name`, 'must be a non-empty string');\n for (const [listKey, kind] of [\n ['elements', 'element'],\n ['links', 'link'],\n ] as const) {\n const list = value[listKey];\n if (list === undefined) continue;\n if (!Array.isArray(list)) fail(`${path}.${listKey}`, 'must be a list');\n list.forEach((entry: unknown, i) => {\n const at = `${path}.${listKey}[${i}]`;\n if (!isObject(entry)) fail(at, `must be an object describing a ${kind} kind`);\n if (typeof entry.kind !== 'string' || entry.kind === '')\n fail(`${at}.kind`, 'must be a string');\n optionalString(entry, 'label', at);\n optionalString(entry, 'behavesLike', at);\n optionalString(entry, 'pistarType', at);\n if (kind === 'element') {\n if (\n entry.category !== undefined &&\n entry.category !== 'node' &&\n entry.category !== 'actor'\n ) {\n fail(`${at}.category`, 'must be \"node\" or \"actor\"');\n }\n checkSize(entry.size, `${at}.size`);\n if (entry.info !== undefined) {\n if (!isObject(entry.info)) fail(`${at}.info`, 'must be an object');\n for (const key of ['canBeInnerElement', 'canBeDependum', 'canBeOnPaper']) {\n optionalBoolean(entry.info, key, `${at}.info`);\n }\n }\n checkShape(entry.shape, `${at}.shape`);\n checkTextBox(entry.textBox, `${at}.textBox`);\n } else {\n if (\n entry.category !== undefined &&\n !['node', 'actor', 'dependency'].includes(entry.category as string)\n ) {\n fail(`${at}.category`, 'must be \"node\", \"actor\" or \"dependency\"');\n }\n if (entry.rules !== undefined) checkRules(entry.rules, `${at}.rules`);\n if ('check' in entry) fail(`${at}.check`, 'cannot be stored in a file (it is code)');\n if (entry.info !== undefined && !isObject(entry.info))\n fail(`${at}.info`, 'must be an object');\n checkLine(entry.line, `${at}.line`);\n }\n });\n }\n return value as FileMetamodel;\n}\n\n/** The block as an extension `extendMetamodel` applies (it ignores the extra keys). */\nexport function fileMetamodelExtension(block: FileMetamodel): MetamodelExtension<string, string> {\n return block as unknown as MetamodelExtension<string, string>;\n}\n","/**\n * Reading and writing piStar save files, ported from `tool/app/istarcore/fileManager.js`.\n *\n * Output is produced with the same key order and `JSON.stringify(_, null, 2)` formatting as the\n * piStar web tool, so a file saved by piStar round-trips byte for byte. Keys this library does\n * not interpret are kept and written back.\n */\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, Metamodel } from './metamodels';\nimport { ISTAR_2_0, MetamodelError, extendMetamodel } from './metamodels';\nimport { sharedWeakMap } from './shared';\nimport type { FileMetamodel } from './file-metamodel';\nimport {\n FILE_METAMODEL_KEY,\n fileMetamodelExtension,\n validateFileMetamodel,\n} from './file-metamodel';\nimport type {\n CustomProperties,\n Diagram,\n ElementDisplay,\n Extra,\n IstarElement,\n IstarLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport {\n dependencyLinksOf,\n hostMetamodelOf,\n metamodelOf,\n setHostMetamodel,\n withMetamodel,\n} from './model';\nimport type { AnyIstarModel } from './model';\n\n// ---------------------------------------------------------------------------------------------\n// File format types\n\nexport interface PistarElementJson {\n id: string;\n text: string;\n type: string;\n x: number;\n y: number;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface PistarActorJson extends PistarElementJson {\n nodes: PistarElementJson[];\n}\n\nexport interface PistarDependencyJson extends PistarElementJson {\n source: string;\n target: string;\n}\n\nexport interface PistarLinkJson {\n id: string;\n type: string;\n source: string;\n target: string;\n name?: string;\n customProperties?: Record<string, string>;\n label?: string;\n [key: string]: unknown;\n}\n\n/** The hub of an n-ary link, in a hub entry: an element without `text`. */\nexport interface PistarHubJson {\n id: string;\n type: string;\n x: number;\n y: number;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/**\n * An n-ary link (see `LinkKindDeclaration.arity`) in `links`, as DSM3-goals writes it: no id of\n * its own, its hub, its legs (`starts`) and its end.\n */\nexport interface PistarHubLinkJson {\n hub: PistarHubJson;\n starts: PistarLinkJson[];\n end?: PistarLinkJson;\n [key: string]: unknown;\n}\n\n/**\n * Key of a hub element's `extra` that holds its entry's unknown keys (those beside `hub`,\n * `starts` and `end`), so they are written back on the entry.\n */\nexport const HUB_ENTRY_KEY = '__hubEntry';\n\nexport interface PistarDiagramJson {\n width?: number;\n height?: number;\n name?: string;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/** A piStar save file. Older piStar versions may omit some sections (e.g. `orphans`). */\nexport interface PistarFile {\n actors: PistarActorJson[];\n orphans?: PistarElementJson[];\n dependencies?: PistarDependencyJson[];\n links?: (PistarLinkJson | PistarHubLinkJson)[];\n display?: Record<string, Record<string, unknown>>;\n tool?: string;\n istar?: string;\n saveDate?: string;\n diagram?: PistarDiagramJson;\n [key: string]: unknown;\n}\n\nexport class PistarParseError extends Error {\n override name = 'PistarParseError';\n}\n\n/** Thrown by `toPistar` for a kind its metamodel doesn't know (rather than writing it wrong). */\nexport class PistarWriteError extends Error {\n override name = 'PistarWriteError';\n}\n\n/**\n * Parse-time bookkeeping that lets `toPistar` reproduce the original key order. It has no\n * meaning for the model itself and may be dropped.\n */\nexport interface SourceLayout {\n /** Top-level keys in file order. */\n readonly keys: readonly string[];\n /** `display` ids in file order. */\n readonly display: readonly string[];\n /**\n * Each element's, link's and hub entry's keys in file order, by id (a hub's entry under\n * `hubEntryLayoutKey(id)`), and the diagram's under `DIAGRAM_LAYOUT_KEY`. Files written by\n * other tools order keys differently from piStar; this keeps them as they were.\n */\n readonly objects?: ReadonlyMap<string, readonly string[]>;\n}\n\n/** The `objects` key of a hub's entry (`{ hub, starts, end }`) in a `SourceLayout`. */\nexport function hubEntryLayoutKey(hubId: string): string {\n return `${hubId}\\u0000entry`;\n}\n/** The `objects` key of the diagram in a `SourceLayout`. */\nexport const DIAGRAM_LAYOUT_KEY = '\\u0000diagram';\n\nconst layouts = sharedWeakMap<SourceLayout>('layouts');\n\n/** The key order recorded when `model` was parsed, if it came from `parsePistar`. */\nexport function getSourceLayout<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): SourceLayout | undefined {\n return layouts.get(model);\n}\n\n/**\n * Carries the recorded key order over to a model derived from `from` (the store does this for\n * every edit, so saving an edited file keeps a stable diff).\n */\nexport function inheritSourceLayout<M extends IstarModel<string, string>>(\n from: IstarModel<string, string>,\n to: M,\n): M {\n const layout = layouts.get(from);\n if (layout && from !== to) layouts.set(to, layout);\n return to;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Parsing\n\nconst ELEMENT_KEYS = new Set(['id', 'text', 'type', 'x', 'y', 'customProperties']);\nconst ACTOR_KEYS = new Set([...ELEMENT_KEYS, 'nodes']);\nconst DEPENDENCY_KEYS = new Set([...ELEMENT_KEYS, 'source', 'target']);\nconst LINK_KEYS = new Set(['id', 'type', 'source', 'target', 'name', 'customProperties', 'label']);\nconst HUB_KEYS = new Set(['id', 'type', 'x', 'y', 'customProperties']);\nconst HUB_ENTRY_KEYS = new Set(['hub', 'starts', 'end']);\nconst DIAGRAM_KEYS = new Set(['width', 'height', 'name', 'customProperties']);\nconst TOP_LEVEL_KEYS = [\n 'actors',\n 'orphans',\n 'dependencies',\n 'links',\n 'display',\n 'tool',\n 'istar',\n 'saveDate',\n 'diagram',\n] as const;\nconst TOP_LEVEL_KEY_SET: ReadonlySet<string> = new Set(TOP_LEVEL_KEYS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction extraOf(json: Record<string, unknown>, known: ReadonlySet<string>): Extra | undefined {\n let extra: Record<string, unknown> | undefined;\n for (const key of Object.keys(json)) {\n if (!known.has(key)) (extra ??= {})[key] = json[key];\n }\n return extra;\n}\n\nfunction asArray(value: unknown, where: string): unknown[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) throw new PistarParseError(`\"${where}\" must be an array`);\n return value;\n}\n\n/**\n * Parses a piStar save file (JSON text or an already-parsed object). The input is not mutated.\n *\n * Unlike the piStar tool, elements with `x` or `y` equal to 0 are kept: upstream's\n * `if (element.x && element.y)` silently drops them, which looks unintended.\n */\nexport interface ParsePistarOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * Read the file's own `\"metamodel\"` block (see `FileMetamodel`) and parse with `metamodel`\n * (or iStar 2.0) extended by it. Default false: the block is kept as an unknown key and not\n * applied, as before. A block whose kinds collide with the metamodel throws `MetamodelError`.\n */\n readonly fileMetamodel?: boolean;\n /**\n * The metamodel whose kinds the file may use. Default iStar 2.0: any other `type` throws,\n * as in the piStar tool. The parsed model remembers it (see `metamodelOf`).\n */\n readonly metamodel?: Metamodel<EK, LK>;\n}\n\n// The iStar 2.0 overload comes last, so `parsePistar` passed as a callback types as before.\n// With the file's own metamodel, kinds are only known at run time.\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<string, string> & { readonly fileMetamodel: true },\n): IstarModel<string, string>;\nexport function parsePistar<EK extends string, LK extends string>(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<EK, LK> & { readonly metamodel: Metamodel<EK, LK> },\n): IstarModel<EK, LK>;\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions,\n): IstarModel;\nexport function parsePistar(input: string | PistarFile | Record<string, unknown>): IstarModel;\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<string, string> = {},\n): AnyIstarModel {\n let metamodel: AnyMetamodel = options.metamodel ?? ISTAR_2_0;\n const categoryOf = (kind: string): string | undefined => metamodel.elements.get(kind)?.category;\n let json: unknown;\n if (typeof input === 'string') {\n try {\n json = JSON.parse(input);\n } catch (error) {\n throw new PistarParseError(`invalid JSON: ${(error as Error).message}`, { cause: error });\n }\n } else {\n json = structuredClone(input);\n }\n if (!isRecord(json)) throw new PistarParseError('a piStar model must be a JSON object');\n\n // The file's own constructs extend the host's metamodel before anything is read with it.\n let host: AnyMetamodel | undefined;\n if (options.fileMetamodel && json[FILE_METAMODEL_KEY] !== undefined) {\n const block = validateFileMetamodel(json[FILE_METAMODEL_KEY]);\n host = metamodel;\n metamodel = extendMetamodel(metamodel, fileMetamodelExtension(block));\n }\n\n const display = isRecord(json.display) ? json.display : {};\n const usedDisplay = new Set<string>();\n const elements = new Map<string, IstarElement<string>>();\n const links = new Map<string, IstarLink<string>>();\n\n const displayFor = (id: string): Record<string, unknown> | undefined => {\n const entry = display[id];\n if (!isRecord(entry)) return undefined;\n usedDisplay.add(id);\n return entry;\n };\n\n const objects = new Map<string, readonly string[]>();\n const readElement = (\n raw: unknown,\n where: string,\n known: ReadonlySet<string>,\n extras: Partial<IstarElement<string>>,\n ): IstarElement<string> => {\n if (!isRecord(raw)) throw new PistarParseError(`${where}: expected an object`);\n const { id, type } = raw;\n if (typeof id !== 'string' || id === '') {\n throw new PistarParseError(`${where}: missing \"id\"`);\n }\n const kind = typeof type === 'string' ? metamodel.elementsByPistarType.get(type) : undefined;\n if (kind === undefined) {\n throw new PistarParseError(`${where} (${id}): unknown element type ${JSON.stringify(type)}`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`${where}: duplicated id \"${id}\"`);\n }\n const element: IstarElement<string> = {\n id,\n kind,\n name: typeof raw.text === 'string' ? raw.text : '',\n x: typeof raw.x === 'number' ? raw.x : 0,\n y: typeof raw.y === 'number' ? raw.y : 0,\n ...extras,\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('display', displayFor(id) as ElementDisplay | undefined),\n ...optional('extra', extraOf(raw, known)),\n };\n elements.set(id, element);\n objects.set(id, Object.keys(raw));\n return element;\n };\n\n asArray(json.actors, 'actors').forEach((raw, i) => {\n const actor = readElement(raw, `actors[${i}]`, ACTOR_KEYS, {});\n if (categoryOf(actor.kind) !== 'actor') {\n throw new PistarParseError(`actors[${i}] (${actor.id}): ${actor.kind} is not an actor kind`);\n }\n asArray((raw as Record<string, unknown>).nodes, `actors[${i}].nodes`).forEach((node, j) => {\n const child = readElement(node, `actors[${i}].nodes[${j}]`, ELEMENT_KEYS, {\n parent: actor.id,\n });\n if (categoryOf(child.kind) === 'actor') {\n throw new PistarParseError(`actors[${i}].nodes[${j}]: actors cannot be nested`);\n }\n });\n });\n\n asArray(json.orphans, 'orphans').forEach((raw, i) => {\n readElement(raw, `orphans[${i}]`, ELEMENT_KEYS, {});\n });\n\n asArray(json.dependencies, 'dependencies').forEach((raw, i) => {\n const r = raw as Record<string, unknown>;\n const dependency =\n typeof r.source === 'string' && typeof r.target === 'string'\n ? { dependency: { source: r.source, target: r.target } }\n : {};\n readElement(raw, `dependencies[${i}]`, DEPENDENCY_KEYS, { isDependum: true, ...dependency });\n });\n\n const readLink = (raw: unknown, where: string): IstarLink<string> => {\n if (!isRecord(raw)) throw new PistarParseError(`${where}: expected an object`);\n const { id, type, source, target } = raw;\n if (typeof id !== 'string' || id === '') throw new PistarParseError(`${where}: missing \"id\"`);\n const kind = typeof type === 'string' ? metamodel.linksByPistarType.get(type) : undefined;\n if (kind === undefined) {\n throw new PistarParseError(`${where} (${id}): unknown link type ${JSON.stringify(type)}`);\n }\n if (typeof source !== 'string' || typeof target !== 'string') {\n throw new PistarParseError(`${where} (${id}): missing \"source\" or \"target\"`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`${where}: duplicated id \"${id}\"`);\n }\n const link: IstarLink<string> = {\n id,\n kind,\n source,\n target,\n ...optional('name', typeof raw.name === 'string' ? raw.name : undefined),\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('label', typeof raw.label === 'string' ? raw.label : undefined),\n ...optional('display', displayFor(id) as LinkDisplay | undefined),\n ...optional('extra', extraOf(raw, LINK_KEYS)),\n };\n links.set(id, link);\n objects.set(id, Object.keys(raw));\n return link;\n };\n\n // An n-ary link: its hub becomes an element, its legs then its end ordinary links.\n const readHubEntry = (raw: Record<string, unknown>, where: string): void => {\n const hub = readElement(raw.hub, `${where}.hub`, HUB_KEYS, {});\n const hubKind = metamodel.elements.get(hub.kind);\n if (hubKind?.role !== 'hub') {\n throw new PistarParseError(`${where}.hub (${hub.id}): ${hub.kind} is not a hub kind`);\n }\n objects.set(hubEntryLayoutKey(hub.id), Object.keys(raw));\n const entryExtra = extraOf(raw, HUB_ENTRY_KEYS);\n if (entryExtra) {\n elements.set(hub.id, { ...hub, extra: { ...hub.extra, [HUB_ENTRY_KEY]: entryExtra } });\n }\n const roleOf = (link: IstarLink<string>): string | undefined => {\n const definition = metamodel.links.get(link.kind);\n return definition?.of === hubKind.of ? definition?.role : undefined;\n };\n asArray(raw.starts, `${where}.starts`).forEach((rawLeg, j) => {\n const leg = readLink(rawLeg, `${where}.starts[${j}]`);\n if (roleOf(leg) !== 'leg' || leg.target !== hub.id) {\n throw new PistarParseError(\n `${where}.starts[${j}] (${leg.id}): not a leg of the hub \"${hub.id}\"`,\n );\n }\n });\n if (raw.end !== undefined) {\n const end = readLink(raw.end, `${where}.end`);\n if (roleOf(end) !== 'end' || end.source !== hub.id) {\n throw new PistarParseError(`${where}.end (${end.id}): not the end of the hub \"${hub.id}\"`);\n }\n }\n };\n\n asArray(json.links, 'links').forEach((raw, i) => {\n if (isRecord(raw) && isRecord(raw.hub)) readHubEntry(raw, `links[${i}]`);\n else readLink(raw, `links[${i}]`);\n });\n\n let extraDisplay: Record<string, unknown> | undefined;\n for (const [id, value] of Object.entries(display)) {\n if (!usedDisplay.has(id)) (extraDisplay ??= {})[id] = value;\n }\n\n let diagram: Diagram | undefined;\n if (isRecord(json.diagram)) {\n const d = json.diagram;\n diagram = {\n ...optional('width', typeof d.width === 'number' ? d.width : undefined),\n ...optional('height', typeof d.height === 'number' ? d.height : undefined),\n ...optional('name', typeof d.name === 'string' ? d.name : undefined),\n ...(isRecord(d.customProperties)\n ? { customProperties: d.customProperties as CustomProperties }\n : {}),\n ...optional('extra', extraOf(d, DIAGRAM_KEYS)),\n };\n objects.set(DIAGRAM_LAYOUT_KEY, Object.keys(d));\n }\n\n const model: AnyIstarModel = {\n elements,\n links,\n ...optional('diagram', diagram),\n ...optional('tool', typeof json.tool === 'string' ? json.tool : undefined),\n ...optional('istar', typeof json.istar === 'string' ? json.istar : undefined),\n ...optional('saveDate', typeof json.saveDate === 'string' ? json.saveDate : undefined),\n ...optional('extraDisplay', extraDisplay),\n ...optional('extra', extraOf(json, TOP_LEVEL_KEY_SET)),\n };\n layouts.set(model, { keys: Object.keys(json), display: Object.keys(display), objects });\n // The block stays in `extra`, so it is written back exactly as read.\n setHostMetamodel(model, host);\n return withMetamodel(model, metamodel);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Which language a file is in\n\nfunction parseJson(json: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof json !== 'string') return json;\n let value: unknown;\n try {\n value = JSON.parse(json);\n } catch (error) {\n throw new PistarParseError(`invalid JSON: ${(error as Error).message}`, { cause: error });\n }\n if (!isRecord(value)) throw new PistarParseError('a piStar model must be a JSON object');\n return value;\n}\n\n/** `kaos` for an object whose `type` is `kaos.Softgoal`. */\nfunction prefixOf(value: unknown): string | undefined {\n const type = isRecord(value) ? value.type : undefined;\n const dot = typeof type === 'string' ? type.indexOf('.') : -1;\n return dot > 0 ? (type as string).slice(0, dot) : undefined;\n}\n\nfunction arrayOf(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\n/**\n * The namespace of the first `type` in a file (`kaos` for `kaos.Softgoal`), looking at actors and\n * their nodes, orphans, dependencies, then links (hub entries included). `undefined` when no\n * element or link has a namespaced type. Throws `PistarParseError` for a string that isn't JSON.\n */\nexport function detectPrefix(json: string | Record<string, unknown>): string | undefined {\n const file = parseJson(json);\n const candidates = function* (): Generator<unknown> {\n for (const actor of arrayOf(file.actors)) {\n yield actor;\n if (isRecord(actor)) yield* arrayOf(actor.nodes);\n }\n yield* arrayOf(file.orphans);\n yield* arrayOf(file.dependencies);\n for (const link of arrayOf(file.links)) {\n if (isRecord(link) && isRecord(link.hub)) {\n yield link.hub;\n yield* arrayOf(link.starts);\n yield link.end;\n } else {\n yield link;\n }\n }\n };\n for (const candidate of candidates()) {\n const prefix = prefixOf(candidate);\n if (prefix !== undefined) return prefix;\n }\n return undefined;\n}\n\n/**\n * Which of `roots` a file is written in: the one whose `prefix` is the file's (`detectPrefix`);\n * for a file without types, the only one whose `file.tool` is the file's `tool`; otherwise\n * `undefined`. Pass the result to `parsePistar(json, { metamodel })`.\n */\nexport function detectFramework(\n json: string | Record<string, unknown>,\n roots: readonly AnyMetamodel[],\n): AnyMetamodel | undefined {\n const file = parseJson(json);\n const prefix = detectPrefix(file);\n if (prefix !== undefined) return roots.find((root) => root.prefix === prefix);\n if (typeof file.tool !== 'string') return undefined;\n const byTool = roots.filter((root) => root.file.tool === file.tool);\n return byTool.length === 1 ? byTool[0] : undefined;\n}\n\nfunction optional<K extends string, V>(key: K, value: V | undefined): { [P in K]?: V } {\n return (value === undefined ? {} : { [key]: value }) as { [P in K]?: V };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Serialization\n\nexport interface ToPistarOptions {\n /** Default: the model's metamodel, or iStar 2.0. Decides each kind's `type` and category. */\n metamodel?: AnyMetamodel;\n /**\n * Value for `saveDate`. Defaults to the model's own `saveDate` (so a load/save round trip is\n * lossless); a parsed file that had none keeps none, and a model that was never a file gets\n * the current time. Pass `new Date()` when saving an edited model, as piStar does.\n */\n saveDate?: string | Date;\n}\n\nfunction formatDate(date: Date): string {\n // piStar uses the deprecated `toGMTString`, an alias of `toUTCString`.\n return date.toUTCString();\n}\n\nfunction pistarTypeOf(type: string | undefined, kind: string, metamodel: AnyMetamodel): string {\n if (type === undefined) {\n throw new PistarWriteError(\n `kind \"${kind}\" is not part of ${metamodel.name}; pass its metamodel (toPistar(model, { metamodel }) or withMetamodel)`,\n );\n }\n return type;\n}\n\n/**\n * `value` with its keys in the order `keys` gives (those present), then the rest as built (piStar's\n * order): an object read from a file is written back with the file's key order, and keys the\n * file lacked follow.\n */\nfunction inSourceOrder<T extends object>(value: T, keys: readonly string[] | undefined): T {\n if (!keys) return value;\n const result: Record<string, unknown> = {};\n const record = value as Record<string, unknown>;\n for (const key of keys) if (key in record) result[key] = record[key];\n for (const key of Object.keys(record)) if (!(key in result)) result[key] = record[key];\n return result as T;\n}\n\nfunction elementJson(element: IstarElement<string>, metamodel: AnyMetamodel): PistarElementJson {\n return {\n id: element.id,\n text: element.name,\n type: pistarTypeOf(metamodel.elements.get(element.kind)?.pistarType, element.kind, metamodel),\n x: element.x,\n y: element.y,\n ...(element.customProperties ? { customProperties: { ...element.customProperties } } : {}),\n };\n}\n\n/** Builds the save-file object for a model. `toPistar` is this plus `JSON.stringify`. */\nexport function toPistarObject<EK extends string, LK extends string>(\n input: IstarModel<EK, LK>,\n options: ToPistarOptions = {},\n): PistarFile {\n const model = input as unknown as AnyIstarModel;\n const metamodel: AnyMetamodel =\n options.metamodel ?? (metamodelOf(input) as unknown as AnyMetamodel);\n const isActorKind = (kind: string): boolean => metamodel.elements.get(kind)?.category === 'actor';\n // Hubs of n-ary links are written in their entry in `links`, not as elements.\n const isHub = (element: IstarElement<string>): boolean =>\n metamodel.elements.get(element.kind)?.role === 'hub';\n const actors: PistarActorJson[] = [];\n const orphans: PistarElementJson[] = [];\n const dependencies: PistarDependencyJson[] = [];\n const children = new Map<string, PistarElementJson[]>();\n const layout = layouts.get(model);\n const sourceOrder = <T extends object>(id: string, value: T): T =>\n inSourceOrder(value, layout?.objects?.get(id));\n\n for (const element of model.elements.values()) {\n if (isHub(element)) continue;\n if (element.parent !== undefined && !isActorKind(element.kind)) {\n let list = children.get(element.parent);\n if (!list) children.set(element.parent, (list = []));\n list.push(sourceOrder(element.id, { ...elementJson(element, metamodel), ...element.extra }));\n }\n }\n\n for (const element of model.elements.values()) {\n if (isHub(element)) continue;\n if (isActorKind(element.kind)) {\n actors.push(\n sourceOrder(element.id, {\n ...elementJson(element, metamodel),\n nodes: children.get(element.id) ?? [],\n ...element.extra,\n }),\n );\n } else if (element.isDependum) {\n // Like piStar, derive depender/dependee from the dependency links.\n const { inbound, outbound } = dependencyLinksOf(model, element.id);\n dependencies.push(\n sourceOrder(element.id, {\n ...elementJson(element, metamodel),\n source: inbound?.source ?? element.dependency?.source ?? '',\n target: outbound?.target ?? element.dependency?.target ?? '',\n ...element.extra,\n }),\n );\n } else if (element.parent === undefined || !model.elements.has(element.parent)) {\n orphans.push(\n sourceOrder(element.id, { ...elementJson(element, metamodel), ...element.extra }),\n );\n }\n }\n\n const linkJson = (link: IstarLink<string>): PistarLinkJson =>\n sourceOrder(link.id, {\n id: link.id,\n type: pistarTypeOf(metamodel.links.get(link.kind)?.pistarType, link.kind, metamodel),\n source: link.source,\n target: link.target,\n ...(link.name !== undefined ? { name: link.name } : {}),\n ...(link.customProperties ? { customProperties: { ...link.customProperties } } : {}),\n ...(link.label !== undefined ? { label: link.label } : {}),\n ...link.extra,\n });\n\n // Each hub's legs (in link order) and end; its entry goes where its first leg or end is.\n const hubs = new Map<string, { legs: IstarLink<string>[]; end?: IstarLink<string> }>();\n const partsOf = (hubId: string) => {\n let parts = hubs.get(hubId);\n if (!parts) hubs.set(hubId, (parts = { legs: [] }));\n return parts;\n };\n const hubOf = (link: IstarLink<string>): string | undefined => {\n const role = metamodel.links.get(link.kind)?.role;\n const id = role === 'leg' ? link.target : role === 'end' ? link.source : undefined;\n const hub = id === undefined ? undefined : model.elements.get(id);\n return hub && isHub(hub) ? hub.id : undefined;\n };\n for (const link of model.links.values()) {\n const hubId = hubOf(link);\n if (hubId === undefined) continue;\n const parts = partsOf(hubId);\n if (metamodel.links.get(link.kind)?.role === 'leg') parts.legs.push(link);\n else parts.end ??= link;\n }\n const hubEntry = (hub: IstarElement<string>): PistarHubLinkJson => {\n const parts = hubs.get(hub.id) ?? { legs: [] };\n const { [HUB_ENTRY_KEY]: entryExtra, ...hubExtra } = hub.extra ?? {};\n return sourceOrder(hubEntryLayoutKey(hub.id), {\n hub: sourceOrder(hub.id, {\n id: hub.id,\n type: pistarTypeOf(metamodel.elements.get(hub.kind)?.pistarType, hub.kind, metamodel),\n x: hub.x,\n y: hub.y,\n ...(hub.customProperties ? { customProperties: { ...hub.customProperties } } : {}),\n ...hubExtra,\n }),\n starts: parts.legs.map(linkJson),\n ...(parts.end ? { end: linkJson(parts.end) } : {}),\n ...(isRecord(entryExtra) ? entryExtra : {}),\n });\n };\n\n const links: (PistarLinkJson | PistarHubLinkJson)[] = [];\n const written = new Set<string>();\n for (const link of model.links.values()) {\n const hubId = hubOf(link);\n const parts = hubId === undefined ? undefined : hubs.get(hubId);\n // A second end of the same hub (an invalid model) is kept as a plain link.\n if (hubId === undefined || !parts || (!parts.legs.includes(link) && parts.end !== link)) {\n links.push(linkJson(link));\n } else if (!written.has(hubId)) {\n written.add(hubId);\n links.push(hubEntry(model.elements.get(hubId)!));\n }\n }\n // Hubs that lost every leg and their end still have an entry, so they aren't lost.\n for (const element of model.elements.values()) {\n if (isHub(element) && !written.has(element.id)) links.push(hubEntry(element));\n }\n\n const display: Record<string, Record<string, unknown>> = {};\n const displayOf = (id: string): Record<string, unknown> | undefined => {\n const owner = model.elements.get(id) ?? model.links.get(id);\n if (owner) return owner.display as Record<string, unknown> | undefined;\n return model.extraDisplay?.[id] as Record<string, unknown> | undefined;\n };\n for (const id of layout?.display ?? []) {\n const entry = displayOf(id);\n if (entry !== undefined) display[id] = { ...entry };\n }\n for (const owner of [...model.elements.values(), ...model.links.values()]) {\n if (owner.display && !(owner.id in display)) display[owner.id] = { ...owner.display };\n }\n for (const [id, entry] of Object.entries(model.extraDisplay ?? {})) {\n if (!(id in display)) display[id] = entry as Record<string, unknown>;\n }\n\n // A file that had no saveDate keeps none until a save passes one (an edit, as piStar does).\n let saveDate: string | undefined;\n if (options.saveDate instanceof Date) saveDate = formatDate(options.saveDate);\n else if (options.saveDate !== undefined || model.saveDate !== undefined)\n saveDate = options.saveDate ?? model.saveDate;\n else if (!layout || layout.keys.includes('saveDate')) saveDate = formatDate(new Date());\n\n const d = model.diagram;\n const diagram: PistarDiagramJson | undefined =\n d &&\n sourceOrder(DIAGRAM_LAYOUT_KEY, {\n ...(d.width !== undefined ? { width: d.width } : {}),\n ...(d.height !== undefined ? { height: d.height } : {}),\n ...(d.name !== undefined ? { name: d.name } : {}),\n ...(d.customProperties ? { customProperties: { ...d.customProperties } } : {}),\n ...d.extra,\n });\n\n const values: Record<string, unknown> = {\n ...model.extra,\n actors,\n orphans,\n dependencies,\n links,\n display,\n tool: model.tool,\n istar: model.istar,\n saveDate,\n diagram,\n };\n\n // Files written by older piStar versions lack some sections (e.g. `orphans`). Keep them\n // absent while they are empty, so such files round-trip unchanged.\n if (layout) {\n for (const key of ['actors', 'orphans', 'dependencies', 'links', 'display'] as const) {\n const value = values[key] as unknown[] | Record<string, unknown>;\n const empty = Array.isArray(value) ? value.length === 0 : Object.keys(value).length === 0;\n if (empty && !layout.keys.includes(key)) values[key] = undefined;\n }\n }\n\n // Emit keys in the order they had in the source file (else the root metamodel's file order),\n // then any new ones in piStar's order.\n const order = [\n ...(layout?.keys ?? metamodel.file.keys ?? []),\n ...TOP_LEVEL_KEYS,\n ...Object.keys(model.extra ?? {}),\n ];\n const file: Record<string, unknown> = {};\n for (const key of order) {\n if (!(key in file) && values[key] !== undefined) file[key] = values[key];\n }\n return file as PistarFile;\n}\n\n/** Serializes a model to piStar's JSON text (2-space indentation, no trailing newline). */\nexport function toPistar<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n options?: ToPistarOptions,\n): string {\n return JSON.stringify(toPistarObject(model, options), null, 2);\n}\n\n// ---------------------------------------------------------------------------------------------\n// A model's own metamodel\n\n/**\n * The constructs the model's file declares in its `\"metamodel\"` block, when they were applied\n * (read with `fileMetamodel: true`, or set with `withFileMetamodel`); `undefined` otherwise.\n * Kinds the host supplied are never part of it.\n */\nexport function fileMetamodelOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): FileMetamodel | undefined {\n if (!hostMetamodelOf(model)) return undefined;\n return model.extra?.[FILE_METAMODEL_KEY] as FileMetamodel | undefined;\n}\n\n/**\n * A copy of `model` whose file declares `block` (`null` removes the block): its metamodel is the\n * host's extended by `block`, and `toPistar` writes the block. This is how a tool's \"Add new\"\n * construct joins a model. Throws `MetamodelError` if the block is malformed, collides with the\n * host's kinds, or leaves out a kind the model still uses.\n */\nexport function withFileMetamodel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n block: FileMetamodel | null,\n): IstarModel<string, string> {\n const any = model as unknown as AnyIstarModel;\n const host = hostMetamodelOf(any) ?? (metamodelOf(any) as unknown as AnyMetamodel);\n let next: AnyMetamodel = host;\n if (block) {\n validateFileMetamodel(block);\n next = extendMetamodel(host, fileMetamodelExtension(block));\n }\n for (const element of any.elements.values()) {\n if (!next.elements.has(element.kind)) {\n throw new MetamodelError(\n `element \"${element.id}\" uses kind \"${element.kind}\", which the new metamodel lacks`,\n );\n }\n }\n for (const link of any.links.values()) {\n if (!next.links.has(link.kind)) {\n throw new MetamodelError(\n `link \"${link.id}\" uses kind \"${link.kind}\", which the new metamodel lacks`,\n );\n }\n }\n const { [FILE_METAMODEL_KEY]: _previous, ...others } = any.extra ?? {};\n // Replacing keeps the block's place among the top-level keys.\n const extra = block ? { ...any.extra, [FILE_METAMODEL_KEY]: structuredClone(block) } : others;\n const { extra: _extra, ...rest } = any;\n const result: AnyIstarModel = inheritSourceLayout(any, {\n ...rest,\n ...(Object.keys(extra).length > 0 ? { extra } : {}),\n });\n setHostMetamodel(result, block ? host : undefined);\n return withMetamodel(result, next);\n}\n","/**\n * Pure model operations. Each takes a model and returns a new one; inputs are never mutated.\n * The store (`store.ts`) wraps these with undo/redo and change events, and the React layer can\n * use them directly for controlled components.\n *\n * Behaviour follows the piStar web tool (`istarFunctions.js` and its UI):\n * - removing an actor removes its inner elements; removing an element removes its links;\n * - a dependency is two `DependencyLink`s around a dependum, and removing any of the three\n * removes the whole dependency (upstream keeps an `otherHalf` reference for this);\n * - moving an actor moves its inner elements with it (they are JointJS-embedded upstream);\n * - an n-ary link (DSM3-goals' split link) is a hub element with legs and an end; removing its\n * end or its last leg removes the hub, and removing the hub removes its legs and end.\n *\n * Kinds are looked up in the model's metamodel (`metamodelOf`, iStar 2.0 by default), so\n * extended actor, node, link and dependency kinds behave like their built-in counterparts.\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { ActorKind, DependencyLinkKind, ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, LinkKindDefinition } from './metamodels';\nimport type {\n AnyIstarModel,\n CustomProperties,\n Diagram,\n ElementDisplay,\n IstarElement,\n IstarLink,\n HubLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport {\n defaultHubPosition,\n dependencyLinksOf,\n hubLinkOf,\n inheritMetamodel,\n metamodelOf,\n} from './model';\nimport { inheritSourceLayout } from './serialization';\n\nexport class ModelOperationError extends Error {\n override name = 'ModelOperationError';\n}\n\n/** Generates ids for new elements and links. piStar uses UUID v4. */\nexport type IdGenerator = () => string;\n\nexport const defaultIdGenerator: IdGenerator = () => {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n // Fallback for non-secure browser contexts, where randomUUID is unavailable.\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n};\n\nexport interface OperationContext {\n readonly createId?: IdGenerator;\n}\n\ntype AnyElement = IstarElement<string>;\ntype AnyLink = IstarLink<string>;\n\nfunction any<EK extends string, LK extends string>(model: IstarModel<EK, LK>): AnyIstarModel {\n return model as unknown as AnyIstarModel;\n}\n\nfunction typed<EK extends string, LK extends string>(model: AnyIstarModel): IstarModel<EK, LK> {\n return model as unknown as IstarModel<EK, LK>;\n}\n\nfunction metaOf(model: AnyIstarModel): AnyMetamodel {\n return metamodelOf(model) as unknown as AnyMetamodel;\n}\n\nfunction isActorIn(model: AnyIstarModel, kind: string): boolean {\n return metaOf(model).elements.get(kind)?.category === 'actor';\n}\n\nfunction derive(from: AnyIstarModel, changes: Partial<AnyIstarModel>): AnyIstarModel {\n return inheritMetamodel(from, inheritSourceLayout(from, { ...from, ...changes }));\n}\n\nfunction requireElement(model: AnyIstarModel, id: string): AnyElement {\n const element = model.elements.get(id);\n if (!element) throw new ModelOperationError(`unknown element \"${id}\"`);\n return element;\n}\n\nfunction requireLink(model: AnyIstarModel, id: string): AnyLink {\n const link = model.links.get(id);\n if (!link) throw new ModelOperationError(`unknown link \"${id}\"`);\n return link;\n}\n\nfunction withoutUndefined<T extends object>(value: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Elements\n\nexport interface NewElement<K extends string = ElementKind> {\n readonly kind: K;\n readonly x: number;\n readonly y: number;\n readonly id?: string;\n /** Defaults to the kind's label (\"Goal\"), like piStar. */\n readonly name?: string;\n /** Actor to place the element in. Required in practice for iStar nodes (see NodeKindInfo). */\n readonly parent?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n}\n\nexport function addElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewElement<EK>,\n ctx: OperationContext = {},\n): { model: IstarModel<EK, LK>; element: IstarElement<EK> } {\n const m = any(model);\n const metamodel = metaOf(m);\n const definition = metamodel.elements.get(input.kind);\n if (!definition) {\n throw new ModelOperationError(`unknown element kind \"${input.kind}\" in ${metamodel.name}`);\n }\n const id = input.id ?? (ctx.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n if (input.parent !== undefined) {\n if (definition.category === 'actor') throw new ModelOperationError('actors cannot be nested');\n if (!isActorIn(m, requireElement(m, input.parent).kind)) {\n throw new ModelOperationError(`parent \"${input.parent}\" is not an actor`);\n }\n }\n const element: AnyElement = withoutUndefined({\n id,\n kind: input.kind,\n name: input.name ?? definition.label,\n x: input.x,\n y: input.y,\n parent: input.parent,\n customProperties: input.customProperties,\n display: input.display,\n });\n const elements = new Map(m.elements).set(id, element);\n return { model: typed(derive(m, { elements })), element: element as IstarElement<EK> };\n}\n\nexport interface ElementPatch {\n readonly name?: string;\n /** Replaces the whole map. Use `null` to remove it. */\n readonly customProperties?: CustomProperties | null;\n /** Merged into the current display; a key set to `undefined` is removed. `null` clears it. */\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction mergeDisplay<D extends object>(\n current: D | undefined,\n patch: { readonly [key: string]: unknown } | null | undefined,\n): D | undefined {\n if (patch === undefined) return current;\n if (patch === null) return undefined;\n const merged: Record<string, unknown> = { ...current };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) delete merged[key];\n else merged[key] = value;\n }\n return Object.keys(merged).length > 0 ? (merged as D) : undefined;\n}\n\nexport function updateElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n patch: ElementPatch,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n const next: AnyElement = withoutUndefined({\n ...current,\n name: patch.name ?? current.name,\n customProperties:\n patch.customProperties === undefined\n ? current.customProperties\n : (patch.customProperties ?? undefined),\n display: mergeDisplay<ElementDisplay>(current.display, patch.display),\n });\n return typed(derive(m, { elements: new Map(m.elements).set(id, next) }));\n}\n\n/**\n * Moves an element to an absolute position. Moving an actor shifts its inner elements by the\n * same offset.\n */\nexport function moveElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n x: number,\n y: number,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n const dx = x - current.x;\n const dy = y - current.y;\n if (dx === 0 && dy === 0) return model;\n const elements = new Map(m.elements);\n elements.set(id, { ...current, x, y });\n if (isActorIn(m, current.kind)) {\n for (const child of m.elements.values()) {\n if (child.parent === id)\n elements.set(child.id, { ...child, x: child.x + dx, y: child.y + dy });\n }\n }\n return typed(derive(m, { elements }));\n}\n\n/**\n * Moves an inner element into another actor (or out of any actor with `null`). The element\n * becomes the actor's last child. Links that become invalid are kept; `validateModel` reports\n * them.\n */\nexport function nestElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n parent: string | null,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n if (isActorIn(m, current.kind)) throw new ModelOperationError('actors cannot be nested');\n if (current.isDependum) throw new ModelOperationError('a dependum cannot be nested');\n if ((current.parent ?? null) === parent) return model;\n if (parent !== null && !isActorIn(m, requireElement(m, parent).kind)) {\n throw new ModelOperationError(`parent \"${parent}\" is not an actor`);\n }\n const elements = new Map(m.elements);\n elements.delete(id);\n const { parent: _old, ...rest } = current;\n elements.set(id, parent === null ? rest : { ...rest, parent });\n return typed(derive(m, { elements }));\n}\n\n/**\n * Removes elements and everything that depends on them: inner elements of removed actors,\n * links touching removed elements (and links targeting removed links), and the rest of any\n * dependency that loses a part.\n */\nexport function removeElements<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n ids: Iterable<string>,\n): IstarModel<EK, LK> {\n return typed(removeCascade(any(model), new Set(ids), new Set()));\n}\n\nexport function removeElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n): IstarModel<EK, LK> {\n requireElement(any(model), id);\n return removeElements(model, [id]);\n}\n\nfunction removeCascade(\n model: AnyIstarModel,\n elementIds: Set<string>,\n linkIds: Set<string>,\n): AnyIstarModel {\n const metamodel = metaOf(model);\n const isDependencyHalf = (link: AnyLink): boolean =>\n metamodel.links.get(link.kind)?.category === 'dependency';\n // Iterate to a fixed point: each round may remove more elements or links.\n let changed = true;\n while (changed) {\n changed = false;\n for (const element of model.elements.values()) {\n if (elementIds.has(element.id)) continue;\n if (element.parent !== undefined && elementIds.has(element.parent)) {\n elementIds.add(element.id);\n changed = true;\n }\n }\n for (const link of model.links.values()) {\n if (linkIds.has(link.id)) continue;\n // A link goes with its endpoints, including a link it targets (see `LinkRules`).\n if (elementIds.has(link.source) || elementIds.has(link.target) || linkIds.has(link.target)) {\n linkIds.add(link.id);\n changed = true;\n }\n }\n // An n-ary link that lost its end or its last leg goes entirely (its hub takes the rest).\n for (const element of model.elements.values()) {\n if (elementIds.has(element.id) || metamodel.elements.get(element.kind)?.role !== 'hub') {\n continue;\n }\n let legs = 0;\n let removedLegs = 0;\n let endRemoved = false;\n for (const link of model.links.values()) {\n const role = metamodel.links.get(link.kind)?.role;\n if (role === 'leg' && link.target === element.id) {\n legs++;\n if (linkIds.has(link.id)) removedLegs++;\n } else if (role === 'end' && link.source === element.id && linkIds.has(link.id)) {\n endRemoved = true;\n }\n }\n if (endRemoved || (legs > 0 && removedLegs === legs)) {\n elementIds.add(element.id);\n changed = true;\n }\n }\n // A dependency that lost a half, or its dependum, goes entirely.\n for (const link of model.links.values()) {\n if (!linkIds.has(link.id) || !isDependencyHalf(link)) continue;\n for (const end of [link.source, link.target]) {\n const element = model.elements.get(end);\n if (element?.isDependum && !elementIds.has(end)) {\n elementIds.add(end);\n changed = true;\n }\n }\n }\n }\n if (elementIds.size === 0 && linkIds.size === 0) return model;\n const elements = new Map(model.elements);\n for (const id of elementIds) elements.delete(id);\n const links = new Map(model.links);\n for (const id of linkIds) links.delete(id);\n return derive(model, { elements, links });\n}\n\n// ---------------------------------------------------------------------------------------------\n// Links\n\nexport interface NewLink<K extends string = LinkKind> {\n /** Any link kind except dependency kinds (use `addDependency` for those). */\n readonly kind: Exclude<K, DependencyLinkKind>;\n readonly source: string;\n /** An element id, or a link id for kinds whose rules target links. */\n readonly target: string;\n readonly id?: string;\n /** Contribution value: make, help, hurt or break. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface ConnectOptions extends OperationContext {\n /** Skip constraint checking (used when loading or scripting known-good data). */\n readonly force?: boolean;\n /**\n * Retry with source and target swapped if the link is invalid as given. Defaults to the\n * metamodel's `tryReversedWhenAdding` (Needed-By and Qualification), as in piStar.\n */\n readonly tryReversed?: boolean;\n}\n\nexport type ConnectResult<EK extends string = ElementKind, LK extends string = LinkKind> =\n | {\n ok: true;\n model: IstarModel<EK, LK>;\n /** The new link; for an n-ary kind, the new leg or (for a new hub) the end. */\n link: IstarLink<LK>;\n reversed: boolean;\n /** For an n-ary kind: the hub link the new link belongs to, as it now is. */\n hub?: HubLink<EK, LK>;\n }\n | Extract<LinkCheck, { ok: false }>;\n\n/**\n * Adds a link between two elements if the iStar constraints allow it.\n *\n * With an n-ary kind (`arity: 'n'`), a `target` that is one of the kind's hubs gets a new leg\n * from `source` (see `addLeg`). Any other target gets a new hub, centred between source and\n * target, with a leg from `source` and an end to `target`. `input.id` and `customProperties`\n * then go to the hub, and `label` and `name` to the end.\n */\nexport function connect<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewLink<LK>,\n options: ConnectOptions = {},\n): ConnectResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const kind: string = input.kind;\n const definition = metamodel.links.get(kind);\n if (definition?.category === 'dependency') {\n throw new ModelOperationError('use addDependency to create dependencies');\n }\n if (definition?.parts) return connectHub(m, definition, input, options);\n let { source, target } = input;\n let reversed = false;\n if (!options.force) {\n let check = canLink(m, source, target, kind);\n const tryReversed = options.tryReversed ?? definition?.info.tryReversedWhenAdding;\n if (!check.ok && tryReversed) {\n const swapped = canLink(m, target, source, kind);\n if (swapped.ok) {\n [source, target] = [target, source];\n reversed = true;\n check = swapped;\n }\n }\n if (!check.ok) return check;\n } else {\n if (!definition) {\n throw new ModelOperationError(`unknown link kind \"${kind}\" in ${metamodel.name}`);\n }\n requireElement(m, source);\n if (!m.links.has(target)) requireElement(m, target);\n }\n const id = input.id ?? (options.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n const link: AnyLink = withoutUndefined({\n id,\n kind,\n source,\n target,\n label: input.label,\n name: input.name,\n customProperties: input.customProperties,\n });\n return {\n ok: true,\n model: typed(derive(m, { links: new Map(m.links).set(id, link) })),\n link: link as IstarLink<LK>,\n reversed,\n };\n}\n\nfunction connectHub<EK extends string, LK extends string>(\n m: AnyIstarModel,\n definition: LinkKindDefinition,\n input: NewLink<string>,\n options: ConnectOptions,\n): ConnectResult<EK, LK> {\n const metamodel = metaOf(m);\n const parts = definition.parts!;\n const { source, target } = input;\n if (m.elements.get(target)?.kind === parts.hub) {\n return addLeg(typed<EK, LK>(m), target, source, options);\n }\n if (!options.force) {\n const check = canLink(m, source, target, definition.kind);\n if (!check.ok) return check;\n }\n const from = requireElement(m, source);\n const to = requireElement(m, target);\n const createId = options.createId ?? defaultIdGenerator;\n const hubId = input.id ?? createId();\n const legId = createId();\n const endId = createId();\n for (const [i, id] of [hubId, legId, endId].entries()) {\n if (m.elements.has(id) || m.links.has(id) || [hubId, legId, endId].indexOf(id) !== i) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n }\n const size = metamodel.elements.get(parts.hub)?.size ?? { width: 20, height: 20 };\n const position = defaultHubPosition(m, from, to, size);\n const hub: AnyElement = withoutUndefined({\n id: hubId,\n kind: parts.hub,\n name: '',\n x: position.x,\n y: position.y,\n customProperties: input.customProperties,\n });\n const leg: AnyLink = { id: legId, kind: parts.leg, source, target: hubId };\n const end: AnyLink = withoutUndefined({\n id: endId,\n kind: parts.end,\n source: hubId,\n target,\n label: input.label,\n name: input.name,\n });\n const next = derive(m, {\n elements: new Map(m.elements).set(hubId, hub),\n links: new Map(m.links).set(legId, leg).set(endId, end),\n });\n return {\n ok: true,\n model: typed(next),\n link: end as IstarLink<LK>,\n reversed: false,\n hub: { hub, legs: [leg], end } as unknown as HubLink<EK, LK>,\n };\n}\n\n/**\n * Adds a leg from `source` to the hub `hubId` of an n-ary link (one more source for it), if the\n * kind's rules allow it. `options.id` is the leg's id.\n */\nexport function addLeg<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n hubId: string,\n source: string,\n options: ConnectOptions & { readonly id?: string } = {},\n): ConnectResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const hub = requireElement(m, hubId);\n const base = metamodel.links.get(metamodel.elements.get(hub.kind)?.of ?? '');\n if (metamodel.elements.get(hub.kind)?.role !== 'hub' || !base?.parts) {\n throw new ModelOperationError(`\"${hubId}\" is not the hub of an n-ary link`);\n }\n const kind = base.parts.leg;\n if (!options.force) {\n const check = canLink(m, source, hubId, kind);\n if (!check.ok) return check;\n } else {\n requireElement(m, source);\n }\n const id = options.id ?? (options.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n const leg: AnyLink = { id, kind, source, target: hubId };\n const next = derive(m, { links: new Map(m.links).set(id, leg) });\n return {\n ok: true,\n model: typed(next),\n link: leg as IstarLink<LK>,\n reversed: false,\n hub: hubLinkOf(typed<EK, LK>(next), hubId),\n };\n}\n\n/**\n * Removes one leg of an n-ary link. Removing its last leg removes the whole link (hub and end),\n * as `disconnect` does.\n */\nexport function removeLeg<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n legId: string,\n): IstarModel<EK, LK> {\n const m = any(model);\n const leg = requireLink(m, legId);\n if (metaOf(m).links.get(leg.kind)?.role !== 'leg') {\n throw new ModelOperationError(`\"${legId}\" is not a leg of an n-ary link`);\n }\n return disconnect(model, legId);\n}\n\nexport interface NewDependency<EK extends string = ElementKind, LK extends string = LinkKind> {\n /** The depender: an actor or one of its inner elements. */\n readonly depender: string;\n /** The dependee: an actor or one of its inner elements. */\n readonly dependee: string;\n readonly dependum: {\n /** A node kind (built-in or extended) that can be a dependum. */\n readonly kind: Exclude<EK, ActorKind>;\n readonly name?: string;\n readonly id?: string;\n /** Defaults to the midpoint between depender and dependee, as in piStar. */\n readonly x?: number;\n readonly y?: number;\n readonly customProperties?: CustomProperties;\n };\n /** A dependency link kind. Default `istar.DependencyLink`. */\n readonly linkKind?: LK;\n readonly linkIds?: readonly [string, string];\n}\n\nexport type AddDependencyResult<EK extends string = ElementKind, LK extends string = LinkKind> =\n | {\n ok: true;\n model: IstarModel<EK, LK>;\n dependum: IstarElement<EK>;\n links: readonly [IstarLink<LK>, IstarLink<LK>];\n }\n | Extract<LinkCheck, { ok: false }>;\n\n/** Adds depender → dependum → dependee. */\nexport function addDependency<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewDependency<EK, LK>,\n options: Omit<ConnectOptions, 'tryReversed'> = {},\n): AddDependencyResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const dependumKind: string = input.dependum.kind;\n const dependumDefinition = metamodel.elements.get(dependumKind);\n if (dependumDefinition?.category !== 'node' || dependumDefinition.info?.canBeDependum === false) {\n throw new ModelOperationError(`${dependumKind} cannot be a dependum`);\n }\n const linkKind: string = input.linkKind ?? 'istar.DependencyLink';\n if (metamodel.links.get(linkKind)?.category !== 'dependency') {\n throw new ModelOperationError(`${linkKind} is not a dependency link kind`);\n }\n if (!options.force) {\n const check = canLink(m, input.depender, input.dependee, linkKind);\n if (!check.ok) return check;\n }\n const depender = requireElement(m, input.depender);\n const dependee = requireElement(m, input.dependee);\n const createId = options.createId ?? defaultIdGenerator;\n const added = addElement(\n m,\n {\n kind: dependumKind,\n id: input.dependum.id,\n name: input.dependum.name,\n x: input.dependum.x ?? (depender.x + dependee.x) / 2,\n y: input.dependum.y ?? (depender.y + dependee.y) / 2,\n customProperties: input.dependum.customProperties,\n },\n { createId },\n );\n const dependum: AnyElement = { ...added.element, isDependum: true };\n const [id1, id2] = input.linkIds ?? [createId(), createId()];\n const first: AnyLink = { id: id1, kind: linkKind, source: depender.id, target: dependum.id };\n const second: AnyLink = { id: id2, kind: linkKind, source: dependum.id, target: dependee.id };\n for (const id of [id1, id2]) {\n if (added.model.elements.has(id) || added.model.links.has(id) || id1 === id2) {\n throw new ModelOperationError(`id \"${id}\" is already in use`);\n }\n }\n return {\n ok: true,\n model: typed(\n derive(m, {\n elements: new Map(added.model.elements).set(dependum.id, dependum),\n links: new Map(m.links).set(id1, first).set(id2, second),\n }),\n ),\n dependum: dependum as IstarElement<EK>,\n links: [first as IstarLink<LK>, second as IstarLink<LK>],\n };\n}\n\n/**\n * Removes a link, and the links that target it. Removing either half of a dependency removes\n * the whole dependency.\n */\nexport function disconnect<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n): IstarModel<EK, LK> {\n const m = any(model);\n requireLink(m, id);\n return typed(removeCascade(m, new Set(), new Set([id])));\n}\n\nexport interface LinkPatch {\n /** `null` removes it. */\n readonly label?: string | null;\n readonly name?: string | null;\n readonly customProperties?: CustomProperties | null;\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction pick<T>(value: T | null | undefined, fallback: T | undefined): T | undefined {\n return value === undefined ? fallback : (value ?? undefined);\n}\n\nexport function updateLink<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n patch: LinkPatch,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireLink(m, id);\n const next: AnyLink = withoutUndefined({\n ...current,\n label: pick(patch.label, current.label),\n name: pick(patch.name, current.name),\n customProperties: pick(patch.customProperties, current.customProperties),\n display: mergeDisplay<LinkDisplay>(current.display, patch.display),\n });\n return typed(derive(m, { links: new Map(m.links).set(id, next) }));\n}\n\n// ---------------------------------------------------------------------------------------------\n// Diagram\n\nexport function updateDiagram<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n patch: Partial<Diagram>,\n): IstarModel<EK, LK> {\n const m = any(model);\n return typed(derive(m, { diagram: withoutUndefined({ ...m.diagram, ...patch }) }));\n}\n\n/** Where dependency depender/dependee currently point (see `dependencyLinksOf`). */\nexport function dependencyEnds<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n dependumId: string,\n): { depender?: string; dependee?: string } {\n const { inbound, outbound } = dependencyLinksOf(model, dependumId);\n const fallback = model.elements.get(dependumId)?.dependency;\n return {\n depender: inbound?.source ?? fallback?.source,\n dependee: outbound?.target ?? fallback?.target,\n };\n}\n","/**\n * An event-emitting store around an immutable `IstarModel`, with undo/redo.\n *\n * Every mutation produces a new model snapshot; history is a stack of snapshots, which is cheap\n * because unchanged elements and links are shared between snapshots. This replaces piStar's\n * `undoManager.js`, which stacked hand-written undo closures.\n *\n * `subscribe` + `getModel` match React's `useSyncExternalStore` contract.\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { Metamodel } from './metamodels';\nimport type { AnyIstarModel, Diagram, IstarElement, IstarLink, IstarModel } from './model';\nimport { createEmptyModel } from './model';\nimport type {\n ConnectOptions,\n ElementPatch,\n IdGenerator,\n LinkPatch,\n NewDependency,\n NewElement,\n NewLink,\n} from './operations';\nimport * as ops from './operations';\n\n/** What happened, for listeners that want more than the new snapshot. */\nexport type ModelChange =\n | { type: 'addElement'; id: string }\n | { type: 'updateElement'; id: string; patch: ElementPatch }\n | { type: 'moveElement'; id: string; x: number; y: number }\n | { type: 'nestElement'; id: string; parent: string | null }\n | { type: 'removeElements'; ids: readonly string[] }\n /** `hubId`: the n-ary link's hub, when the new link is a leg or a new hub's end. */\n | { type: 'connect'; id: string; hubId?: string }\n | { type: 'removeLeg'; id: string }\n | { type: 'addDependency'; dependumId: string; linkIds: readonly [string, string] }\n | { type: 'updateLink'; id: string; patch: LinkPatch }\n | { type: 'disconnect'; id: string }\n | { type: 'updateDiagram'; patch: Partial<Diagram> }\n | { type: 'replace' };\n\nexport interface ModelChangeEvent<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly model: IstarModel<EK, LK>;\n readonly previous: IstarModel<EK, LK>;\n /** `undo`/`redo`/`load` carry no changes; a transaction carries all of its changes. */\n readonly changes: readonly ModelChange[];\n readonly source: 'edit' | 'undo' | 'redo' | 'load';\n}\n\nexport type ModelListener<EK extends string = ElementKind, LK extends string = LinkKind> = (\n event: ModelChangeEvent<EK, LK>,\n) => void;\n\nexport interface ModelStoreOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * Metamodel for the default empty model, when no initial model is given. A given initial\n * model keeps its own (see `metamodelOf`).\n */\n readonly metamodel?: Metamodel<EK, LK>;\n readonly createId?: IdGenerator;\n /** Maximum number of undo steps kept. Default 100. */\n readonly historyLimit?: number;\n}\n\nexport interface ModelStore<EK extends string = ElementKind, LK extends string = LinkKind> {\n getModel(): IstarModel<EK, LK>;\n /** Returns an unsubscribe function. */\n subscribe(listener: ModelListener<EK, LK>): () => void;\n\n canLink(\n source: string | IstarElement<EK>,\n target: string | IstarElement<EK> | IstarLink<LK>,\n kind: LK,\n ): LinkCheck;\n\n addElement(input: NewElement<EK>): IstarElement<EK>;\n updateElement(id: string, patch: ElementPatch): void;\n moveElement(id: string, x: number, y: number): void;\n nestElement(id: string, parent: string | null): void;\n removeElement(id: string): void;\n removeElements(ids: Iterable<string>): void;\n setCollapsed(actorId: string, collapsed: boolean): void;\n\n connect(\n input: NewLink<LK>,\n options?: Omit<ConnectOptions, 'createId'>,\n ): ops.ConnectResult<EK, LK>;\n addDependency(\n input: NewDependency<EK, LK>,\n options?: Omit<ConnectOptions, 'createId' | 'tryReversed'>,\n ): ops.AddDependencyResult<EK, LK>;\n /** Adds a leg from `source` to the hub of an n-ary link (see `ops.addLeg`). */\n addLeg(\n hubId: string,\n source: string,\n options?: Omit<ConnectOptions, 'createId' | 'tryReversed'> & { readonly id?: string },\n ): ops.ConnectResult<EK, LK>;\n /** Removes a leg; the last one takes its hub and end with it. */\n removeLeg(id: string): void;\n updateLink(id: string, patch: LinkPatch): void;\n disconnect(id: string): void;\n updateDiagram(patch: Partial<Diagram>): void;\n\n /** Replaces the model as one undoable edit. */\n replace(model: IstarModel<EK, LK>): void;\n /** Replaces the model and clears history (like opening a file in piStar). */\n load(model: IstarModel<EK, LK>): void;\n\n /**\n * Groups several edits into one undo step and one change event. Nested calls join the\n * outermost transaction. If `fn` throws, the model is rolled back.\n */\n transaction<T>(fn: () => T): T;\n\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n clearHistory(): void;\n}\n\n// The iStar 2.0 overload comes last, so function references type as before.\nexport function createModelStore<EK extends string, LK extends string>(\n initial: IstarModel<EK, LK>,\n options?: ModelStoreOptions<EK, LK>,\n): ModelStore<EK, LK>;\nexport function createModelStore<EK extends string, LK extends string>(\n initial: undefined,\n options: ModelStoreOptions<EK, LK> & { readonly metamodel: Metamodel<EK, LK> },\n): ModelStore<EK, LK>;\nexport function createModelStore(initial?: IstarModel, options?: ModelStoreOptions): ModelStore;\nexport function createModelStore(\n initial?: AnyIstarModel,\n options: ModelStoreOptions<string, string> = {},\n): ModelStore<string, string> {\n initial ??= options.metamodel\n ? createEmptyModel(undefined, { metamodel: options.metamodel })\n : (createEmptyModel() as AnyIstarModel);\n const limit = options.historyLimit ?? 100;\n const ctx = { createId: options.createId ?? ops.defaultIdGenerator };\n const listeners = new Set<ModelListener<string, string>>();\n let model = initial;\n let past: AnyIstarModel[] = [];\n let future: AnyIstarModel[] = [];\n let tx: { start: AnyIstarModel; changes: ModelChange[]; depth: number } | undefined;\n\n const emit = (event: ModelChangeEvent<string, string>): void => {\n for (const listener of listeners) listener(event);\n };\n\n const commit = (next: AnyIstarModel, change: ModelChange): void => {\n if (next === model) return;\n if (tx) {\n model = next;\n tx.changes.push(change);\n return;\n }\n const previous = model;\n past.push(previous);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n model = next;\n emit({ model, previous, changes: [change], source: 'edit' });\n };\n\n const store: ModelStore<string, string> = {\n getModel: () => model,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n canLink: (source, target, kind) => canLink(model, source, target, kind),\n\n addElement(input) {\n const result = ops.addElement(model, input, ctx);\n commit(result.model, { type: 'addElement', id: result.element.id });\n return result.element;\n },\n updateElement(id, patch) {\n commit(ops.updateElement(model, id, patch), { type: 'updateElement', id, patch });\n },\n moveElement(id, x, y) {\n commit(ops.moveElement(model, id, x, y), { type: 'moveElement', id, x, y });\n },\n nestElement(id, parent) {\n commit(ops.nestElement(model, id, parent), { type: 'nestElement', id, parent });\n },\n removeElement(id) {\n commit(ops.removeElement(model, id), { type: 'removeElements', ids: [id] });\n },\n removeElements(ids) {\n const list = [...ids];\n commit(ops.removeElements(model, list), { type: 'removeElements', ids: list });\n },\n setCollapsed(actorId, collapsed) {\n const patch = { display: { collapsed: collapsed ? true : undefined } };\n commit(ops.updateElement(model, actorId, patch), {\n type: 'updateElement',\n id: actorId,\n patch,\n });\n },\n\n connect(input, connectOptions) {\n const result = ops.connect(model, input, { ...connectOptions, ...ctx });\n if (result.ok) {\n commit(result.model, {\n type: 'connect',\n id: result.link.id,\n ...(result.hub ? { hubId: result.hub.hub.id } : {}),\n });\n }\n return result;\n },\n addLeg(hubId, source, legOptions) {\n const result = ops.addLeg(model, hubId, source, { ...legOptions, ...ctx });\n if (result.ok) commit(result.model, { type: 'connect', id: result.link.id, hubId });\n return result;\n },\n removeLeg(id) {\n commit(ops.removeLeg(model, id), { type: 'removeLeg', id });\n },\n addDependency(input, dependencyOptions) {\n const result = ops.addDependency(model, input, { ...dependencyOptions, ...ctx });\n if (result.ok) {\n commit(result.model, {\n type: 'addDependency',\n dependumId: result.dependum.id,\n linkIds: [result.links[0].id, result.links[1].id],\n });\n }\n return result;\n },\n updateLink(id, patch) {\n commit(ops.updateLink(model, id, patch), { type: 'updateLink', id, patch });\n },\n disconnect(id) {\n commit(ops.disconnect(model, id), { type: 'disconnect', id });\n },\n updateDiagram(patch) {\n commit(ops.updateDiagram(model, patch), { type: 'updateDiagram', patch });\n },\n\n replace(next) {\n commit(next, { type: 'replace' });\n },\n load(next) {\n if (tx) throw new ops.ModelOperationError('cannot load inside a transaction');\n const previous = model;\n model = next;\n past = [];\n future = [];\n emit({ model, previous, changes: [], source: 'load' });\n },\n\n transaction<T>(fn: () => T): T {\n if (tx) {\n tx.depth++;\n try {\n return fn();\n } finally {\n tx.depth--;\n }\n }\n tx = { start: model, changes: [], depth: 1 };\n let result: T;\n try {\n result = fn();\n } catch (error) {\n model = tx.start;\n tx = undefined;\n throw error;\n }\n const { start, changes } = tx;\n tx = undefined;\n if (model !== start) {\n past.push(start);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n emit({ model, previous: start, changes, source: 'edit' });\n }\n return result;\n },\n\n undo() {\n const previous = past.pop();\n if (!previous || tx) return false;\n future.push(model);\n const current = model;\n model = previous;\n emit({ model, previous: current, changes: [], source: 'undo' });\n return true;\n },\n redo() {\n const next = future.pop();\n if (!next || tx) return false;\n past.push(model);\n const current = model;\n model = next;\n emit({ model, previous: current, changes: [], source: 'redo' });\n return true;\n },\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n clearHistory() {\n past = [];\n future = [];\n },\n };\n return store;\n}\n","import type { ElementKind, LinkKind } from './metamodel';\nimport type { CustomProperties, IstarModel } from './model';\n\nexport type PropertyResult<T> = { ok: true; value: T } | { ok: false; error: string };\n\nexport interface PropertyOptions<T> {\n default?: T;\n optional?: boolean;\n label?: string;\n description?: string;\n}\n\nexport interface PropertyType<T> {\n readonly type: 'string' | 'number' | 'boolean' | 'enum' | 'reference';\n readonly options: PropertyOptions<T>;\n readonly values?: readonly string[];\n readonly integer?: boolean;\n readonly min?: number;\n readonly max?: number;\n /**\n * Numbers with `max: 1` (a probability, a rate): the value may also be written as a\n * percentage (`20.00%`). CAIRIS writes `0.2`, KAOSTools `.2` and `20.00%`.\n */\n readonly percent?: boolean;\n /** References: the element or link kinds the id may name; absent, any kind. */\n readonly kinds?: readonly string[];\n parse(raw: string): PropertyResult<T>;\n /**\n * The value as a string. `previous`, the raw string being replaced, lets a type keep the form\n * it was read in (a number read as `20.00%` is written as a percentage).\n */\n serialize(value: T, previous?: string): string;\n}\n\nexport function string(options?: PropertyOptions<string>): PropertyType<string> {\n const opts: PropertyOptions<string> = options ?? {};\n return {\n type: 'string',\n options: opts,\n parse(raw: string): PropertyResult<string> {\n return { ok: true, value: raw };\n },\n serialize(value: string): string {\n return value;\n },\n };\n}\n\n/** `20.00%` → 20.00 as text, or undefined when `raw` isn't a percentage. */\nfunction percentBody(raw: string): string | undefined {\n const text = raw.trim();\n if (!text.endsWith('%')) return undefined;\n const body = text.slice(0, -1).trim();\n return body === '' ? undefined : body;\n}\n\n/** Digits after the decimal point of a number written as text (`20.00` → 2). */\nfunction decimals(text: string): number {\n const dot = text.indexOf('.');\n return dot === -1 ? 0 : text.length - dot - 1;\n}\n\n/** `value` without floating-point noise from a ×100 (0.35 * 100 = 35.00000000000001). */\nfunction plain(value: number): string {\n return String(Number(value.toPrecision(12)));\n}\n\n/** Writes `value` in the form of `previous`: a percentage, a leading dot, or plain. */\nfunction formatNumber(value: number, previous: string | undefined, percent: boolean): string {\n if (previous === undefined) return String(value);\n const body = percent ? percentBody(previous) : undefined;\n if (body !== undefined) {\n const text = plain(value * 100);\n const places = decimals(body);\n return `${places > decimals(text) ? (value * 100).toFixed(places) : text}%`;\n }\n if (/^\\s*[+-]?\\.\\d/.test(previous) && Math.abs(value) < 1) {\n return String(value).replace(/^(-?)0\\./, '$1.');\n }\n return String(value);\n}\n\nexport function number(\n options?: PropertyOptions<number> & { integer?: boolean; min?: number; max?: number },\n): PropertyType<number> {\n const opts: PropertyOptions<number> = options ?? {};\n const integer = options?.integer;\n const min = options?.min;\n const max = options?.max;\n // A number in [·, 1] is a probability or a rate, which tools also write as a percentage.\n const percent = max === 1;\n return {\n type: 'number',\n options: opts,\n integer,\n min,\n max,\n ...(percent ? { percent } : {}),\n parse(raw: string): PropertyResult<number> {\n const body = percent ? percentBody(raw) : undefined;\n const value = body !== undefined ? Number(body) / 100 : Number(raw);\n if (!Number.isFinite(value)) {\n return { ok: false, error: 'must be a finite number' };\n }\n if (integer && !Number.isInteger(value)) {\n return { ok: false, error: 'must be an integer' };\n }\n if (min !== undefined && value < min) {\n return { ok: false, error: `must be at least ${min}` };\n }\n if (max !== undefined && value > max) {\n return { ok: false, error: `must be at most ${max}` };\n }\n return { ok: true, value };\n },\n serialize(value: number, previous?: string): string {\n return formatNumber(value, previous, percent);\n },\n };\n}\n\nexport function boolean(options?: PropertyOptions<boolean>): PropertyType<boolean> {\n const opts: PropertyOptions<boolean> = options ?? {};\n return {\n type: 'boolean',\n options: opts,\n parse(raw: string): PropertyResult<boolean> {\n if (raw === 'true') return { ok: true, value: true };\n if (raw === 'false') return { ok: true, value: false };\n return { ok: false, error: 'must be true or false' };\n },\n serialize(value: boolean): string {\n return value ? 'true' : 'false';\n },\n };\n}\n\nexport function enumOf<const V extends readonly string[]>(\n values: V,\n options?: PropertyOptions<V[number]>,\n): PropertyType<V[number]> {\n const opts: PropertyOptions<V[number]> = options ?? {};\n return {\n type: 'enum',\n options: opts,\n values,\n parse(raw: string): PropertyResult<V[number]> {\n if ((values as readonly string[]).includes(raw)) {\n return { ok: true, value: raw as V[number] };\n }\n return { ok: false, error: `must be one of: ${values.join(', ')}` };\n },\n serialize(value: V[number]): string {\n return value;\n },\n };\n}\n\n/**\n * A value that is another element's or link's id, e.g. the goal a KAOS resolution restores. The\n * schema only checks it is non-empty; `validateModelProperties` reports an id that isn't in the\n * model or names a kind outside `kinds`.\n */\nexport function reference(\n options?: PropertyOptions<string> & { kinds?: readonly string[] },\n): PropertyType<string> {\n const { kinds, ...opts } = options ?? {};\n return {\n type: 'reference',\n options: opts,\n ...(kinds ? { kinds } : {}),\n parse(raw: string): PropertyResult<string> {\n return { ok: true, value: raw };\n },\n serialize(value: string): string {\n return value;\n },\n };\n}\n\nexport const prop: {\n string: typeof string;\n number: typeof number;\n boolean: typeof boolean;\n enum: typeof enumOf;\n reference: typeof reference;\n} = {\n string,\n number,\n boolean,\n enum: enumOf,\n reference,\n};\n\nexport type PropertyShape = Record<string, PropertyType<unknown>>;\n\nexport type InferProperties<S extends PropertyShape> = {\n [K in keyof S]: S[K] extends PropertyType<infer T> ? T : never;\n};\n\nexport interface PropertyIssue {\n key: string;\n message: string;\n}\n\n/**\n * Typed custom properties of one element or link kind. `K` is the kind: iStar 2.0's kinds by\n * default; any extension kind (see `extendMetamodel`) is accepted too.\n */\nexport interface PropertySchema<\n S extends PropertyShape = PropertyShape,\n K extends string = ElementKind | LinkKind,\n> {\n readonly kind: K;\n readonly shape: S;\n read(source: CustomProperties | undefined | PropertyOwner): {\n values: Partial<InferProperties<S>>;\n issues: PropertyIssue[];\n };\n validate(source: CustomProperties | undefined | PropertyOwner): PropertyIssue[];\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties;\n defaults(): CustomProperties;\n}\n\n/** An element or link, read through its `customProperties`. */\nexport interface PropertyOwner {\n readonly kind: string;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface ModelPropertyIssue extends PropertyIssue {\n id: string;\n}\n\ntype PropertySource = CustomProperties | undefined | PropertyOwner;\n\nfunction isCustomPropertiesRecord(source: NonNullable<PropertySource>): source is CustomProperties {\n // Elements and links are passed whole, possibly without `customProperties`; recognize them by\n // shape, whatever their metamodel: a namespaced `kind` (every metamodel's kinds are, e.g.\n // `istar.Goal`, `kaos.Goal`) with a numeric `x` (elements) or a `source` and `target` (links).\n if ('customProperties' in source) return false;\n const owner = source as { kind?: unknown; x?: unknown; source?: unknown; target?: unknown };\n const isModelObject =\n typeof owner.kind === 'string' &&\n owner.kind.includes('.') &&\n (typeof owner.x === 'number' ||\n (typeof owner.source === 'string' && typeof owner.target === 'string'));\n return !isModelObject;\n}\n\nfunction resolveCustomProperties(source: PropertySource): CustomProperties | undefined {\n if (source === undefined) return undefined;\n if (isCustomPropertiesRecord(source)) return source;\n return source.customProperties;\n}\n\nfunction isRequired(options: PropertyOptions<unknown>): boolean {\n return options.optional !== true && options.default === undefined;\n}\n\nfunction emptyMeansAbsent(\n type: PropertyType<unknown>['type'],\n optional: boolean | undefined,\n): boolean {\n return type !== 'string' && optional === true;\n}\n\nfunction readShape<S extends PropertyShape>(\n shape: S,\n source: PropertySource,\n): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n const custom = resolveCustomProperties(source);\n const values: Partial<InferProperties<S>> = {};\n const issues: PropertyIssue[] = [];\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const opts = field.options;\n const hasKey = custom !== undefined && Object.prototype.hasOwnProperty.call(custom, key);\n const raw = hasKey ? custom[key] : undefined;\n\n if (raw === undefined) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n } else if (isRequired(opts)) {\n issues.push({ key, message: 'is required' });\n }\n continue;\n }\n\n if (raw === '' && field.type !== 'string') {\n if (emptyMeansAbsent(field.type, opts.optional)) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n }\n continue;\n }\n issues.push({\n key,\n message:\n field.type === 'boolean'\n ? 'must be true or false'\n : field.type === 'enum'\n ? `must be one of: ${field.values?.join(', ') ?? ''}`\n : field.type === 'reference'\n ? 'must be an element or link id'\n : 'must be a finite number',\n });\n continue;\n }\n\n const parsed = field.parse(raw);\n if (!parsed.ok) {\n issues.push({ key, message: parsed.error });\n continue;\n }\n (values as Record<string, unknown>)[key] = parsed.value;\n }\n\n return { values, issues };\n}\n\n/**\n * A patched value as a string, written back as read: the current string is kept when it already\n * holds the value (`.2` stays `.2`), and otherwise the type writes the value in its form.\n */\nfunction writeField(field: PropertyType<unknown>, value: unknown, current: string): string {\n const parsed = field.parse(current);\n if (parsed.ok && Object.is(parsed.value, value)) return current;\n return field.serialize(value as never, current);\n}\n\nexport function defineProperties<\n const S extends PropertyShape,\n const Kind extends string = ElementKind | LinkKind,\n>(\n kind: Kind,\n shape: S,\n options?: { validate?: (values: Partial<InferProperties<S>>) => PropertyIssue[] },\n): PropertySchema<S, Kind> {\n const crossValidate = options?.validate;\n\n return {\n kind,\n shape,\n read(source: PropertySource): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n return readShape(shape, source);\n },\n validate(source: PropertySource): PropertyIssue[] {\n const { values, issues } = readShape(shape, source);\n const cross = crossValidate ? crossValidate(values) : [];\n return [...issues, ...cross];\n },\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties {\n const result: Record<string, string> = {};\n const seen = new Set<string>();\n\n if (current) {\n for (const [key, value] of Object.entries(current)) {\n if (Object.prototype.hasOwnProperty.call(patch, key)) {\n const patched = patch[key as keyof S];\n if (patched === undefined) {\n continue;\n }\n const field = shape[key];\n if (field) {\n result[key] = writeField(field, patched, value);\n }\n } else {\n result[key] = value;\n }\n seen.add(key);\n }\n }\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n if (seen.has(key)) continue;\n if (!Object.prototype.hasOwnProperty.call(patch, key)) continue;\n const patched = patch[key];\n if (patched === undefined) continue;\n const field = shape[key];\n if (field) {\n result[key] = field.serialize(patched as never);\n }\n }\n\n return result;\n },\n defaults(): CustomProperties {\n const result: Record<string, string> = {};\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const def = field.options.default;\n if (def !== undefined) {\n result[key] = field.serialize(def as never);\n }\n }\n return result;\n },\n };\n}\n\nexport function validateModelProperties<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n schemas: readonly PropertySchema<PropertyShape, string>[],\n): ModelPropertyIssue[] {\n const byKind = new Map<string, PropertySchema<PropertyShape, string>[]>();\n for (const schema of schemas) {\n const list = byKind.get(schema.kind) ?? [];\n list.push(schema);\n byKind.set(schema.kind, list);\n }\n\n const issues: ModelPropertyIssue[] = [];\n\n const check = (owner: PropertyOwner & { readonly id: string }): void => {\n const kindSchemas = byKind.get(owner.kind);\n if (!kindSchemas) return;\n for (const schema of kindSchemas) {\n for (const issue of schema.validate(owner)) {\n issues.push({ ...issue, id: owner.id });\n }\n for (const issue of referenceIssues(model, schema.shape, owner.customProperties)) {\n issues.push({ ...issue, id: owner.id });\n }\n }\n };\n for (const element of model.elements.values()) check(element);\n for (const link of model.links.values()) check(link);\n\n return issues;\n}\n\n/** References (`prop.reference`) to ids that aren't in the model, or to the wrong kind. */\nfunction referenceIssues<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n shape: PropertyShape,\n custom: CustomProperties | undefined,\n): PropertyIssue[] {\n const issues: PropertyIssue[] = [];\n for (const [key, field] of Object.entries(shape)) {\n if (field.type !== 'reference') continue;\n const id = custom?.[key];\n if (id === undefined || id === '') continue;\n const target = model.elements.get(id) ?? model.links.get(id);\n if (!target) {\n issues.push({ key, message: `refers to \"${id}\", which is not in the model` });\n } else if (field.kinds && !field.kinds.includes(target.kind)) {\n issues.push({ key, message: `must refer to a ${field.kinds.join(' or ')}` });\n }\n }\n return issues;\n}\n","/**\n * The Goal Model Diagnostics Protocol: findings about a model's elements and links, published by\n * any analyser (a language server, a validator, a simulation…) and anchored by element id rather\n * than by text position. Data only: diagnostics are never part of the model and are never\n * written to disk.\n *\n * See goal-controller issue #24 (option D). Producers publish per source; consumers see the\n * union of every source, deduplicated by `(elementId, key, message)`.\n */\n\nexport type DiagnosticSeverity = 'error' | 'warning' | 'info' | 'hint';\n\n/** Most severe first. */\nexport const DIAGNOSTIC_SEVERITIES: readonly DiagnosticSeverity[] = [\n 'error',\n 'warning',\n 'info',\n 'hint',\n];\n\n/** A zero-based position in the producer's document (as in LSP). */\nexport interface DiagnosticPosition {\n readonly line: number;\n readonly character: number;\n}\n\nexport interface DiagnosticRange {\n readonly start: DiagnosticPosition;\n readonly end: DiagnosticPosition;\n}\n\nexport interface GoalDiagnostic {\n /** Id of the element or link the diagnostic is about. */\n readonly elementId: string;\n /** The custom property it is about; absent for the element as a whole. */\n readonly key?: string;\n readonly severity: DiagnosticSeverity;\n readonly message: string;\n /** Who published it (e.g. `mutrose`, `goal-language`). */\n readonly source?: string;\n /** Where it was found in the producer's document, if it has one. */\n readonly range?: DiagnosticRange;\n readonly code?: string;\n /** Producer data, passed through untouched. */\n readonly data?: unknown;\n}\n\nconst RANK: Readonly<Record<DiagnosticSeverity, number>> = {\n error: 0,\n warning: 1,\n info: 2,\n hint: 3,\n};\n\n/** Negative when `a` is more severe than `b`. */\nexport function compareSeverity(a: DiagnosticSeverity, b: DiagnosticSeverity): number {\n return RANK[a] - RANK[b];\n}\n\n/** The most severe severity in a list (what a badge shows), or `undefined` if it is empty. */\nexport function worstDiagnosticSeverity(\n diagnostics: readonly { readonly severity: DiagnosticSeverity }[] | undefined,\n): DiagnosticSeverity | undefined {\n let worst: DiagnosticSeverity | undefined;\n for (const d of diagnostics ?? []) {\n if (worst === undefined || RANK[d.severity] < RANK[worst]) worst = d.severity;\n if (worst === 'error') break;\n }\n return worst;\n}\n\nfunction identity(d: GoalDiagnostic): string {\n return `${d.elementId}\\u0000${d.key ?? ''}\\u0000${d.message}`;\n}\n\n/**\n * The union of several lists, in order, without duplicates: diagnostics with the same\n * `(elementId, key, message)` count once, keeping the first one's position and the most severe\n * severity among them.\n */\nexport function mergeDiagnostics(\n lists: Iterable<readonly GoalDiagnostic[] | undefined>,\n): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n const index = new Map<string, number>();\n for (const list of lists) {\n for (const d of list ?? []) {\n const id = identity(d);\n const at = index.get(id);\n if (at === undefined) {\n index.set(id, result.length);\n result.push(d);\n } else if (RANK[d.severity] < RANK[result[at]!.severity]) {\n result[at] = { ...result[at]!, severity: d.severity };\n }\n }\n }\n return result;\n}\n\n/** Diagnostics by element (or link) id, each list in the input order. */\nexport function groupDiagnostics(\n diagnostics: readonly GoalDiagnostic[] | undefined,\n): ReadonlyMap<string, readonly GoalDiagnostic[]> {\n const map = new Map<string, GoalDiagnostic[]>();\n for (const d of diagnostics ?? []) {\n const list = map.get(d.elementId);\n if (list) list.push(d);\n else map.set(d.elementId, [d]);\n }\n return map;\n}\n\n/**\n * Holds the diagnostics of several sources. Each `publish` replaces that source's set, so a\n * producer re-publishes everything it currently reports, as an LSP server does.\n */\nexport interface DiagnosticsStore {\n /**\n * Replaces `source`'s diagnostics (an empty list clears them). Entries without a `source` get\n * this one.\n */\n publish(source: string, diagnostics: readonly GoalDiagnostic[]): void;\n /** Removes one source's diagnostics, or every source's. */\n clear(source?: string): void;\n /** Sources with diagnostics, in the order they first published. */\n sources(): readonly string[];\n /** One source's diagnostics. */\n get(source: string): readonly GoalDiagnostic[];\n /**\n * Every source's diagnostics, merged (see `mergeDiagnostics`). The same array until the next\n * change, so it can back `useSyncExternalStore`.\n */\n getAll(): readonly GoalDiagnostic[];\n subscribe(listener: () => void): () => void;\n}\n\nconst NONE: readonly GoalDiagnostic[] = [];\n\nexport function createDiagnosticsStore(): DiagnosticsStore {\n const bySource = new Map<string, readonly GoalDiagnostic[]>();\n const listeners = new Set<() => void>();\n let merged: readonly GoalDiagnostic[] = NONE;\n const changed = (): void => {\n merged = bySource.size === 0 ? NONE : mergeDiagnostics(bySource.values());\n for (const listener of listeners) listener();\n };\n return {\n publish(source, diagnostics) {\n if (diagnostics.length === 0) {\n if (bySource.delete(source)) changed();\n return;\n }\n bySource.set(\n source,\n diagnostics.map((d) => (d.source === undefined ? { ...d, source } : d)),\n );\n changed();\n },\n clear(source) {\n if (source === undefined) {\n if (bySource.size === 0) return;\n bySource.clear();\n } else if (!bySource.delete(source)) {\n return;\n }\n changed();\n },\n sources: () => [...bySource.keys()],\n get: (source) => bySource.get(source) ?? NONE,\n getAll: () => merged,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Adapters\n\n/**\n * The parts of an LSP `Diagnostic` the adapter reads (structurally typed, so no LSP library is\n * needed). The element is taken from `data.elementId`, or MutRoSe's `data.nodeId`; the property\n * from `data.key`.\n */\nexport interface LspDiagnosticLike {\n readonly range?: DiagnosticRange;\n /** LSP numbering: 1 error, 2 warning, 3 information, 4 hint. */\n readonly severity?: number;\n readonly message: string | { readonly value: string };\n readonly source?: string;\n readonly code?: string | number | { readonly value: string | number };\n readonly data?: unknown;\n}\n\nexport interface FromLspOptions<D extends LspDiagnosticLike = LspDiagnosticLike> {\n /**\n * The element of a diagnostic whose `data` names none, e.g. by looking its range up in the\n * document. Return `undefined` to drop it.\n */\n readonly elementIdFor?: (diagnostic: D) => string | undefined;\n /**\n * `'vscode'` for `vscode.Diagnostic` objects, whose severity counts from 0 (error) to 3\n * (hint). Default `'lsp'`, the protocol's 1 to 4.\n */\n readonly severityNumbering?: 'lsp' | 'vscode';\n}\n\nconst LSP_SEVERITIES: readonly DiagnosticSeverity[] = ['error', 'warning', 'info', 'hint'];\n\nfunction anchorOf(data: unknown): { elementId?: string; key?: string } {\n if (typeof data !== 'object' || data === null) return {};\n const record = data as Record<string, unknown>;\n const elementId =\n typeof record.elementId === 'string'\n ? record.elementId\n : typeof record.nodeId === 'string'\n ? record.nodeId\n : undefined;\n return {\n ...(elementId ? { elementId } : {}),\n ...(typeof record.key === 'string' ? { key: record.key } : {}),\n };\n}\n\nfunction convertLsp<D extends LspDiagnosticLike>(\n d: D,\n options: FromLspOptions<D>,\n): GoalDiagnostic | undefined {\n const anchor = anchorOf(d.data);\n const elementId = anchor.elementId ?? options.elementIdFor?.(d);\n if (!elementId) return undefined;\n const base = options.severityNumbering === 'vscode' ? 0 : 1;\n // LSP leaves a missing severity to the client; VS Code shows it as an error.\n const severity =\n d.severity === undefined ? 'error' : (LSP_SEVERITIES[d.severity - base] ?? 'error');\n const code = typeof d.code === 'object' ? d.code.value : d.code;\n return {\n elementId,\n ...(anchor.key !== undefined ? { key: anchor.key } : {}),\n severity,\n message: typeof d.message === 'string' ? d.message : d.message.value,\n ...(d.source !== undefined ? { source: d.source } : {}),\n ...(d.range ? { range: d.range } : {}),\n ...(code !== undefined ? { code: String(code) } : {}),\n ...(d.data !== undefined ? { data: d.data } : {}),\n };\n}\n\n/**\n * One LSP diagnostic anchored by `data.elementId` (or `data.nodeId`), or `undefined` when it\n * names no element. For range-anchored diagnostics use `fromLspDiagnostics` with `elementIdFor`.\n */\nexport function fromLspDiagnostic(diagnostic: LspDiagnosticLike): GoalDiagnostic | undefined {\n return convertLsp(diagnostic, {});\n}\n\n/** LSP diagnostics as goal diagnostics; those that can't be anchored to an element are dropped. */\nexport function fromLspDiagnostics<D extends LspDiagnosticLike>(\n diagnostics: readonly D[],\n options: FromLspOptions<D> = {},\n): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n for (const d of diagnostics) {\n const converted = convertLsp(d, options);\n if (converted) result.push(converted);\n }\n return result;\n}\n\n/**\n * The shape MutRoSe's VS Code extension posts to its webview: `{ nodeId, severity, message }`\n * (plus `range` and `source`). `nodeId` is missing when no node could be found.\n */\nexport interface NodeIdDiagnostic {\n readonly nodeId?: string;\n readonly key?: string;\n readonly severity: DiagnosticSeverity | string;\n readonly message: string;\n readonly source?: string;\n readonly range?: DiagnosticRange;\n readonly code?: string;\n}\n\n/** One `{ nodeId, severity, message }` diagnostic, or `undefined` without a `nodeId`. */\nexport function fromNodeIdDiagnostic(diagnostic: NodeIdDiagnostic): GoalDiagnostic | undefined {\n const { nodeId, severity, ...rest } = diagnostic;\n if (!nodeId) return undefined;\n return {\n ...rest,\n elementId: nodeId,\n severity: Object.hasOwn(RANK, severity) ? (severity as DiagnosticSeverity) : 'info',\n };\n}\n\n/**\n * `{ nodeId, severity, message }` diagnostics (MutRoSe) as goal diagnostics, dropping those\n * without a node: `store.publish('mutrose', fromNodeIdDiagnostics(message.diagnostics))`.\n */\nexport function fromNodeIdDiagnostics(diagnostics: readonly NodeIdDiagnostic[]): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n for (const d of diagnostics) {\n const converted = fromNodeIdDiagnostic(d);\n if (converted) result.push(converted);\n }\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["fail","isActorIn","ops.defaultIdGenerator","ops.addElement","ops.updateElement","ops.moveElement","ops.nestElement","ops.removeElement","ops.removeElements","ops.connect","ops.addLeg","ops.removeLeg","ops.addDependency","ops.updateLink","ops.disconnect","ops.updateDiagram","ops.ModelOperationError"],"sources":["../src/metamodel.ts","../src/metamodels.ts","../src/shared.ts","../src/model.ts","../src/constraints.ts","../src/file-metamodel.ts","../src/serialization.ts","../src/operations.ts","../src/store.ts","../src/properties.ts","../src/diagnostics.ts","../src/palette.ts"],"sourcesContent":["/**\n * The iStar 2.0 metamodel, ported from piStar's `tool/language/metamodel.js`.\n *\n * Kind names carry the `istar.` prefix exactly as they appear in piStar save files.\n */\n\nexport const ISTAR_PREFIX = 'istar';\nexport const METAMODEL_VERSION = '0.2';\n\n/** Containers: elements that hold inner elements (piStar `metamodel.containers`). */\nexport const ACTOR_KINDS = ['istar.Actor', 'istar.Agent', 'istar.Role'] as const;\nexport type ActorKind = (typeof ACTOR_KINDS)[number];\n\n/** Intentional elements (piStar `metamodel.nodes`). */\nexport const NODE_KINDS = ['istar.Goal', 'istar.Quality', 'istar.Resource', 'istar.Task'] as const;\nexport type NodeKind = (typeof NODE_KINDS)[number];\n\nexport type ElementKind = ActorKind | NodeKind;\nexport const ELEMENT_KINDS: readonly ElementKind[] = [...ACTOR_KINDS, ...NODE_KINDS];\n\n/** Links between two containers (piStar `metamodel.containerLinks`). */\nexport const ACTOR_LINK_KINDS = ['istar.IsALink', 'istar.ParticipatesInLink'] as const;\nexport type ActorLinkKind = (typeof ACTOR_LINK_KINDS)[number];\n\n/** Links that connect two containers through a dependum (piStar `metamodel.dependencyLinks`). */\nexport const DEPENDENCY_LINK_KINDS = ['istar.DependencyLink'] as const;\nexport type DependencyLinkKind = (typeof DEPENDENCY_LINK_KINDS)[number];\n\n/** Links between two intentional elements (piStar `metamodel.nodeLinks`). */\nexport const NODE_LINK_KINDS = [\n 'istar.AndRefinementLink',\n 'istar.OrRefinementLink',\n 'istar.NeededByLink',\n 'istar.QualificationLink',\n 'istar.ContributionLink',\n] as const;\nexport type NodeLinkKind = (typeof NODE_LINK_KINDS)[number];\n\nexport type LinkKind = ActorLinkKind | DependencyLinkKind | NodeLinkKind;\nexport const LINK_KINDS: readonly LinkKind[] = [\n ...ACTOR_LINK_KINDS,\n ...DEPENDENCY_LINK_KINDS,\n ...NODE_LINK_KINDS,\n];\n\n/** Possible values of a Contribution link's `label`. */\nexport const CONTRIBUTION_LABELS = ['make', 'help', 'hurt', 'break'] as const;\nexport type ContributionLabel = (typeof CONTRIBUTION_LABELS)[number];\n\nexport interface NodeKindInfo {\n /** Can be added inside an actor. */\n readonly canBeInnerElement: boolean;\n /** Can be the dependum of a dependency. */\n readonly canBeDependum: boolean;\n /** Can be placed directly on the diagram, outside any actor. */\n readonly canBeOnPaper: boolean;\n}\n\nexport interface LinkKindInfo {\n /** Fixed text drawn on the link (e.g. \"is-a\"). */\n readonly label?: string;\n /** piStar retries with source and target swapped when the first attempt is invalid. */\n readonly tryReversedWhenAdding?: boolean;\n /** The link carries a user-selectable label, stored as `label` in the save file. */\n readonly changeableLabel?: boolean;\n readonly possibleLabels?: readonly string[];\n}\n\nconst innerNode: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: false,\n};\n\nexport const NODE_KIND_INFO: Readonly<Record<NodeKind, NodeKindInfo>> = {\n 'istar.Goal': innerNode,\n 'istar.Quality': innerNode,\n 'istar.Resource': innerNode,\n 'istar.Task': innerNode,\n};\n\nexport const LINK_KIND_INFO: Readonly<Record<LinkKind, LinkKindInfo>> = {\n 'istar.IsALink': { label: 'is-a' },\n 'istar.ParticipatesInLink': { label: 'participates-in' },\n 'istar.DependencyLink': {},\n 'istar.AndRefinementLink': {},\n 'istar.OrRefinementLink': {},\n 'istar.NeededByLink': { tryReversedWhenAdding: true },\n 'istar.QualificationLink': { tryReversedWhenAdding: true },\n 'istar.ContributionLink': { changeableLabel: true, possibleLabels: CONTRIBUTION_LABELS },\n};\n\nexport interface Size {\n width: number;\n height: number;\n}\n\n/**\n * Default sizes of each element kind, from piStar's `shapes.js`. For actors this is the\n * initial boundary size; the collapsed actor symbol is a circle of radius 40.\n */\nexport const DEFAULT_ELEMENT_SIZE: Readonly<Record<ElementKind, Size>> = {\n 'istar.Actor': { width: 200, height: 120 },\n 'istar.Agent': { width: 200, height: 120 },\n 'istar.Role': { width: 200, height: 120 },\n 'istar.Goal': { width: 90, height: 35 },\n 'istar.Quality': { width: 90, height: 55 },\n 'istar.Resource': { width: 90, height: 35 },\n 'istar.Task': { width: 95, height: 36 },\n};\n\nconst actorKinds: ReadonlySet<string> = new Set(ACTOR_KINDS);\nconst nodeKinds: ReadonlySet<string> = new Set(NODE_KINDS);\nconst elementKinds: ReadonlySet<string> = new Set(ELEMENT_KINDS);\nconst linkKinds: ReadonlySet<string> = new Set(LINK_KINDS);\nconst actorLinkKinds: ReadonlySet<string> = new Set(ACTOR_LINK_KINDS);\nconst nodeLinkKinds: ReadonlySet<string> = new Set(NODE_LINK_KINDS);\n\nexport function isActorKind(kind: string): kind is ActorKind {\n return actorKinds.has(kind);\n}\nexport function isNodeKind(kind: string): kind is NodeKind {\n return nodeKinds.has(kind);\n}\nexport function isElementKind(kind: string): kind is ElementKind {\n return elementKinds.has(kind);\n}\nexport function isLinkKind(kind: string): kind is LinkKind {\n return linkKinds.has(kind);\n}\nexport function isActorLinkKind(kind: string): kind is ActorLinkKind {\n return actorLinkKinds.has(kind);\n}\nexport function isNodeLinkKind(kind: string): kind is NodeLinkKind {\n return nodeLinkKinds.has(kind);\n}\nexport function isDependencyLinkKind(kind: string): kind is DependencyLinkKind {\n return kind === 'istar.DependencyLink';\n}\nexport function isContributionLabel(value: string): value is ContributionLabel {\n return (CONTRIBUTION_LABELS as readonly string[]).includes(value);\n}\n\n/** `'istar.Goal'` → `'Goal'` */\nexport function shortKindName(kind: ElementKind | LinkKind): string {\n return kind.slice(ISTAR_PREFIX.length + 1);\n}\n","/**\n * Metamodels as values. A root metamodel (`defineMetamodel`) is a whole modelling language:\n * iStar 2.0 (`ISTAR_2_0`) is one, and other goal languages (KAOS, NFR, …) can be others.\n * Dialects of a root are built with `extendMetamodel`, which adds element kinds (e.g.\n * iStar4RationalAgents' Planning and Plan) and link kinds.\n *\n * The constants in `metamodel.ts` (`ELEMENT_KINDS`, `NODE_KIND_INFO`, …) describe iStar 2.0 and\n * stay as they are; this module declares `ISTAR_2_0` from them. Everything that accepts a\n * metamodel defaults to `ISTAR_2_0`, so code that never mentions one behaves exactly as before.\n *\n * Extensions follow piStar-ext (Gonçalves et al., iStar 2020): a new construct has a name, a\n * node-or-link category and, for links, the kinds it may connect. Two additions make them\n * usable as a library: `behavesLike` lets a new kind reuse an existing kind's link rules\n * (Planning behaves like a Task, so it can be refined and be a dependum), and kinds are\n * namespaced (`rationalAgents.Planning`), with the root's prefix (`istar.` for iStar 2.0)\n * reserved for the root.\n */\nimport type { LinkCheck, LinkRuleContext } from './constraints';\nimport type { ElementKind, LinkKind, LinkKindInfo, NodeKindInfo, Size } from './metamodel';\nimport {\n ACTOR_KINDS,\n ACTOR_LINK_KINDS,\n DEFAULT_ELEMENT_SIZE,\n DEPENDENCY_LINK_KINDS,\n ISTAR_PREFIX,\n LINK_KIND_INFO,\n NODE_KINDS,\n NODE_KIND_INFO,\n NODE_LINK_KINDS,\n} from './metamodel';\n\nexport type ElementCategory = 'actor' | 'node';\n\n/**\n * Presentation hints a kind may carry, as data (core never draws). `@istar-ts/react` uses them as\n * the defaults for the kind: a shape as SVG path data, the label's text box, a link's line.\n */\nexport interface KindShape {\n readonly path: string;\n readonly viewBox?: string;\n /** SVG `stroke-dasharray` of the outline, e.g. `'8,4'` for a dashed shape. */\n readonly dash?: string;\n /** Outline width, when it differs from the renderer's default. */\n readonly strokeWidth?: number;\n /**\n * Default fill (any CSS colour) of the kind's elements and palette icon, when the element has\n * no `display.backgroundColor`; absent: the renderer's node fill (DSM3's KAOS is grey, its\n * NFR white).\n */\n readonly fill?: string;\n}\nexport interface KindTextBox {\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n readonly left: number;\n}\nexport interface KindLine {\n readonly dash?: string;\n readonly marker?: string | false;\n readonly markerFilled?: boolean;\n}\nexport type LinkCategory = 'actor' | 'node' | 'dependency';\n\n/** A resolved element kind of a metamodel. */\nexport interface ElementKindDefinition<K extends string = string> {\n readonly kind: K;\n readonly category: ElementCategory;\n /** Human-readable name, e.g. \"Goal\" or \"Planning\". */\n readonly label: string;\n /** Default size; for actors the initial boundary size. */\n readonly size: Size;\n /** Containment rules (nodes only; actors have none). */\n readonly info?: NodeKindInfo;\n /** The kind whose link rules this kind follows (built-in kinds have none). */\n readonly behavesLike?: string;\n /** The `type` written in piStar files. Equal to `kind` unless declared otherwise. */\n readonly pistarType: string;\n /** Name of the extension that declared it; absent for iStar 2.0 kinds. */\n readonly extension?: string;\n /** Presentation hints (drawn by `@istar-ts/react`). */\n readonly shape?: KindShape;\n readonly textBox?: KindTextBox;\n /** `hub` for the kind generated for an n-ary link kind's hubs (see `LinkKindDeclaration.arity`). */\n readonly role?: 'hub';\n /** For a hub kind: the n-ary link kind it was generated for. */\n readonly of?: string;\n}\n\n/** The kinds generated for an n-ary link kind: its hub element kind, leg and end link kinds. */\nexport interface HubLinkParts {\n readonly hub: string;\n readonly leg: string;\n readonly end: string;\n}\n\n/**\n * The kinds an n-ary link kind `K` generates under the default names: its hub element kind\n * (`<K>Hub`), its leg (`<K>Start`) and its end (`<K>End`). A schema for one of them is declared\n * like any other: `defineProperties('kaos.RefinementLinkStart', { … })`.\n */\nexport type HubPartKind<K extends string> = `${K}Hub` | `${K}Start` | `${K}End`;\n\n/**\n * Declarative link rules, as piStar-ext's \"Create a new Construct\" dialog collects them:\n * which kinds may be the source and target. Entries are kind names (`istar.Goal`,\n * `rationalAgents.Plan`) or categories (`node`, `actor`, `*`). A kind name also matches kinds\n * that behave like it, so `istar.Task` accepts a Planning that behaves like a Task.\n *\n * A link may also target another link (NFR's Argument link points at a Contribution): `targets`\n * then holds `link` (any link) or link kind names. Sources are always elements.\n */\nexport interface LinkRules {\n readonly sources: readonly string[];\n /** Element selectors as for `sources`, plus `link` and link kind names. */\n readonly targets: readonly string[];\n /**\n * Source and target must belong to the same actor (iStar 2.0 Guide, page 14). Default true\n * for node links, ignored for actor links.\n */\n readonly sameActor?: boolean;\n /** Allow a dependum as source or target. Default false. */\n readonly allowDependum?: boolean;\n /** Allow a link from an element onto itself. Default false. */\n readonly allowSelf?: boolean;\n /**\n * At most one link `'kind'` of this kind, or `'any'` link at all, between the same two\n * elements (in either direction); `false` for no limit. Default `'kind'`.\n */\n readonly unique?: 'kind' | 'any' | false;\n}\n\n/** A resolved link kind of a metamodel. */\nexport interface LinkKindDefinition<K extends string = string> {\n readonly kind: K;\n readonly category: LinkCategory;\n readonly label: string;\n readonly info: LinkKindInfo;\n /** The link kind whose rules (and meaning, for other rules) this kind takes on. */\n readonly behavesLike?: string;\n /** Declarative rules, for link kinds that don't behave like another kind. */\n readonly rules?: LinkRules;\n /** An extra predicate, checked after the inherited or declarative rules pass. */\n readonly check?: (context: LinkRuleContext) => LinkCheck;\n readonly pistarType: string;\n readonly extension?: string;\n /** Presentation hint (drawn by `@istar-ts/react`). */\n readonly line?: KindLine;\n /** `'n'` for an n-ary link kind (several sources joined at a hub); absent means 1. */\n readonly arity?: 1 | 'n';\n /** For an n-ary kind: the kinds generated for it. */\n readonly parts?: HubLinkParts;\n /** For a generated kind: `leg` (a source → the hub) or `end` (the hub → the target). */\n readonly role?: 'leg' | 'end';\n /** For a generated kind: the n-ary link kind it was generated for. */\n readonly of?: string;\n}\n\n/**\n * How a root metamodel's files look, for models that don't come from a file (`createEmptyModel`)\n * and for writing them (`toPistar`). Files that were read keep their own layout.\n */\nexport interface MetamodelFileHints {\n /** The `tool` a new model records. Default: piStar's `pistar.2.1.0`. */\n readonly tool?: string;\n /** The `istar` version a new model records; only iStar 2.0 sets it (`'2.0'`). */\n readonly istar?: string;\n /** Extra top-level keys of a new model (its `extra`), e.g. `{ metamodelVersion: '1.0' }`. */\n readonly extra?: Readonly<Record<string, unknown>>;\n /** Top-level key order for models without a source layout. Default: piStar's. */\n readonly keys?: readonly string[];\n}\n\n/** A metamodel: the element and link kinds a model may use, and their rules. */\nexport interface Metamodel<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * The root's name (`istar-2.0`), followed by the names of the extensions applied, e.g.\n * `istar-2.0+rationalAgents`.\n */\n readonly name: string;\n /** The root metamodel's name, e.g. `istar-2.0`; extensions keep it. */\n readonly framework: string;\n /** The root's namespace (`istar`). Extensions may not declare kinds in it. */\n readonly prefix: string;\n /** How the root's files look (see `MetamodelFileHints`); extensions keep it. */\n readonly file: MetamodelFileHints;\n readonly extensions: readonly string[];\n /** In declaration order: the root's kinds first, then each extension's. */\n readonly elements: ReadonlyMap<EK, ElementKindDefinition<EK>>;\n readonly links: ReadonlyMap<LK, LinkKindDefinition<LK>>;\n /** `type` in piStar files → kind. */\n readonly elementsByPistarType: ReadonlyMap<string, EK>;\n readonly linksByPistarType: ReadonlyMap<string, LK>;\n}\n\n/** The kinds of a metamodel, as type-level unions. */\nexport type ElementKindOf<M> = M extends Metamodel<infer EK, string> ? EK : never;\nexport type LinkKindOf<M> = M extends Metamodel<string, infer LK> ? LK : never;\n\n/** A metamodel of any dialect, for code that handles every kind generically. */\nexport type AnyMetamodel = Metamodel<string, string>;\n\n// ---------------------------------------------------------------------------------------------\n// Declarations\n\nexport interface ElementKindDeclaration<K extends string = string> {\n /** Namespaced kind name, e.g. `rationalAgents.Planning`. */\n readonly kind: K;\n /** Default: the part after the namespace (\"Planning\"). */\n readonly label?: string;\n /** Required unless `behavesLike` is given (then it is the same category). */\n readonly category?: ElementCategory;\n /** An existing element kind whose link rules this kind follows, e.g. `istar.Task`. */\n readonly behavesLike?: string;\n /**\n * Containment rules for nodes. Default: those of `behavesLike`, else piStar-ext's (inner,\n * dependum) in an extension and DSM3's (inner, dependum, on paper) in a root.\n */\n readonly info?: Partial<NodeKindInfo>;\n /** Default: that of `behavesLike`, else piStar-ext's 90×55 for nodes and 200×120 for actors. */\n readonly size?: Size;\n /**\n * The `type` used in piStar files, when it differs from `kind`. piStar-ext saves its new\n * constructs as `istar.<Name>`, so `pistarType: 'istar.Planning'` reads its files.\n */\n readonly pistarType?: string;\n /** Presentation hints, kept as data for renderers (`@istar-ts/react` draws them). */\n readonly shape?: KindShape;\n readonly textBox?: KindTextBox;\n}\n\nexport interface LinkKindDeclaration<K extends string = string> {\n readonly kind: K;\n readonly label?: string;\n /** Default: that of `behavesLike`, else `node`. */\n readonly category?: LinkCategory;\n /** An existing link kind whose rules this kind takes on, e.g. `istar.OrRefinementLink`. */\n readonly behavesLike?: string;\n /**\n * Declarative rules; give these or `behavesLike`, not both. A root's link kind may give\n * neither when the library has built-in rules for it (iStar 2.0's links).\n */\n readonly rules?: LinkRules;\n /** An extra predicate, checked after the other rules pass. */\n readonly check?: (context: LinkRuleContext) => LinkCheck;\n /** Default: that of `behavesLike`, else none (no fixed label, no changeable value). */\n readonly info?: LinkKindInfo;\n readonly pistarType?: string;\n /** Presentation hint, kept as data for renderers (`@istar-ts/react` draws it). */\n readonly line?: KindLine;\n /**\n * `'n'` for a link with several sources, like KAOS's AND-refinement: in a model it is a hub\n * element joined to each source by a leg link and to the target by an end link, as DSM3-goals\n * draws and saves it. Declaring it generates three kinds, named after this one (`parts`):\n * `<kind>Hub`, `<kind>Start` and `<kind>End`, written as `<pistarType>Hub` etc. Needs `rules`\n * and the `node` category.\n */\n readonly arity?: 'n';\n /** Names of the generated kinds, when the defaults don't suit. */\n readonly parts?: Partial<HubLinkParts>;\n /** The hub's size. Default 20×20, as in DSM3-goals. */\n readonly hubSize?: Size;\n}\n\n/** A whole modelling language, turned into a `Metamodel` by `defineMetamodel`. */\nexport interface RootMetamodelDeclaration<EK extends string = string, LK extends string = string> {\n /** Identifies the language; the metamodel's `name` and `framework`, e.g. `istar-2.0`. */\n readonly name: string;\n /** The language's namespace, e.g. `istar`. Extensions may not declare kinds in it. */\n readonly prefix: string;\n readonly elements: readonly ElementKindDeclaration<EK>[];\n readonly links: readonly LinkKindDeclaration<LK>[];\n readonly file?: MetamodelFileHints;\n}\n\n/** A named set of new kinds, applied to a metamodel with `extendMetamodel`. */\nexport interface MetamodelExtension<NEK extends string = string, NLK extends string = string> {\n /** Identifies the extension, e.g. `rationalAgents`. */\n readonly name: string;\n readonly elements?: readonly ElementKindDeclaration<NEK>[];\n readonly links?: readonly LinkKindDeclaration<NLK>[];\n}\n\nexport class MetamodelError extends Error {\n override name = 'MetamodelError';\n}\n\n/**\n * Declares an extension, keeping its kind names as literal types (so `extendMetamodel` can\n * type the result). Identity at runtime.\n */\nexport function defineMetamodelExtension<\n const NEK extends string = never,\n const NLK extends string = never,\n>(extension: MetamodelExtension<NEK, NLK>): MetamodelExtension<NEK, NLK> {\n return extension;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Building kinds. `defineMetamodel` and `extendMetamodel` add kinds to a mutable table, one\n// declaration at a time, so `behavesLike` and rule selectors resolve against the kinds the\n// table already holds: the base metamodel's, then those declared earlier.\n\nconst KIND_NAME = /^[A-Za-z_][\\w-]*\\.[A-Za-z_][\\w-]*$/;\nconst PREFIX_NAME = /^[A-Za-z_][\\w-]*$/;\nconst CATEGORY_SELECTORS: ReadonlySet<string> = new Set(['node', 'actor', '*']);\n/** The `targets` selector for any link (see `LinkRules`). */\nexport const LINK_SELECTOR = 'link';\n\n/** piStar-ext's defaults for an extension's new nodes (tool/language/metamodel.js). */\nconst EXTENSION_NODE_INFO: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: false,\n};\n\n/** DSM3-goals' defaults for a root's nodes (istarcore metamodelManager). */\n/** A hub sits on the paper, outside any actor, and is never a dependum. */\nconst HUB_INFO: NodeKindInfo = {\n canBeInnerElement: false,\n canBeDependum: false,\n canBeOnPaper: true,\n};\n\n/** A circle filling the hub's box (DSM3-goals draws a circle of radius 10 in 20×20). */\nconst HUB_SHAPE: KindShape = {\n path: 'M 0 10 A 10 10 0 1 0 20 10 A 10 10 0 1 0 0 10 Z',\n viewBox: '0 0 20 20',\n};\n\nconst ROOT_NODE_INFO: NodeKindInfo = {\n canBeInnerElement: true,\n canBeDependum: true,\n canBeOnPaper: true,\n};\n\ninterface KindTable {\n /** `extension \"x\"` or `metamodel \"x\"`, opening every error message. */\n readonly where: string;\n /** The namespace suggested in errors: the extension's name, or the root's prefix. */\n readonly namespace: string;\n /** The root's prefix, when the table builds an extension (a root may use any namespace). */\n readonly reserved?: string;\n /** Name of the extension being built; absent for a root. */\n readonly extension?: string;\n readonly elements: Map<string, ElementKindDefinition<string>>;\n readonly links: Map<string, LinkKindDefinition<string>>;\n readonly elementsByType: Map<string, string>;\n readonly linksByType: Map<string, string>;\n}\n\nfunction shortName(kind: string): string {\n const dot = kind.indexOf('.');\n return dot === -1 ? kind : kind.slice(dot + 1);\n}\n\nfunction claimName(table: KindTable, kind: string, what: string): void {\n const { where } = table;\n if (typeof kind !== 'string' || !KIND_NAME.test(kind)) {\n throw new MetamodelError(\n `${where}: ${what} kind ${JSON.stringify(kind)} must be namespaced, e.g. \"${table.namespace}.Name\"`,\n );\n }\n if (table.reserved !== undefined && kind.startsWith(`${table.reserved}.`)) {\n throw new MetamodelError(\n `${where}: ${what} kind \"${kind}\" uses the reserved \"${table.reserved}.\" prefix; ` +\n `name it \"${table.namespace}.${shortName(kind)}\" and set pistarType: \"${kind}\" to read files that use it`,\n );\n }\n if (table.elements.has(kind) || table.links.has(kind)) {\n throw new MetamodelError(`${where}: kind \"${kind}\" already exists`);\n }\n}\n\nfunction claimType(table: KindTable, type: string, kind: string): void {\n const { where } = table;\n if (typeof type !== 'string' || type === '') {\n throw new MetamodelError(`${where}: kind \"${kind}\" has an empty pistarType`);\n }\n if (\n table.elementsByType.has(type) ||\n table.linksByType.has(type) ||\n table.elements.has(type) ||\n table.links.has(type)\n ) {\n throw new MetamodelError(\n `${where}: pistarType \"${type}\" of kind \"${kind}\" is already used by another kind`,\n );\n }\n}\n\nfunction isCompleteNodeInfo(info: Partial<NodeKindInfo> | undefined): info is NodeKindInfo {\n return (\n info !== undefined &&\n typeof info.canBeInnerElement === 'boolean' &&\n typeof info.canBeDependum === 'boolean' &&\n typeof info.canBeOnPaper === 'boolean'\n );\n}\n\nfunction addElementKind(table: KindTable, declaration: ElementKindDeclaration<string>): void {\n const { where } = table;\n const { kind } = declaration;\n claimName(table, kind, 'element');\n let parent: ElementKindDefinition<string> | undefined;\n if (declaration.behavesLike !== undefined) {\n parent = table.elements.get(declaration.behavesLike);\n if (!parent) {\n throw new MetamodelError(\n `${where}: \"${kind}\" behaves like unknown element kind \"${declaration.behavesLike}\"`,\n );\n }\n }\n const category = declaration.category ?? parent?.category;\n if (category !== 'actor' && category !== 'node') {\n throw new MetamodelError(\n `${where}: element kind \"${kind}\" needs a category (\"node\" or \"actor\") or behavesLike`,\n );\n }\n if (parent && parent.category !== category) {\n throw new MetamodelError(\n `${where}: \"${kind}\" is a ${category} but behaves like \"${parent.kind}\", a ${parent.category}`,\n );\n }\n const type = declaration.pistarType ?? kind;\n claimType(table, type, kind);\n // A complete `info` is kept as given (iStar 2.0's `NODE_KIND_INFO` objects keep their identity).\n const info: NodeKindInfo = isCompleteNodeInfo(declaration.info)\n ? declaration.info\n : {\n ...(parent?.info ?? (table.extension === undefined ? ROOT_NODE_INFO : EXTENSION_NODE_INFO)),\n ...declaration.info,\n };\n const definition: ElementKindDefinition<string> = {\n kind,\n category,\n label: declaration.label ?? shortName(kind),\n size:\n declaration.size ??\n parent?.size ??\n (category === 'actor' ? { width: 200, height: 120 } : { width: 90, height: 55 }),\n ...(category === 'node' ? { info } : {}),\n ...(parent ? { behavesLike: parent.kind } : {}),\n pistarType: type,\n ...(table.extension !== undefined ? { extension: table.extension } : {}),\n ...(declaration.shape ? { shape: declaration.shape } : {}),\n ...(declaration.textBox ? { textBox: declaration.textBox } : {}),\n };\n table.elements.set(kind, definition);\n table.elementsByType.set(type, kind);\n}\n\nfunction addLinkKind(table: KindTable, declaration: LinkKindDeclaration<string>): void {\n const { where } = table;\n const { kind } = declaration;\n claimName(table, kind, 'link');\n const isRoot = table.extension === undefined;\n if (declaration.behavesLike !== undefined && declaration.rules !== undefined) {\n throw new MetamodelError(\n isRoot\n ? `${where}: link kind \"${kind}\" needs at most one of behavesLike or rules`\n : `${where}: link kind \"${kind}\" needs exactly one of behavesLike or rules`,\n );\n }\n // A root's link kind may give neither: its rules are then built in (iStar 2.0's links).\n if (!isRoot && declaration.behavesLike === undefined && declaration.rules === undefined) {\n throw new MetamodelError(\n `${where}: link kind \"${kind}\" needs exactly one of behavesLike or rules`,\n );\n }\n let parent: LinkKindDefinition<string> | undefined;\n if (declaration.behavesLike !== undefined) {\n parent = table.links.get(declaration.behavesLike);\n if (!parent) {\n throw new MetamodelError(\n `${where}: \"${kind}\" behaves like unknown link kind \"${declaration.behavesLike}\"`,\n );\n }\n }\n const category = declaration.category ?? parent?.category ?? 'node';\n if (category !== 'node' && category !== 'actor' && category !== 'dependency') {\n throw new MetamodelError(`${where}: link kind \"${kind}\" has an unknown category \"${category}\"`);\n }\n if (declaration.arity !== undefined) {\n if (declaration.arity !== 'n') {\n throw new MetamodelError(\n `${where}: link kind \"${kind}\" has an unknown arity ${JSON.stringify(declaration.arity)}`,\n );\n }\n if (!declaration.rules || category !== 'node') {\n throw new MetamodelError(\n `${where}: n-ary link kind \"${kind}\" needs rules and the \"node\" category`,\n );\n }\n }\n if (parent && parent.category !== category) {\n throw new MetamodelError(\n `${where}: \"${kind}\" is a ${category} link but behaves like \"${parent.kind}\", a ${parent.category} link`,\n );\n }\n if (category === 'dependency' && !parent && (!isRoot || declaration.rules !== undefined)) {\n throw new MetamodelError(\n `${where}: dependency link kind \"${kind}\" must behave like a dependency link (its dependum makes declarative rules ambiguous)`,\n );\n }\n if (declaration.rules) {\n for (const [side, selectors] of [\n ['sources', declaration.rules.sources],\n ['targets', declaration.rules.targets],\n ] as const) {\n if (!Array.isArray(selectors) || selectors.length === 0) {\n throw new MetamodelError(`${where}: link kind \"${kind}\" needs at least one of ${side}`);\n }\n for (const selector of selectors) {\n const known =\n CATEGORY_SELECTORS.has(selector) ||\n table.elements.has(selector) ||\n // Targets may also name links: any, an earlier kind, or this kind itself.\n (side === 'targets' &&\n (selector === LINK_SELECTOR || table.links.has(selector) || selector === kind));\n if (!known) {\n throw new MetamodelError(\n `${where}: ${side} of \"${kind}\" names unknown element kind \"${selector}\"`,\n );\n }\n }\n }\n }\n const type = declaration.pistarType ?? kind;\n claimType(table, type, kind);\n const definition: LinkKindDefinition<string> = {\n kind,\n category,\n label: declaration.label ?? shortName(kind),\n info: declaration.info ?? parent?.info ?? {},\n ...(parent ? { behavesLike: parent.kind } : {}),\n ...(declaration.rules ? { rules: declaration.rules } : {}),\n ...(declaration.check ? { check: declaration.check } : {}),\n pistarType: type,\n ...(table.extension !== undefined ? { extension: table.extension } : {}),\n ...(declaration.line ? { line: declaration.line } : {}),\n };\n if (declaration.arity !== 'n') {\n table.links.set(kind, definition);\n table.linksByType.set(type, kind);\n return;\n }\n const parts: HubLinkParts = {\n hub: declaration.parts?.hub ?? `${kind}Hub`,\n leg: declaration.parts?.leg ?? `${kind}Start`,\n end: declaration.parts?.end ?? `${kind}End`,\n };\n table.links.set(kind, { ...definition, arity: 'n', parts });\n table.linksByType.set(type, kind);\n addHubKinds(table, table.links.get(kind)!, parts, declaration.hubSize);\n}\n\n/**\n * Adds the kinds an n-ary link kind is made of, as DSM3-goals' `setupSplitLinks` generates them:\n * the hub (an element), the legs (each source → the hub, at most one per source) and the end\n * (the hub → the target).\n */\nfunction addHubKinds(\n table: KindTable,\n base: LinkKindDefinition<string>,\n parts: HubLinkParts,\n hubSize: Size | undefined,\n): void {\n const rules = base.rules!;\n // Generated kinds go through the usual checks; their errors name the kind they come from.\n const claim = (kind: string, type: string, what: string): void => {\n try {\n claimName(table, kind, what);\n claimType(table, type, kind);\n } catch (error) {\n if (!(error instanceof MetamodelError)) throw error;\n throw new MetamodelError(`${error.message} (generated for n-ary link kind \"${base.kind}\")`);\n }\n };\n const owner = table.extension !== undefined ? { extension: table.extension } : {};\n claim(parts.hub, `${base.pistarType}Hub`, 'element');\n table.elements.set(parts.hub, {\n kind: parts.hub,\n category: 'node',\n label: `${base.label} hub`,\n size: hubSize ?? { width: 20, height: 20 },\n info: HUB_INFO,\n pistarType: `${base.pistarType}Hub`,\n ...owner,\n shape: HUB_SHAPE,\n role: 'hub',\n of: base.kind,\n });\n table.elementsByType.set(`${base.pistarType}Hub`, parts.hub);\n // The base kind's same-actor rule is checked between a leg's source and the end's target\n // (`canLink`): the hub itself belongs to no actor.\n const common = {\n category: 'node' as const,\n ...owner,\n of: base.kind,\n };\n claim(parts.leg, `${base.pistarType}Start`, 'link');\n table.links.set(parts.leg, {\n ...common,\n kind: parts.leg,\n label: `${base.label} leg`,\n info: {},\n rules: {\n sources: rules.sources,\n targets: [parts.hub],\n sameActor: false,\n ...(rules.allowDependum !== undefined ? { allowDependum: rules.allowDependum } : {}),\n unique: 'kind',\n },\n pistarType: `${base.pistarType}Start`,\n role: 'leg',\n });\n table.linksByType.set(`${base.pistarType}Start`, parts.leg);\n claim(parts.end, `${base.pistarType}End`, 'link');\n table.links.set(parts.end, {\n ...common,\n kind: parts.end,\n label: `${base.label} end`,\n info: base.info,\n rules: {\n sources: [parts.hub],\n targets: rules.targets,\n sameActor: false,\n ...(rules.allowDependum !== undefined ? { allowDependum: rules.allowDependum } : {}),\n unique: 'kind',\n },\n pistarType: `${base.pistarType}End`,\n ...(base.line ? { line: base.line } : {}),\n role: 'end',\n });\n table.linksByType.set(`${base.pistarType}End`, parts.end);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Root metamodels\n\n/**\n * Builds a root metamodel: a modelling language of its own, such as iStar 2.0, KAOS or NFR.\n * Kinds are namespaced (any namespace; usually `prefix`), declared in order: `behavesLike` and\n * link rules refer to kinds declared before them. Extensions of the result may not use `prefix`.\n *\n * Throws `MetamodelError` on the same declaration errors as `extendMetamodel`.\n */\nexport function defineMetamodel<const EK extends string, const LK extends string>(\n declaration: RootMetamodelDeclaration<EK, LK>,\n): Metamodel<EK, LK> {\n const { name, prefix } = declaration;\n if (!name || typeof name !== 'string') {\n throw new MetamodelError('a root metamodel needs a name');\n }\n const where = `metamodel \"${name}\"`;\n if (typeof prefix !== 'string' || !PREFIX_NAME.test(prefix)) {\n throw new MetamodelError(\n `${where}: prefix ${JSON.stringify(prefix)} must be a name without dots, e.g. \"istar\"`,\n );\n }\n const table: KindTable = {\n where,\n namespace: prefix,\n elements: new Map(),\n links: new Map(),\n elementsByType: new Map(),\n linksByType: new Map(),\n };\n for (const element of declaration.elements) addElementKind(table, element);\n for (const link of declaration.links) addLinkKind(table, link);\n return {\n name,\n framework: name,\n prefix,\n file: declaration.file ?? {},\n extensions: [],\n elements: table.elements,\n links: table.links,\n elementsByPistarType: table.elementsByType,\n linksByPistarType: table.linksByType,\n } as unknown as Metamodel<EK, LK>;\n}\n\nconst ISTAR_LINK_LABELS: Readonly<Record<LinkKind, string>> = {\n 'istar.IsALink': 'Is-A',\n 'istar.ParticipatesInLink': 'Participates-In',\n 'istar.DependencyLink': 'Dependency',\n 'istar.AndRefinementLink': 'And-Refinement',\n 'istar.OrRefinementLink': 'Or-Refinement',\n 'istar.NeededByLink': 'Needed-By',\n 'istar.QualificationLink': 'Qualification',\n 'istar.ContributionLink': 'Contribution',\n};\n\nfunction istarLinks(\n kinds: readonly LinkKind[],\n category: LinkCategory,\n): LinkKindDeclaration<LinkKind>[] {\n // No rules: iStar 2.0's link rules are built in (`constraints.ts`).\n return kinds.map((kind) => ({\n kind,\n category,\n label: ISTAR_LINK_LABELS[kind],\n info: LINK_KIND_INFO[kind],\n }));\n}\n\n/** iStar 2.0's declaration, built from the constants in `metamodel.ts`. */\nexport const ISTAR_2_0_DECLARATION: RootMetamodelDeclaration<ElementKind, LinkKind> = {\n name: 'istar-2.0',\n prefix: ISTAR_PREFIX,\n elements: [\n ...ACTOR_KINDS.map((kind): ElementKindDeclaration<ElementKind> => ({\n kind,\n category: 'actor',\n size: DEFAULT_ELEMENT_SIZE[kind],\n })),\n ...NODE_KINDS.map((kind): ElementKindDeclaration<ElementKind> => ({\n kind,\n category: 'node',\n size: DEFAULT_ELEMENT_SIZE[kind],\n info: NODE_KIND_INFO[kind],\n })),\n ],\n links: [\n ...istarLinks(ACTOR_LINK_KINDS, 'actor'),\n ...istarLinks(DEPENDENCY_LINK_KINDS, 'dependency'),\n ...istarLinks(NODE_LINK_KINDS, 'node'),\n ],\n // `PISTAR_TOOL` and `ISTAR_VERSION` (model.ts), which can't be imported here without a cycle.\n file: { tool: 'pistar.2.1.0', istar: '2.0' },\n};\n\n/** iStar 2.0, as the piStar tool implements it. The default metamodel everywhere. */\nexport const ISTAR_2_0: Metamodel = defineMetamodel(ISTAR_2_0_DECLARATION);\n\n// ---------------------------------------------------------------------------------------------\n// Extensions\n\n/**\n * Returns a new metamodel with the extension's kinds added. `base` is not modified. The result\n * keeps `base`'s `framework`, `prefix` and `file`.\n *\n * Throws `MetamodelError` when a kind name isn't namespaced, uses the root's reserved prefix\n * (`istar.` for iStar 2.0), collides with an existing kind or piStar type, or refers to an\n * unknown kind.\n */\nexport function extendMetamodel<\n EK extends string,\n LK extends string,\n const NEK extends string = never,\n const NLK extends string = never,\n>(base: Metamodel<EK, LK>, extension: MetamodelExtension<NEK, NLK>): Metamodel<EK | NEK, LK | NLK> {\n if (!extension.name || typeof extension.name !== 'string') {\n throw new MetamodelError('an extension needs a name');\n }\n const where = `extension \"${extension.name}\"`;\n if (base.extensions.includes(extension.name)) {\n throw new MetamodelError(`${where} is already applied`);\n }\n const table: KindTable = {\n where,\n namespace: extension.name,\n reserved: base.prefix,\n extension: extension.name,\n elements: new Map<string, ElementKindDefinition<string>>(base.elements),\n links: new Map<string, LinkKindDefinition<string>>(base.links),\n elementsByType: new Map<string, string>(base.elementsByPistarType),\n linksByType: new Map<string, string>(base.linksByPistarType),\n };\n for (const element of extension.elements ?? []) addElementKind(table, element);\n for (const link of extension.links ?? []) addLinkKind(table, link);\n return {\n name: `${base.name}+${extension.name}`,\n framework: base.framework,\n prefix: base.prefix,\n file: base.file,\n extensions: [...base.extensions, extension.name],\n elements: table.elements,\n links: table.links,\n elementsByPistarType: table.elementsByType,\n linksByPistarType: table.linksByType,\n } as unknown as Metamodel<EK | NEK, LK | NLK>;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Queries. They accept any string so code handling models of unknown dialects can ask.\n\nexport function elementKindDefinition(\n metamodel: AnyMetamodel,\n kind: string,\n): ElementKindDefinition | undefined {\n return metamodel.elements.get(kind);\n}\n\nexport function linkKindDefinition(\n metamodel: AnyMetamodel,\n kind: string,\n): LinkKindDefinition | undefined {\n return metamodel.links.get(kind);\n}\n\n/** True for actor-category kinds (Actor, Agent, Role and extensions behaving like them). */\nexport function isActorKindIn(metamodel: AnyMetamodel, kind: string): boolean {\n return metamodel.elements.get(kind)?.category === 'actor';\n}\n\n/** True for node-category kinds (intentional elements, built-in or extended). */\nexport function isNodeKindIn(metamodel: AnyMetamodel, kind: string): boolean {\n return metamodel.elements.get(kind)?.category === 'node';\n}\n\n/**\n * The built-in (or rule-carrying) kind an element kind ultimately behaves like: `istar.Task`\n * for a Planning that behaves like a Task; the kind itself when it behaves like nothing.\n */\nexport function effectiveElementKind(metamodel: AnyMetamodel, kind: string): string {\n let current = metamodel.elements.get(kind);\n const seen = new Set<string>();\n while (current?.behavesLike !== undefined && !seen.has(current.kind)) {\n seen.add(current.kind);\n const next = metamodel.elements.get(current.behavesLike);\n if (!next) break;\n current = next;\n }\n return current?.kind ?? kind;\n}\n\n/** Like `effectiveElementKind`, for link kinds. */\nexport function effectiveLinkKind(metamodel: AnyMetamodel, kind: string): string {\n let current = metamodel.links.get(kind);\n const seen = new Set<string>();\n while (current?.behavesLike !== undefined && !seen.has(current.kind)) {\n seen.add(current.kind);\n const next = metamodel.links.get(current.behavesLike);\n if (!next) break;\n current = next;\n }\n return current?.kind ?? kind;\n}\n\n/** True when link `kind` is `ancestor` or (transitively) behaves like it. */\nexport function linkBehavesLike(metamodel: AnyMetamodel, kind: string, ancestor: string): boolean {\n let current: string | undefined = kind;\n const seen = new Set<string>();\n while (current !== undefined && !seen.has(current)) {\n if (current === ancestor) return true;\n seen.add(current);\n current = metamodel.links.get(current)?.behavesLike;\n }\n return false;\n}\n\n/** True when a link kind's rules let it target links (`link` or a link kind in `targets`). */\nexport function targetsLinks(metamodel: AnyMetamodel, kind: string): boolean {\n const root = metamodel.links.get(effectiveLinkKind(metamodel, kind));\n return (\n root?.rules?.targets.some(\n (selector) => selector === LINK_SELECTOR || metamodel.links.has(selector),\n ) ?? false\n );\n}\n\n/** True when `kind` is `ancestor` or (transitively) behaves like it. */\nexport function elementBehavesLike(\n metamodel: AnyMetamodel,\n kind: string,\n ancestor: string,\n): boolean {\n let current: string | undefined = kind;\n const seen = new Set<string>();\n while (current !== undefined && !seen.has(current)) {\n if (current === ancestor) return true;\n seen.add(current);\n current = metamodel.elements.get(current)?.behavesLike;\n }\n return false;\n}\n","/**\n * Registries the library keeps beside models (their metamodel, their file's layout) are\n * shared across every copy of `@istar-ts/core` loaded in a process. A bundle may load the\n * package twice, once as ESM and once as CommonJS (an application parsing with the ESM build\n * while a CommonJS dependency reads the model with the CJS build): a module-level WeakMap in\n * each copy would make a model parsed by one copy unknown to the other, so `metamodelOf`\n * would fall back to iStar 2.0 there. The registries live on `globalThis` under one symbol\n * instead, keyed by name, and every copy finds the same ones.\n */\nconst REGISTRIES: unique symbol = Symbol.for('@istar-ts/core/registries');\n\ntype Registries = Map<string, WeakMap<object, unknown>>;\n\n/** The WeakMap named `name`, the same object in every copy of the library in this process. */\nexport function sharedWeakMap<V>(name: string): WeakMap<object, V> {\n const host = globalThis as { [REGISTRIES]?: Registries };\n const registries = (host[REGISTRIES] ??= new Map());\n let map = registries.get(name);\n if (!map) registries.set(name, (map = new WeakMap()));\n return map as WeakMap<object, V>;\n}\n","import type { ActorKind, ElementKind, LinkKind, NodeKind, Size } from './metamodel';\nimport type { AnyMetamodel, Metamodel } from './metamodels';\nimport { ISTAR_2_0, isActorKindIn } from './metamodels';\nimport { sharedWeakMap } from './shared';\n\n/**\n * piStar stores every custom property value as a string (e.g. `\"initialValue\": \"false\"`).\n * Typed access is layered on top with property schemas (see `properties.ts`).\n */\nexport type CustomProperties = Readonly<Record<string, string>>;\n\n/** Arbitrary JSON keys the library does not interpret; kept so they survive a round trip. */\nexport type Extra = Readonly<Record<string, unknown>>;\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\n/** Per-element entry of the save file's `display` section. */\nexport interface ElementDisplay {\n readonly backgroundColor?: string;\n readonly width?: number;\n readonly height?: number;\n /** Actors only. */\n readonly collapsed?: boolean;\n readonly [key: string]: unknown;\n}\n\n/** Per-link entry of the save file's `display` section. */\nexport interface LinkDisplay {\n readonly vertices?: readonly Point[];\n readonly [key: string]: unknown;\n}\n\n/**\n * An element of the model. `K` is the kind union: iStar 2.0's by default, wider for models of an\n * extended metamodel (see `extendMetamodel`).\n */\nexport interface IstarElement<K extends string = ElementKind> {\n readonly id: string;\n readonly kind: K;\n /** The element's label; `text` in the save file. */\n readonly name: string;\n /** Absolute diagram coordinates, as in the save file (children are not relative to actors). */\n readonly x: number;\n readonly y: number;\n /** Id of the containing actor, for inner elements. */\n readonly parent?: string;\n /** True when the element is the dependum of a dependency (lives in `dependencies`). */\n readonly isDependum?: boolean;\n /**\n * Depender/dependee recorded in the save file for a dependum. The dependency links are the\n * source of truth; this is only a fallback used when those links are missing.\n */\n readonly dependency?: { readonly source: string; readonly target: string };\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n readonly extra?: Extra;\n}\n\nexport type IstarActor = IstarElement<ActorKind>;\nexport type IstarNode = IstarElement<NodeKind>;\n\nexport interface IstarLink<K extends string = LinkKind> {\n readonly id: string;\n readonly kind: K;\n readonly source: string;\n readonly target: string;\n /** Contribution value (`make`/`help`/`hurt`/`break`), stored as `label` in the save file. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: LinkDisplay;\n readonly extra?: Extra;\n}\n\nexport interface Diagram {\n readonly width?: number;\n readonly height?: number;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\n readonly extra?: Extra;\n}\n\n/**\n * An immutable iStar model. Maps preserve insertion order, which is the order elements and\n * links are written back to disk.\n *\n * `EK`/`LK` are the element and link kind unions; they default to iStar 2.0's.\n */\nexport interface IstarModel<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly elements: ReadonlyMap<string, IstarElement<EK>>;\n readonly links: ReadonlyMap<string, IstarLink<LK>>;\n readonly diagram?: Diagram;\n readonly tool?: string;\n readonly istar?: string;\n readonly saveDate?: string;\n /** `display` entries whose id matches no element or link. */\n readonly extraDisplay?: Extra;\n /** Unknown top-level keys (e.g. `metamodelVersion`). */\n readonly extra?: Extra;\n}\n\n/** Tool identifier written by piStar 2.1.0, whose file format this library emulates. */\nexport const PISTAR_TOOL = 'pistar.2.1.0';\nexport const ISTAR_VERSION = '2.0';\n\n/**\n * DSM3-goals' file conventions, shared by its languages (KAOS, NFR; see `@istar-ts/dsm3-kaos`\n * and `@istar-ts/dsm3-nfr`): the `tool` its editors write, and the order of their top-level keys\n * (`fileManager.js`). Use them as a root's `file.tool` and `file.keys`.\n */\nexport const DSM3_TOOL = 'dsm3-goals';\nexport const DSM3_FILE_KEYS: readonly string[] = [\n 'actors',\n 'orphans',\n 'dependencies',\n 'links',\n 'display',\n 'tool',\n 'metamodelVersion',\n 'saveDate',\n 'diagram',\n];\n\nexport const DEFAULT_DIAGRAM: Diagram = { width: 2000, height: 1300 };\n\n/** A model of any dialect, for code that handles every kind generically. */\nexport type AnyIstarModel = IstarModel<string, string>;\n\n/**\n * The metamodel of each model that isn't iStar 2.0. Kept beside the model rather than in it,\n * so a model's shape (and `JSON.stringify`, deep equality, snapshots) is the same as before\n * metamodels existed. Operations and the store carry it to every model they derive.\n */\nconst metamodels = sharedWeakMap<AnyMetamodel>('metamodels');\n\n/**\n * Associates `metamodel` with `model` and returns the same model, typed for it. Use when a\n * model was built without the library's operations (e.g. with an object spread), which loses\n * the association.\n */\nexport function withMetamodel<EK extends string, LK extends string>(\n model: IstarModel<string, string>,\n metamodel: Metamodel<EK, LK>,\n): IstarModel<EK, LK> {\n if ((metamodel as unknown) === ISTAR_2_0) metamodels.delete(model);\n else metamodels.set(model, metamodel as unknown as AnyMetamodel);\n return model as unknown as IstarModel<EK, LK>;\n}\n\n/**\n * For models whose file declares part of their metamodel (see `withFileMetamodel`): the\n * metamodel the host supplied, without the file's kinds.\n */\nconst hostMetamodels = sharedWeakMap<AnyMetamodel>('hostMetamodels');\n\n/** @internal Records the host part of a model's metamodel (used by serialization). */\nexport function setHostMetamodel(model: object, metamodel: AnyMetamodel | undefined): void {\n if (metamodel) hostMetamodels.set(model, metamodel);\n else hostMetamodels.delete(model);\n}\n\n/** @internal The host part of a model's metamodel, if the file declares the rest. */\nexport function hostMetamodelOf(model: object): AnyMetamodel | undefined {\n return hostMetamodels.get(model);\n}\n\n/** Gives `to` the metamodel of `from` (used for every model an operation derives). */\nexport function inheritMetamodel<M extends IstarModel<string, string>>(\n from: IstarModel<string, string>,\n to: M,\n): M {\n if (from === to) return to;\n const metamodel = metamodels.get(from);\n if (metamodel) metamodels.set(to, metamodel);\n const host = hostMetamodels.get(from);\n if (host) hostMetamodels.set(to, host);\n return to;\n}\n\n// The iStar 2.0 overload comes last: TypeScript resolves function references (e.g.\n// `useIstarStore(createEmptyModel)`) against the last one, as before metamodels existed.\nexport function createEmptyModel<EK extends string, LK extends string>(\n diagram: Diagram | undefined,\n options: { metamodel: Metamodel<EK, LK> },\n): IstarModel<EK, LK>;\nexport function createEmptyModel(diagram?: Diagram): IstarModel;\nexport function createEmptyModel(\n diagram: Diagram = DEFAULT_DIAGRAM,\n options: { metamodel?: AnyMetamodel } = {},\n): AnyIstarModel {\n // The root metamodel's file hints say what a new file records: iStar 2.0 writes piStar's\n // `tool` and `istar: \"2.0\"`; other roots their own tool and top-level keys.\n const { file } = (options.metamodel ?? ISTAR_2_0) as AnyMetamodel;\n const model: AnyIstarModel = {\n elements: new Map(),\n links: new Map(),\n diagram,\n tool: file.tool ?? PISTAR_TOOL,\n ...(file.istar !== undefined ? { istar: file.istar } : {}),\n ...(file.extra !== undefined ? { extra: { ...file.extra } } : {}),\n };\n return options.metamodel ? withMetamodel(model, options.metamodel) : model;\n}\n\n/**\n * The metamodel a model was read or created with (see `parsePistar`, `createEmptyModel`), or\n * iStar 2.0. Constraints, operations and serialization use it unless given another one.\n */\nexport function metamodelOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): Metamodel<EK, LK> {\n return (metamodels.get(model) ?? ISTAR_2_0) as unknown as Metamodel<EK, LK>;\n}\n\n/**\n * True for iStar 2.0 actors (Actor, Agent, Role). One argument, so it is safe as an array\n * callback (`elements.filter(isActor)`). For extended actor kinds use `isActorIn(metamodel)`.\n */\nexport function isActor(element: IstarElement<string> | undefined): element is IstarActor {\n return element !== undefined && isActorKindIn(ISTAR_2_0, element.kind);\n}\n\n/** True for iStar 2.0 intentional elements. For extended kinds use `isNodeIn(metamodel)`. */\nexport function isNode(element: IstarElement<string> | undefined): element is IstarNode {\n return element !== undefined && !isActorKindIn(ISTAR_2_0, element.kind);\n}\n\n/**\n * A predicate for actor-category elements of `metamodel`, extended actor kinds included:\n * `elements.filter(isActorIn(metamodelOf(model)))`.\n */\nexport function isActorIn(\n metamodel: AnyMetamodel,\n): (element: IstarElement<string> | undefined) => boolean {\n return (element) => element !== undefined && isActorKindIn(metamodel, element.kind);\n}\n\n/** A predicate for node-category elements of `metamodel`, extended node kinds included. */\nexport function isNodeIn(\n metamodel: AnyMetamodel,\n): (element: IstarElement<string> | undefined) => boolean {\n return (element) =>\n element !== undefined && metamodel.elements.get(element.kind)?.category === 'node';\n}\n\n/** Inner elements of an actor, in model order. */\nexport function childrenOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n actorId: string,\n): IstarElement<EK>[] {\n const result: IstarElement<EK>[] = [];\n for (const element of model.elements.values()) {\n if (element.parent === actorId) result.push(element);\n }\n return result;\n}\n\n/**\n * Links that have the element as source or target. Given a link id, the links that target that\n * link (see `LinkRules`).\n */\nexport function linksOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n elementId: string,\n): IstarLink<LK>[] {\n const result: IstarLink<LK>[] = [];\n for (const link of model.links.values()) {\n if (link.source === elementId || link.target === elementId) result.push(link);\n }\n return result;\n}\n\n/** For a dependum, the two halves of its dependency: depender → dependum → dependee. */\nexport function dependencyLinksOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n dependumId: string,\n): { inbound?: IstarLink<LK>; outbound?: IstarLink<LK> } {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n let inbound: IstarLink<LK> | undefined;\n let outbound: IstarLink<LK> | undefined;\n for (const link of model.links.values()) {\n if (metamodel.links.get(link.kind)?.category !== 'dependency') continue;\n if (link.target === dependumId && !inbound) inbound = link;\n if (link.source === dependumId && !outbound) outbound = link;\n }\n return { inbound, outbound };\n}\n\n/** What a link points at: an element, or a link for kinds whose rules target links. */\nexport function linkTargetOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n link: IstarLink<LK>,\n): IstarElement<EK> | IstarLink<LK> | undefined {\n return model.elements.get(link.target) ?? model.links.get(link.target);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Hub links (n-ary link kinds, see `LinkKindDeclaration.arity`)\n\n/** An n-ary link as it lives in a model: its hub element, its legs (in link order), its end. */\nexport interface HubLink<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly hub: IstarElement<EK>;\n readonly legs: readonly IstarLink<LK>[];\n /** Absent only in an incomplete model (`validateModel` reports it). */\n readonly end?: IstarLink<LK>;\n}\n\n/** True when `element` is the hub of an n-ary link. */\nexport function isHubElement(\n metamodel: AnyMetamodel,\n element: IstarElement<string> | undefined,\n): boolean {\n return element !== undefined && metamodel.elements.get(element.kind)?.role === 'hub';\n}\n\n/** The n-ary link whose hub is `hubId`; `undefined` when it isn't a hub. */\nexport function hubLinkOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n hubId: string,\n): HubLink<EK, LK> | undefined {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const hub = model.elements.get(hubId);\n if (!hub || !isHubElement(metamodel, hub)) return undefined;\n const legs: IstarLink<LK>[] = [];\n let end: IstarLink<LK> | undefined;\n for (const link of model.links.values()) {\n const role = metamodel.links.get(link.kind)?.role;\n if (role === 'leg' && link.target === hubId) legs.push(link);\n else if (role === 'end' && link.source === hubId) end ??= link;\n }\n return { hub, legs, ...(end ? { end } : {}) };\n}\n\n/** The hub a leg or end link belongs to. */\nexport function hubOfLink<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n linkId: string,\n): IstarElement<EK> | undefined {\n const metamodel = metamodelOf(model) as AnyMetamodel;\n const link = model.links.get(linkId);\n const role = link && metamodel.links.get(link.kind)?.role;\n if (!link || !role) return undefined;\n const hub = model.elements.get(role === 'leg' ? link.target : link.source);\n return isHubElement(metamodel, hub) ? hub : undefined;\n}\n\n/** The centre of an element's box: its display size, else its kind's default size. */\nexport function elementCenter<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n element: IstarElement<EK>,\n): Point {\n const size = (metamodelOf(model) as AnyMetamodel).elements.get(element.kind)?.size;\n const width = element.display?.width ?? size?.width ?? 0;\n const height = element.display?.height ?? size?.height ?? 0;\n return { x: element.x + width / 2, y: element.y + height / 2 };\n}\n\n/**\n * Where a new hub goes: centred between the source and the target, as DSM3-goals places it.\n * Returns its top-left corner for a hub of `size`.\n */\nexport function defaultHubPosition<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n source: IstarElement<EK>,\n target: IstarElement<EK>,\n size: Size,\n): Point {\n const a = elementCenter(model, source);\n const b = elementCenter(model, target);\n return { x: (a.x + b.x) / 2 - size.width / 2, y: (a.y + b.y) / 2 - size.height / 2 };\n}\n\nexport interface Box extends Point, Size {}\n\n/** Space kept between inner elements and an actor's boundary (piStar's `updateBoundary` adds 10px). */\nexport const ACTOR_PADDING = 10;\n\n/** A kind's default size, absent any per-host override (see `actorBounds`' `defaultSizeOf`). */\nfunction metamodelSizeOf(metamodel: AnyMetamodel, kind: string): Size {\n return metamodel.elements.get(kind)?.size ?? { width: 0, height: 0 };\n}\n\n/**\n * An actor's boundary: the kind's default-size rectangle at the actor's position, grown to\n * include every inner element (each padded by `ACTOR_PADDING`), like piStar's `updateBoundary`\n * (which floors on the kind's default size, not the actor's last expanded `display` size; an\n * inner element's own `display` size does override, same as its rendered size elsewhere).\n * Shared by `@istar-ts/react`'s node layout and `@istar-ts/glsp`'s GModel, so an actor draws the\n * same box in both: children are looked up by category (`metamodelOf`), not `istar.*` names.\n *\n * `defaultSizeOf` resolves a kind's default size; it defaults to the metamodel's, but a host\n * whose registry overrides a kind's size independently of the metamodel (`@istar-ts/react`'s\n * `IstarRegistry`) must pass one that reads its own sizes, or its boundary would stop matching\n * what it actually draws.\n */\nexport function actorBounds<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n actorId: string,\n metamodel: Metamodel<EK, LK> = metamodelOf(model),\n defaultSizeOf: (kind: EK) => Size = (kind) =>\n metamodelSizeOf(metamodel as unknown as AnyMetamodel, kind),\n): Box {\n const actor = model.elements.get(actorId);\n if (!actor) throw new Error(`no element \"${actorId}\" in the model`);\n const meta = metamodel as unknown as AnyMetamodel;\n const ownSize = defaultSizeOf(actor.kind);\n let minX = actor.x;\n let minY = actor.y;\n let maxX = actor.x + ownSize.width;\n let maxY = actor.y + ownSize.height;\n for (const child of model.elements.values()) {\n if (child.parent !== actorId) continue;\n if (meta.elements.get(child.kind)?.category === 'actor') continue;\n const base = defaultSizeOf(child.kind);\n const width = child.display?.width ?? base.width;\n const height = child.display?.height ?? base.height;\n minX = Math.min(minX, child.x - ACTOR_PADDING);\n minY = Math.min(minY, child.y - ACTOR_PADDING);\n maxX = Math.max(maxX, child.x + width + ACTOR_PADDING);\n maxY = Math.max(maxY, child.y + height + ACTOR_PADDING);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n","/**\n * iStar 2.0 link constraints, ported from piStar's `tool/language/constraints.js`.\n *\n * Each check runs in the same order as upstream so the reported reason is the one piStar\n * would show. Upstream messages embed HTML and illustrative images; here they are plain text.\n */\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, LinkKindDefinition, LinkRules, Metamodel } from './metamodels';\nimport {\n LINK_SELECTOR,\n effectiveElementKind,\n effectiveLinkKind,\n elementBehavesLike,\n linkBehavesLike,\n} from './metamodels';\nimport type { AnyIstarModel, IstarElement, IstarLink, IstarModel } from './model';\nimport { metamodelOf } from './model';\n\nexport type ConstraintCode =\n | 'unknown-element'\n | 'unknown-link-kind'\n | 'invalid-source'\n | 'invalid-target'\n | 'actor-types-differ'\n | 'self-link'\n | 'duplicate-link'\n | 'dependum-endpoint'\n | 'same-actor'\n | 'different-actors'\n | 'refined-depender'\n | 'contributed-depender'\n | 'depender-target'\n | 'mixed-refinement'\n | 'contribution-and-qualification'\n /** A link other than a leg towards the hub of an n-ary link. */\n | 'hub-target'\n /** `validateModel`: the hub of an n-ary link lacks its end or every leg. */\n | 'incomplete-hub';\n\nexport type LinkCheck =\n | { ok: true }\n | { ok: false; reason: string; code: ConstraintCode; end?: 'source' | 'target' };\n\nconst OK: LinkCheck = { ok: true };\n\nfunction fail(code: ConstraintCode, reason: string, end?: 'source' | 'target'): LinkCheck {\n return { ok: false, code, reason, end };\n}\n\ntype ElementRef = string | { readonly id: string };\n\n/**\n * True for a link, as opposed to an element: the target of a link kind whose rules target links\n * (see `LinkRules`) may be either.\n */\nexport function isLinkRef<EK extends string, LK extends string>(\n value: IstarElement<EK> | IstarLink<LK>,\n): value is IstarLink<LK> {\n const candidate = value as { source?: unknown; target?: unknown };\n return typeof candidate.source === 'string' && typeof candidate.target === 'string';\n}\n\nexport interface CanLinkOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /** Default: the model's metamodel, or iStar 2.0. */\n readonly metamodel?: Metamodel<EK, LK>;\n}\n\n/**\n * Checks whether a link of `kind` may be added from `source` to `target` in `model`.\n *\n * For dependency links, `source` is the depender and `target` the dependee (an actor or one of\n * its inner elements); the dependum sits between them and is not part of the check.\n *\n * Extended kinds (see `extendMetamodel`) are checked with the rules of the kind they behave\n * like, or with their declarative rules, then with their extra predicate.\n *\n * `target` may be a link (or a link id) for kinds whose rules target links (`LinkRules`).\n *\n * For an n-ary kind (`arity: 'n'`), a `target` that is one of its hubs is checked as a new leg\n * of that hub; any other target, as a new link from `source` to `target`.\n */\nexport function canLink<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n source: string | IstarElement<EK>,\n target: string | IstarElement<EK> | IstarLink<LK>,\n kind: LK,\n options: CanLinkOptions<EK, LK> = {},\n): LinkCheck {\n const any = model as unknown as AnyIstarModel;\n const metamodel = (options.metamodel ?? metamodelOf(model)) as unknown as AnyMetamodel;\n const s = resolve(any, source);\n const t = resolve(any, target) ?? any.links.get(refId(target));\n if (!s) return fail('unknown-element', `unknown source element \"${refId(source)}\"`, 'source');\n if (!t) return fail('unknown-element', `unknown target element \"${refId(target)}\"`, 'target');\n let definition = metamodel.links.get(kind);\n if (!definition) return fail('unknown-link-kind', `unknown link kind \"${String(kind)}\"`);\n // Linking to one of the kind's own hubs adds a leg to it.\n if (definition.parts && !isLinkRef(t) && metamodel.elements.get(t.kind)?.of === definition.kind) {\n definition = metamodel.links.get(definition.parts.leg) ?? definition;\n }\n return checkWith(new Graph(any, metamodel), definition, s, t);\n}\n\n/** Runs the rule a link kind resolves to, then every extra predicate along its chain. */\nfunction checkWith(\n graph: Graph,\n definition: LinkKindDefinition,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n): LinkCheck {\n const chain: LinkKindDefinition[] = [];\n for (\n let current: LinkKindDefinition | undefined = definition;\n current && !chain.includes(current);\n current = current.behavesLike ? graph.metamodel.links.get(current.behavesLike) : undefined\n ) {\n chain.push(current);\n }\n const root = chain[chain.length - 1]!;\n const builtIn = CHECKS[root.kind as LinkKind];\n let result: LinkCheck;\n if (root.rules)\n result = declarativeCheck(graph, definition, root.rules, root.kind, source, target);\n else if (isLinkRef(target)) result = elementTargetOnly(definition);\n else if (builtIn) result = builtIn(graph, source, target);\n else result = fail('unknown-link-kind', `link kind \"${definition.kind}\" has no rules`);\n if (!result.ok) return result;\n if (definition.role !== undefined && !isLinkRef(target)) {\n const hubResult = hubCheck(graph, definition, source, target);\n if (!hubResult.ok) return hubResult;\n }\n const context = graph.context(definition.kind, source, target);\n for (const step of chain.toReversed()) {\n if (!step.check) continue;\n const extra = step.check(context);\n if (!extra.ok) return extra;\n }\n return OK;\n}\n\n/**\n * What a leg or end must also respect: an n-ary link has one end, and the base kind's same-actor\n * rule holds between each leg's source and the end's target (the hub belongs to no actor).\n */\nfunction hubCheck(\n graph: Graph,\n definition: LinkKindDefinition,\n source: IstarElement<string>,\n target: IstarElement<string>,\n): LinkCheck {\n const base = definition.of === undefined ? undefined : graph.metamodel.links.get(definition.of);\n if (!base) return OK;\n const roleOf = (link: IstarLink<string>): string | undefined =>\n graph.metamodel.links.get(link.kind)?.role;\n if (definition.role === 'end') {\n for (const link of graph.model.links.values()) {\n if (link.source === source.id && roleOf(link) === 'end') {\n return fail('duplicate-link', `the hub of a ${base.label} link has only one end`);\n }\n }\n return OK;\n }\n if (base.rules?.sameActor === false) return OK;\n for (const link of graph.model.links.values()) {\n if (link.source !== target.id || roleOf(link) !== 'end') continue;\n if (graph.model.elements.get(link.target)?.parent !== source.parent) {\n return fail(\n 'different-actors',\n `the sources and target of a ${base.label} link must pertain to the same actor`,\n );\n }\n }\n return OK;\n}\n\n/** The built-in (iStar 2.0) rules only know element targets. */\nfunction elementTargetOnly(definition: LinkKindDefinition): LinkCheck {\n const article = /^[aeiou]/i.test(definition.label) ? 'an' : 'a';\n return fail(\n 'invalid-target',\n `the target of ${article} ${definition.label} link must be an element, not a link`,\n 'target',\n );\n}\n\nfunction refId(ref: ElementRef): string {\n return typeof ref === 'string' ? ref : ref.id;\n}\n\nfunction resolve(model: AnyIstarModel, ref: ElementRef): IstarElement<string> | undefined {\n // Always look the element up so a stale object can't be checked against a newer model.\n return model.elements.get(refId(ref));\n}\n\n/**\n * What an extension's `check` predicate receives: the model, the endpoints, and the graph\n * queries the iStar 2.0 rules use.\n */\nexport interface LinkRuleContext {\n readonly model: AnyIstarModel;\n readonly metamodel: AnyMetamodel;\n /** The link kind being added. */\n readonly kind: string;\n readonly source: IstarElement<string>;\n /** An element, or a link for kinds whose rules target links (narrow with `isLinkRef`). */\n readonly target: IstarElement<string> | IstarLink<string>;\n /**\n * A link (optionally of `kind`, or a kind behaving like it) joins `a` and `b`, either way. Both\n * may be elements or links.\n */\n isThereLinkBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind?: string,\n ): boolean;\n /** `element` is the source of a link of `kind` (or a kind behaving like it). */\n isSourceOfType(element: IstarElement<string>, kind: string): boolean;\n /** `element` is the target of a link of `kind` (or a kind behaving like it). */\n isTargetOfType(element: IstarElement<string>, kind: string): boolean;\n}\n\n/**\n * The graph queries used by upstream constraints (`istar.isThereLinkBetween`, etc.). Link kinds\n * are compared by what they behave like, so an extension link behaving like an OR-refinement\n * counts as one for the iStar 2.0 rules (no mixing with AND, no refining a depender…).\n */\nclass Graph {\n constructor(\n readonly model: AnyIstarModel,\n readonly metamodel: AnyMetamodel,\n ) {}\n\n private matches(link: IstarLink<string>, kind: string): boolean {\n return link.kind === kind || effectiveLinkKind(this.metamodel, link.kind) === kind;\n }\n\n /**\n * True when a link (optionally of `kind`) already connects the two elements, in either\n * direction. Mirrors `istar.isThereLinkBetween`.\n */\n isThereLinkBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind?: string,\n ): boolean {\n for (const link of this.model.links.values()) {\n if (kind && !this.matches(link, kind)) continue;\n if (\n (link.source === a.id && link.target === b.id) ||\n (link.source === b.id && link.target === a.id)\n ) {\n return true;\n }\n }\n return false;\n }\n\n /** Like `isThereLinkBetween`, counting only links of exactly `kind`. */\n isThereLinkOfKindBetween(\n a: { readonly id: string },\n b: { readonly id: string },\n kind: string,\n ): boolean {\n for (const link of this.model.links.values()) {\n if (link.kind !== kind) continue;\n if (\n (link.source === a.id && link.target === b.id) ||\n (link.source === b.id && link.target === a.id)\n ) {\n return true;\n }\n }\n return false;\n }\n\n isSourceOfType(element: IstarElement<string>, kind: string): boolean {\n for (const link of this.model.links.values()) {\n if (link.source === element.id && this.matches(link, kind)) return true;\n }\n return false;\n }\n\n isTargetOfType(element: IstarElement<string>, kind: string): boolean {\n for (const link of this.model.links.values()) {\n if (link.target === element.id && this.matches(link, kind)) return true;\n }\n return false;\n }\n\n /** The kind the iStar 2.0 rules see: built-in kinds as they are, extensions as what they behave like. */\n kindOf(element: IstarElement<string>): string {\n return effectiveElementKind(this.metamodel, element.kind);\n }\n\n isActor(element: IstarElement<string>): boolean {\n return this.metamodel.elements.get(element.kind)?.category === 'actor';\n }\n\n context(\n kind: string,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n ): LinkRuleContext {\n return {\n model: this.model,\n metamodel: this.metamodel,\n kind,\n source,\n target,\n isThereLinkBetween: (a, b, k) => this.isThereLinkBetween(a, b, k),\n isSourceOfType: (e, k) => this.isSourceOfType(e, k),\n isTargetOfType: (e, k) => this.isTargetOfType(e, k),\n };\n }\n}\n\ntype Check = (\n graph: Graph,\n source: IstarElement<string>,\n target: IstarElement<string>,\n) => LinkCheck;\n\nconst is = (graph: Graph, element: IstarElement<string>, ...shortNames: string[]): boolean => {\n const kind = graph.kindOf(element);\n return shortNames.some((name) => kind === `istar.${name}`);\n};\n\nconst isDependum = (element: IstarElement<string>): boolean => element.isDependum === true;\n\nconst isALink: Check = (graph, source, target) => {\n // Upstream evaluates the source-kind check after the type-equality check without guarding\n // on the previous result, so its message wins when both fail. Reproduced here.\n if (!is(graph, source, 'Actor', 'Role')) {\n return fail(\n 'invalid-source',\n 'the source of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n 'source',\n );\n }\n if (source.kind !== target.kind) {\n return fail(\n 'actor-types-differ',\n 'the source and target of Is-A links must be of the same type - Actor and Actor, or Role and Role (iStar 2.0 Guide, Page 6).',\n );\n }\n if (!is(graph, target, 'Actor', 'Role')) {\n return fail(\n 'invalid-target',\n 'the target of Is-A links must be a Role or a general Actor (iStar 2.0 Guide, Page 6).',\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make Is-A links from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\nconst participatesInLink: Check = (graph, source, target) => {\n if (!graph.isActor(source)) {\n return fail(\n 'invalid-source',\n 'the source of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n 'source',\n );\n }\n if (!graph.isActor(target)) {\n return fail(\n 'invalid-target',\n 'the target of a Participates-In link must be some kind of actor (iStar 2.0 Guide, Page 6)',\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Participates-In link from an actor onto itself.');\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Actor link between the same two actors (iStar 2.0 Guide, Page 14).',\n );\n }\n return OK;\n};\n\n/** The actor an element belongs to: itself for actors, its parent for inner elements. */\nfunction owningActorId(graph: Graph, element: IstarElement<string>): string | undefined {\n return graph.isActor(element) ? element.id : element.parent;\n}\n\nconst dependencyLink: Check = (graph, source, target) => {\n if (source.id === target.id) {\n return fail('self-link', 'a Dependency link cannot link an element onto itself');\n }\n if (isDependum(source)) {\n return fail('dependum-endpoint', 'a Dependency link cannot start from a dependum', 'source');\n }\n if (isDependum(target)) {\n return fail('dependum-endpoint', 'a Dependency link cannot end in a dependum', 'target');\n }\n if (owningActorId(graph, source) === owningActorId(graph, target)) {\n return fail(\n 'same-actor',\n 'a Dependency link must involve two different actors (iStar 2.0 Guide, Page 14)',\n );\n }\n if (\n graph.isTargetOfType(source, 'istar.OrRefinementLink') ||\n graph.isTargetOfType(source, 'istar.AndRefinementLink')\n ) {\n return fail(\n 'refined-depender',\n 'a refined element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n 'source',\n );\n }\n if (graph.isTargetOfType(source, 'istar.ContributionLink')) {\n return fail(\n 'contributed-depender',\n 'a contributed element cannot be the Depender Element in a Dependency link (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to add the Dependency originating from a child.',\n 'source',\n );\n }\n return OK;\n};\n\nfunction refinementLink(label: 'AND' | 'OR'): Check {\n const other = label === 'AND' ? 'istar.OrRefinementLink' : 'istar.AndRefinementLink';\n return (graph, source, target) => {\n if (!is(graph, source, 'Task', 'Goal')) {\n return fail(\n 'invalid-source',\n `the source of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n 'source',\n );\n }\n if (!is(graph, target, 'Task', 'Goal')) {\n return fail(\n 'invalid-target',\n `the target of an ${label}-refinement link must be a Goal or a Task (iStar 2.0 Guide, Table 1)`,\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n `you cannot make an ${label}-refinement link from an element onto itself`,\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n `you cannot make an ${label}-refinement link with a dependum (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n `the source and target of an ${label}-refinement link must pertain to the same actor (iStar 2.0 Guide, Page 14)`,\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one refinement link between the same two elements',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot refine a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-element.',\n 'target',\n );\n }\n if (graph.isTargetOfType(target, other)) {\n const mix =\n label === 'AND'\n ? 'you cannot mix AND-refinements with OR-refinements targeting the same element (iStar 2.0 Guide, Page 10).'\n : 'you cannot mix OR-refinements with AND-refinements targeting the same element (iStar 2.0 Guide, Page 10).';\n return fail('mixed-refinement', mix, 'target');\n }\n return OK;\n };\n}\n\nconst neededByLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Needed-By link must be a Resource (iStar 2.0 Guide, Table 1)',\n 'source',\n );\n }\n if (!is(graph, target, 'Task')) {\n return fail(\n 'invalid-target',\n 'the target of a Needed-By link must be a Task (iStar 2.0 Guide, Table 1)',\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Needed-By link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Needed-By link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Needed-By link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target)) {\n return fail(\n 'duplicate-link',\n 'there can only be one Needed-By link between the same two elements',\n );\n }\n return OK;\n};\n\nconst contributionLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Goal', 'Quality', 'Task', 'Resource')) {\n return fail(\n 'invalid-source',\n 'the source of a Contribution link must be a Goal, a Quality, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n 'source',\n );\n }\n if (!is(graph, target, 'Quality')) {\n return fail(\n 'invalid-target',\n 'the target of a Contribution link must be a Quality (iStar 2.0 Guide, Table 1)',\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail(\n 'self-link',\n 'you cannot make a Contribution link from an element onto itself (iStar 2.0 Guide, Page 15)',\n );\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Contribution link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Contribution link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Contribution link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Contribution and Qualification links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n if (graph.isSourceOfType(target, 'istar.DependencyLink')) {\n return fail(\n 'depender-target',\n 'you cannot contribute to a Depender Element; that is, an element that is the source of a Dependency (iStar 2.0 Guide, Page 14). ' +\n 'Instead, you can try to move the dependency to the sub-quality.',\n 'target',\n );\n }\n return OK;\n};\n\nconst qualificationLink: Check = (graph, source, target) => {\n if (!is(graph, source, 'Quality')) {\n return fail(\n 'invalid-source',\n 'the source of a Qualification link must be a Quality (iStar 2.0 Guide, Table 1)',\n 'source',\n );\n }\n if (!is(graph, target, 'Goal', 'Task', 'Resource')) {\n return fail(\n 'invalid-target',\n 'the target of a Qualification link must be a Goal, a Task or a Resource (iStar 2.0 Guide, Table 1)',\n 'target',\n );\n }\n if (source.id === target.id) {\n return fail('self-link', 'you cannot make a Qualification link from an element onto itself');\n }\n if (isDependum(source) || isDependum(target)) {\n return fail(\n 'dependum-endpoint',\n 'you cannot make a Qualification link with a dependum (iStar 2.0 Guide, Page 14)',\n );\n }\n if (source.parent !== target.parent) {\n return fail(\n 'different-actors',\n 'the source and target of a Qualification link must pertain to the same actor (iStar 2.0 Guide, Page 14)',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.QualificationLink')) {\n return fail(\n 'duplicate-link',\n 'there can only be one Qualification link between the same two elements',\n );\n }\n if (graph.isThereLinkBetween(source, target, 'istar.ContributionLink')) {\n return fail(\n 'contribution-and-qualification',\n 'you cannot have Qualification and Contribution links between the same two elements (iStar 2.0 Guide, Page 15)',\n );\n }\n return OK;\n};\n\n/** The words used for a list of kind selectors in messages: \"a Goal or a Task\". */\nfunction describe(graph: Graph, selectors: readonly string[]): string {\n const names = selectors.map((selector) => {\n if (selector === '*') return 'any element';\n if (selector === 'node') return 'an intentional element';\n if (selector === 'actor') return 'an actor';\n if (selector === LINK_SELECTOR) return 'a link';\n const linkLabel = graph.metamodel.links.get(selector)?.label;\n if (linkLabel !== undefined) {\n return /^[aeiou]/i.test(linkLabel) ? `an ${linkLabel} link` : `a ${linkLabel} link`;\n }\n const label = graph.metamodel.elements.get(selector)?.label ?? selector;\n return /^[aeiou]/i.test(label) ? `an ${label}` : `a ${label}`;\n });\n return names.length <= 2\n ? names.join(' or ')\n : `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}`;\n}\n\nfunction matchesSelector(\n graph: Graph,\n element: IstarElement<string> | IstarLink<string>,\n selector: string,\n): boolean {\n // Links match `link` and link kinds (and what behaves like them); elements never do.\n if (isLinkRef(element)) {\n return selector === LINK_SELECTOR || linkBehavesLike(graph.metamodel, element.kind, selector);\n }\n if (selector === LINK_SELECTOR) return false;\n // A hub is only matched by its own kind's name: categories never include it.\n if (graph.metamodel.elements.get(element.kind)?.role === 'hub') {\n return element.kind === selector;\n }\n if (selector === '*') return true;\n const category = graph.metamodel.elements.get(element.kind)?.category;\n if (selector === 'node' || selector === 'actor') return category === selector;\n return elementBehavesLike(graph.metamodel, element.kind, selector);\n}\n\n/**\n * Declarative rules of an extension link kind, checked in the order of the iStar 2.0 node-link\n * rules (and of piStar-ext's generated `isValid`): source kind, target kind, self link,\n * dependum, same actor, duplicates. A link target skips the self, dependum and same-actor rules,\n * which are about elements.\n */\nfunction declarativeCheck(\n graph: Graph,\n definition: LinkKindDefinition,\n rules: LinkRules,\n rulesKind: string,\n source: IstarElement<string>,\n target: IstarElement<string> | IstarLink<string>,\n): LinkCheck {\n const name = definition.label;\n const article = /^[aeiou]/i.test(name) ? 'an' : 'a';\n if (!rules.sources.some((selector) => matchesSelector(graph, source, selector))) {\n return fail(\n 'invalid-source',\n `the source of ${article} ${name} link must be ${describe(graph, rules.sources)}`,\n 'source',\n );\n }\n if (!rules.targets.some((selector) => matchesSelector(graph, target, selector))) {\n const targetKind = isLinkRef(target) ? undefined : graph.metamodel.elements.get(target.kind);\n const hubOf =\n targetKind?.role === 'hub' && targetKind.of !== undefined\n ? graph.metamodel.links.get(targetKind.of)\n : undefined;\n if (hubOf) {\n return fail(\n 'hub-target',\n `you cannot make ${article} ${name} link towards the hub of ${/^[aeiou]/i.test(hubOf.label) ? 'an' : 'a'} ${hubOf.label} link`,\n 'target',\n );\n }\n return fail(\n 'invalid-target',\n `the target of ${article} ${name} link must be ${describe(graph, rules.targets)}`,\n 'target',\n );\n }\n if (!rules.allowSelf && source.id === target.id) {\n return fail('self-link', `you cannot make ${article} ${name} link from an element onto itself`);\n }\n if (definition.category === 'node' && !isLinkRef(target)) {\n if (!rules.allowDependum && (isDependum(source) || isDependum(target))) {\n return fail('dependum-endpoint', `you cannot make ${article} ${name} link with a dependum`);\n }\n if (rules.sameActor !== false && source.parent !== target.parent) {\n return fail(\n 'different-actors',\n `the source and target of ${article} ${name} link must pertain to the same actor (iStar 2.0 Guide, Page 14)`,\n );\n }\n }\n const unique = rules.unique ?? 'kind';\n if (\n (unique === 'any' && graph.isThereLinkBetween(source, target)) ||\n (unique === 'kind' && graph.isThereLinkOfKindBetween(source, target, definition.kind)) ||\n // A kind inheriting these rules shares the limit with the kind that declares them.\n (unique === 'kind' &&\n rulesKind !== definition.kind &&\n graph.isThereLinkOfKindBetween(source, target, rulesKind))\n ) {\n return fail(\n 'duplicate-link',\n `there can only be one ${name} link between the same two elements`,\n );\n }\n return OK;\n}\n\nconst CHECKS: Partial<Readonly<Record<string, Check>>> = {\n 'istar.IsALink': isALink,\n 'istar.ParticipatesInLink': participatesInLink,\n 'istar.DependencyLink': dependencyLink,\n 'istar.AndRefinementLink': refinementLink('AND'),\n 'istar.OrRefinementLink': refinementLink('OR'),\n 'istar.NeededByLink': neededByLink,\n 'istar.ContributionLink': contributionLink,\n 'istar.QualificationLink': qualificationLink,\n};\n\nexport interface ModelIssue<LK extends string = LinkKind> {\n readonly linkId: string;\n readonly kind: LK;\n readonly source: string;\n readonly target: string;\n readonly code: ConstraintCode;\n readonly message: string;\n}\n\n/**\n * Re-validates every link of a model, the way piStar does when loading a file: dependencies\n * first (each checked before its own links are added), then the remaining links in file\n * order, each against the graph built so far, and last the links that target links. Invalid\n * links are reported, not removed. A hub without an end or legs is reported with code\n * `incomplete-hub`, the hub's id as `linkId` and the n-ary kind as `kind`.\n */\nexport function validateModel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n options: CanLinkOptions<EK, LK>,\n): ModelIssue<LK>[];\nexport function validateModel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): ModelIssue<LK>[];\n// 0.7.0's exact signature comes last, so `models.map(validateModel)` types as before.\nexport function validateModel(model: IstarModel): ModelIssue[];\nexport function validateModel<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n options?: CanLinkOptions<EK, LK>,\n): ModelIssue<LK>[] {\n // As an array callback the second argument is an index: ignore anything but options.\n const given = typeof options === 'object' && options !== null ? options.metamodel : undefined;\n const metamodel = (given ?? metamodelOf(model)) as unknown as AnyMetamodel;\n const any = model as unknown as AnyIstarModel;\n const issues: ModelIssue<LK>[] = [];\n const accepted = new Map<string, IstarLink<string>>();\n const view = (): AnyIstarModel => ({ ...any, links: accepted });\n const check = (source: string, target: string, kind: string): LinkCheck =>\n canLink(view(), source, target, kind, { metamodel });\n const isDependency = (link: IstarLink<string>): boolean =>\n metamodel.links.get(link.kind)?.category === 'dependency';\n\n const report = (\n linkId: string,\n kind: string,\n source: string,\n target: string,\n result: LinkCheck,\n ): void => {\n if (!result.ok) {\n issues.push({\n linkId,\n kind: kind as LK,\n source,\n target,\n code: result.code,\n message: result.reason,\n });\n }\n };\n\n const dependencyLinks = [...any.links.values()].filter(isDependency);\n for (const dependum of any.elements.values()) {\n if (!dependum.isDependum) continue;\n const inbound = dependencyLinks.find((l) => l.target === dependum.id);\n const outbound = dependencyLinks.find((l) => l.source === dependum.id);\n const depender = inbound?.source ?? dependum.dependency?.source;\n const dependee = outbound?.target ?? dependum.dependency?.target;\n const kind = inbound?.kind ?? outbound?.kind ?? 'istar.DependencyLink';\n if (depender !== undefined && dependee !== undefined) {\n report(inbound?.id ?? dependum.id, kind, depender, dependee, check(depender, dependee, kind));\n }\n if (inbound) accepted.set(inbound.id, inbound);\n if (outbound) accepted.set(outbound.id, outbound);\n }\n\n // Links that target links come second, so the links they point at are known whatever the\n // order (an Argument may be written before the Contribution it argues about).\n const rest = [...any.links.values()].filter((link) => !isDependency(link));\n const targetsLink = (link: IstarLink<string>): boolean =>\n !any.elements.has(link.target) && any.links.has(link.target);\n for (const link of [\n ...rest.filter((l) => !targetsLink(l)),\n ...rest.filter((l) => targetsLink(l)),\n ]) {\n if (any.elements.has(link.source) && (any.elements.has(link.target) || targetsLink(link))) {\n report(\n link.id,\n link.kind,\n link.source,\n link.target,\n check(link.source, link.target, link.kind),\n );\n } else {\n report(link.id, link.kind, link.source, link.target, {\n ok: false,\n code: 'unknown-element',\n reason: 'the link refers to an element that does not exist',\n });\n }\n accepted.set(link.id, link);\n }\n\n // Each hub needs an end and at least one leg.\n for (const hub of any.elements.values()) {\n const hubKind = metamodel.elements.get(hub.kind);\n if (hubKind?.role !== 'hub' || hubKind.of === undefined) continue;\n const base = metamodel.links.get(hubKind.of);\n const roleOf = (link: IstarLink<string>): string | undefined =>\n metamodel.links.get(link.kind)?.role;\n const legs = rest.filter((l) => l.target === hub.id && roleOf(l) === 'leg');\n const end = rest.find((l) => l.source === hub.id && roleOf(l) === 'end');\n if (legs.length > 0 && end) continue;\n const label = base?.label ?? hubKind.of;\n issues.push({\n linkId: hub.id,\n kind: hubKind.of as LK,\n source: legs[0]?.source ?? hub.id,\n target: end?.target ?? hub.id,\n code: 'incomplete-hub',\n message: end\n ? `the hub of a ${label} link needs at least one leg`\n : `the hub of a ${label} link needs an end`,\n });\n }\n return issues;\n}\n","/**\n * A model file's own metamodel: the top-level `\"metamodel\"` block, in which a file declares the\n * constructs it adds to iStar (as piStar-ext's \"Add new\" creates them), so they travel with the\n * model instead of living only in a tool's localStorage.\n *\n * The block has the shape `extendMetamodel` takes (`MetamodelExtension`), as JSON: no `check`\n * predicates, and presentation hints (`shape`, `textBox`, `line`) kept as data. Keys this\n * library doesn't know, in the block or in any entry, are left alone (hosts keep dialect data,\n * such as stereotypes, beside it) and are written back unchanged.\n */\nimport type { ElementKindDeclaration, LinkKindDeclaration, MetamodelExtension } from './metamodels';\nimport { MetamodelError } from './metamodels';\n\n/** The top-level key of the block in piStar JSON. */\nexport const FILE_METAMODEL_KEY = 'metamodel';\n\nexport interface FileElementKind extends Omit<ElementKindDeclaration<string>, 'info'> {\n readonly info?: {\n readonly canBeInnerElement?: boolean;\n readonly canBeDependum?: boolean;\n readonly canBeOnPaper?: boolean;\n };\n readonly [key: string]: unknown;\n}\n\nexport interface FileLinkKind extends Omit<LinkKindDeclaration<string>, 'check'> {\n readonly [key: string]: unknown;\n}\n\n/** The `\"metamodel\"` block of a model file. */\nexport interface FileMetamodel {\n /** Identifies the constructs' dialect, e.g. `iStar4RationalAgents`. */\n readonly name: string;\n readonly elements?: readonly FileElementKind[];\n readonly links?: readonly FileLinkKind[];\n readonly [key: string]: unknown;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction fail(path: string, message: string): never {\n throw new MetamodelError(`${path} ${message}`);\n}\n\nfunction optionalString(entry: Record<string, unknown>, key: string, path: string): void {\n if (entry[key] !== undefined && typeof entry[key] !== 'string') {\n fail(`${path}.${key}`, 'must be a string');\n }\n}\n\nfunction optionalBoolean(entry: Record<string, unknown>, key: string, path: string): void {\n if (entry[key] !== undefined && typeof entry[key] !== 'boolean') {\n fail(`${path}.${key}`, 'must be true or false');\n }\n}\n\nfunction checkSize(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { width, height }');\n for (const key of ['width', 'height']) {\n const n = value[key];\n if (typeof n !== 'number' || !Number.isFinite(n) || n <= 0) {\n fail(`${path}.${key}`, 'must be a positive number');\n }\n }\n}\n\nfunction checkShape(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { path, viewBox? }');\n if (typeof value.path !== 'string' || value.path.trim() === '') {\n fail(`${path}.path`, 'must be SVG path data');\n }\n optionalString(value, 'viewBox', path);\n}\n\nfunction checkTextBox(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { top, right, bottom, left }');\n for (const key of ['top', 'right', 'bottom', 'left']) {\n const n = value[key];\n if (typeof n !== 'number' || n < 0 || n >= 1) {\n fail(`${path}.${key}`, 'must be a fraction from 0 (inclusive) to 1 (exclusive)');\n }\n }\n}\n\nfunction checkLine(value: unknown, path: string): void {\n if (value === undefined) return;\n if (!isObject(value)) fail(path, 'must be an object { dash?, marker?, markerFilled? }');\n optionalString(value, 'dash', path);\n if (value.marker !== undefined && value.marker !== false && typeof value.marker !== 'string') {\n fail(`${path}.marker`, 'must be SVG path data or false');\n }\n optionalBoolean(value, 'markerFilled', path);\n}\n\nfunction checkStringList(value: unknown, path: string): void {\n if (!Array.isArray(value) || value.length === 0 || value.some((v) => typeof v !== 'string')) {\n fail(path, 'must be a non-empty list of kind names or categories');\n }\n}\n\nfunction checkRules(value: unknown, path: string): void {\n if (!isObject(value)) fail(path, 'must be an object { sources, targets, … }');\n checkStringList(value.sources, `${path}.sources`);\n checkStringList(value.targets, `${path}.targets`);\n for (const key of ['sameActor', 'allowDependum', 'allowSelf']) optionalBoolean(value, key, path);\n if (value.unique !== undefined && !['kind', 'any', false].includes(value.unique as never)) {\n fail(`${path}.unique`, 'must be \"kind\", \"any\" or false');\n }\n}\n\n/**\n * Checks that `value` is a well-formed `\"metamodel\"` block and returns it typed. Throws\n * `MetamodelError` naming the offending path (`metamodel.elements[1].kind must be a string`).\n * Whether its kinds fit a given metamodel (namespacing, collisions, `behavesLike` targets) is\n * checked when it is applied, by `extendMetamodel`.\n */\nexport function validateFileMetamodel(\n value: unknown,\n path: string = FILE_METAMODEL_KEY,\n): FileMetamodel {\n if (!isObject(value)) fail(path, 'must be an object { name, elements?, links? }');\n if (typeof value.name !== 'string' || value.name === '')\n fail(`${path}.name`, 'must be a non-empty string');\n for (const [listKey, kind] of [\n ['elements', 'element'],\n ['links', 'link'],\n ] as const) {\n const list = value[listKey];\n if (list === undefined) continue;\n if (!Array.isArray(list)) fail(`${path}.${listKey}`, 'must be a list');\n list.forEach((entry: unknown, i) => {\n const at = `${path}.${listKey}[${i}]`;\n if (!isObject(entry)) fail(at, `must be an object describing a ${kind} kind`);\n if (typeof entry.kind !== 'string' || entry.kind === '')\n fail(`${at}.kind`, 'must be a string');\n optionalString(entry, 'label', at);\n optionalString(entry, 'behavesLike', at);\n optionalString(entry, 'pistarType', at);\n if (kind === 'element') {\n if (\n entry.category !== undefined &&\n entry.category !== 'node' &&\n entry.category !== 'actor'\n ) {\n fail(`${at}.category`, 'must be \"node\" or \"actor\"');\n }\n checkSize(entry.size, `${at}.size`);\n if (entry.info !== undefined) {\n if (!isObject(entry.info)) fail(`${at}.info`, 'must be an object');\n for (const key of ['canBeInnerElement', 'canBeDependum', 'canBeOnPaper']) {\n optionalBoolean(entry.info, key, `${at}.info`);\n }\n }\n checkShape(entry.shape, `${at}.shape`);\n checkTextBox(entry.textBox, `${at}.textBox`);\n } else {\n if (\n entry.category !== undefined &&\n !['node', 'actor', 'dependency'].includes(entry.category as string)\n ) {\n fail(`${at}.category`, 'must be \"node\", \"actor\" or \"dependency\"');\n }\n if (entry.rules !== undefined) checkRules(entry.rules, `${at}.rules`);\n if ('check' in entry) fail(`${at}.check`, 'cannot be stored in a file (it is code)');\n if (entry.info !== undefined && !isObject(entry.info))\n fail(`${at}.info`, 'must be an object');\n checkLine(entry.line, `${at}.line`);\n }\n });\n }\n return value as FileMetamodel;\n}\n\n/** The block as an extension `extendMetamodel` applies (it ignores the extra keys). */\nexport function fileMetamodelExtension(block: FileMetamodel): MetamodelExtension<string, string> {\n return block as unknown as MetamodelExtension<string, string>;\n}\n","/**\n * Reading and writing piStar save files, ported from `tool/app/istarcore/fileManager.js`.\n *\n * Output is produced with the same key order and `JSON.stringify(_, null, 2)` formatting as the\n * piStar web tool, so a file saved by piStar round-trips byte for byte. Keys this library does\n * not interpret are kept and written back.\n */\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, Metamodel } from './metamodels';\nimport { ISTAR_2_0, MetamodelError, extendMetamodel } from './metamodels';\nimport { sharedWeakMap } from './shared';\nimport type { FileMetamodel } from './file-metamodel';\nimport {\n FILE_METAMODEL_KEY,\n fileMetamodelExtension,\n validateFileMetamodel,\n} from './file-metamodel';\nimport type {\n CustomProperties,\n Diagram,\n ElementDisplay,\n Extra,\n IstarElement,\n IstarLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport {\n dependencyLinksOf,\n hostMetamodelOf,\n metamodelOf,\n setHostMetamodel,\n withMetamodel,\n} from './model';\nimport type { AnyIstarModel } from './model';\n\n// ---------------------------------------------------------------------------------------------\n// File format types\n\nexport interface PistarElementJson {\n id: string;\n text: string;\n type: string;\n x: number;\n y: number;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\nexport interface PistarActorJson extends PistarElementJson {\n nodes: PistarElementJson[];\n}\n\nexport interface PistarDependencyJson extends PistarElementJson {\n source: string;\n target: string;\n}\n\nexport interface PistarLinkJson {\n id: string;\n type: string;\n source: string;\n target: string;\n name?: string;\n customProperties?: Record<string, string>;\n label?: string;\n [key: string]: unknown;\n}\n\n/** The hub of an n-ary link, in a hub entry: an element without `text`. */\nexport interface PistarHubJson {\n id: string;\n type: string;\n x: number;\n y: number;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/**\n * An n-ary link (see `LinkKindDeclaration.arity`) in `links`, as DSM3-goals writes it: no id of\n * its own, its hub, its legs (`starts`) and its end.\n */\nexport interface PistarHubLinkJson {\n hub: PistarHubJson;\n starts: PistarLinkJson[];\n end?: PistarLinkJson;\n [key: string]: unknown;\n}\n\n/**\n * Key of a hub element's `extra` that holds its entry's unknown keys (those beside `hub`,\n * `starts` and `end`), so they are written back on the entry.\n */\nexport const HUB_ENTRY_KEY = '__hubEntry';\n\nexport interface PistarDiagramJson {\n width?: number;\n height?: number;\n name?: string;\n customProperties?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/** A piStar save file. Older piStar versions may omit some sections (e.g. `orphans`). */\nexport interface PistarFile {\n actors: PistarActorJson[];\n orphans?: PistarElementJson[];\n dependencies?: PistarDependencyJson[];\n links?: (PistarLinkJson | PistarHubLinkJson)[];\n display?: Record<string, Record<string, unknown>>;\n tool?: string;\n istar?: string;\n saveDate?: string;\n diagram?: PistarDiagramJson;\n [key: string]: unknown;\n}\n\nexport class PistarParseError extends Error {\n override name = 'PistarParseError';\n}\n\n/** Thrown by `toPistar` for a kind its metamodel doesn't know (rather than writing it wrong). */\nexport class PistarWriteError extends Error {\n override name = 'PistarWriteError';\n}\n\n/**\n * Parse-time bookkeeping that lets `toPistar` reproduce the original key order. It has no\n * meaning for the model itself and may be dropped.\n */\nexport interface SourceLayout {\n /** Top-level keys in file order. */\n readonly keys: readonly string[];\n /** `display` ids in file order. */\n readonly display: readonly string[];\n /**\n * Each element's, link's and hub entry's keys in file order, by id (a hub's entry under\n * `hubEntryLayoutKey(id)`), and the diagram's under `DIAGRAM_LAYOUT_KEY`. Files written by\n * other tools order keys differently from piStar; this keeps them as they were.\n */\n readonly objects?: ReadonlyMap<string, readonly string[]>;\n}\n\n/** The `objects` key of a hub's entry (`{ hub, starts, end }`) in a `SourceLayout`. */\nexport function hubEntryLayoutKey(hubId: string): string {\n return `${hubId}\\u0000entry`;\n}\n/** The `objects` key of the diagram in a `SourceLayout`. */\nexport const DIAGRAM_LAYOUT_KEY = '\\u0000diagram';\n\nconst layouts = sharedWeakMap<SourceLayout>('layouts');\n\n/** The key order recorded when `model` was parsed, if it came from `parsePistar`. */\nexport function getSourceLayout<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): SourceLayout | undefined {\n return layouts.get(model);\n}\n\n/**\n * Carries the recorded key order over to a model derived from `from` (the store does this for\n * every edit, so saving an edited file keeps a stable diff).\n */\nexport function inheritSourceLayout<M extends IstarModel<string, string>>(\n from: IstarModel<string, string>,\n to: M,\n): M {\n const layout = layouts.get(from);\n if (layout && from !== to) layouts.set(to, layout);\n return to;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Parsing\n\nconst ELEMENT_KEYS = new Set(['id', 'text', 'type', 'x', 'y', 'customProperties']);\nconst ACTOR_KEYS = new Set([...ELEMENT_KEYS, 'nodes']);\nconst DEPENDENCY_KEYS = new Set([...ELEMENT_KEYS, 'source', 'target']);\nconst LINK_KEYS = new Set(['id', 'type', 'source', 'target', 'name', 'customProperties', 'label']);\nconst HUB_KEYS = new Set(['id', 'type', 'x', 'y', 'customProperties']);\nconst HUB_ENTRY_KEYS = new Set(['hub', 'starts', 'end']);\nconst DIAGRAM_KEYS = new Set(['width', 'height', 'name', 'customProperties']);\nconst TOP_LEVEL_KEYS = [\n 'actors',\n 'orphans',\n 'dependencies',\n 'links',\n 'display',\n 'tool',\n 'istar',\n 'saveDate',\n 'diagram',\n] as const;\nconst TOP_LEVEL_KEY_SET: ReadonlySet<string> = new Set(TOP_LEVEL_KEYS);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction extraOf(json: Record<string, unknown>, known: ReadonlySet<string>): Extra | undefined {\n let extra: Record<string, unknown> | undefined;\n for (const key of Object.keys(json)) {\n if (!known.has(key)) (extra ??= {})[key] = json[key];\n }\n return extra;\n}\n\nfunction asArray(value: unknown, where: string): unknown[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) throw new PistarParseError(`\"${where}\" must be an array`);\n return value;\n}\n\n/**\n * Parses a piStar save file (JSON text or an already-parsed object). The input is not mutated.\n *\n * Unlike the piStar tool, elements with `x` or `y` equal to 0 are kept: upstream's\n * `if (element.x && element.y)` silently drops them, which looks unintended.\n */\nexport interface ParsePistarOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * Read the file's own `\"metamodel\"` block (see `FileMetamodel`) and parse with `metamodel`\n * (or iStar 2.0) extended by it. Default false: the block is kept as an unknown key and not\n * applied, as before. A block whose kinds collide with the metamodel throws `MetamodelError`.\n */\n readonly fileMetamodel?: boolean;\n /**\n * The metamodel whose kinds the file may use. Default iStar 2.0: any other `type` throws,\n * as in the piStar tool. The parsed model remembers it (see `metamodelOf`).\n */\n readonly metamodel?: Metamodel<EK, LK>;\n}\n\n// The iStar 2.0 overload comes last, so `parsePistar` passed as a callback types as before.\n// With the file's own metamodel, kinds are only known at run time.\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<string, string> & { readonly fileMetamodel: true },\n): IstarModel<string, string>;\nexport function parsePistar<EK extends string, LK extends string>(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<EK, LK> & { readonly metamodel: Metamodel<EK, LK> },\n): IstarModel<EK, LK>;\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions,\n): IstarModel;\nexport function parsePistar(input: string | PistarFile | Record<string, unknown>): IstarModel;\nexport function parsePistar(\n input: string | PistarFile | Record<string, unknown>,\n options: ParsePistarOptions<string, string> = {},\n): AnyIstarModel {\n let metamodel: AnyMetamodel = options.metamodel ?? ISTAR_2_0;\n const categoryOf = (kind: string): string | undefined => metamodel.elements.get(kind)?.category;\n let json: unknown;\n if (typeof input === 'string') {\n try {\n json = JSON.parse(input);\n } catch (error) {\n throw new PistarParseError(`invalid JSON: ${(error as Error).message}`, { cause: error });\n }\n } else {\n json = structuredClone(input);\n }\n if (!isRecord(json)) throw new PistarParseError('a piStar model must be a JSON object');\n\n // The file's own constructs extend the host's metamodel before anything is read with it.\n let host: AnyMetamodel | undefined;\n if (options.fileMetamodel && json[FILE_METAMODEL_KEY] !== undefined) {\n const block = validateFileMetamodel(json[FILE_METAMODEL_KEY]);\n host = metamodel;\n metamodel = extendMetamodel(metamodel, fileMetamodelExtension(block));\n }\n\n const display = isRecord(json.display) ? json.display : {};\n const usedDisplay = new Set<string>();\n const elements = new Map<string, IstarElement<string>>();\n const links = new Map<string, IstarLink<string>>();\n\n const displayFor = (id: string): Record<string, unknown> | undefined => {\n const entry = display[id];\n if (!isRecord(entry)) return undefined;\n usedDisplay.add(id);\n return entry;\n };\n\n const objects = new Map<string, readonly string[]>();\n const readElement = (\n raw: unknown,\n where: string,\n known: ReadonlySet<string>,\n extras: Partial<IstarElement<string>>,\n ): IstarElement<string> => {\n if (!isRecord(raw)) throw new PistarParseError(`${where}: expected an object`);\n const { id, type } = raw;\n if (typeof id !== 'string' || id === '') {\n throw new PistarParseError(`${where}: missing \"id\"`);\n }\n const kind = typeof type === 'string' ? metamodel.elementsByPistarType.get(type) : undefined;\n if (kind === undefined) {\n throw new PistarParseError(`${where} (${id}): unknown element type ${JSON.stringify(type)}`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`${where}: duplicated id \"${id}\"`);\n }\n const element: IstarElement<string> = {\n id,\n kind,\n name: typeof raw.text === 'string' ? raw.text : '',\n x: typeof raw.x === 'number' ? raw.x : 0,\n y: typeof raw.y === 'number' ? raw.y : 0,\n ...extras,\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('display', displayFor(id) as ElementDisplay | undefined),\n ...optional('extra', extraOf(raw, known)),\n };\n elements.set(id, element);\n objects.set(id, Object.keys(raw));\n return element;\n };\n\n asArray(json.actors, 'actors').forEach((raw, i) => {\n const actor = readElement(raw, `actors[${i}]`, ACTOR_KEYS, {});\n if (categoryOf(actor.kind) !== 'actor') {\n throw new PistarParseError(`actors[${i}] (${actor.id}): ${actor.kind} is not an actor kind`);\n }\n asArray((raw as Record<string, unknown>).nodes, `actors[${i}].nodes`).forEach((node, j) => {\n const child = readElement(node, `actors[${i}].nodes[${j}]`, ELEMENT_KEYS, {\n parent: actor.id,\n });\n if (categoryOf(child.kind) === 'actor') {\n throw new PistarParseError(`actors[${i}].nodes[${j}]: actors cannot be nested`);\n }\n });\n });\n\n asArray(json.orphans, 'orphans').forEach((raw, i) => {\n readElement(raw, `orphans[${i}]`, ELEMENT_KEYS, {});\n });\n\n asArray(json.dependencies, 'dependencies').forEach((raw, i) => {\n const r = raw as Record<string, unknown>;\n const dependency =\n typeof r.source === 'string' && typeof r.target === 'string'\n ? { dependency: { source: r.source, target: r.target } }\n : {};\n readElement(raw, `dependencies[${i}]`, DEPENDENCY_KEYS, { isDependum: true, ...dependency });\n });\n\n const readLink = (raw: unknown, where: string): IstarLink<string> => {\n if (!isRecord(raw)) throw new PistarParseError(`${where}: expected an object`);\n const { id, type, source, target } = raw;\n if (typeof id !== 'string' || id === '') throw new PistarParseError(`${where}: missing \"id\"`);\n const kind = typeof type === 'string' ? metamodel.linksByPistarType.get(type) : undefined;\n if (kind === undefined) {\n throw new PistarParseError(`${where} (${id}): unknown link type ${JSON.stringify(type)}`);\n }\n if (typeof source !== 'string' || typeof target !== 'string') {\n throw new PistarParseError(`${where} (${id}): missing \"source\" or \"target\"`);\n }\n if (elements.has(id) || links.has(id)) {\n throw new PistarParseError(`${where}: duplicated id \"${id}\"`);\n }\n const link: IstarLink<string> = {\n id,\n kind,\n source,\n target,\n ...optional('name', typeof raw.name === 'string' ? raw.name : undefined),\n ...(isRecord(raw.customProperties)\n ? { customProperties: raw.customProperties as CustomProperties }\n : {}),\n ...optional('label', typeof raw.label === 'string' ? raw.label : undefined),\n ...optional('display', displayFor(id) as LinkDisplay | undefined),\n ...optional('extra', extraOf(raw, LINK_KEYS)),\n };\n links.set(id, link);\n objects.set(id, Object.keys(raw));\n return link;\n };\n\n // An n-ary link: its hub becomes an element, its legs then its end ordinary links.\n const readHubEntry = (raw: Record<string, unknown>, where: string): void => {\n const hub = readElement(raw.hub, `${where}.hub`, HUB_KEYS, {});\n const hubKind = metamodel.elements.get(hub.kind);\n if (hubKind?.role !== 'hub') {\n throw new PistarParseError(`${where}.hub (${hub.id}): ${hub.kind} is not a hub kind`);\n }\n objects.set(hubEntryLayoutKey(hub.id), Object.keys(raw));\n const entryExtra = extraOf(raw, HUB_ENTRY_KEYS);\n if (entryExtra) {\n elements.set(hub.id, { ...hub, extra: { ...hub.extra, [HUB_ENTRY_KEY]: entryExtra } });\n }\n const roleOf = (link: IstarLink<string>): string | undefined => {\n const definition = metamodel.links.get(link.kind);\n return definition?.of === hubKind.of ? definition?.role : undefined;\n };\n asArray(raw.starts, `${where}.starts`).forEach((rawLeg, j) => {\n const leg = readLink(rawLeg, `${where}.starts[${j}]`);\n if (roleOf(leg) !== 'leg' || leg.target !== hub.id) {\n throw new PistarParseError(\n `${where}.starts[${j}] (${leg.id}): not a leg of the hub \"${hub.id}\"`,\n );\n }\n });\n if (raw.end !== undefined) {\n const end = readLink(raw.end, `${where}.end`);\n if (roleOf(end) !== 'end' || end.source !== hub.id) {\n throw new PistarParseError(`${where}.end (${end.id}): not the end of the hub \"${hub.id}\"`);\n }\n }\n };\n\n asArray(json.links, 'links').forEach((raw, i) => {\n if (isRecord(raw) && isRecord(raw.hub)) readHubEntry(raw, `links[${i}]`);\n else readLink(raw, `links[${i}]`);\n });\n\n let extraDisplay: Record<string, unknown> | undefined;\n for (const [id, value] of Object.entries(display)) {\n if (!usedDisplay.has(id)) (extraDisplay ??= {})[id] = value;\n }\n\n let diagram: Diagram | undefined;\n if (isRecord(json.diagram)) {\n const d = json.diagram;\n diagram = {\n ...optional('width', typeof d.width === 'number' ? d.width : undefined),\n ...optional('height', typeof d.height === 'number' ? d.height : undefined),\n ...optional('name', typeof d.name === 'string' ? d.name : undefined),\n ...(isRecord(d.customProperties)\n ? { customProperties: d.customProperties as CustomProperties }\n : {}),\n ...optional('extra', extraOf(d, DIAGRAM_KEYS)),\n };\n objects.set(DIAGRAM_LAYOUT_KEY, Object.keys(d));\n }\n\n const model: AnyIstarModel = {\n elements,\n links,\n ...optional('diagram', diagram),\n ...optional('tool', typeof json.tool === 'string' ? json.tool : undefined),\n ...optional('istar', typeof json.istar === 'string' ? json.istar : undefined),\n ...optional('saveDate', typeof json.saveDate === 'string' ? json.saveDate : undefined),\n ...optional('extraDisplay', extraDisplay),\n ...optional('extra', extraOf(json, TOP_LEVEL_KEY_SET)),\n };\n layouts.set(model, { keys: Object.keys(json), display: Object.keys(display), objects });\n // The block stays in `extra`, so it is written back exactly as read.\n setHostMetamodel(model, host);\n return withMetamodel(model, metamodel);\n}\n\n// ---------------------------------------------------------------------------------------------\n// Which language a file is in\n\nfunction parseJson(json: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof json !== 'string') return json;\n let value: unknown;\n try {\n value = JSON.parse(json);\n } catch (error) {\n throw new PistarParseError(`invalid JSON: ${(error as Error).message}`, { cause: error });\n }\n if (!isRecord(value)) throw new PistarParseError('a piStar model must be a JSON object');\n return value;\n}\n\n/** `kaos` for an object whose `type` is `kaos.Softgoal`. */\nfunction prefixOf(value: unknown): string | undefined {\n const type = isRecord(value) ? value.type : undefined;\n const dot = typeof type === 'string' ? type.indexOf('.') : -1;\n return dot > 0 ? (type as string).slice(0, dot) : undefined;\n}\n\nfunction arrayOf(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\n/**\n * The namespace of the first `type` in a file (`kaos` for `kaos.Softgoal`), looking at actors and\n * their nodes, orphans, dependencies, then links (hub entries included). `undefined` when no\n * element or link has a namespaced type. Throws `PistarParseError` for a string that isn't JSON.\n */\nexport function detectPrefix(json: string | Record<string, unknown>): string | undefined {\n const file = parseJson(json);\n const candidates = function* (): Generator<unknown> {\n for (const actor of arrayOf(file.actors)) {\n yield actor;\n if (isRecord(actor)) yield* arrayOf(actor.nodes);\n }\n yield* arrayOf(file.orphans);\n yield* arrayOf(file.dependencies);\n for (const link of arrayOf(file.links)) {\n if (isRecord(link) && isRecord(link.hub)) {\n yield link.hub;\n yield* arrayOf(link.starts);\n yield link.end;\n } else {\n yield link;\n }\n }\n };\n for (const candidate of candidates()) {\n const prefix = prefixOf(candidate);\n if (prefix !== undefined) return prefix;\n }\n return undefined;\n}\n\n/**\n * Which of `roots` a file is written in: the one whose `prefix` is the file's (`detectPrefix`);\n * for a file without types, the only one whose `file.tool` is the file's `tool`; otherwise\n * `undefined`. Pass the result to `parsePistar(json, { metamodel })`.\n */\nexport function detectFramework(\n json: string | Record<string, unknown>,\n roots: readonly AnyMetamodel[],\n): AnyMetamodel | undefined {\n const file = parseJson(json);\n const prefix = detectPrefix(file);\n if (prefix !== undefined) return roots.find((root) => root.prefix === prefix);\n if (typeof file.tool !== 'string') return undefined;\n const byTool = roots.filter((root) => root.file.tool === file.tool);\n return byTool.length === 1 ? byTool[0] : undefined;\n}\n\nfunction optional<K extends string, V>(key: K, value: V | undefined): { [P in K]?: V } {\n return (value === undefined ? {} : { [key]: value }) as { [P in K]?: V };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Serialization\n\nexport interface ToPistarOptions {\n /** Default: the model's metamodel, or iStar 2.0. Decides each kind's `type` and category. */\n metamodel?: AnyMetamodel;\n /**\n * Value for `saveDate`. Defaults to the model's own `saveDate` (so a load/save round trip is\n * lossless); a parsed file that had none keeps none, and a model that was never a file gets\n * the current time. Pass `new Date()` when saving an edited model, as piStar does.\n */\n saveDate?: string | Date;\n}\n\nfunction formatDate(date: Date): string {\n // piStar uses the deprecated `toGMTString`, an alias of `toUTCString`.\n return date.toUTCString();\n}\n\nfunction pistarTypeOf(type: string | undefined, kind: string, metamodel: AnyMetamodel): string {\n if (type === undefined) {\n throw new PistarWriteError(\n `kind \"${kind}\" is not part of ${metamodel.name}; pass its metamodel (toPistar(model, { metamodel }) or withMetamodel)`,\n );\n }\n return type;\n}\n\n/**\n * `value` with its keys in the order `keys` gives (those present), then the rest as built (piStar's\n * order): an object read from a file is written back with the file's key order, and keys the\n * file lacked follow.\n */\nfunction inSourceOrder<T extends object>(value: T, keys: readonly string[] | undefined): T {\n if (!keys) return value;\n const result: Record<string, unknown> = {};\n const record = value as Record<string, unknown>;\n for (const key of keys) if (key in record) result[key] = record[key];\n for (const key of Object.keys(record)) if (!(key in result)) result[key] = record[key];\n return result as T;\n}\n\nfunction elementJson(element: IstarElement<string>, metamodel: AnyMetamodel): PistarElementJson {\n return {\n id: element.id,\n text: element.name,\n type: pistarTypeOf(metamodel.elements.get(element.kind)?.pistarType, element.kind, metamodel),\n x: element.x,\n y: element.y,\n ...(element.customProperties ? { customProperties: { ...element.customProperties } } : {}),\n };\n}\n\n/** Builds the save-file object for a model. `toPistar` is this plus `JSON.stringify`. */\nexport function toPistarObject<EK extends string, LK extends string>(\n input: IstarModel<EK, LK>,\n options: ToPistarOptions = {},\n): PistarFile {\n const model = input as unknown as AnyIstarModel;\n const metamodel: AnyMetamodel =\n options.metamodel ?? (metamodelOf(input) as unknown as AnyMetamodel);\n const isActorKind = (kind: string): boolean => metamodel.elements.get(kind)?.category === 'actor';\n // Hubs of n-ary links are written in their entry in `links`, not as elements.\n const isHub = (element: IstarElement<string>): boolean =>\n metamodel.elements.get(element.kind)?.role === 'hub';\n const actors: PistarActorJson[] = [];\n const orphans: PistarElementJson[] = [];\n const dependencies: PistarDependencyJson[] = [];\n const children = new Map<string, PistarElementJson[]>();\n const layout = layouts.get(model);\n const sourceOrder = <T extends object>(id: string, value: T): T =>\n inSourceOrder(value, layout?.objects?.get(id));\n\n for (const element of model.elements.values()) {\n if (isHub(element)) continue;\n if (element.parent !== undefined && !isActorKind(element.kind)) {\n let list = children.get(element.parent);\n if (!list) children.set(element.parent, (list = []));\n list.push(sourceOrder(element.id, { ...elementJson(element, metamodel), ...element.extra }));\n }\n }\n\n for (const element of model.elements.values()) {\n if (isHub(element)) continue;\n if (isActorKind(element.kind)) {\n actors.push(\n sourceOrder(element.id, {\n ...elementJson(element, metamodel),\n nodes: children.get(element.id) ?? [],\n ...element.extra,\n }),\n );\n } else if (element.isDependum) {\n // Like piStar, derive depender/dependee from the dependency links.\n const { inbound, outbound } = dependencyLinksOf(model, element.id);\n dependencies.push(\n sourceOrder(element.id, {\n ...elementJson(element, metamodel),\n source: inbound?.source ?? element.dependency?.source ?? '',\n target: outbound?.target ?? element.dependency?.target ?? '',\n ...element.extra,\n }),\n );\n } else if (element.parent === undefined || !model.elements.has(element.parent)) {\n orphans.push(\n sourceOrder(element.id, { ...elementJson(element, metamodel), ...element.extra }),\n );\n }\n }\n\n const linkJson = (link: IstarLink<string>): PistarLinkJson =>\n sourceOrder(link.id, {\n id: link.id,\n type: pistarTypeOf(metamodel.links.get(link.kind)?.pistarType, link.kind, metamodel),\n source: link.source,\n target: link.target,\n ...(link.name !== undefined ? { name: link.name } : {}),\n ...(link.customProperties ? { customProperties: { ...link.customProperties } } : {}),\n ...(link.label !== undefined ? { label: link.label } : {}),\n ...link.extra,\n });\n\n // Each hub's legs (in link order) and end; its entry goes where its first leg or end is.\n const hubs = new Map<string, { legs: IstarLink<string>[]; end?: IstarLink<string> }>();\n const partsOf = (hubId: string) => {\n let parts = hubs.get(hubId);\n if (!parts) hubs.set(hubId, (parts = { legs: [] }));\n return parts;\n };\n const hubOf = (link: IstarLink<string>): string | undefined => {\n const role = metamodel.links.get(link.kind)?.role;\n const id = role === 'leg' ? link.target : role === 'end' ? link.source : undefined;\n const hub = id === undefined ? undefined : model.elements.get(id);\n return hub && isHub(hub) ? hub.id : undefined;\n };\n for (const link of model.links.values()) {\n const hubId = hubOf(link);\n if (hubId === undefined) continue;\n const parts = partsOf(hubId);\n if (metamodel.links.get(link.kind)?.role === 'leg') parts.legs.push(link);\n else parts.end ??= link;\n }\n const hubEntry = (hub: IstarElement<string>): PistarHubLinkJson => {\n const parts = hubs.get(hub.id) ?? { legs: [] };\n const { [HUB_ENTRY_KEY]: entryExtra, ...hubExtra } = hub.extra ?? {};\n return sourceOrder(hubEntryLayoutKey(hub.id), {\n hub: sourceOrder(hub.id, {\n id: hub.id,\n type: pistarTypeOf(metamodel.elements.get(hub.kind)?.pistarType, hub.kind, metamodel),\n x: hub.x,\n y: hub.y,\n ...(hub.customProperties ? { customProperties: { ...hub.customProperties } } : {}),\n ...hubExtra,\n }),\n starts: parts.legs.map(linkJson),\n ...(parts.end ? { end: linkJson(parts.end) } : {}),\n ...(isRecord(entryExtra) ? entryExtra : {}),\n });\n };\n\n const links: (PistarLinkJson | PistarHubLinkJson)[] = [];\n const written = new Set<string>();\n for (const link of model.links.values()) {\n const hubId = hubOf(link);\n const parts = hubId === undefined ? undefined : hubs.get(hubId);\n // A second end of the same hub (an invalid model) is kept as a plain link.\n if (hubId === undefined || !parts || (!parts.legs.includes(link) && parts.end !== link)) {\n links.push(linkJson(link));\n } else if (!written.has(hubId)) {\n written.add(hubId);\n links.push(hubEntry(model.elements.get(hubId)!));\n }\n }\n // Hubs that lost every leg and their end still have an entry, so they aren't lost.\n for (const element of model.elements.values()) {\n if (isHub(element) && !written.has(element.id)) links.push(hubEntry(element));\n }\n\n const display: Record<string, Record<string, unknown>> = {};\n const displayOf = (id: string): Record<string, unknown> | undefined => {\n const owner = model.elements.get(id) ?? model.links.get(id);\n if (owner) return owner.display as Record<string, unknown> | undefined;\n return model.extraDisplay?.[id] as Record<string, unknown> | undefined;\n };\n for (const id of layout?.display ?? []) {\n const entry = displayOf(id);\n if (entry !== undefined) display[id] = { ...entry };\n }\n for (const owner of [...model.elements.values(), ...model.links.values()]) {\n if (owner.display && !(owner.id in display)) display[owner.id] = { ...owner.display };\n }\n for (const [id, entry] of Object.entries(model.extraDisplay ?? {})) {\n if (!(id in display)) display[id] = entry as Record<string, unknown>;\n }\n\n // A file that had no saveDate keeps none until a save passes one (an edit, as piStar does).\n let saveDate: string | undefined;\n if (options.saveDate instanceof Date) saveDate = formatDate(options.saveDate);\n else if (options.saveDate !== undefined || model.saveDate !== undefined)\n saveDate = options.saveDate ?? model.saveDate;\n else if (!layout || layout.keys.includes('saveDate')) saveDate = formatDate(new Date());\n\n const d = model.diagram;\n const diagram: PistarDiagramJson | undefined =\n d &&\n sourceOrder(DIAGRAM_LAYOUT_KEY, {\n ...(d.width !== undefined ? { width: d.width } : {}),\n ...(d.height !== undefined ? { height: d.height } : {}),\n ...(d.name !== undefined ? { name: d.name } : {}),\n ...(d.customProperties ? { customProperties: { ...d.customProperties } } : {}),\n ...d.extra,\n });\n\n const values: Record<string, unknown> = {\n ...model.extra,\n actors,\n orphans,\n dependencies,\n links,\n display,\n tool: model.tool,\n istar: model.istar,\n saveDate,\n diagram,\n };\n\n // Files written by older piStar versions lack some sections (e.g. `orphans`). Keep them\n // absent while they are empty, so such files round-trip unchanged.\n if (layout) {\n for (const key of ['actors', 'orphans', 'dependencies', 'links', 'display'] as const) {\n const value = values[key] as unknown[] | Record<string, unknown>;\n const empty = Array.isArray(value) ? value.length === 0 : Object.keys(value).length === 0;\n if (empty && !layout.keys.includes(key)) values[key] = undefined;\n }\n }\n\n // Emit keys in the order they had in the source file (else the root metamodel's file order),\n // then any new ones in piStar's order.\n const order = [\n ...(layout?.keys ?? metamodel.file.keys ?? []),\n ...TOP_LEVEL_KEYS,\n ...Object.keys(model.extra ?? {}),\n ];\n const file: Record<string, unknown> = {};\n for (const key of order) {\n if (!(key in file) && values[key] !== undefined) file[key] = values[key];\n }\n return file as PistarFile;\n}\n\n/** Serializes a model to piStar's JSON text (2-space indentation, no trailing newline). */\nexport function toPistar<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n options?: ToPistarOptions,\n): string {\n return JSON.stringify(toPistarObject(model, options), null, 2);\n}\n\n// ---------------------------------------------------------------------------------------------\n// A model's own metamodel\n\n/**\n * The constructs the model's file declares in its `\"metamodel\"` block, when they were applied\n * (read with `fileMetamodel: true`, or set with `withFileMetamodel`); `undefined` otherwise.\n * Kinds the host supplied are never part of it.\n */\nexport function fileMetamodelOf<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n): FileMetamodel | undefined {\n if (!hostMetamodelOf(model)) return undefined;\n return model.extra?.[FILE_METAMODEL_KEY] as FileMetamodel | undefined;\n}\n\n/**\n * A copy of `model` whose file declares `block` (`null` removes the block): its metamodel is the\n * host's extended by `block`, and `toPistar` writes the block. This is how a tool's \"Add new\"\n * construct joins a model. Throws `MetamodelError` if the block is malformed, collides with the\n * host's kinds, or leaves out a kind the model still uses.\n */\nexport function withFileMetamodel<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n block: FileMetamodel | null,\n): IstarModel<string, string> {\n const any = model as unknown as AnyIstarModel;\n const host = hostMetamodelOf(any) ?? (metamodelOf(any) as unknown as AnyMetamodel);\n let next: AnyMetamodel = host;\n if (block) {\n validateFileMetamodel(block);\n next = extendMetamodel(host, fileMetamodelExtension(block));\n }\n for (const element of any.elements.values()) {\n if (!next.elements.has(element.kind)) {\n throw new MetamodelError(\n `element \"${element.id}\" uses kind \"${element.kind}\", which the new metamodel lacks`,\n );\n }\n }\n for (const link of any.links.values()) {\n if (!next.links.has(link.kind)) {\n throw new MetamodelError(\n `link \"${link.id}\" uses kind \"${link.kind}\", which the new metamodel lacks`,\n );\n }\n }\n const { [FILE_METAMODEL_KEY]: _previous, ...others } = any.extra ?? {};\n // Replacing keeps the block's place among the top-level keys.\n const extra = block ? { ...any.extra, [FILE_METAMODEL_KEY]: structuredClone(block) } : others;\n const { extra: _extra, ...rest } = any;\n const result: AnyIstarModel = inheritSourceLayout(any, {\n ...rest,\n ...(Object.keys(extra).length > 0 ? { extra } : {}),\n });\n setHostMetamodel(result, block ? host : undefined);\n return withMetamodel(result, next);\n}\n","/**\n * Pure model operations. Each takes a model and returns a new one; inputs are never mutated.\n * The store (`store.ts`) wraps these with undo/redo and change events, and the React layer can\n * use them directly for controlled components.\n *\n * Behaviour follows the piStar web tool (`istarFunctions.js` and its UI):\n * - removing an actor removes its inner elements; removing an element removes its links;\n * - a dependency is two `DependencyLink`s around a dependum, and removing any of the three\n * removes the whole dependency (upstream keeps an `otherHalf` reference for this);\n * - moving an actor moves its inner elements with it (they are JointJS-embedded upstream);\n * - an n-ary link (DSM3-goals' split link) is a hub element with legs and an end; removing its\n * end or its last leg removes the hub, and removing the hub removes its legs and end.\n *\n * Kinds are looked up in the model's metamodel (`metamodelOf`, iStar 2.0 by default), so\n * extended actor, node, link and dependency kinds behave like their built-in counterparts.\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { GoalDiagnostic } from './diagnostics';\nimport type { ActorKind, DependencyLinkKind, ElementKind, LinkKind } from './metamodel';\nimport type { AnyMetamodel, LinkKindDefinition } from './metamodels';\nimport type {\n AnyIstarModel,\n CustomProperties,\n Diagram,\n ElementDisplay,\n IstarElement,\n IstarLink,\n HubLink,\n IstarModel,\n LinkDisplay,\n} from './model';\nimport {\n defaultHubPosition,\n dependencyLinksOf,\n hubLinkOf,\n inheritMetamodel,\n metamodelOf,\n} from './model';\nimport { inheritSourceLayout } from './serialization';\n\nexport class ModelOperationError extends Error {\n override name = 'ModelOperationError';\n /** The element or link the error is about, when the operation named one. */\n readonly elementId?: string;\n\n constructor(message: string, elementId?: string) {\n super(message);\n this.elementId = elementId;\n }\n\n /** As a `GoalDiagnostic`, anchored on `elementId` (empty string if the error names none). */\n toDiagnostic(): GoalDiagnostic {\n return {\n elementId: this.elementId ?? '',\n severity: 'error',\n message: this.message,\n };\n }\n}\n\n/** Generates ids for new elements and links. piStar uses UUID v4. */\nexport type IdGenerator = () => string;\n\nexport const defaultIdGenerator: IdGenerator = () => {\n const c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n if (c?.randomUUID) return c.randomUUID();\n // Fallback for non-secure browser contexts, where randomUUID is unavailable.\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n};\n\nexport interface OperationContext {\n readonly createId?: IdGenerator;\n}\n\ntype AnyElement = IstarElement<string>;\ntype AnyLink = IstarLink<string>;\n\nfunction any<EK extends string, LK extends string>(model: IstarModel<EK, LK>): AnyIstarModel {\n return model as unknown as AnyIstarModel;\n}\n\nfunction typed<EK extends string, LK extends string>(model: AnyIstarModel): IstarModel<EK, LK> {\n return model as unknown as IstarModel<EK, LK>;\n}\n\nfunction metaOf(model: AnyIstarModel): AnyMetamodel {\n return metamodelOf(model) as unknown as AnyMetamodel;\n}\n\nfunction isActorIn(model: AnyIstarModel, kind: string): boolean {\n return metaOf(model).elements.get(kind)?.category === 'actor';\n}\n\nfunction derive(from: AnyIstarModel, changes: Partial<AnyIstarModel>): AnyIstarModel {\n return inheritMetamodel(from, inheritSourceLayout(from, { ...from, ...changes }));\n}\n\nfunction requireElement(model: AnyIstarModel, id: string): AnyElement {\n const element = model.elements.get(id);\n if (!element) throw new ModelOperationError(`unknown element \"${id}\"`, id);\n return element;\n}\n\nfunction requireLink(model: AnyIstarModel, id: string): AnyLink {\n const link = model.links.get(id);\n if (!link) throw new ModelOperationError(`unknown link \"${id}\"`, id);\n return link;\n}\n\nfunction withoutUndefined<T extends object>(value: T): T {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) if (v !== undefined) out[k] = v;\n return out as T;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Elements\n\nexport interface NewElement<K extends string = ElementKind> {\n readonly kind: K;\n readonly x: number;\n readonly y: number;\n readonly id?: string;\n /** Defaults to the kind's label (\"Goal\"), like piStar. */\n readonly name?: string;\n /** Actor to place the element in. Required in practice for iStar nodes (see NodeKindInfo). */\n readonly parent?: string;\n readonly customProperties?: CustomProperties;\n readonly display?: ElementDisplay;\n}\n\nexport function addElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewElement<EK>,\n ctx: OperationContext = {},\n): { model: IstarModel<EK, LK>; element: IstarElement<EK> } {\n const m = any(model);\n const metamodel = metaOf(m);\n const definition = metamodel.elements.get(input.kind);\n if (!definition) {\n throw new ModelOperationError(`unknown element kind \"${input.kind}\" in ${metamodel.name}`);\n }\n const id = input.id ?? (ctx.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`, id);\n }\n if (input.parent !== undefined) {\n if (definition.category === 'actor') throw new ModelOperationError('actors cannot be nested');\n if (!isActorIn(m, requireElement(m, input.parent).kind)) {\n throw new ModelOperationError(`parent \"${input.parent}\" is not an actor`, input.parent);\n }\n }\n const element: AnyElement = withoutUndefined({\n id,\n kind: input.kind,\n name: input.name ?? definition.label,\n x: input.x,\n y: input.y,\n parent: input.parent,\n customProperties: input.customProperties,\n display: input.display,\n });\n const elements = new Map(m.elements).set(id, element);\n return { model: typed(derive(m, { elements })), element: element as IstarElement<EK> };\n}\n\nexport interface ElementPatch {\n readonly name?: string;\n /** Replaces the whole map. Use `null` to remove it. */\n readonly customProperties?: CustomProperties | null;\n /** Merged into the current display; a key set to `undefined` is removed. `null` clears it. */\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction mergeDisplay<D extends object>(\n current: D | undefined,\n patch: { readonly [key: string]: unknown } | null | undefined,\n): D | undefined {\n if (patch === undefined) return current;\n if (patch === null) return undefined;\n const merged: Record<string, unknown> = { ...current };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) delete merged[key];\n else merged[key] = value;\n }\n return Object.keys(merged).length > 0 ? (merged as D) : undefined;\n}\n\nexport function updateElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n patch: ElementPatch,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n const next: AnyElement = withoutUndefined({\n ...current,\n name: patch.name ?? current.name,\n customProperties:\n patch.customProperties === undefined\n ? current.customProperties\n : (patch.customProperties ?? undefined),\n display: mergeDisplay<ElementDisplay>(current.display, patch.display),\n });\n return typed(derive(m, { elements: new Map(m.elements).set(id, next) }));\n}\n\n/**\n * Moves an element to an absolute position. Moving an actor shifts its inner elements by the\n * same offset.\n */\nexport function moveElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n x: number,\n y: number,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n const dx = x - current.x;\n const dy = y - current.y;\n if (dx === 0 && dy === 0) return model;\n const elements = new Map(m.elements);\n elements.set(id, { ...current, x, y });\n if (isActorIn(m, current.kind)) {\n for (const child of m.elements.values()) {\n if (child.parent === id)\n elements.set(child.id, { ...child, x: child.x + dx, y: child.y + dy });\n }\n }\n return typed(derive(m, { elements }));\n}\n\n/**\n * Moves an inner element into another actor (or out of any actor with `null`). The element\n * becomes the actor's last child. Links that become invalid are kept; `validateModel` reports\n * them.\n */\nexport function nestElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n parent: string | null,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireElement(m, id);\n if (isActorIn(m, current.kind)) throw new ModelOperationError('actors cannot be nested', id);\n if (current.isDependum) throw new ModelOperationError('a dependum cannot be nested', id);\n if ((current.parent ?? null) === parent) return model;\n if (parent !== null && !isActorIn(m, requireElement(m, parent).kind)) {\n throw new ModelOperationError(`parent \"${parent}\" is not an actor`, parent);\n }\n const elements = new Map(m.elements);\n elements.delete(id);\n const { parent: _old, ...rest } = current;\n elements.set(id, parent === null ? rest : { ...rest, parent });\n return typed(derive(m, { elements }));\n}\n\n/**\n * Removes elements and everything that depends on them: inner elements of removed actors,\n * links touching removed elements (and links targeting removed links), and the rest of any\n * dependency that loses a part.\n */\nexport function removeElements<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n ids: Iterable<string>,\n): IstarModel<EK, LK> {\n return typed(removeCascade(any(model), new Set(ids), new Set()));\n}\n\nexport function removeElement<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n): IstarModel<EK, LK> {\n requireElement(any(model), id);\n return removeElements(model, [id]);\n}\n\nfunction removeCascade(\n model: AnyIstarModel,\n elementIds: Set<string>,\n linkIds: Set<string>,\n): AnyIstarModel {\n const metamodel = metaOf(model);\n const isDependencyHalf = (link: AnyLink): boolean =>\n metamodel.links.get(link.kind)?.category === 'dependency';\n // Iterate to a fixed point: each round may remove more elements or links.\n let changed = true;\n while (changed) {\n changed = false;\n for (const element of model.elements.values()) {\n if (elementIds.has(element.id)) continue;\n if (element.parent !== undefined && elementIds.has(element.parent)) {\n elementIds.add(element.id);\n changed = true;\n }\n }\n for (const link of model.links.values()) {\n if (linkIds.has(link.id)) continue;\n // A link goes with its endpoints, including a link it targets (see `LinkRules`).\n if (elementIds.has(link.source) || elementIds.has(link.target) || linkIds.has(link.target)) {\n linkIds.add(link.id);\n changed = true;\n }\n }\n // An n-ary link that lost its end or its last leg goes entirely (its hub takes the rest).\n for (const element of model.elements.values()) {\n if (elementIds.has(element.id) || metamodel.elements.get(element.kind)?.role !== 'hub') {\n continue;\n }\n let legs = 0;\n let removedLegs = 0;\n let endRemoved = false;\n for (const link of model.links.values()) {\n const role = metamodel.links.get(link.kind)?.role;\n if (role === 'leg' && link.target === element.id) {\n legs++;\n if (linkIds.has(link.id)) removedLegs++;\n } else if (role === 'end' && link.source === element.id && linkIds.has(link.id)) {\n endRemoved = true;\n }\n }\n if (endRemoved || (legs > 0 && removedLegs === legs)) {\n elementIds.add(element.id);\n changed = true;\n }\n }\n // A dependency that lost a half, or its dependum, goes entirely.\n for (const link of model.links.values()) {\n if (!linkIds.has(link.id) || !isDependencyHalf(link)) continue;\n for (const end of [link.source, link.target]) {\n const element = model.elements.get(end);\n if (element?.isDependum && !elementIds.has(end)) {\n elementIds.add(end);\n changed = true;\n }\n }\n }\n }\n if (elementIds.size === 0 && linkIds.size === 0) return model;\n const elements = new Map(model.elements);\n for (const id of elementIds) elements.delete(id);\n const links = new Map(model.links);\n for (const id of linkIds) links.delete(id);\n return derive(model, { elements, links });\n}\n\n// ---------------------------------------------------------------------------------------------\n// Links\n\nexport interface NewLink<K extends string = LinkKind> {\n /** Any link kind except dependency kinds (use `addDependency` for those). */\n readonly kind: Exclude<K, DependencyLinkKind>;\n readonly source: string;\n /** An element id, or a link id for kinds whose rules target links. */\n readonly target: string;\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).\n */\n readonly id?: string;\n /** Contribution value: make, help, hurt or break. */\n readonly label?: string;\n readonly name?: string;\n readonly customProperties?: CustomProperties;\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\nexport interface ConnectOptions extends OperationContext {\n /** Skip constraint checking (used when loading or scripting known-good data). */\n readonly force?: boolean;\n /**\n * Retry with source and target swapped if the link is invalid as given. Defaults to the\n * metamodel's `tryReversedWhenAdding` (Needed-By and Qualification), as in piStar.\n */\n readonly tryReversed?: boolean;\n}\n\nexport type ConnectResult<EK extends string = ElementKind, LK extends string = LinkKind> =\n | {\n ok: true;\n model: IstarModel<EK, LK>;\n /** The new link; for an n-ary kind, the new leg or (for a new hub) the end. */\n link: IstarLink<LK>;\n reversed: boolean;\n /** For an n-ary kind: the hub link the new link belongs to, as it now is. */\n hub?: HubLink<EK, LK>;\n }\n | Extract<LinkCheck, { ok: false }>;\n\n/**\n * Maps a failing `connect` result to a `GoalDiagnostic`, anchored on the end named by the\n * `LinkCheck`'s `end` field (`target` when a check doesn't single out one end, such as\n * `self-link` or `actor-types-differ`). `undefined` for a successful result.\n */\nexport function connectResultToDiagnostic<\n EK extends string = ElementKind,\n LK extends string = LinkKind,\n>(\n result: ConnectResult<EK, LK>,\n endpoints: { readonly source: string; readonly target: string },\n): GoalDiagnostic | undefined {\n if (result.ok) return undefined;\n const elementId = (result.end ?? 'target') === 'source' ? endpoints.source : endpoints.target;\n return {\n elementId,\n severity: 'error',\n message: result.reason,\n code: result.code,\n };\n}\n\n/**\n * Adds a link between two elements if the iStar constraints allow it.\n *\n * With an n-ary kind (`arity: 'n'`), a `target` that is one of the kind's hubs gets a new leg\n * from `source` (see `addLeg`), taking `input.id` or `input.legId` (default a fresh id) as the\n * leg's id. Any other target gets a new hub, centred between source and target, with a leg from\n * `source` and an end to `target`. `input.id` and `customProperties` then go to the hub, `label`\n * and `name` to the end, and `legId`/`endId` (default fresh ids) to the leg and end.\n */\nexport function connect<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewLink<LK>,\n options: ConnectOptions = {},\n): ConnectResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const kind: string = input.kind;\n const definition = metamodel.links.get(kind);\n if (definition?.category === 'dependency') {\n throw new ModelOperationError('use addDependency to create dependencies');\n }\n if (definition?.parts) return connectHub(m, definition, input, options);\n let { source, target } = input;\n let reversed = false;\n if (!options.force) {\n let check = canLink(m, source, target, kind);\n const tryReversed = options.tryReversed ?? definition?.info.tryReversedWhenAdding;\n if (!check.ok && tryReversed) {\n const swapped = canLink(m, target, source, kind);\n if (swapped.ok) {\n [source, target] = [target, source];\n reversed = true;\n check = swapped;\n }\n }\n if (!check.ok) return check;\n } else {\n if (!definition) {\n throw new ModelOperationError(`unknown link kind \"${kind}\" in ${metamodel.name}`);\n }\n requireElement(m, source);\n if (!m.links.has(target)) requireElement(m, target);\n }\n const id = input.id ?? (options.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`, id);\n }\n const link: AnyLink = withoutUndefined({\n id,\n kind,\n source,\n target,\n label: input.label,\n name: input.name,\n customProperties: input.customProperties,\n });\n return {\n ok: true,\n model: typed(derive(m, { links: new Map(m.links).set(id, link) })),\n link: link as IstarLink<LK>,\n reversed,\n };\n}\n\nfunction connectHub<EK extends string, LK extends string>(\n m: AnyIstarModel,\n definition: LinkKindDefinition,\n input: NewLink<string>,\n options: ConnectOptions,\n): ConnectResult<EK, LK> {\n const metamodel = metaOf(m);\n const parts = definition.parts!;\n const { source, target } = input;\n if (m.elements.get(target)?.kind === parts.hub) {\n const legId = input.id ?? input.legId;\n return addLeg(typed<EK, LK>(m), target, source, {\n ...options,\n ...(legId === undefined ? {} : { id: legId }),\n });\n }\n if (!options.force) {\n const check = canLink(m, source, target, definition.kind);\n if (!check.ok) return check;\n }\n const from = requireElement(m, source);\n const to = requireElement(m, target);\n const createId = options.createId ?? defaultIdGenerator;\n const hubId = input.id ?? createId();\n const legId = input.legId ?? createId();\n const endId = input.endId ?? createId();\n for (const [i, id] of [hubId, legId, endId].entries()) {\n if (m.elements.has(id) || m.links.has(id) || [hubId, legId, endId].indexOf(id) !== i) {\n throw new ModelOperationError(`id \"${id}\" is already in use`, id);\n }\n }\n const size = metamodel.elements.get(parts.hub)?.size ?? { width: 20, height: 20 };\n const position = defaultHubPosition(m, from, to, size);\n const hub: AnyElement = withoutUndefined({\n id: hubId,\n kind: parts.hub,\n name: '',\n x: position.x,\n y: position.y,\n customProperties: input.customProperties,\n });\n const leg: AnyLink = { id: legId, kind: parts.leg, source, target: hubId };\n const end: AnyLink = withoutUndefined({\n id: endId,\n kind: parts.end,\n source: hubId,\n target,\n label: input.label,\n name: input.name,\n });\n const next = derive(m, {\n elements: new Map(m.elements).set(hubId, hub),\n links: new Map(m.links).set(legId, leg).set(endId, end),\n });\n return {\n ok: true,\n model: typed(next),\n link: end as IstarLink<LK>,\n reversed: false,\n hub: { hub, legs: [leg], end } as unknown as HubLink<EK, LK>,\n };\n}\n\n/**\n * Adds a leg from `source` to the hub `hubId` of an n-ary link (one more source for it), if the\n * kind's rules allow it. `options.id` is the leg's id.\n */\nexport function addLeg<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n hubId: string,\n source: string,\n options: ConnectOptions & { readonly id?: string } = {},\n): ConnectResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const hub = requireElement(m, hubId);\n const base = metamodel.links.get(metamodel.elements.get(hub.kind)?.of ?? '');\n if (metamodel.elements.get(hub.kind)?.role !== 'hub' || !base?.parts) {\n throw new ModelOperationError(`\"${hubId}\" is not the hub of an n-ary link`, hubId);\n }\n const kind = base.parts.leg;\n if (!options.force) {\n const check = canLink(m, source, hubId, kind);\n if (!check.ok) return check;\n } else {\n requireElement(m, source);\n }\n const id = options.id ?? (options.createId ?? defaultIdGenerator)();\n if (m.elements.has(id) || m.links.has(id)) {\n throw new ModelOperationError(`id \"${id}\" is already in use`, id);\n }\n const leg: AnyLink = { id, kind, source, target: hubId };\n const next = derive(m, { links: new Map(m.links).set(id, leg) });\n return {\n ok: true,\n model: typed(next),\n link: leg as IstarLink<LK>,\n reversed: false,\n hub: hubLinkOf(typed<EK, LK>(next), hubId),\n };\n}\n\n/**\n * Removes one leg of an n-ary link. Removing its last leg removes the whole link (hub and end),\n * as `disconnect` does.\n */\nexport function removeLeg<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n legId: string,\n): IstarModel<EK, LK> {\n const m = any(model);\n const leg = requireLink(m, legId);\n if (metaOf(m).links.get(leg.kind)?.role !== 'leg') {\n throw new ModelOperationError(`\"${legId}\" is not a leg of an n-ary link`, legId);\n }\n return disconnect(model, legId);\n}\n\nexport interface NewDependency<EK extends string = ElementKind, LK extends string = LinkKind> {\n /** The depender: an actor or one of its inner elements. */\n readonly depender: string;\n /** The dependee: an actor or one of its inner elements. */\n readonly dependee: string;\n readonly dependum: {\n /** A node kind (built-in or extended) that can be a dependum. */\n readonly kind: Exclude<EK, ActorKind>;\n readonly name?: string;\n readonly id?: string;\n /** Defaults to the midpoint between depender and dependee, as in piStar. */\n readonly x?: number;\n readonly y?: number;\n readonly customProperties?: CustomProperties;\n };\n /** A dependency link kind. Default `istar.DependencyLink`. */\n readonly linkKind?: LK;\n readonly linkIds?: readonly [string, string];\n}\n\nexport type AddDependencyResult<EK extends string = ElementKind, LK extends string = LinkKind> =\n | {\n ok: true;\n model: IstarModel<EK, LK>;\n dependum: IstarElement<EK>;\n links: readonly [IstarLink<LK>, IstarLink<LK>];\n }\n | Extract<LinkCheck, { ok: false }>;\n\n/** Adds depender → dependum → dependee. */\nexport function addDependency<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n input: NewDependency<EK, LK>,\n options: Omit<ConnectOptions, 'tryReversed'> = {},\n): AddDependencyResult<EK, LK> {\n const m = any(model);\n const metamodel = metaOf(m);\n const dependumKind: string = input.dependum.kind;\n const dependumDefinition = metamodel.elements.get(dependumKind);\n if (dependumDefinition?.category !== 'node' || dependumDefinition.info?.canBeDependum === false) {\n throw new ModelOperationError(`${dependumKind} cannot be a dependum`);\n }\n const linkKind: string = input.linkKind ?? 'istar.DependencyLink';\n if (metamodel.links.get(linkKind)?.category !== 'dependency') {\n throw new ModelOperationError(`${linkKind} is not a dependency link kind`);\n }\n if (!options.force) {\n const check = canLink(m, input.depender, input.dependee, linkKind);\n if (!check.ok) return check;\n }\n const depender = requireElement(m, input.depender);\n const dependee = requireElement(m, input.dependee);\n const createId = options.createId ?? defaultIdGenerator;\n const added = addElement(\n m,\n {\n kind: dependumKind,\n id: input.dependum.id,\n name: input.dependum.name,\n x: input.dependum.x ?? (depender.x + dependee.x) / 2,\n y: input.dependum.y ?? (depender.y + dependee.y) / 2,\n customProperties: input.dependum.customProperties,\n },\n { createId },\n );\n const dependum: AnyElement = { ...added.element, isDependum: true };\n const [id1, id2] = input.linkIds ?? [createId(), createId()];\n const first: AnyLink = { id: id1, kind: linkKind, source: depender.id, target: dependum.id };\n const second: AnyLink = { id: id2, kind: linkKind, source: dependum.id, target: dependee.id };\n for (const id of [id1, id2]) {\n if (added.model.elements.has(id) || added.model.links.has(id) || id1 === id2) {\n throw new ModelOperationError(`id \"${id}\" is already in use`, id);\n }\n }\n return {\n ok: true,\n model: typed(\n derive(m, {\n elements: new Map(added.model.elements).set(dependum.id, dependum),\n links: new Map(m.links).set(id1, first).set(id2, second),\n }),\n ),\n dependum: dependum as IstarElement<EK>,\n links: [first as IstarLink<LK>, second as IstarLink<LK>],\n };\n}\n\n/**\n * Removes a link, and the links that target it. Removing either half of a dependency removes\n * the whole dependency.\n */\nexport function disconnect<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n): IstarModel<EK, LK> {\n const m = any(model);\n requireLink(m, id);\n return typed(removeCascade(m, new Set(), new Set([id])));\n}\n\nexport interface LinkPatch {\n /** `null` removes it. */\n readonly label?: string | null;\n readonly name?: string | null;\n readonly customProperties?: CustomProperties | null;\n readonly display?: { readonly [key: string]: unknown } | null;\n}\n\nfunction pick<T>(value: T | null | undefined, fallback: T | undefined): T | undefined {\n return value === undefined ? fallback : (value ?? undefined);\n}\n\nexport function updateLink<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n id: string,\n patch: LinkPatch,\n): IstarModel<EK, LK> {\n const m = any(model);\n const current = requireLink(m, id);\n const next: AnyLink = withoutUndefined({\n ...current,\n label: pick(patch.label, current.label),\n name: pick(patch.name, current.name),\n customProperties: pick(patch.customProperties, current.customProperties),\n display: mergeDisplay<LinkDisplay>(current.display, patch.display),\n });\n return typed(derive(m, { links: new Map(m.links).set(id, next) }));\n}\n\n// ---------------------------------------------------------------------------------------------\n// Diagram\n\nexport function updateDiagram<EK extends string = ElementKind, LK extends string = LinkKind>(\n model: IstarModel<EK, LK>,\n patch: Partial<Diagram>,\n): IstarModel<EK, LK> {\n const m = any(model);\n return typed(derive(m, { diagram: withoutUndefined({ ...m.diagram, ...patch }) }));\n}\n\n/** Where dependency depender/dependee currently point (see `dependencyLinksOf`). */\nexport function dependencyEnds<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n dependumId: string,\n): { depender?: string; dependee?: string } {\n const { inbound, outbound } = dependencyLinksOf(model, dependumId);\n const fallback = model.elements.get(dependumId)?.dependency;\n return {\n depender: inbound?.source ?? fallback?.source,\n dependee: outbound?.target ?? fallback?.target,\n };\n}\n","/**\n * An event-emitting store around an immutable `IstarModel`, with undo/redo.\n *\n * Every mutation produces a new model snapshot; history is a stack of snapshots, which is cheap\n * because unchanged elements and links are shared between snapshots. This replaces piStar's\n * `undoManager.js`, which stacked hand-written undo closures.\n *\n * `subscribe` + `getModel` match React's `useSyncExternalStore` contract.\n */\nimport type { LinkCheck } from './constraints';\nimport { canLink } from './constraints';\nimport type { ElementKind, LinkKind } from './metamodel';\nimport type { Metamodel } from './metamodels';\nimport type { AnyIstarModel, Diagram, IstarElement, IstarLink, IstarModel } from './model';\nimport { createEmptyModel } from './model';\nimport type {\n ConnectOptions,\n ElementPatch,\n IdGenerator,\n LinkPatch,\n NewDependency,\n NewElement,\n NewLink,\n} from './operations';\nimport * as ops from './operations';\n\n/** What happened, for listeners that want more than the new snapshot. */\nexport type ModelChange =\n | { type: 'addElement'; id: string }\n | { type: 'updateElement'; id: string; patch: ElementPatch }\n | { type: 'moveElement'; id: string; x: number; y: number }\n | { type: 'nestElement'; id: string; parent: string | null }\n | { type: 'removeElements'; ids: readonly string[] }\n /** `hubId`: the n-ary link's hub, when the new link is a leg or a new hub's end. */\n | { type: 'connect'; id: string; hubId?: string }\n | { type: 'removeLeg'; id: string }\n | { type: 'addDependency'; dependumId: string; linkIds: readonly [string, string] }\n | { type: 'updateLink'; id: string; patch: LinkPatch }\n | { type: 'disconnect'; id: string }\n | { type: 'updateDiagram'; patch: Partial<Diagram> }\n | { type: 'replace' };\n\nexport interface ModelChangeEvent<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly model: IstarModel<EK, LK>;\n readonly previous: IstarModel<EK, LK>;\n /** `undo`/`redo`/`load` carry no changes; a transaction carries all of its changes. */\n readonly changes: readonly ModelChange[];\n readonly source: 'edit' | 'undo' | 'redo' | 'load';\n}\n\nexport type ModelListener<EK extends string = ElementKind, LK extends string = LinkKind> = (\n event: ModelChangeEvent<EK, LK>,\n) => void;\n\nexport interface ModelStoreOptions<EK extends string = ElementKind, LK extends string = LinkKind> {\n /**\n * Metamodel for the default empty model, when no initial model is given. A given initial\n * model keeps its own (see `metamodelOf`).\n */\n readonly metamodel?: Metamodel<EK, LK>;\n readonly createId?: IdGenerator;\n /** Maximum number of undo steps kept. Default 100. */\n readonly historyLimit?: number;\n}\n\nexport interface ModelStore<EK extends string = ElementKind, LK extends string = LinkKind> {\n getModel(): IstarModel<EK, LK>;\n /** Returns an unsubscribe function. */\n subscribe(listener: ModelListener<EK, LK>): () => void;\n\n canLink(\n source: string | IstarElement<EK>,\n target: string | IstarElement<EK> | IstarLink<LK>,\n kind: LK,\n ): LinkCheck;\n\n addElement(input: NewElement<EK>): IstarElement<EK>;\n updateElement(id: string, patch: ElementPatch): void;\n moveElement(id: string, x: number, y: number): void;\n nestElement(id: string, parent: string | null): void;\n removeElement(id: string): void;\n removeElements(ids: Iterable<string>): void;\n setCollapsed(actorId: string, collapsed: boolean): void;\n\n connect(\n input: NewLink<LK>,\n options?: Omit<ConnectOptions, 'createId'>,\n ): ops.ConnectResult<EK, LK>;\n addDependency(\n input: NewDependency<EK, LK>,\n options?: Omit<ConnectOptions, 'createId' | 'tryReversed'>,\n ): ops.AddDependencyResult<EK, LK>;\n /** Adds a leg from `source` to the hub of an n-ary link (see `ops.addLeg`). */\n addLeg(\n hubId: string,\n source: string,\n options?: Omit<ConnectOptions, 'createId' | 'tryReversed'> & { readonly id?: string },\n ): ops.ConnectResult<EK, LK>;\n /** Removes a leg; the last one takes its hub and end with it. */\n removeLeg(id: string): void;\n updateLink(id: string, patch: LinkPatch): void;\n disconnect(id: string): void;\n updateDiagram(patch: Partial<Diagram>): void;\n\n /** Replaces the model as one undoable edit. */\n replace(model: IstarModel<EK, LK>): void;\n /** Replaces the model and clears history (like opening a file in piStar). */\n load(model: IstarModel<EK, LK>): void;\n\n /**\n * Groups several edits into one undo step and one change event. Nested calls join the\n * outermost transaction. If `fn` throws, the model is rolled back.\n */\n transaction<T>(fn: () => T): T;\n\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n clearHistory(): void;\n}\n\n// The iStar 2.0 overload comes last, so function references type as before.\nexport function createModelStore<EK extends string, LK extends string>(\n initial: IstarModel<EK, LK>,\n options?: ModelStoreOptions<EK, LK>,\n): ModelStore<EK, LK>;\nexport function createModelStore<EK extends string, LK extends string>(\n initial: undefined,\n options: ModelStoreOptions<EK, LK> & { readonly metamodel: Metamodel<EK, LK> },\n): ModelStore<EK, LK>;\nexport function createModelStore(initial?: IstarModel, options?: ModelStoreOptions): ModelStore;\nexport function createModelStore(\n initial?: AnyIstarModel,\n options: ModelStoreOptions<string, string> = {},\n): ModelStore<string, string> {\n initial ??= options.metamodel\n ? createEmptyModel(undefined, { metamodel: options.metamodel })\n : (createEmptyModel() as AnyIstarModel);\n const limit = options.historyLimit ?? 100;\n const ctx = { createId: options.createId ?? ops.defaultIdGenerator };\n const listeners = new Set<ModelListener<string, string>>();\n let model = initial;\n let past: AnyIstarModel[] = [];\n let future: AnyIstarModel[] = [];\n let tx: { start: AnyIstarModel; changes: ModelChange[]; depth: number } | undefined;\n\n const emit = (event: ModelChangeEvent<string, string>): void => {\n for (const listener of listeners) listener(event);\n };\n\n const commit = (next: AnyIstarModel, change: ModelChange): void => {\n if (next === model) return;\n if (tx) {\n model = next;\n tx.changes.push(change);\n return;\n }\n const previous = model;\n past.push(previous);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n model = next;\n emit({ model, previous, changes: [change], source: 'edit' });\n };\n\n const store: ModelStore<string, string> = {\n getModel: () => model,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n canLink: (source, target, kind) => canLink(model, source, target, kind),\n\n addElement(input) {\n const result = ops.addElement(model, input, ctx);\n commit(result.model, { type: 'addElement', id: result.element.id });\n return result.element;\n },\n updateElement(id, patch) {\n commit(ops.updateElement(model, id, patch), { type: 'updateElement', id, patch });\n },\n moveElement(id, x, y) {\n commit(ops.moveElement(model, id, x, y), { type: 'moveElement', id, x, y });\n },\n nestElement(id, parent) {\n commit(ops.nestElement(model, id, parent), { type: 'nestElement', id, parent });\n },\n removeElement(id) {\n commit(ops.removeElement(model, id), { type: 'removeElements', ids: [id] });\n },\n removeElements(ids) {\n const list = [...ids];\n commit(ops.removeElements(model, list), { type: 'removeElements', ids: list });\n },\n setCollapsed(actorId, collapsed) {\n const patch = { display: { collapsed: collapsed ? true : undefined } };\n commit(ops.updateElement(model, actorId, patch), {\n type: 'updateElement',\n id: actorId,\n patch,\n });\n },\n\n connect(input, connectOptions) {\n const result = ops.connect(model, input, { ...connectOptions, ...ctx });\n if (result.ok) {\n commit(result.model, {\n type: 'connect',\n id: result.link.id,\n ...(result.hub ? { hubId: result.hub.hub.id } : {}),\n });\n }\n return result;\n },\n addLeg(hubId, source, legOptions) {\n const result = ops.addLeg(model, hubId, source, { ...legOptions, ...ctx });\n if (result.ok) commit(result.model, { type: 'connect', id: result.link.id, hubId });\n return result;\n },\n removeLeg(id) {\n commit(ops.removeLeg(model, id), { type: 'removeLeg', id });\n },\n addDependency(input, dependencyOptions) {\n const result = ops.addDependency(model, input, { ...dependencyOptions, ...ctx });\n if (result.ok) {\n commit(result.model, {\n type: 'addDependency',\n dependumId: result.dependum.id,\n linkIds: [result.links[0].id, result.links[1].id],\n });\n }\n return result;\n },\n updateLink(id, patch) {\n commit(ops.updateLink(model, id, patch), { type: 'updateLink', id, patch });\n },\n disconnect(id) {\n commit(ops.disconnect(model, id), { type: 'disconnect', id });\n },\n updateDiagram(patch) {\n commit(ops.updateDiagram(model, patch), { type: 'updateDiagram', patch });\n },\n\n replace(next) {\n commit(next, { type: 'replace' });\n },\n load(next) {\n if (tx) throw new ops.ModelOperationError('cannot load inside a transaction');\n const previous = model;\n model = next;\n past = [];\n future = [];\n emit({ model, previous, changes: [], source: 'load' });\n },\n\n transaction<T>(fn: () => T): T {\n if (tx) {\n tx.depth++;\n try {\n return fn();\n } finally {\n tx.depth--;\n }\n }\n tx = { start: model, changes: [], depth: 1 };\n let result: T;\n try {\n result = fn();\n } catch (error) {\n model = tx.start;\n tx = undefined;\n throw error;\n }\n const { start, changes } = tx;\n tx = undefined;\n if (model !== start) {\n past.push(start);\n if (past.length > limit) past = past.slice(past.length - limit);\n future = [];\n emit({ model, previous: start, changes, source: 'edit' });\n }\n return result;\n },\n\n undo() {\n const previous = past.pop();\n if (!previous || tx) return false;\n future.push(model);\n const current = model;\n model = previous;\n emit({ model, previous: current, changes: [], source: 'undo' });\n return true;\n },\n redo() {\n const next = future.pop();\n if (!next || tx) return false;\n past.push(model);\n const current = model;\n model = next;\n emit({ model, previous: current, changes: [], source: 'redo' });\n return true;\n },\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n clearHistory() {\n past = [];\n future = [];\n },\n };\n return store;\n}\n","import type { ElementKind, LinkKind } from './metamodel';\nimport type { CustomProperties, IstarModel } from './model';\n\nexport type PropertyResult<T> = { ok: true; value: T } | { ok: false; error: string };\n\nexport interface PropertyOptions<T> {\n default?: T;\n optional?: boolean;\n label?: string;\n description?: string;\n}\n\nexport interface PropertyType<T> {\n readonly type: 'string' | 'number' | 'boolean' | 'enum' | 'reference';\n readonly options: PropertyOptions<T>;\n readonly values?: readonly string[];\n readonly integer?: boolean;\n readonly min?: number;\n readonly max?: number;\n /**\n * Numbers with `max: 1` (a probability, a rate): the value may also be written as a\n * percentage (`20.00%`). CAIRIS writes `0.2`, KAOSTools `.2` and `20.00%`.\n */\n readonly percent?: boolean;\n /** References: the element or link kinds the id may name; absent, any kind. */\n readonly kinds?: readonly string[];\n parse(raw: string): PropertyResult<T>;\n /**\n * The value as a string. `previous`, the raw string being replaced, lets a type keep the form\n * it was read in (a number read as `20.00%` is written as a percentage).\n */\n serialize(value: T, previous?: string): string;\n}\n\nexport function string(options?: PropertyOptions<string>): PropertyType<string> {\n const opts: PropertyOptions<string> = options ?? {};\n return {\n type: 'string',\n options: opts,\n parse(raw: string): PropertyResult<string> {\n return { ok: true, value: raw };\n },\n serialize(value: string): string {\n return value;\n },\n };\n}\n\n/** `20.00%` → 20.00 as text, or undefined when `raw` isn't a percentage. */\nfunction percentBody(raw: string): string | undefined {\n const text = raw.trim();\n if (!text.endsWith('%')) return undefined;\n const body = text.slice(0, -1).trim();\n return body === '' ? undefined : body;\n}\n\n/** Digits after the decimal point of a number written as text (`20.00` → 2). */\nfunction decimals(text: string): number {\n const dot = text.indexOf('.');\n return dot === -1 ? 0 : text.length - dot - 1;\n}\n\n/** `value` without floating-point noise from a ×100 (0.35 * 100 = 35.00000000000001). */\nfunction plain(value: number): string {\n return String(Number(value.toPrecision(12)));\n}\n\n/** Writes `value` in the form of `previous`: a percentage, a leading dot, or plain. */\nfunction formatNumber(value: number, previous: string | undefined, percent: boolean): string {\n if (previous === undefined) return String(value);\n const body = percent ? percentBody(previous) : undefined;\n if (body !== undefined) {\n const text = plain(value * 100);\n const places = decimals(body);\n return `${places > decimals(text) ? (value * 100).toFixed(places) : text}%`;\n }\n if (/^\\s*[+-]?\\.\\d/.test(previous) && Math.abs(value) < 1) {\n return String(value).replace(/^(-?)0\\./, '$1.');\n }\n return String(value);\n}\n\nexport function number(\n options?: PropertyOptions<number> & { integer?: boolean; min?: number; max?: number },\n): PropertyType<number> {\n const opts: PropertyOptions<number> = options ?? {};\n const integer = options?.integer;\n const min = options?.min;\n const max = options?.max;\n // A number in [·, 1] is a probability or a rate, which tools also write as a percentage.\n const percent = max === 1;\n return {\n type: 'number',\n options: opts,\n integer,\n min,\n max,\n ...(percent ? { percent } : {}),\n parse(raw: string): PropertyResult<number> {\n const body = percent ? percentBody(raw) : undefined;\n const value = body !== undefined ? Number(body) / 100 : Number(raw);\n if (!Number.isFinite(value)) {\n return { ok: false, error: 'must be a finite number' };\n }\n if (integer && !Number.isInteger(value)) {\n return { ok: false, error: 'must be an integer' };\n }\n if (min !== undefined && value < min) {\n return { ok: false, error: `must be at least ${min}` };\n }\n if (max !== undefined && value > max) {\n return { ok: false, error: `must be at most ${max}` };\n }\n return { ok: true, value };\n },\n serialize(value: number, previous?: string): string {\n return formatNumber(value, previous, percent);\n },\n };\n}\n\nexport function boolean(options?: PropertyOptions<boolean>): PropertyType<boolean> {\n const opts: PropertyOptions<boolean> = options ?? {};\n return {\n type: 'boolean',\n options: opts,\n parse(raw: string): PropertyResult<boolean> {\n if (raw === 'true') return { ok: true, value: true };\n if (raw === 'false') return { ok: true, value: false };\n return { ok: false, error: 'must be true or false' };\n },\n serialize(value: boolean): string {\n return value ? 'true' : 'false';\n },\n };\n}\n\nexport function enumOf<const V extends readonly string[]>(\n values: V,\n options?: PropertyOptions<V[number]>,\n): PropertyType<V[number]> {\n const opts: PropertyOptions<V[number]> = options ?? {};\n return {\n type: 'enum',\n options: opts,\n values,\n parse(raw: string): PropertyResult<V[number]> {\n if ((values as readonly string[]).includes(raw)) {\n return { ok: true, value: raw as V[number] };\n }\n return { ok: false, error: `must be one of: ${values.join(', ')}` };\n },\n serialize(value: V[number]): string {\n return value;\n },\n };\n}\n\n/**\n * A value that is another element's or link's id, e.g. the goal a KAOS resolution restores. The\n * schema only checks it is non-empty; `validateModelProperties` reports an id that isn't in the\n * model or names a kind outside `kinds`.\n */\nexport function reference(\n options?: PropertyOptions<string> & { kinds?: readonly string[] },\n): PropertyType<string> {\n const { kinds, ...opts } = options ?? {};\n return {\n type: 'reference',\n options: opts,\n ...(kinds ? { kinds } : {}),\n parse(raw: string): PropertyResult<string> {\n return { ok: true, value: raw };\n },\n serialize(value: string): string {\n return value;\n },\n };\n}\n\nexport const prop: {\n string: typeof string;\n number: typeof number;\n boolean: typeof boolean;\n enum: typeof enumOf;\n reference: typeof reference;\n} = {\n string,\n number,\n boolean,\n enum: enumOf,\n reference,\n};\n\nexport type PropertyShape = Record<string, PropertyType<unknown>>;\n\nexport type InferProperties<S extends PropertyShape> = {\n [K in keyof S]: S[K] extends PropertyType<infer T> ? T : never;\n};\n\nexport interface PropertyIssue {\n key: string;\n message: string;\n}\n\n/**\n * Typed custom properties of one element or link kind. `K` is the kind: iStar 2.0's kinds by\n * default; any extension kind (see `extendMetamodel`) is accepted too.\n */\nexport interface PropertySchema<\n S extends PropertyShape = PropertyShape,\n K extends string = ElementKind | LinkKind,\n> {\n readonly kind: K;\n readonly shape: S;\n read(source: CustomProperties | undefined | PropertyOwner): {\n values: Partial<InferProperties<S>>;\n issues: PropertyIssue[];\n };\n validate(source: CustomProperties | undefined | PropertyOwner): PropertyIssue[];\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties;\n defaults(): CustomProperties;\n}\n\n/** An element or link, read through its `customProperties`. */\nexport interface PropertyOwner {\n readonly kind: string;\n readonly customProperties?: CustomProperties;\n}\n\nexport interface ModelPropertyIssue extends PropertyIssue {\n id: string;\n}\n\ntype PropertySource = CustomProperties | undefined | PropertyOwner;\n\nfunction isCustomPropertiesRecord(source: NonNullable<PropertySource>): source is CustomProperties {\n // Elements and links are passed whole, possibly without `customProperties`; recognize them by\n // shape, whatever their metamodel: a namespaced `kind` (every metamodel's kinds are, e.g.\n // `istar.Goal`, `kaos.Goal`) with a numeric `x` (elements) or a `source` and `target` (links).\n if ('customProperties' in source) return false;\n const owner = source as { kind?: unknown; x?: unknown; source?: unknown; target?: unknown };\n const isModelObject =\n typeof owner.kind === 'string' &&\n owner.kind.includes('.') &&\n (typeof owner.x === 'number' ||\n (typeof owner.source === 'string' && typeof owner.target === 'string'));\n return !isModelObject;\n}\n\nfunction resolveCustomProperties(source: PropertySource): CustomProperties | undefined {\n if (source === undefined) return undefined;\n if (isCustomPropertiesRecord(source)) return source;\n return source.customProperties;\n}\n\nfunction isRequired(options: PropertyOptions<unknown>): boolean {\n return options.optional !== true && options.default === undefined;\n}\n\nfunction emptyMeansAbsent(\n type: PropertyType<unknown>['type'],\n optional: boolean | undefined,\n): boolean {\n return type !== 'string' && optional === true;\n}\n\nfunction readShape<S extends PropertyShape>(\n shape: S,\n source: PropertySource,\n): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n const custom = resolveCustomProperties(source);\n const values: Partial<InferProperties<S>> = {};\n const issues: PropertyIssue[] = [];\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const opts = field.options;\n const hasKey = custom !== undefined && Object.prototype.hasOwnProperty.call(custom, key);\n const raw = hasKey ? custom[key] : undefined;\n\n if (raw === undefined) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n } else if (isRequired(opts)) {\n issues.push({ key, message: 'is required' });\n }\n continue;\n }\n\n if (raw === '' && field.type !== 'string') {\n if (emptyMeansAbsent(field.type, opts.optional)) {\n if (opts.default !== undefined) {\n (values as Record<string, unknown>)[key] = opts.default;\n }\n continue;\n }\n issues.push({\n key,\n message:\n field.type === 'boolean'\n ? 'must be true or false'\n : field.type === 'enum'\n ? `must be one of: ${field.values?.join(', ') ?? ''}`\n : field.type === 'reference'\n ? 'must be an element or link id'\n : 'must be a finite number',\n });\n continue;\n }\n\n const parsed = field.parse(raw);\n if (!parsed.ok) {\n issues.push({ key, message: parsed.error });\n continue;\n }\n (values as Record<string, unknown>)[key] = parsed.value;\n }\n\n return { values, issues };\n}\n\n/**\n * A patched value as a string, written back as read: the current string is kept when it already\n * holds the value (`.2` stays `.2`), and otherwise the type writes the value in its form.\n */\nfunction writeField(field: PropertyType<unknown>, value: unknown, current: string): string {\n const parsed = field.parse(current);\n if (parsed.ok && Object.is(parsed.value, value)) return current;\n return field.serialize(value as never, current);\n}\n\nexport function defineProperties<\n const S extends PropertyShape,\n const Kind extends string = ElementKind | LinkKind,\n>(\n kind: Kind,\n shape: S,\n options?: { validate?: (values: Partial<InferProperties<S>>) => PropertyIssue[] },\n): PropertySchema<S, Kind> {\n const crossValidate = options?.validate;\n\n return {\n kind,\n shape,\n read(source: PropertySource): { values: Partial<InferProperties<S>>; issues: PropertyIssue[] } {\n return readShape(shape, source);\n },\n validate(source: PropertySource): PropertyIssue[] {\n const { values, issues } = readShape(shape, source);\n const cross = crossValidate ? crossValidate(values) : [];\n return [...issues, ...cross];\n },\n write(\n current: CustomProperties | undefined,\n patch: { [K in keyof S]?: InferProperties<S>[K] | undefined },\n ): CustomProperties {\n const result: Record<string, string> = {};\n const seen = new Set<string>();\n\n if (current) {\n for (const [key, value] of Object.entries(current)) {\n if (Object.prototype.hasOwnProperty.call(patch, key)) {\n const patched = patch[key as keyof S];\n if (patched === undefined) {\n continue;\n }\n const field = shape[key];\n if (field) {\n result[key] = writeField(field, patched, value);\n }\n } else {\n result[key] = value;\n }\n seen.add(key);\n }\n }\n\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n if (seen.has(key)) continue;\n if (!Object.prototype.hasOwnProperty.call(patch, key)) continue;\n const patched = patch[key];\n if (patched === undefined) continue;\n const field = shape[key];\n if (field) {\n result[key] = field.serialize(patched as never);\n }\n }\n\n return result;\n },\n defaults(): CustomProperties {\n const result: Record<string, string> = {};\n for (const key of Object.keys(shape) as (keyof S & string)[]) {\n const field = shape[key];\n if (!field) continue;\n const def = field.options.default;\n if (def !== undefined) {\n result[key] = field.serialize(def as never);\n }\n }\n return result;\n },\n };\n}\n\nexport function validateModelProperties<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n schemas: readonly PropertySchema<PropertyShape, string>[],\n): ModelPropertyIssue[] {\n const byKind = new Map<string, PropertySchema<PropertyShape, string>[]>();\n for (const schema of schemas) {\n const list = byKind.get(schema.kind) ?? [];\n list.push(schema);\n byKind.set(schema.kind, list);\n }\n\n const issues: ModelPropertyIssue[] = [];\n\n const check = (owner: PropertyOwner & { readonly id: string }): void => {\n const kindSchemas = byKind.get(owner.kind);\n if (!kindSchemas) return;\n for (const schema of kindSchemas) {\n for (const issue of schema.validate(owner)) {\n issues.push({ ...issue, id: owner.id });\n }\n for (const issue of referenceIssues(model, schema.shape, owner.customProperties)) {\n issues.push({ ...issue, id: owner.id });\n }\n }\n };\n for (const element of model.elements.values()) check(element);\n for (const link of model.links.values()) check(link);\n\n return issues;\n}\n\n/** References (`prop.reference`) to ids that aren't in the model, or to the wrong kind. */\nfunction referenceIssues<EK extends string, LK extends string>(\n model: IstarModel<EK, LK>,\n shape: PropertyShape,\n custom: CustomProperties | undefined,\n): PropertyIssue[] {\n const issues: PropertyIssue[] = [];\n for (const [key, field] of Object.entries(shape)) {\n if (field.type !== 'reference') continue;\n const id = custom?.[key];\n if (id === undefined || id === '') continue;\n const target = model.elements.get(id) ?? model.links.get(id);\n if (!target) {\n issues.push({ key, message: `refers to \"${id}\", which is not in the model` });\n } else if (field.kinds && !field.kinds.includes(target.kind)) {\n issues.push({ key, message: `must refer to a ${field.kinds.join(' or ')}` });\n }\n }\n return issues;\n}\n","/**\n * The Goal Model Diagnostics Protocol: findings about a model's elements and links, published by\n * any analyser (a language server, a validator, a simulation…) and anchored by element id rather\n * than by text position. Data only: diagnostics are never part of the model and are never\n * written to disk.\n *\n * See goal-controller issue #24 (option D). Producers publish per source; consumers see the\n * union of every source, deduplicated by `(elementId, key, message)`.\n */\n\nexport type DiagnosticSeverity = 'error' | 'warning' | 'info' | 'hint';\n\n/** Most severe first. */\nexport const DIAGNOSTIC_SEVERITIES: readonly DiagnosticSeverity[] = [\n 'error',\n 'warning',\n 'info',\n 'hint',\n];\n\n/** A zero-based position in the producer's document (as in LSP). */\nexport interface DiagnosticPosition {\n readonly line: number;\n readonly character: number;\n}\n\nexport interface DiagnosticRange {\n readonly start: DiagnosticPosition;\n readonly end: DiagnosticPosition;\n}\n\nexport interface GoalDiagnostic {\n /** Id of the element or link the diagnostic is about. */\n readonly elementId: string;\n /** The custom property it is about; absent for the element as a whole. */\n readonly key?: string;\n readonly severity: DiagnosticSeverity;\n readonly message: string;\n /** Who published it (e.g. `mutrose`, `goal-language`). */\n readonly source?: string;\n /** Where it was found in the producer's document, if it has one. */\n readonly range?: DiagnosticRange;\n readonly code?: string;\n /** Producer data, passed through untouched. */\n readonly data?: unknown;\n}\n\nconst RANK: Readonly<Record<DiagnosticSeverity, number>> = {\n error: 0,\n warning: 1,\n info: 2,\n hint: 3,\n};\n\n/** Negative when `a` is more severe than `b`. */\nexport function compareSeverity(a: DiagnosticSeverity, b: DiagnosticSeverity): number {\n return RANK[a] - RANK[b];\n}\n\n/** The most severe severity in a list (what a badge shows), or `undefined` if it is empty. */\nexport function worstDiagnosticSeverity(\n diagnostics: readonly { readonly severity: DiagnosticSeverity }[] | undefined,\n): DiagnosticSeverity | undefined {\n let worst: DiagnosticSeverity | undefined;\n for (const d of diagnostics ?? []) {\n if (worst === undefined || RANK[d.severity] < RANK[worst]) worst = d.severity;\n if (worst === 'error') break;\n }\n return worst;\n}\n\nfunction identity(d: GoalDiagnostic): string {\n return `${d.elementId}\\u0000${d.key ?? ''}\\u0000${d.message}`;\n}\n\n/**\n * The union of several lists, in order, without duplicates: diagnostics with the same\n * `(elementId, key, message)` count once, keeping the first one's position and the most severe\n * severity among them.\n */\nexport function mergeDiagnostics(\n lists: Iterable<readonly GoalDiagnostic[] | undefined>,\n): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n const index = new Map<string, number>();\n for (const list of lists) {\n for (const d of list ?? []) {\n const id = identity(d);\n const at = index.get(id);\n if (at === undefined) {\n index.set(id, result.length);\n result.push(d);\n } else if (RANK[d.severity] < RANK[result[at]!.severity]) {\n result[at] = { ...result[at]!, severity: d.severity };\n }\n }\n }\n return result;\n}\n\n/** Diagnostics by element (or link) id, each list in the input order. */\nexport function groupDiagnostics(\n diagnostics: readonly GoalDiagnostic[] | undefined,\n): ReadonlyMap<string, readonly GoalDiagnostic[]> {\n const map = new Map<string, GoalDiagnostic[]>();\n for (const d of diagnostics ?? []) {\n const list = map.get(d.elementId);\n if (list) list.push(d);\n else map.set(d.elementId, [d]);\n }\n return map;\n}\n\n/**\n * Holds the diagnostics of several sources. Each `publish` replaces that source's set, so a\n * producer re-publishes everything it currently reports, as an LSP server does.\n */\nexport interface DiagnosticsStore {\n /**\n * Replaces `source`'s diagnostics (an empty list clears them). Entries without a `source` get\n * this one.\n */\n publish(source: string, diagnostics: readonly GoalDiagnostic[]): void;\n /** Removes one source's diagnostics, or every source's. */\n clear(source?: string): void;\n /** Sources with diagnostics, in the order they first published. */\n sources(): readonly string[];\n /** One source's diagnostics. */\n get(source: string): readonly GoalDiagnostic[];\n /**\n * Every source's diagnostics, merged (see `mergeDiagnostics`). The same array until the next\n * change, so it can back `useSyncExternalStore`.\n */\n getAll(): readonly GoalDiagnostic[];\n subscribe(listener: () => void): () => void;\n}\n\nconst NONE: readonly GoalDiagnostic[] = [];\n\nexport function createDiagnosticsStore(): DiagnosticsStore {\n const bySource = new Map<string, readonly GoalDiagnostic[]>();\n const listeners = new Set<() => void>();\n let merged: readonly GoalDiagnostic[] = NONE;\n const changed = (): void => {\n merged = bySource.size === 0 ? NONE : mergeDiagnostics(bySource.values());\n for (const listener of listeners) listener();\n };\n return {\n publish(source, diagnostics) {\n if (diagnostics.length === 0) {\n if (bySource.delete(source)) changed();\n return;\n }\n bySource.set(\n source,\n diagnostics.map((d) => (d.source === undefined ? { ...d, source } : d)),\n );\n changed();\n },\n clear(source) {\n if (source === undefined) {\n if (bySource.size === 0) return;\n bySource.clear();\n } else if (!bySource.delete(source)) {\n return;\n }\n changed();\n },\n sources: () => [...bySource.keys()],\n get: (source) => bySource.get(source) ?? NONE,\n getAll: () => merged,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Adapters\n\n/**\n * The parts of an LSP `Diagnostic` the adapter reads (structurally typed, so no LSP library is\n * needed). The element is taken from `data.elementId`, or MutRoSe's `data.nodeId`; the property\n * from `data.key`.\n */\nexport interface LspDiagnosticLike {\n readonly range?: DiagnosticRange;\n /** LSP numbering: 1 error, 2 warning, 3 information, 4 hint. */\n readonly severity?: number;\n readonly message: string | { readonly value: string };\n readonly source?: string;\n readonly code?: string | number | { readonly value: string | number };\n readonly data?: unknown;\n}\n\nexport interface FromLspOptions<D extends LspDiagnosticLike = LspDiagnosticLike> {\n /**\n * The element of a diagnostic whose `data` names none, e.g. by looking its range up in the\n * document. Return `undefined` to drop it.\n */\n readonly elementIdFor?: (diagnostic: D) => string | undefined;\n /**\n * `'vscode'` for `vscode.Diagnostic` objects, whose severity counts from 0 (error) to 3\n * (hint). Default `'lsp'`, the protocol's 1 to 4.\n */\n readonly severityNumbering?: 'lsp' | 'vscode';\n}\n\nconst LSP_SEVERITIES: readonly DiagnosticSeverity[] = ['error', 'warning', 'info', 'hint'];\n\nfunction anchorOf(data: unknown): { elementId?: string; key?: string } {\n if (typeof data !== 'object' || data === null) return {};\n const record = data as Record<string, unknown>;\n const elementId =\n typeof record.elementId === 'string'\n ? record.elementId\n : typeof record.nodeId === 'string'\n ? record.nodeId\n : undefined;\n return {\n ...(elementId ? { elementId } : {}),\n ...(typeof record.key === 'string' ? { key: record.key } : {}),\n };\n}\n\nfunction convertLsp<D extends LspDiagnosticLike>(\n d: D,\n options: FromLspOptions<D>,\n): GoalDiagnostic | undefined {\n const anchor = anchorOf(d.data);\n const elementId = anchor.elementId ?? options.elementIdFor?.(d);\n if (!elementId) return undefined;\n const base = options.severityNumbering === 'vscode' ? 0 : 1;\n // LSP leaves a missing severity to the client; VS Code shows it as an error.\n const severity =\n d.severity === undefined ? 'error' : (LSP_SEVERITIES[d.severity - base] ?? 'error');\n const code = typeof d.code === 'object' ? d.code.value : d.code;\n return {\n elementId,\n ...(anchor.key !== undefined ? { key: anchor.key } : {}),\n severity,\n message: typeof d.message === 'string' ? d.message : d.message.value,\n ...(d.source !== undefined ? { source: d.source } : {}),\n ...(d.range ? { range: d.range } : {}),\n ...(code !== undefined ? { code: String(code) } : {}),\n ...(d.data !== undefined ? { data: d.data } : {}),\n };\n}\n\n/**\n * One LSP diagnostic anchored by `data.elementId` (or `data.nodeId`), or `undefined` when it\n * names no element. For range-anchored diagnostics use `fromLspDiagnostics` with `elementIdFor`.\n */\nexport function fromLspDiagnostic(diagnostic: LspDiagnosticLike): GoalDiagnostic | undefined {\n return convertLsp(diagnostic, {});\n}\n\n/** LSP diagnostics as goal diagnostics; those that can't be anchored to an element are dropped. */\nexport function fromLspDiagnostics<D extends LspDiagnosticLike>(\n diagnostics: readonly D[],\n options: FromLspOptions<D> = {},\n): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n for (const d of diagnostics) {\n const converted = convertLsp(d, options);\n if (converted) result.push(converted);\n }\n return result;\n}\n\n/**\n * The shape MutRoSe's VS Code extension posts to its webview: `{ nodeId, severity, message }`\n * (plus `range` and `source`). `nodeId` is missing when no node could be found.\n */\nexport interface NodeIdDiagnostic {\n readonly nodeId?: string;\n readonly key?: string;\n readonly severity: DiagnosticSeverity | string;\n readonly message: string;\n readonly source?: string;\n readonly range?: DiagnosticRange;\n readonly code?: string;\n}\n\n/** One `{ nodeId, severity, message }` diagnostic, or `undefined` without a `nodeId`. */\nexport function fromNodeIdDiagnostic(diagnostic: NodeIdDiagnostic): GoalDiagnostic | undefined {\n const { nodeId, severity, ...rest } = diagnostic;\n if (!nodeId) return undefined;\n return {\n ...rest,\n elementId: nodeId,\n severity: Object.hasOwn(RANK, severity) ? (severity as DiagnosticSeverity) : 'info',\n };\n}\n\n/**\n * `{ nodeId, severity, message }` diagnostics (MutRoSe) as goal diagnostics, dropping those\n * without a node: `store.publish('mutrose', fromNodeIdDiagnostics(message.diagnostics))`.\n */\nexport function fromNodeIdDiagnostics(diagnostics: readonly NodeIdDiagnostic[]): GoalDiagnostic[] {\n const result: GoalDiagnostic[] = [];\n for (const d of diagnostics) {\n const converted = fromNodeIdDiagnostic(d);\n if (converted) result.push(converted);\n }\n return result;\n}\n","/**\n * The data part of each kind's palette entry: label, grouping, ordering, and the presets a\n * toolbar entry creates with (a link's `value`, a dependency's `dependum`, an element's\n * `properties`). React-free so a host can answer \"what can I add here\" (GLSP's\n * `RequestContextActions`) without the react package. Icons, titles and components are\n * presentation and stay in `packages/react/src/registry`, which derives its default entries\n * from `DEFAULT_PALETTE`.\n */\nimport {\n CONTRIBUTION_LABELS,\n ELEMENT_KINDS,\n LINK_KINDS,\n NODE_KINDS,\n isActorKind,\n shortKindName,\n} from './metamodel';\nimport type { ElementKind, LinkKind, NodeKind } from './metamodel';\nimport type { CustomProperties } from './model';\n\nexport interface PaletteEntryDescription {\n readonly label: string;\n /** Lower comes first. */\n readonly order?: number;\n /** Entries sharing a group collapse into one dropdown button (e.g. Actor / Agent / Role). */\n readonly group?: string;\n /** Sections are separated by a divider. Default palette: \"actors\" and \"elements\". */\n readonly section?: string;\n}\n\nexport interface ElementToolEntryDescription extends PaletteEntryDescription {\n /** customProperties preset on the element this entry creates, over `defaultProperties`. */\n readonly properties?: CustomProperties;\n}\n\nexport interface LinkToolEntryDescription<\n DK extends string = NodeKind,\n> extends PaletteEntryDescription {\n /** Contribution value to set on the new link. */\n readonly value?: string;\n /** For dependencies: the kind of dependum to create. */\n readonly dependum?: DK;\n}\n\nexport interface PaletteGroupDescription {\n readonly label: string;\n}\n\n/**\n * Per-kind palette data. `elements`/`links` entries are `false` for kinds hidden from the\n * palette, one entry for most element kinds, or several for a kind with more than one toolbar\n * button (a link's values, a dependency's dependum kinds).\n */\nexport interface PaletteDescription<EK extends string = ElementKind, LK extends string = LinkKind> {\n readonly elements: Readonly<\n Record<EK, PaletteEntryDescription | readonly ElementToolEntryDescription[] | false>\n >;\n readonly links: Readonly<Record<LK, readonly LinkToolEntryDescription[] | false>>;\n /** Labels for palette groups, keyed by `PaletteEntryDescription.group`. */\n readonly groups: Readonly<Record<string, PaletteGroupDescription>>;\n}\n\n/** A palette description of any dialect, for code that handles every kind generically. */\nexport type AnyPaletteDescription = PaletteDescription<string, string>;\n\nfunction defaultElementEntry(kind: ElementKind, index: number): PaletteEntryDescription {\n const actor = isActorKind(kind);\n return {\n label: shortKindName(kind),\n // piStar order: Actor… | Actor links… | Dependency… ‖ Goal Quality Resource Task | links\n order: actor ? index : 30 + index,\n section: actor ? 'actors' : 'elements',\n ...(actor ? { group: 'actors' } : {}),\n };\n}\n\nconst CONTRIBUTION_ENTRY_LABELS: Readonly<Record<string, string>> = {\n make: 'Make (++)',\n help: 'Help (+)',\n hurt: 'Hurt (-)',\n break: 'Break (--)',\n};\n\nconst LINK_ENTRIES: Readonly<Record<LinkKind, readonly LinkToolEntryDescription[]>> = {\n 'istar.IsALink': [{ label: 'Is A', order: 10, group: 'actor-links', section: 'actors' }],\n 'istar.ParticipatesInLink': [\n { label: 'Participates-In', order: 11, group: 'actor-links', section: 'actors' },\n ],\n 'istar.DependencyLink': NODE_KINDS.map((dependum, i) => ({\n label: `${shortKindName(dependum)} dependency`,\n dependum,\n order: 20 + i,\n group: 'dependencies',\n section: 'actors',\n })),\n 'istar.AndRefinementLink': [{ label: 'And', order: 40, section: 'elements' }],\n 'istar.OrRefinementLink': [{ label: 'Or', order: 41, section: 'elements' }],\n 'istar.NeededByLink': [{ label: 'Needed-By', order: 42, section: 'elements' }],\n 'istar.QualificationLink': [{ label: 'Qualification', order: 43, section: 'elements' }],\n 'istar.ContributionLink': CONTRIBUTION_LABELS.map((value, i) => ({\n label: CONTRIBUTION_ENTRY_LABELS[value]!,\n value,\n order: 50 + i,\n group: 'contributions',\n section: 'elements',\n })),\n};\n\n/** piStar's dropdown buttons. */\nconst DEFAULT_PALETTE_GROUPS: Readonly<Record<string, PaletteGroupDescription>> = {\n actors: { label: 'Actor' },\n 'actor-links': { label: 'Actor links' },\n dependencies: { label: 'Dependency' },\n contributions: { label: 'Contribution' },\n};\n\nfunction buildDefaultPalette(): PaletteDescription {\n const elements = {} as Record<ElementKind, PaletteEntryDescription>;\n ELEMENT_KINDS.forEach((kind, i) => {\n elements[kind] = defaultElementEntry(kind, i);\n });\n const links = {} as Record<LinkKind, readonly LinkToolEntryDescription[]>;\n for (const kind of LINK_KINDS) links[kind] = LINK_ENTRIES[kind];\n return { elements, links, groups: DEFAULT_PALETTE_GROUPS };\n}\n\n/** The palette data of iStar 2.0, as piStar's toolbar presents it. */\nexport const DEFAULT_PALETTE: PaletteDescription = buildDefaultPalette();\n"],"mappings":"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"}