@graphty/graph-io 0.3.36 → 0.3.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{choose-494CpuXQ.js → choose-CsO24U-5.js} +2 -2
- package/dist/chunks/{choose-494CpuXQ.js.map → choose-CsO24U-5.js.map} +1 -1
- package/dist/chunks/{constants-BBK4rsQZ.js → constants-BPRiVyBu.js} +2 -2
- package/dist/chunks/{constants-BBK4rsQZ.js.map → constants-BPRiVyBu.js.map} +1 -1
- package/dist/chunks/{escape-wVIEtLv6.js → escape-BRcyzD77.js} +4 -4
- package/dist/chunks/{escape-wVIEtLv6.js.map → escape-BRcyzD77.js.map} +1 -1
- package/dist/chunks/{export-Cbt4h_0n.js → export-CTUlibzr.js} +4 -4
- package/dist/chunks/export-CTUlibzr.js.map +1 -0
- package/dist/chunks/{exporter-CkPnJCXU.js → exporter-2UNIxzcu.js} +3 -3
- package/dist/chunks/{exporter-CkPnJCXU.js.map → exporter-2UNIxzcu.js.map} +1 -1
- package/dist/chunks/{exporter-LZTIAzkS.js → exporter-B_YFZ4ix.js} +8 -8
- package/dist/chunks/exporter-B_YFZ4ix.js.map +1 -0
- package/dist/chunks/{exporter-CqnmKk-f.js → exporter-Bn4jdYfd.js} +5 -5
- package/dist/chunks/{exporter-CqnmKk-f.js.map → exporter-Bn4jdYfd.js.map} +1 -1
- package/dist/chunks/{exporter-DMxRy-0l.js → exporter-flsHFoER.js} +4 -4
- package/dist/chunks/{exporter-DMxRy-0l.js.map → exporter-flsHFoER.js.map} +1 -1
- package/dist/chunks/{importer-C1VMuEBQ.js → importer-BD3mi2QH.js} +10 -10
- package/dist/chunks/importer-BD3mi2QH.js.map +1 -0
- package/dist/chunks/{importer-DvPvd4Yy.js → importer-Bgb9sgZZ.js} +9 -9
- package/dist/chunks/importer-Bgb9sgZZ.js.map +1 -0
- package/dist/chunks/{importer-CSmH218L.js → importer-CEuUmyPe.js} +10 -10
- package/dist/chunks/importer-CEuUmyPe.js.map +1 -0
- package/dist/chunks/{importer-DMgcD1wI.js → importer-DqMtyYLX.js} +11 -11
- package/dist/chunks/importer-DqMtyYLX.js.map +1 -0
- package/dist/chunks/{importer-BTSvNJUB.js → importer-Dwqepe_B.js} +3 -3
- package/dist/chunks/{importer-BTSvNJUB.js.map → importer-Dwqepe_B.js.map} +1 -1
- package/dist/chunks/{importer-BTbjwN10.js → importer-oIUx9u_g.js} +9 -9
- package/dist/chunks/importer-oIUx9u_g.js.map +1 -0
- package/dist/chunks/{importer-DtKPzhVp.js → importer-yWUPR_nU.js} +13 -13
- package/dist/chunks/importer-yWUPR_nU.js.map +1 -0
- package/dist/chunks/{json-elements-CxJF-Szz.js → json-elements-AkglPS3m.js} +4 -4
- package/dist/chunks/json-elements-AkglPS3m.js.map +1 -0
- package/dist/chunks/{ontology-export-p1PsPenq.js → ontology-export-DDoG3egY.js} +2 -2
- package/dist/chunks/{ontology-export-p1PsPenq.js.map → ontology-export-DDoG3egY.js.map} +1 -1
- package/dist/chunks/{records-BrfHycmg.js → records-ChmWZGuz.js} +2 -2
- package/dist/chunks/{records-BrfHycmg.js.map → records-ChmWZGuz.js.map} +1 -1
- package/dist/chunks/{text-BD-TzLNm.js → text-Btw3sBe_.js} +2 -2
- package/dist/chunks/{text-BD-TzLNm.js.map → text-Btw3sBe_.js.map} +1 -1
- package/dist/csv.js +4 -4
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +1 -1
- package/dist/gexf.js +30 -30
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +8 -8
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +28 -28
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +2 -2
- package/dist/json.js +1 -1
- package/dist/neo4j.js +6 -6
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/attributes.d.ts +1 -2
- package/dist/src/common/attributes.d.ts.map +1 -1
- package/dist/src/common/attributes.js +2 -2
- package/dist/src/common/attributes.js.map +1 -1
- package/dist/src/common/direction.d.ts +1 -2
- package/dist/src/common/direction.d.ts.map +1 -1
- package/dist/src/common/direction.js +2 -2
- package/dist/src/common/direction.js.map +1 -1
- package/dist/src/common/escape.js +1 -1
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.js +1 -1
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/ids.d.ts +1 -2
- package/dist/src/common/ids.d.ts.map +1 -1
- package/dist/src/common/ids.js +1 -2
- package/dist/src/common/ids.js.map +1 -1
- package/dist/src/common/input.d.ts +1 -2
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +2 -2
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.js +1 -1
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/options.d.ts +1 -2
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +1 -1
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/common/xml.js +1 -1
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/formats/cx/importer.js +6 -6
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cys/importer.js +3 -3
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/tables.js +1 -1
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.js +3 -3
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.js +1 -1
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +24 -27
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +1 -2
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +5 -5
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gml/exporter.js +4 -4
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/syntax.js +1 -1
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/exporter.js +3 -3
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.js +2 -2
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/tree.js +2 -2
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/json/exporter.js +1 -1
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.js +1 -1
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +3 -3
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.js +4 -4
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/document.js +6 -6
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.js +2 -2
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +1 -1
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.js +1 -1
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/registry.js +2 -2
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.js +1 -1
- package/dist/src/sniff.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/package.json +2 -2
- package/src/common/attributes.ts +1 -2
- package/src/common/direction.ts +2 -2
- package/src/common/escape.ts +1 -1
- package/src/common/export.ts +1 -1
- package/src/common/ids.ts +1 -3
- package/src/common/input.ts +2 -2
- package/src/common/json-elements.ts +1 -1
- package/src/common/options.ts +1 -1
- package/src/common/xml.ts +1 -1
- package/src/formats/cx/importer.ts +6 -6
- package/src/formats/cys/importer.ts +3 -3
- package/src/formats/cys/tables.ts +1 -1
- package/src/formats/dot/exporter.ts +3 -3
- package/src/formats/dot/importer.ts +1 -1
- package/src/formats/gexf/exporter.ts +24 -28
- package/src/formats/gexf/importer.ts +5 -5
- package/src/formats/gml/exporter.ts +4 -4
- package/src/formats/gml/syntax.ts +1 -1
- package/src/formats/graphml/exporter.ts +3 -3
- package/src/formats/graphml/importer.ts +2 -2
- package/src/formats/graphml/tree.ts +2 -2
- package/src/formats/json/exporter.ts +1 -1
- package/src/formats/json/importer.ts +1 -1
- package/src/formats/neo4j/exporter.ts +3 -3
- package/src/formats/pajek/exporter.ts +4 -4
- package/src/formats/xgmml/document.ts +6 -6
- package/src/formats/xgmml/emit.ts +2 -2
- package/src/formats/xgmml/exporter.ts +1 -1
- package/src/formats/xgmml/importer.ts +1 -1
- package/src/registry.ts +2 -2
- package/src/sniff.ts +1 -1
- package/dist/chunks/export-Cbt4h_0n.js.map +0 -1
- package/dist/chunks/exporter-LZTIAzkS.js.map +0 -1
- package/dist/chunks/importer-BTbjwN10.js.map +0 -1
- package/dist/chunks/importer-C1VMuEBQ.js.map +0 -1
- package/dist/chunks/importer-CSmH218L.js.map +0 -1
- package/dist/chunks/importer-DMgcD1wI.js.map +0 -1
- package/dist/chunks/importer-DtKPzhVp.js.map +0 -1
- package/dist/chunks/importer-DvPvd4Yy.js.map +0 -1
- package/dist/chunks/json-elements-CxJF-Szz.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exporter-LZTIAzkS.js","sources":["../../src/formats/json/dialect.ts","../../src/sniff.ts","../../src/formats/json/importer.ts","../../src/formats/json/obographs.ts","../../src/formats/json/obographs-export.ts","../../src/formats/json/exporter.ts"],"sourcesContent":["/**\n * What the JSON importer and exporter share (design sections 8.2 and 8.5): the dialect names, the\n * reserved `meta.extra.json` shape record the importer writes and the exporter reads back, the\n * per-dialect capability tables, the fixed key sets of each dialect and the small JSON value\n * helpers both sides use.\n *\n * Dialects: NetworkX node-link (`nodes` + `links` / `edges`, graph-level `directed` / `multigraph`\n * / `graph`), the d3 lineage of the same shape (`links`, `name` ids, integer index endpoints),\n * JSON Graph Format v2 (`graph.nodes` keyed by id, per-edge `directed`, hyperedges), Cytoscape.js\n * elements (`data.id` / `data.source` / `data.target`, `position`, `classes`, `data.parent`),\n * graphology serialization (`key` / `attributes`, `undirected` edges, `options.type` / `multi`) and\n * vis.js (`from` / `to`); read only: NetworkX adjacency_data (`nodes` + `adjacency`) and tree_data\n * (nested `id` / `children`).\n */\n\nimport { type GraphMeta, type GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { capabilities } from \"../../common/export.js\";\nimport { trimTrailingZeros } from \"../../common/text.js\";\nimport { type ExportCapabilities } from \"../../types.js\";\n\n/**\n * The JSON dialects the plugin reads and writes.\n * @category Built-in formats\n */\nexport type JsonDialect = \"node-link\" | \"d3\" | \"jgf\" | \"cytoscape\" | \"graphology\" | \"vis\" | \"obographs\";\n\n/**\n * Every dialect name, for option checking and messages.\n * @category Built-in formats\n */\nexport const JSON_DIALECTS: readonly JsonDialect[] = Object.freeze([\n \"node-link\",\n \"d3\",\n \"jgf\",\n \"cytoscape\",\n \"graphology\",\n \"vis\",\n \"obographs\",\n]);\n\n/**\n * The dialects the importer reads: every JsonDialect plus two it only reads, NetworkX\n * adjacency_data (`nodes` plus one neighbor list per node under `adjacency`) and tree_data (a\n * nested `id` / `children` record). The exporter writes neither.\n * @category Built-in formats\n */\nexport type JsonImportDialect = JsonDialect | \"adjacency\" | \"tree\";\n\n/**\n * Every dialect the importer reads, for option checking and messages.\n * @category Plugin helpers\n */\nexport const JSON_IMPORT_DIALECTS: readonly JsonImportDialect[] = Object.freeze([\n ...JSON_DIALECTS,\n \"adjacency\",\n \"tree\",\n]);\n\n/**\n * The key under `meta.extra` that holds the shape record (design section 8.5).\n * @category Plugin helpers\n */\nexport const META_KEY = \"json\";\n\n/**\n * The shape information the importer records under `meta.extra.json` so the exporter can write the\n * same file back; `jsonShapeOf(snapshot)` reads it. Every field is optional because a graph may\n * come from another format.\n * @category Built-in formats\n */\nexport interface JsonShapeMeta {\n /** The dialect the file was read as. */\n readonly dialect?: JsonDialect | undefined;\n /** node-link / d3: the key the edge array was under (\"links\" or \"edges\"). */\n readonly edgesKey?: string | undefined;\n /** node-link / d3: the key holding the node id (\"id\", \"name\", ...); null when nodes were positional. */\n readonly nodeIdKey?: string | null | undefined;\n /** node-link / d3: whether edge endpoints were array positions rather than ids. */\n readonly indexLinks?: boolean | undefined;\n /** node-link / d3 / vis: the endpoint keys the file used. */\n readonly sourceKey?: string | undefined;\n /** node-link / d3 / vis: the endpoint keys the file used. */\n readonly targetKey?: string | undefined;\n /** jgf: the graph `id`. */\n readonly id?: string | undefined;\n /** jgf: the graph `type`. */\n readonly type?: string | undefined;\n /** graphology: `options.allowSelfLoops` as declared. */\n readonly allowSelfLoops?: boolean | undefined;\n /** cytoscape: every top-level key besides `elements` and `data` (style, zoom, pan, ...), verbatim. */\n readonly cytoscape?: Readonly<Record<string, unknown>> | undefined;\n}\n\n/**\n * What a JSON import recorded about the document's shape: the dialect it was read as\n * (`jsonShapeOf(snapshot)?.dialect`), the keys it used, and so on. A JSON export with default\n * options writes the same shape back.\n * @param snapshot - a graph read from a JSON document\n * @returns the shape, or null for a graph that was not read from JSON\n * @category Built-in formats\n */\nexport function jsonShapeOf(snapshot: GraphSnapshot): JsonShapeMeta | null {\n const shape = snapshot.meta.extra[META_KEY];\n return isJsonObject(shape) ? shape : null;\n}\n\n/**\n * Whether a value is a plain JSON object (not null, not an array).\n * @param value - any value\n * @returns true for an object that is not an array\n * @category Plugin helpers\n */\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Whether a record has an own property; JSON.parse output is checked with hasOwnProperty so a key\n * named \"constructor\" or \"__proto__\" is never read from the prototype.\n * @param record - the record\n * @param key - the key\n * @returns true when the key is an own property\n * @category Plugin helpers\n */\nexport function hasKey(record: Readonly<Record<string, unknown>>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\n/**\n * Whether a text names a dialect.\n * @param value - any value\n * @returns true for one of JSON_DIALECTS\n * @category Plugin helpers\n */\nexport function isJsonDialect(value: unknown): value is JsonDialect {\n return typeof value === \"string\" && (JSON_DIALECTS as readonly string[]).includes(value);\n}\n\n/**\n * Whether a text names a dialect the importer reads.\n * @param value - any value\n * @returns true for one of JSON_IMPORT_DIALECTS\n * @category Plugin helpers\n */\nexport function isJsonImportDialect(value: unknown): value is JsonImportDialect {\n return typeof value === \"string\" && (JSON_IMPORT_DIALECTS as readonly string[]).includes(value);\n}\n\n/**\n * The dialect of a parsed JSON document, by the shape rules of design section 8.2 (Cytoscape:\n * `elements` or a top-level array of `{ data }` elements; OBO Graphs: `graphs[]` whose first graph\n * has an edge with `sub` (or `subj`) and `obj` or a `pred`, or a node with `lbl`, `meta` or an OWL\n * `type`; JGF: `graph.nodes` / `graph.edges` or any other `graphs[]`; graphology: `options.type` / `options.multi`, `key` nodes without `id`, edges with\n * `undirected` or an `attributes` record, and vis: edges with `from` / `to`, both only without\n * NetworkX's `links` / `directed` / `multigraph` / `graph` keys; d3: `links` without\n * `directed` / `multigraph` / `graph`; NetworkX adjacency_data: `nodes` and `adjacency` without\n * `links` / `edges`; NetworkX tree_data: `children` without `nodes` / `links` / `edges`; else\n * node-link). Pure: the importer wraps it with its issue\n * codes, the registry's sniff() uses it on a head that parses as a whole document.\n * @param root - the parsed document\n * @returns the dialect, or null when the document is not a graph document in any dialect\n * @category Plugin helpers\n */\nexport function sniffJsonDialect(root: unknown): JsonImportDialect | null {\n if (Array.isArray(root)) {\n const first = firstJsonObject(root);\n return root.length === 0 || (first !== null && isJsonObject(first.data)) ? \"cytoscape\" : null;\n }\n if (!isJsonObject(root)) {\n return null;\n }\n if (hasKey(root, \"elements\")) {\n return \"cytoscape\";\n }\n if (isJsonObject(root.graph) && (hasKey(root.graph, \"nodes\") || hasKey(root.graph, \"edges\"))) {\n return \"jgf\";\n }\n if (Array.isArray(root.graphs)) {\n // any graph decides: an ontology's first graph may be an empty stub before its imports\n return root.graphs.some((g: unknown) => isJsonObject(g) && isOboGraph(g)) ? \"obographs\" : \"jgf\";\n }\n if (!hasKey(root, \"edges\") && !hasKey(root, \"links\")) {\n if (hasKey(root, \"nodes\") && hasKey(root, \"adjacency\")) {\n return \"adjacency\";\n }\n if (!hasKey(root, \"nodes\")) {\n return hasKey(root, \"children\") ? \"tree\" : null;\n }\n }\n const firstNode = firstJsonObject(root.nodes);\n const firstEdge = firstJsonObject(hasKey(root, \"edges\") ? root.edges : root.links);\n if (isJsonObject(root.options) && (hasKey(root.options, \"type\") || hasKey(root.options, \"multi\"))) {\n return \"graphology\";\n }\n // NetworkX's own keys (links, directed, multigraph, graph) settle node-link: one attribute named\n // like a graphology or vis field (`attributes`, `undirected`, `key`, `from`) must not re-route it\n const networkx =\n hasKey(root, \"links\") || hasKey(root, \"directed\") || hasKey(root, \"multigraph\") || hasKey(root, \"graph\");\n if (!networkx && firstNode !== null && hasKey(firstNode, \"key\") && !hasKey(firstNode, \"id\")) {\n return \"graphology\";\n }\n if (!networkx && firstEdge !== null && !hasKey(firstEdge, \"from\")) {\n if (hasKey(firstEdge, \"undirected\") || isJsonObject(firstEdge.attributes)) {\n return \"graphology\";\n }\n }\n if (\n !networkx &&\n firstEdge !== null &&\n hasKey(firstEdge, \"from\") &&\n hasKey(firstEdge, \"to\") &&\n !hasKey(firstEdge, \"source\")\n ) {\n return \"vis\";\n }\n const bare = !hasKey(root, \"directed\") && !hasKey(root, \"multigraph\") && !hasKey(root, \"graph\");\n return bare && hasKey(root, \"links\") ? \"d3\" : \"node-link\";\n}\n\n/** The node types of OBO Graphs (the OWL entity kinds). */\nconst OBOGRAPHS_NODE_TYPES: ReadonlySet<unknown> = new Set([\"CLASS\", \"INDIVIDUAL\", \"PROPERTY\"]);\n\n/**\n * Whether a graph of a `graphs[]` document is an OBO Graphs graph rather than JGF: anywhere in its\n * nodes or edges, an edge with `sub` (or the outdated `subj`) and `obj`, or a `pred`, or a node\n * with `lbl`, `meta` or a `type` of CLASS / INDIVIDUAL / PROPERTY (design 1.6: looking only at the\n * first node and edge misses graphs with no edges and graphs whose first node has no `lbl`).\n * @param graph - the first graph, or null\n * @returns true for OBO Graphs\n */\nfunction isOboGraph(graph: Record<string, unknown> | null): boolean {\n if (graph === null) {\n return false;\n }\n const isEdge = (e: unknown): boolean =>\n isJsonObject(e) && ((hasKey(e, \"obj\") && (hasKey(e, \"sub\") || hasKey(e, \"subj\"))) || hasKey(e, \"pred\"));\n const isNode = (n: unknown): boolean =>\n isJsonObject(n) && (hasKey(n, \"lbl\") || hasKey(n, \"meta\") || OBOGRAPHS_NODE_TYPES.has(n.type));\n return (\n (Array.isArray(graph.edges) && graph.edges.some(isEdge)) ||\n (Array.isArray(graph.nodes) && graph.nodes.some(isNode))\n );\n}\n\n/**\n * The first object of an array, or null.\n * @param value - maybe an array\n * @returns the first element that is an object\n */\nfunction firstJsonObject(value: unknown): Record<string, unknown> | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const found: unknown = value.find((item) => isJsonObject(item));\n return isJsonObject(found) ? found : null;\n}\n\n/**\n * The shape record of a snapshot's metadata, or an empty record when the snapshot did not come\n * from the JSON importer.\n * @param meta - the snapshot's metadata\n * @returns the fields found under `meta.extra.json`, each only when it has the expected type\n * @category Plugin helpers\n */\nexport function shapeMetaOf(meta: GraphMeta): JsonShapeMeta {\n const raw: unknown = meta.extra[META_KEY];\n if (!isJsonObject(raw)) {\n return {};\n }\n const text = (key: string): string | undefined => (typeof raw[key] === \"string\" ? raw[key] : undefined);\n const flag = (key: string): boolean | undefined => (typeof raw[key] === \"boolean\" ? raw[key] : undefined);\n const { nodeIdKey } = raw;\n return {\n dialect: isJsonDialect(raw.dialect) ? raw.dialect : undefined,\n edgesKey: text(\"edgesKey\"),\n nodeIdKey: nodeIdKey === null || typeof nodeIdKey === \"string\" ? nodeIdKey : undefined,\n indexLinks: flag(\"indexLinks\"),\n sourceKey: text(\"sourceKey\"),\n targetKey: text(\"targetKey\"),\n id: text(\"id\"),\n type: text(\"type\"),\n allowSelfLoops: flag(\"allowSelfLoops\"),\n cytoscape: isJsonObject(raw.cytoscape) ? raw.cytoscape : undefined,\n };\n}\n\n/**\n * The direction a dialect assumes when the file declares none (design section 8.4, `defaultDirected`).\n * @category Plugin helpers\n */\nexport const DIALECT_DEFAULT_DIRECTED: Readonly<Record<JsonImportDialect, boolean>> = Object.freeze({\n \"node-link\": false,\n d3: false,\n jgf: true,\n cytoscape: true,\n graphology: true,\n vis: false,\n // networkx adjacency_data declares `directed`; tree_graph always builds a DiGraph\n adjacency: false,\n tree: true,\n // OBO Graphs edges point from the subject (child) to the object (parent)\n obographs: true,\n});\n\n/**\n * The dtypes a JSON dialect keeps as declared: JSON declares no types, so a value reads back as\n * what the importer's inference gives it (design section 5.1: integral numbers i32, other numbers\n * f64, booleans, strings). f32 values re-read as f64 differ from the f32 ones, u32 / u8 come back\n * i32, dict comes back string, a multi-component or list value comes back json.\n */\nconst JSON_DTYPES = Object.freeze([\"f64\", \"i32\", \"bool\", \"string\"] as const);\n\nconst COMMON = {\n multiEdges: true,\n selfLoops: true,\n idCharset: \"any\",\n dtypes: JSON_DTYPES,\n components: false,\n lists: false,\n json: true,\n defaults: false,\n options: false,\n temporal: \"none\",\n positions: false,\n viz: false,\n} as const;\n\nconst TABLES: Readonly<Record<JsonDialect, ExportCapabilities>> = Object.freeze({\n \"node-link\": capabilities({\n ...COMMON,\n mixedDirection: false,\n edgeIds: \"none\",\n hierarchy: false,\n graphAttributes: true,\n }),\n d3: capabilities({\n ...COMMON,\n mixedDirection: false,\n edgeIds: \"none\",\n hierarchy: false,\n graphAttributes: false,\n }),\n jgf: capabilities({\n ...COMMON,\n mixedDirection: true,\n edgeIds: \"optional\",\n hierarchy: false,\n graphAttributes: true,\n }),\n cytoscape: capabilities({\n ...COMMON,\n positions: true,\n mixedDirection: false,\n edgeIds: \"required\",\n hierarchy: true,\n graphAttributes: true,\n }),\n graphology: capabilities({\n ...COMMON,\n mixedDirection: true,\n edgeIds: \"optional\",\n hierarchy: false,\n graphAttributes: true,\n }),\n vis: capabilities({\n ...COMMON,\n mixedDirection: false,\n edgeIds: \"optional\",\n hierarchy: false,\n graphAttributes: false,\n }),\n // the OBO flat file's table: no column of the snapshot's own reads back as a column (the\n // vocabulary columns have their places; every other one becomes property values or edge meta)\n obographs: capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"any\",\n }),\n});\n\n/**\n * What one dialect can express: positions and visual columns are written as\n * plain attributes (an array for a multi-component column) and read back without their role,\n * except Cytoscape's `position` object; containment only as the Cytoscape `data.parent`; mixed\n * direction only where the dialect carries a per-edge flag (JGF `directed`, graphology\n * `undirected`); edge ids where the dialect has a slot (not node-link / d3); nothing temporal;\n * graph attributes everywhere but d3 (the bare shape) and vis.\n * @param dialect - the dialect\n * @returns its frozen capability table\n * @category Built-in formats\n */\nexport function dialectCapabilities(dialect: JsonDialect): ExportCapabilities {\n return TABLES[dialect];\n}\n\n/**\n * The Cytoscape element-level keys (everything else on an element lives under `data`).\n * @category Plugin helpers\n */\nexport const CYTOSCAPE_ELEMENT_KEYS: ReadonlySet<string> = new Set([\n \"selected\",\n \"selectable\",\n \"locked\",\n \"grabbable\",\n \"pannable\",\n \"removed\",\n \"scratch\",\n \"renderedPosition\",\n]);\n\n/**\n * The Cytoscape element keys the importer maps structurally rather than to columns.\n * @category Plugin helpers\n */\nexport const CYTOSCAPE_STRUCTURAL_KEYS: ReadonlySet<string> = new Set([\"data\", \"group\", \"position\", \"classes\"]);\n\n/**\n * The suffix the importer appends to a column name that collides with a structural column or a\n * reserved key of its dialect (design section 5.6 names collisions deterministically); the exporter\n * strips it when the value goes back to the level the suffix names.\n * @category Plugin helpers\n */\nexport const SUFFIX = Object.freeze({\n /** A Cytoscape `data` key or a JGF / graphology attribute that collides with a structural column. */\n data: \"#data\",\n /** An element-level key the dialect does not define (Cytoscape, JGF, graphology). */\n element: \"#element\",\n});\n\n/**\n * The default source keys of a node-link edge record, tried in order (as fromRecords does).\n * @category Plugin helpers\n */\nexport const NODE_LINK_SOURCE_KEYS: readonly string[] = Object.freeze([\"source\", \"src\", \"from\"]);\n\n/**\n * The default target keys of a node-link edge record, tried in order.\n * @category Plugin helpers\n */\nexport const NODE_LINK_TARGET_KEYS: readonly string[] = Object.freeze([\"target\", \"dst\", \"to\"]);\n\n/**\n * The name of the position column every JSON dialect writes / reads (design section 5.2).\n * @category Plugin helpers\n */\nexport const POSITION_COLUMN = \"position\";\n\n/**\n * The name of the Cytoscape classes column (a list of strings with role \"classes\").\n * @category Plugin helpers\n */\nexport const CLASSES_COLUMN = \"classes\";\n\n/**\n * The name of the Cytoscape parent column (u32 refersTo node, role \"parent\").\n * @category Plugin helpers\n */\nexport const PARENT_COLUMN = \"parent\";\n\n/**\n * An integer text beyond 2^53 in exponent form (`100000000000000000000` -> `1e+20`, the same\n * digits): the importer reads an integer literal that large as its exact digits (a string), so\n * a number must not be written as one.\n * @param text - the shortest decimal text of a finite number\n * @returns the text, or its exponent form for an integer literal of 16 or more digits\n * @category Plugin helpers\n */\nexport function exponentIfUnsafe(text: string): string {\n const match = /^(-?)(\\d{16,})$/.exec(text);\n if (match === null || Number.isSafeInteger(Number(text))) {\n return text;\n }\n const [, sign, digits] = match;\n const mantissa = trimTrailingZeros(digits);\n const fraction = mantissa.length > 1 ? `.${mantissa.slice(1)}` : \"\";\n return `${sign}${mantissa[0]}${fraction}e+${digits.length - 1}`;\n}\n","/**\n * Format detection (design sections 8.2 and 13.1: the registry's `sniff()`, the successor of\n * graphty-element's `format-detection.ts`): which of the registered importers a file is for, from\n * any combination of a filename (its extension), a MIME type and the first bytes of the content.\n *\n * Every importer declares `extensions`, `mimeTypes` and a `sniff(head)` content confidence in\n * 0..1; this module combines them into one ranked answer so that content\n * always beats a hint: a `.csv` whose first line is a neo4j-admin header is Neo4j, a `.xml` is\n * GEXF or GraphML by its root element, a `.txt` holding `graph [` is GML. The confidence of a\n * candidate is\n *\n * - `0.5 + 0.35 * content + 0.1 * [extension matches] + 0.05 * [MIME type matches]` when the\n * importer recognizes the content (`content > 0`), so a content match always scores at least\n * 0.5 and at most 1;\n * - `0.25 * content + 0.05 * [MIME type matches]` for a weak content match (content below 0.5,\n * such as plain delimited text read as CSV) when the file name's extension belongs to another\n * format, so that format wins;\n * - `0.3 * [extension matches] + 0.1 * [MIME type matches]` when the content is absent or the\n * importer rejects it, so a hint alone never reaches 0.5;\n * - nothing (the format is not a candidate) otherwise.\n *\n * Ties are broken by the order the importers were registered in, which is why the default\n * registry lists the common formats first. The JSON dialect is sniffed from the head as a hint\n * (the importer's detection on the parsed document is authoritative, design section 8.2).\n */\n\nimport { type JsonImportDialect, sniffJsonDialect } from \"./formats/json/dialect.js\";\nimport { type GraphImporter } from \"./types.js\";\n\n/**\n * The names of the built-in formats.\n * @category Formats and detection\n */\nexport type GraphFormatName =\n \"gexf\" | \"graphml\" | \"gml\" | \"dot\" | \"pajek\" | \"csv\" | \"json\" | \"neo4j\" | \"xgmml\" | \"cx2\" | \"cx\" | \"obo\" | \"cys\";\n\n/**\n * A format name: one of the built-in names (with editor autocomplete) or the name of a format you\n * registered yourself.\n * @example\n * ```ts\n * const format: FormatName = \"pajek\"; // or \"my-format\" after registry.registerImporter(myImporter)\n * ```\n * @category Formats and detection\n */\nexport type FormatName = GraphFormatName | (string & {}); // NOSONAR(S4335): keeps editor completion of the built-in names\n\n/**\n * The built-in format names in the default registry's order, which is also the tie-break order of\n * sniffing: the more common format wins an extension two formats claim (`.xml` GraphML before GEXF,\n * `.csv` CSV before Neo4j) when the content does not decide.\n * @category Formats and detection\n */\nexport const GRAPH_FORMATS: readonly GraphFormatName[] = Object.freeze([\n \"json\",\n \"graphml\",\n \"gexf\",\n \"csv\",\n \"gml\",\n \"dot\",\n \"pajek\",\n \"neo4j\",\n \"xgmml\",\n \"cx2\",\n \"cx\",\n \"obo\",\n \"cys\",\n]);\n\n/** Content confidence below this is a weak guess, which loses to a file extension another format claims. */\nconst WEAK_CONTENT = 0.5;\n\n/**\n * How many bytes of the input the sniffers look at; the registry reads no more than this before deciding.\n * @category Formats and detection\n */\nexport const SNIFF_HEAD_BYTES = 8192;\n\n/**\n * What is known about an input before it is read.\n * @category Formats and detection\n */\nexport interface SniffHints {\n /** A file name or path; only its extension is used. */\n readonly filename?: string | null | undefined;\n /** A MIME type, with or without parameters (`text/csv; charset=utf-8`). */\n readonly mimeType?: string | null | undefined;\n /** The first bytes (or characters) of the content; detection reads at most SNIFF_HEAD_BYTES of it. */\n readonly head?: Uint8Array | string | null | undefined;\n}\n\n/**\n * One ranked candidate of a sniff.\n * @category Formats and detection\n */\nexport interface SniffResult {\n /** The importer's format name. */\n readonly format: string;\n /** The combined confidence in 0..1: at least 0.5 when the content was clearly recognized, at most 0.4 from a name or MIME type alone. */\n readonly confidence: number;\n /** The importer's own content confidence, 0 when no head was given or it rejected the head. */\n readonly content: number;\n /** Whether the filename's extension is one the importer claims. */\n readonly extension: boolean;\n /** Whether the MIME type is one the importer claims. */\n readonly mimeType: boolean;\n /** For the JSON format: the dialect the head suggests, or null when unknown; always null for other formats. */\n readonly dialect: JsonImportDialect | null;\n}\n\n/**\n * Where the query or fragment of a name starts: at the first `?` or `#` of a URL; in a plain name, at\n * the first `?` or `#` that no dot follows.\n * @param filename - the name, path or URL\n * @param url - whether the name is a URL\n * @returns the offset, or the name's length when it has neither\n */\nfunction queryStart(filename: string, url: boolean): number {\n const from = url ? 0 : filename.lastIndexOf(\".\") + 1;\n for (let i = from; i < filename.length; i++) {\n if (filename[i] === \"?\" || filename[i] === \"#\") {\n return i;\n }\n }\n return filename.length;\n}\n\n/**\n * The lower-cased extension of a file name, path or URL, with its dot. A URL's `?query` and\n * `#fragment` are not part of it; in a plain name, `?` and `#` are ordinary characters (`net#2.gexf`)\n * unless no dot follows them (`g.graphml#v2`).\n * @param filename - the name, path or URL\n * @returns the extension (`.gexf`), or null when the name has none\n * @category Formats and detection\n */\nexport function extensionOf(filename: string): string | null {\n // a scheme of two or more letters, so a Windows drive (`C:`) is not one\n const url = /^[a-z][a-z\\d+.-]+:/i.test(filename);\n const path = filename.slice(0, queryStart(filename, url));\n const base = path.slice(Math.max(path.lastIndexOf(\"/\"), path.lastIndexOf(\"\\\\\")) + 1);\n const dot = base.lastIndexOf(\".\");\n if (dot <= 0 || dot === base.length - 1) {\n return null;\n }\n return base.slice(dot).toLowerCase();\n}\n\n/**\n * A MIME type without parameters, lower-cased, for comparison with an importer's list.\n * @param mimeType - the type as received (`Text/CSV; charset=utf-8`)\n * @returns the bare type (`text/csv`)\n * @category Plugin helpers\n */\nexport function normalizeMimeType(mimeType: string): string {\n const semicolon = mimeType.indexOf(\";\");\n return (semicolon < 0 ? mimeType : mimeType.slice(0, semicolon)).trim().toLowerCase();\n}\n\n/**\n * The head as bytes for the importers' sniff functions: at most SNIFF_HEAD_BYTES, a string\n * encoded as UTF-8, a UTF-16 head with a byte order mark transcoded to UTF-8.\n * @param head - the head as given\n * @returns the bytes\n * @category Plugin helpers\n */\nexport function headBytes(head: Uint8Array | string): Uint8Array {\n if (typeof head === \"string\") {\n return new TextEncoder().encode(head.slice(0, SNIFF_HEAD_BYTES)).subarray(0, SNIFF_HEAD_BYTES);\n }\n if (head.byteLength >= 2 && ((head[0] === 0xff && head[1] === 0xfe) || (head[0] === 0xfe && head[1] === 0xff))) {\n // UTF-16 with a BOM (Excel's \"Unicode text\"): the sniffers read UTF-8, so transcode the head\n const encoding = head[0] === 0xff ? \"utf-16le\" : \"utf-16be\";\n return headBytes(new TextDecoder(encoding).decode(head.subarray(0, SNIFF_HEAD_BYTES)));\n }\n return head.byteLength > SNIFF_HEAD_BYTES ? head.subarray(0, SNIFF_HEAD_BYTES) : head;\n}\n\n/**\n * Rank a list of importers for an input. Most callers want `registry.sniffAll(hints)`, which passes\n * the registered importers for you. An importer is a candidate when it recognizes the content or\n * its extension or MIME type matches. A content match scores 0.5 to 1 (more with a matching\n * extension or MIME type); a name or MIME type alone scores at most 0.4; a weak content guess (a\n * confidence below 0.5 from the importer, such as plain delimited text for CSV) scores below 0.25\n * when the file's extension belongs to another format. Ties go to the importer listed first.\n * @param hints - `{ filename, mimeType, head }`, any of them\n * @param importers - the importers to rank, in tie-break order (`registry.importers()`)\n * @param onSniffError - called with the format and the error when an importer's sniff() throws\n * (that importer is then treated as not recognizing the head)\n * @returns the candidates, best first; empty when nothing matches\n * @category Formats and detection\n */\nexport function rankFormats(\n hints: SniffHints,\n importers: Iterable<GraphImporter>,\n onSniffError?: (format: string, error: unknown) => void,\n): readonly SniffResult[] {\n const extension = typeof hints.filename === \"string\" ? extensionOf(hints.filename) : null;\n const mime = typeof hints.mimeType === \"string\" ? normalizeMimeType(hints.mimeType) : null;\n const head = hints.head === undefined || hints.head === null ? null : headBytes(hints.head);\n const all = [...importers];\n const extensionClaimed =\n extension !== null && all.some((i) => i.extensions.some((e) => e.toLowerCase() === extension));\n const candidates: { readonly result: SniffResult; readonly rank: number }[] = [];\n let rank = 0;\n for (const importer of all) {\n const extensionMatch = extension !== null && importer.extensions.some((e) => e.toLowerCase() === extension);\n const mimeMatch = mime !== null && importer.mimeTypes.some((m) => m.toLowerCase() === mime);\n const sniffed = head !== null && head.byteLength > 0 && typeof importer.sniff === \"function\";\n const content = sniffed ? contentConfidence(importer, head, onSniffError) : 0;\n const confidence = combinedConfidence(content, { extensionMatch, mimeMatch, extensionClaimed, sniffed });\n if (confidence === null) {\n continue;\n }\n const dialect = importer.format === \"json\" && head !== null ? sniffJsonDialectHead(head) : null;\n const result: SniffResult = Object.freeze({\n format: importer.format,\n confidence: Math.min(1, confidence),\n content,\n extension: extensionMatch,\n mimeType: mimeMatch,\n dialect,\n });\n candidates.push({ result, rank: rank++ });\n }\n candidates.sort((a, b) => b.result.confidence - a.result.confidence || a.rank - b.rank);\n return candidates.map((c) => c.result);\n}\n\n/**\n * An importer's confidence that it recognizes a head, 0 when its sniffer throws (one buggy\n * importer must not break the detection of every other format, but the error is handed on).\n * @param importer - the importer, which has a sniffer\n * @param head - the head\n * @param onSniffError - called with the format and the error when the sniffer throws\n * @returns the confidence in 0..1\n */\nfunction contentConfidence(\n importer: GraphImporter,\n head: Uint8Array,\n onSniffError: ((format: string, error: unknown) => void) | undefined,\n): number {\n try {\n return clamp(importer.sniff?.(head) ?? 0);\n } catch (err) {\n onSniffError?.(importer.format, err);\n return 0;\n }\n}\n\n/**\n * The ranking score of one importer from what matched, or null when it is not a candidate.\n * @param content - the importer's content confidence\n * @param match - what else matched\n * @param match.extensionMatch - the file's extension is one the importer claims\n * @param match.mimeMatch - the MIME type is one the importer claims\n * @param match.extensionClaimed - some importer claims the file's extension\n * @param match.sniffed - the importer looked at the content\n * @returns the score, or null\n */\nfunction combinedConfidence(\n content: number,\n match: { extensionMatch: boolean; mimeMatch: boolean; extensionClaimed: boolean; sniffed: boolean },\n): number | null {\n const { extensionMatch, mimeMatch } = match;\n const mimeBonus = mimeMatch ? 0.05 : 0;\n if (content > 0 && content < WEAK_CONTENT && match.extensionClaimed && !extensionMatch) {\n // a weak guess (plain delimited text read as CSV) never overrides another format's extension\n return 0.25 * content + mimeBonus;\n }\n if (content > 0) {\n return 0.5 + 0.35 * content + (extensionMatch ? 0.1 : 0) + mimeBonus;\n }\n if (extensionMatch || (mimeMatch && !match.sniffed)) {\n // a MIME type alone does not override an importer that looked at the content and said no:\n // servers send text/plain for any text file, and a sentence is not a CSV edge list\n return (extensionMatch ? 0.3 : 0) + (mimeMatch ? 0.1 : 0);\n }\n return null;\n}\n\n/**\n * Format detection over a list of importers you pass in, for code that keeps importers outside any\n * registry. To detect a file's format, call `sniff(hints)` instead: it takes the same hints and\n * knows every built-in and registered format. Returns the best candidate of rankFormats(), or null\n * when no importer matches.\n * @param hints - `{ filename, mimeType, head }`, any of them\n * @param importers - the importers to rank, in tie-break order (`registry.importers()`)\n * @returns the best candidate, or null\n * @category Plugin helpers\n */\nexport function sniffFormat(hints: SniffHints, importers: Iterable<GraphImporter>): SniffResult | null {\n const ranked = rankFormats(hints, importers);\n return ranked.length > 0 ? ranked[0] : null;\n}\n\n/**\n * The JSON dialect a head suggests. A head that parses as a whole document is classified exactly\n * (sniffJsonDialect); a truncated head is scanned for its top-level keys, the keys of `graph` and\n * `options`, and the keys of the first object under `nodes` / `edges` / `links`, and the same\n * rule is applied to that skeleton. The result is a hint: the importer decides on the parsed\n * document.\n * @param head - the first bytes or characters of the document\n * @returns the dialect, or null when the head is not a JSON graph document\n * @category Plugin helpers\n */\nexport function sniffJsonDialectHead(head: Uint8Array | string): JsonImportDialect | null {\n const text = typeof head === \"string\" ? head : new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n const body = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n const trimmed = body.trimStart();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return null;\n }\n let root: unknown;\n try {\n root = JSON.parse(trimmed);\n } catch {\n const skeleton = skeletonOf(trimmed);\n root = skeleton;\n // a head cut inside a long `nodes` array has not reached the keys that tell node-link from d3\n // (`links`, `directed`, `graph`, ...): no guess rather than a wrong one\n if (\n typeof skeleton === \"object\" &&\n skeleton !== null &&\n !Array.isArray(skeleton) &&\n ![\"edges\", \"links\", \"directed\", \"multigraph\", \"graph\"].some((key) => key in skeleton)\n ) {\n const guess = sniffJsonDialect(skeleton);\n return guess === \"node-link\" ? null : guess;\n }\n }\n return sniffJsonDialect(root);\n}\n\n/** Where a key was seen while scanning a truncated head. */\ntype KeyPath =\n \"\" | \"graph\" | \"options\" | \"nodes[0]\" | \"edges[0]\" | \"links[0]\" | \"graphs[0].nodes[]\" | \"graphs[0].edges[]\";\n\n/**\n * A partial document rebuilt from the keys a truncated head reveals: every key gets a placeholder\n * value of the shape the dialect rule tests for (an object for `graph`, `options`, `attributes`\n * and `data`, an array holding the first element's skeleton for `nodes` / `edges` / `links` /\n * `graphs`, `true` otherwise), so sniffJsonDialect() can classify it.\n * @param text - the head, starting with `{` or `[`\n * @returns the skeleton, or null when the scan finds no key at all\n */\nfunction skeletonOf(text: string): unknown {\n const keys = scanKeys(text);\n if (text.startsWith(\"[\")) {\n // a cut array whose first element has not been seen tells nothing (a whole `[]` is Cytoscape)\n const first = keys.get(\"nodes[0]\");\n return first === undefined ? null : [objectOf(first)];\n }\n const rootKeys = keys.get(\"\");\n if (rootKeys === undefined) {\n return null;\n }\n const root: Record<string, unknown> = {};\n for (const key of rootKeys) {\n switch (key) {\n case \"graph\":\n case \"options\":\n root[key] = objectOf(keys.get(key));\n break;\n case \"graphs\": {\n // the keys of any node or edge of the first graph: OBO Graphs or JGF (design 1.6)\n const nodes = keys.get(\"graphs[0].nodes[]\");\n const edges = keys.get(\"graphs[0].edges[]\");\n const graph: Record<string, unknown> = {};\n if (nodes !== undefined) {\n graph.nodes = [objectOf(nodes)];\n }\n if (edges !== undefined) {\n graph.edges = [objectOf(edges)];\n }\n root[key] = nodes === undefined && edges === undefined ? [] : [graph];\n break;\n }\n case \"nodes\":\n case \"edges\":\n case \"links\": {\n const first = keys.get(`${key}[0]`);\n root[key] = first === undefined ? [] : [objectOf(first)];\n break;\n }\n default:\n root[key] = true;\n break;\n }\n }\n return root;\n}\n\n/**\n * An object holding placeholder values for a key set: `{}` for the keys the rule tests with\n * isJsonObject (`attributes`, `data`), `true` otherwise.\n * @param names - the keys, possibly undefined\n * @returns the object\n */\nfunction objectOf(names: ReadonlySet<string> | undefined): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (names !== undefined) {\n for (const name of names) {\n out[name] = name === \"attributes\" || name === \"data\" ? {} : true;\n }\n }\n return out;\n}\n\n/**\n * Scan a (possibly truncated) JSON text for the keys at the paths the dialect rule reads. The\n * scanner tracks a container stack (the key each object sits under, the index of each array\n * element) and records a key when it is at one of the watched paths; a head cut inside a string\n * or a number simply ends the scan. For a top-level array the first element's keys are recorded\n * under `nodes[0]`; the keys of every node and edge of `graphs[0]` under `graphs[0].nodes[]` and\n * `graphs[0].edges[]`.\n * @param text - the head, starting with `{` or `[`\n * @returns key sets by path\n */\nfunction scanKeys(text: string): Map<KeyPath, Set<string>> {\n const found = new Map<KeyPath, Set<string>>();\n // one frame per open container: its kind, the key or index it sits under, and the element index\n const kinds: (\"object\" | \"array\")[] = [];\n const labels: string[] = [];\n const counts: number[] = [];\n let pendingKey: string | null = null;\n let expectingKey = false;\n const pathOf = (): KeyPath | null => {\n const depth = kinds.length;\n if (depth === 1) {\n return kinds[0] === \"object\" ? \"\" : null;\n }\n if (depth === 2 && kinds[0] === \"array\" && kinds[1] === \"object\" && labels[1] === \"0\") {\n return \"nodes[0]\";\n }\n if (depth === 2 && kinds[0] === \"object\" && kinds[1] === \"object\") {\n return labels[1] === \"graph\" || labels[1] === \"options\" ? labels[1] : null;\n }\n if (\n depth === 5 &&\n kinds.join() === \"object,array,object,array,object\" &&\n labels[1] === \"graphs\" &&\n labels[2] === \"0\" &&\n (labels[3] === \"nodes\" || labels[3] === \"edges\")\n ) {\n return labels[3] === \"nodes\" ? \"graphs[0].nodes[]\" : \"graphs[0].edges[]\";\n }\n if (depth === 3 && kinds[0] === \"object\" && kinds[1] === \"array\" && kinds[2] === \"object\") {\n const section = labels[1];\n if ((section === \"nodes\" || section === \"edges\" || section === \"links\") && labels[2] === \"0\") {\n return `${section}[0]`;\n }\n }\n return null;\n };\n let i = 0;\n const n = text.length;\n while (i < n) {\n const ch = text[i];\n if (ch === '\"') {\n const end = scanString(text, i + 1);\n if (end < 0) {\n break;\n }\n const literal = text.slice(i + 1, end);\n i = end + 1;\n if (expectingKey) {\n pendingKey = decodeKey(literal);\n expectingKey = false;\n }\n continue;\n }\n if (ch === \"{\" || ch === \"[\") {\n let label = \"\";\n if (kinds.length > 0) {\n label = kinds[kinds.length - 1] === \"object\" ? (pendingKey ?? \"\") : String(counts[counts.length - 1]);\n }\n kinds.push(ch === \"{\" ? \"object\" : \"array\");\n labels.push(label);\n counts.push(0);\n expectingKey = ch === \"{\";\n pendingKey = null;\n } else if (ch === \"}\" || ch === \"]\") {\n kinds.pop();\n labels.pop();\n counts.pop();\n expectingKey = false;\n pendingKey = null;\n } else if (ch === \":\") {\n if (pendingKey !== null) {\n const path = pathOf();\n if (path !== null) {\n let set = found.get(path);\n if (set === undefined) {\n set = new Set();\n found.set(path, set);\n }\n set.add(pendingKey);\n }\n }\n } else if (ch === \",\") {\n const top = kinds.length - 1;\n if (top >= 0) {\n counts[top]++;\n expectingKey = kinds[top] === \"object\";\n }\n pendingKey = null;\n }\n i++;\n }\n return found;\n}\n\n/**\n * The index of the closing quote of a JSON string starting after its opening quote.\n * @param text - the text\n * @param from - the index after the opening quote\n * @returns the index of the closing quote, or -1 when the text ends first\n */\nfunction scanString(text: string, from: number): number {\n let i = from;\n while (i < text.length) {\n const ch = text[i];\n if (ch === \"\\\\\") {\n i += 2;\n continue;\n }\n if (ch === '\"') {\n return i;\n }\n i++;\n }\n return -1;\n}\n\n/**\n * A key literal decoded when it holds escapes, kept as written otherwise.\n * @param literal - the text between the quotes\n * @returns the key\n */\nfunction decodeKey(literal: string): string {\n if (!literal.includes(\"\\\\\")) {\n return literal;\n }\n try {\n return JSON.parse(`\"${literal}\"`) as string;\n } catch {\n return literal;\n }\n}\n\n/**\n * Coerce a sniff confidence into 0..1 (NaN counts as 0).\n * @param value - the importer's answer\n * @returns the clamped value\n */\nfunction clamp(value: number): number {\n if (!(value > 0)) {\n return 0;\n }\n return value > 1 ? 1 : value;\n}\n","/**\n * The JSON importer (design sections 8.2, 8.4 and 8.5): one GraphImporter that sniffs the dialect\n * of a parsed document -- NetworkX node-link (old `links` and new `edges` key forms, graph-level\n * `directed` / `multigraph` / `graph`), the d3 lineage of the same shape (`name` ids, integer\n * index endpoints), JSON Graph Format v2 (nodes keyed by id, per-edge `directed`, hyperedges),\n * Cytoscape.js elements (`data.id` / `data.source` / `data.target`, `position`, `classes`,\n * `data.parent`), graphology serialization (`key` / `attributes`, `undirected` edges, `options`)\n * vis.js (`from` / `to`), and NetworkX adjacency_data (`nodes` + `adjacency`) and tree_data (nested\n * `id` / `children`) -- and pushes it scalar by scalar into the sink.\n *\n * Python's json module writes the bare tokens NaN, Infinity and -Infinity, which strict JSON\n * refuses; they are read as the JavaScript numbers with one warning. An integer literal beyond\n * 2^53 is read as its exact digits (a string, the canonical id rule of the text formats) rather\n * than a rounded float, again with one warning.\n *\n * JSON awaits the whole text (design section 8.4: `JSON.parse` on 100 MB is fine; a streaming\n * tokeniser is a later improvement). The parsed records are iterated in place; the importer never\n * builds an intermediate array of node or edge objects. Ids are coerced per `ids` (\"keep\" by\n * default: JSON values are already typed); node ids that are JSON `true` / `false` / `null` are\n * reported as `unsupported` and coerced with `String(v)` only under `ids: \"string\"`. Attribute\n * columns are inferred per column by the sink (design section 5.1); the structural fields of a\n * dialect (Cytoscape `position` / `classes` / `parent`, JGF `label` / `relation`, edge ids) are\n * declared up front with their roles when the file uses them. Direction goes through the\n * DirectionResolver of design section 8.4; per-element errors are aggregated into the ImportReport\n * until the error limit (design section 8.6).\n *\n * Fatal errors (ImportError at once): empty input, invalid JSON, an unrecognised top-level shape, a\n * section that is not an array / object. Recoverable errors (an issue, the element skipped): a\n * missing nodes or edges array, a node without an id, an edge without an endpoint, a bad index\n * endpoint, a declared field of the wrong type, an unknown Cytoscape parent, an id the coercion rule\n * rejects.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n BAD_VALUE_CODE,\n COLUMN_RENAMED_CODE,\n DANGLING_REFERENCE_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n ELEMENT_ISSUE,\n EMPTY_COLUMN_DROPPED_CODE,\n EMPTY_INPUT_CODE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n HYPEREDGE_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n JSON_NONSTANDARD_NUMBER_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n OPTION_IGNORED_CODE,\n PARENT_CYCLE_CODE,\n PRECISION_CODE,\n ROLE_TAKEN_CODE,\n SYNTAX_CODE,\n TOO_LARGE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n findDuplicateKeys,\n flipY,\n MAYBE_INEXACT_EXPONENT,\n MAYBE_UNSAFE_INTEGER,\n rewriteNumbers,\n} from \"../../common/json-elements.js\";\nimport {\n chooseGraph,\n graphChosen,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n SINK_OPTION_CODE,\n} from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { weightFromValue } from \"../../common/weights.js\";\nimport { headBytes, sniffJsonDialectHead } from \"../../sniff.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type GraphListing,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport {\n CLASSES_COLUMN,\n CYTOSCAPE_ELEMENT_KEYS,\n CYTOSCAPE_STRUCTURAL_KEYS,\n DIALECT_DEFAULT_DIRECTED,\n hasKey,\n isJsonImportDialect,\n isJsonObject,\n JSON_IMPORT_DIALECTS,\n type JsonImportDialect,\n type JsonShapeMeta,\n META_KEY,\n NODE_LINK_SOURCE_KEYS,\n NODE_LINK_TARGET_KEYS,\n PARENT_COLUMN,\n POSITION_COLUMN,\n sniffJsonDialect,\n SUFFIX,\n} from \"./dialect.js\";\nimport { importObographs } from \"./obographs.js\";\n\n/**\n * The format-specific options of the JSON importer. `graphIndex` / `graphName` choose one graph of\n * a JGF or OBO Graphs `graphs` array (the first by default); a graph's name is its `id`, else its\n * label.\n * @category Built-in formats\n */\nexport interface JsonImportOptions extends GraphChoiceOptions, CommonImportOptions {\n /**\n * The dialect to read; \"auto\" detects it from the document. `jsonShapeOf(snapshot).dialect` is\n * the dialect that was read.\n * @defaultValue \"auto\"\n */\n dialect?: JsonImportDialect | \"auto\" | undefined;\n /**\n * node-link, d3, vis, adjacency and tree documents: the node key that holds the id. The default\n * is \"id\" (for node-link and d3, \"name\" when no node has an \"id\").\n * @defaultValue \"id\"\n */\n nodeIdKey?: string | undefined;\n /**\n * node-link and d3 documents: the top-level key that holds the edges. The default is \"edges\"\n * when the document has it, else \"links\".\n * @defaultValue \"edges\" or \"links\"\n */\n edgesKey?: string | undefined;\n /**\n * node-link, d3 and vis documents: the edge key that holds the source. The default is the first\n * of \"source\", \"src\" and \"from\" the edges use (vis: \"from\").\n * @defaultValue \"source\"\n */\n sourceKey?: string | undefined;\n /**\n * node-link, d3 and vis documents: the edge key that holds the target. The default is the first\n * of \"target\", \"dst\" and \"to\" the edges use (vis: \"to\").\n * @defaultValue \"target\"\n */\n targetKey?: string | undefined;\n /**\n * node-link and d3 documents: whether edge ends are positions in the node array rather than\n * ids; \"auto\" says yes when every end is an integer below the number of nodes and no node id is\n * a number.\n * @defaultValue \"auto\"\n */\n indexLinks?: boolean | \"auto\" | undefined;\n /**\n * OBO Graphs documents: \"curie\" reads `http://purl.obolibrary.org/obo/GO_0008150` as\n * `GO:0008150` and `.../obo/go#regulates` as `regulates`, the ids the `.obo` file of the same\n * ontology uses; \"iri\" keeps every IRI as written.\n * @defaultValue \"curie\"\n */\n oboIds?: \"curie\" | \"iri\" | undefined;\n /**\n * OBO Graphs documents: \"metadata\" keeps the relation definitions (PROPERTY nodes, with their\n * subPropertyOf and inverseOf edges) in `snapshot.meta.extra.obographs`, the way the OBO\n * importer keeps `[Typedef]` frames; \"nodes\" makes them nodes and edges of the graph.\n * @defaultValue \"metadata\"\n */\n typedefs?: \"metadata\" | \"nodes\" | undefined;\n /**\n * node-link, d3, vis and graphology documents: where the node array is, as a dotted path of\n * keys and array positions from the top of the document (`\"data.nodes\"`, `\"graphs.0.nodes\"`).\n * The object that holds the array is read as the graph (its `directed`, `multigraph`, `graph`\n * and edge keys). A path that leads nowhere is reported as E_MISSING_SECTION and the graph has\n * no nodes.\n * @defaultValue \"nodes\"\n */\n nodesPath?: string | undefined;\n /**\n * node-link, d3, vis and graphology documents: where the edge array is, as a dotted path\n * (`\"data.links\"`). The default is the edges or links key next to the node array. A path that\n * leads nowhere is reported as E_MISSING_SECTION and the graph has no edges.\n * @defaultValue next to the nodes\n */\n edgesPath?: string | undefined;\n}\n\n/**\n * The issue codes the JSON importer records, by name: the codes shared with\n * the other importers and the JSON-specific ones. A key is the code without\n * its severity and format prefixes.\n * @category Built-in formats\n */\nexport const JSON_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /** The text is empty or whitespace. The import stops. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The text is not valid JSON. The import stops. */\n SYNTAX: SYNTAX_CODE,\n /** No dialect matches the document's top-level shape. The import stops. */\n DIALECT: \"E_JSON_DIALECT\",\n /** A section (nodes, edges, elements, graph) has the wrong JSON type. */\n SHAPE: \"E_JSON_SHAPE\",\n /**\n * A section the dialect expects is not there: a node-link document without its nodes or its edges array, an\n * adjacency document without lists for some nodes, or a `nodesPath` / `edgesPath` that names nothing. Nothing is\n * skipped: the graph is read without that section (nodes come from the edges, or there are no edges).\n */\n MISSING_SECTION: \"W_MISSING_SECTION\",\n /** A node record or an element is not an object. */\n BAD_ELEMENT: \"E_BAD_ELEMENT\",\n /** A node record has no id. */\n MISSING_ID: MISSING_ID_CODE,\n /**\n * A node id is a JSON boolean or null, which graph-io cannot use as an id; the node is skipped. With `ids:\n * \"string\"` it is read as the text \"true\", \"false\" or \"null\".\n */\n UNSUPPORTED_ID: \"E_UNSUPPORTED_ID\",\n /** An edge record has no source or no target. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** An index endpoint is not an integer below the node count, or names a skipped node. */\n BAD_INDEX: \"E_BAD_INDEX\",\n /** A declared field has the wrong JSON type (JGF label / relation / metadata, Cytoscape position / classes). */\n BAD_VALUE: BAD_VALUE_CODE,\n /** A graph-level flag (`directed`, `multigraph`, graphology `options`) has the wrong type; the default is used. */\n BAD_FLAG: \"W_BAD_FLAG\",\n /** A Cytoscape `data.parent` names an unknown node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** A node id repeated by a later record; the records are merged (the later attributes win). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id (Cytoscape data.id, graphology key, vis id) repeated by a later edge; the edge is skipped. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /** Two different id texts became the same number because `ids` is \"number\", so their nodes were merged. */\n ID_MERGED: ID_MERGED_CODE,\n /** Edge ids of mixed JSON types were stored as text. */\n EDGE_ID_STRINGIFIED: \"W_EDGE_ID_STRINGIFIED\",\n /**\n * The file holds several graphs and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph.\n * `importAllGraphs()` reads every one.\n */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /**\n * `graphIndex` is past the end of the `graphs` array, or `graphName` matches none of its graphs. The import stops.\n */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches more than one graph of the `graphs` array. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** Obographs: an edge uses the outdated `subj` key of the OBO Graphs README; it is read as `sub`. */\n OBOGRAPHS_SUBJ: \"W_JSON_OBOGRAPHS_SUBJ\",\n /**\n * Obographs: an edge endpoint missing from `nodes` (a placeholder node is made, or the edge dropped under\n * addMissingNodes false).\n */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The document is longer than a JavaScript string can hold. The import stops. */\n TOO_LARGE: TOO_LARGE_CODE,\n /** A JGF hyperedge (an edge with more than two ends) while `hyperedges` is \"error\". */\n HYPEREDGE: HYPEREDGE_CODE,\n /**\n * JGF hyperedges were skipped, because `hyperedges` is \"skip\" (the default). Pass \"star\" or \"clique\" to keep them.\n */\n HYPEREDGES_SKIPPED: \"W_HYPEREDGES_SKIPPED\",\n /** A JGF hyperedge with neither a nodes array nor source / target arrays. */\n HYPEREDGE_SHAPE: \"E_HYPEREDGE_SHAPE\",\n /** The nodes have no id key at all; array positions became the ids. */\n POSITIONAL_NODES: \"W_POSITIONAL_NODES\",\n /** A node-link / d3 top-level key the importer does not read (the other of edges / links, an unknown key); it is dropped. */\n UNREAD_KEY: \"W_JSON_UNREAD_KEY\",\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** The input is not valid UTF-8. The import stops. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the\n * `encoding` option). The import stops.\n */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** The document uses the non-standard tokens NaN / Infinity / -Infinity (Python's json writes them); read as numbers. */\n NONSTANDARD_NUMBER: JSON_NONSTANDARD_NUMBER_CODE,\n /** Integer literals beyond 2^53 were read as their exact digits (strings), not as rounded numbers. */\n BIG_INTEGER: \"W_JSON_BIG_INTEGER\",\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /**\n * The document contradicts itself: a declared option its edges break (multigraph false with\n * parallel links, graphology's options), a record whose section disagrees with its shape, a\n * JGF inner id other than its key, the two listings of one adjacency edge.\n */\n INCONSISTENT: \"W_JSON_INCONSISTENT\",\n /** IndexLinks \"auto\" read integer endpoints as array positions although they also name node ids. */\n INDEX_LINKS: \"W_JSON_INDEX_LINKS\",\n /** A Cytoscape parent link that would close a cycle; that link is dropped. */\n PARENT_CYCLE: PARENT_CYCLE_CODE,\n /** An attribute key that is null on every element makes no column (NetworkX writes None as null). */\n EMPTY_COLUMN_DROPPED: EMPTY_COLUMN_DROPPED_CODE,\n /** OBO Graphs: a node type or synonym predicate outside the schema's set; kept as written, once per name. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /**\n * A key repeated in one JSON object (JSON.parse keeps the last value, the earlier is dropped),\n * or, in OBO Graphs, a single-valued OBO tag given twice in basicPropertyValues (the first is kept).\n */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example\n * two attributes declared with the same name.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n});\n\n/** The common options the JSON importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"hyperedges\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"keep\", defaultDirected: false, weightFrom: \"weight\" };\n\n/** Bytes of the head sniff() inspects. */\nconst SNIFF_BYTES = 4096;\n\n/** How many dangling endpoints the W_DANGLING_REFERENCE message names. */\nconst DANGLING_SHOWN = 5;\n\n/** Elements pushed between two checks of the cancellation signal (the whole document is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The top-level keys whose presence in the head marks a graph document rather than arbitrary JSON. */\nconst SNIFF_KEYS: readonly string[] = ['\"nodes\"', '\"links\"', '\"edges\"', '\"elements\"', '\"graph\"', '\"graphs\"'];\n\nconst BOM = String.fromCharCode(0xfeff);\n\n/** The JGF edge keys that are not metadata. */\nconst JGF_EDGE_KEYS: ReadonlySet<string> = new Set([\n \"id\",\n \"source\",\n \"target\",\n \"relation\",\n \"directed\",\n \"label\",\n \"metadata\",\n]);\n\n/** The JGF hyperedge keys that are not metadata. */\nconst JGF_HYPEREDGE_KEYS: ReadonlySet<string> = new Set([...JGF_EDGE_KEYS, \"nodes\"]);\n\n/** The JGF node keys that are not metadata. */\nconst JGF_NODE_KEYS: ReadonlySet<string> = new Set([\"label\", \"metadata\"]);\n\n/** The graphology node keys that are not attributes. */\nconst GRAPHOLOGY_NODE_KEYS: ReadonlySet<string> = new Set([\"key\", \"attributes\"]);\n\n/** The graphology edge keys that are not attributes. */\nconst GRAPHOLOGY_EDGE_KEYS: ReadonlySet<string> = new Set([\"key\", \"source\", \"target\", \"attributes\", \"undirected\"]);\n\n/** The vis.js endpoint keys. */\nconst VIS_SOURCE_KEYS: readonly string[] = Object.freeze([\"from\"]);\nconst VIS_TARGET_KEYS: readonly string[] = Object.freeze([\"to\"]);\n\nexport type JsonRecord = Record<string, unknown>;\n\n/** An edge id column declared from a scan of the file's edge ids. */\ninterface EdgeIdColumn {\n readonly handle: ColumnHandle;\n /** Whether numeric ids are stored as text (the file mixes numbers and strings). */\n readonly stringify: boolean;\n /** The id texts seen so far when the dialect requires unique ids, else null. */\n readonly seen: Set<string> | null;\n}\n\n/** The dialects whose node and edge arrays nodesPath and edgesPath can point at. */\nconst PATH_DIALECTS: ReadonlySet<JsonImportDialect> = new Set<JsonImportDialect>([\n \"node-link\",\n \"d3\",\n \"vis\",\n \"graphology\",\n]);\n\n/** The resolved format-specific options. */\ninterface ResolvedJsonOptions {\n readonly dialect: JsonImportDialect | \"auto\";\n readonly nodeIdKey: string | null;\n readonly edgesKey: string | null;\n readonly sourceKey: string | null;\n readonly targetKey: string | null;\n readonly indexLinks: boolean | \"auto\";\n readonly graphIndex: number;\n /** The caller's graphIndex / graphName, as given, for chooseGraph(). */\n readonly choice: GraphChoiceOptions;\n /** obographs: CURIE or IRI ids. */\n readonly oboIds: \"curie\" | \"iri\";\n /** obographs: PROPERTY nodes as metadata or as nodes. */\n readonly typedefs: \"metadata\" | \"nodes\";\n /** The dotted path segments of the node array, or null for the root's own nodes key. */\n readonly nodesPath: readonly string[] | null;\n /** The dotted path segments of the edge array, or null for the edges / links key beside the nodes. */\n readonly edgesPath: readonly string[] | null;\n /** Set by importAll(): every graph of a `graphs` array is read, so none is reported as skipped. */\n readonly all?: boolean;\n}\n\n/**\n * Check the format-specific options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for a bad value\n */\nfunction resolveJsonOptions(options: (JsonImportOptions & CommonImportOptions) | undefined): ResolvedJsonOptions {\n const o = options ?? {};\n const dialect = o.dialect ?? \"auto\";\n if (dialect !== \"auto\" && !isJsonImportDialect(dialect)) {\n throw unsupportedOption(\"dialect\", dialect, [...JSON_IMPORT_DIALECTS, \"auto\"]);\n }\n const indexLinks = o.indexLinks ?? \"auto\";\n if (indexLinks !== \"auto\" && typeof indexLinks !== \"boolean\") {\n throw unsupportedOption(\"indexLinks\", indexLinks, [\"true\", \"false\", \"auto\"]);\n }\n const graphIndex = o.graphIndex ?? 0;\n if (!Number.isInteger(graphIndex) || graphIndex < 0) {\n throw unsupportedOption(\"graphIndex\", graphIndex, [\"a non-negative integer\"]);\n }\n const oboIds = o.oboIds ?? \"curie\";\n if (oboIds !== \"curie\" && oboIds !== \"iri\") {\n throw unsupportedOption(\"oboIds\", oboIds, [\"curie\", \"iri\"]);\n }\n const typedefs = o.typedefs ?? \"metadata\";\n if (typedefs !== \"metadata\" && typedefs !== \"nodes\") {\n throw unsupportedOption(\"typedefs\", typedefs, [\"metadata\", \"nodes\"]);\n }\n const nodesPath = pathOption(\"nodesPath\", o.nodesPath);\n const edgesPath = pathOption(\"edgesPath\", o.edgesPath);\n if ((nodesPath !== null || edgesPath !== null) && dialect !== \"auto\" && !PATH_DIALECTS.has(dialect)) {\n throw unsupportedOption(nodesPath === null ? \"edgesPath\" : \"nodesPath\", dialect, [...PATH_DIALECTS]);\n }\n return {\n dialect,\n nodeIdKey: keyOption(\"nodeIdKey\", o.nodeIdKey),\n edgesKey: keyOption(\"edgesKey\", o.edgesKey),\n sourceKey: keyOption(\"sourceKey\", o.sourceKey),\n targetKey: keyOption(\"targetKey\", o.targetKey),\n indexLinks,\n graphIndex,\n choice: { graphIndex: o.graphIndex, graphName: o.graphName },\n oboIds,\n typedefs,\n nodesPath,\n edgesPath,\n };\n}\n\n/**\n * Check a dotted path option: object keys joined by dots, none of them empty.\n * @param name - the option name\n * @param value - the caller's value\n * @returns the segments, or null when absent\n */\nfunction pathOption(name: string, value: unknown): readonly string[] | null {\n if (value === undefined) {\n return null;\n }\n const segments = typeof value === \"string\" ? value.split(\".\") : [];\n if (segments.length === 0 || segments.some((segment) => segment.length === 0)) {\n throw unsupportedOption(name, value, [\"a dotted path of non-empty keys\"]);\n }\n return segments;\n}\n\n/**\n * The value at a path of object keys and array positions (`graphs.0.nodes`), or undefined when a\n * step is missing.\n * @param root - the document\n * @param segments - the keys; a decimal integer indexes an array\n * @returns the value\n */\nfunction valueAt(root: unknown, segments: readonly string[]): unknown {\n let value = root;\n for (const segment of segments) {\n if (Array.isArray(value) && /^(0|[1-9]\\d*)$/.test(segment) && Number(segment) < value.length) {\n value = value[Number(segment)];\n } else if (isJsonObject(value) && hasKey(value, segment)) {\n value = value[segment];\n } else {\n return undefined;\n }\n }\n return value;\n}\n\n/**\n * The graph record nodesPath and edgesPath describe: the object holding the node array (the\n * document itself by default) with its nodes key and its edges / links key replaced by the arrays\n * the paths name. A path that names nothing is recorded as E_MISSING_SECTION and stands for an\n * empty array, so the import goes on.\n * @param root - the parsed document\n * @param json - the resolved options\n * @param report - the report\n * @returns the document unchanged when no path is given, else the graph record\n */\nfunction applyPaths(root: unknown, json: ResolvedJsonOptions, report: ImportReportBuilder): unknown {\n const { nodesPath, edgesPath } = json;\n if (nodesPath === null && edgesPath === null) {\n return root;\n }\n const lookup = (option: string, segments: readonly string[]): unknown => {\n const value = valueAt(root, segments);\n if (value === undefined) {\n const path = segments.join(\".\");\n report.warning(\n \"missing-value\",\n JSON_ISSUE.MISSING_SECTION,\n `${option} ${JSON.stringify(path)} names nothing in the document`,\n { element: path },\n );\n return [];\n }\n return value;\n };\n const holderPath = nodesPath === null ? [] : nodesPath.slice(0, -1);\n const holder = valueAt(root, holderPath);\n // the keys the paths replace: the nodes key, and every edge key when edgesPath names the edges\n const replaced = new Set<string>();\n if (nodesPath !== null) {\n replaced.add(nodesPath[nodesPath.length - 1]);\n }\n if (edgesPath !== null) {\n replaced.add(\"edges\");\n replaced.add(\"links\");\n }\n let record: JsonRecord = Object.fromEntries(\n Object.entries(isJsonObject(holder) ? holder : {}).filter(([key]) => !replaced.has(key)),\n );\n // edges inside the holder (`data.graph.links` under `data`) leave the holder, and only they do:\n // the rest of the key they sit in (the `graph` attributes) is still read\n if (edgesPath !== null && edgesPath.length > holderPath.length && holderPath.every((k, i) => edgesPath[i] === k)) {\n const rest = withoutPath(record, edgesPath.slice(holderPath.length));\n record = isJsonObject(rest) ? rest : {};\n }\n if (nodesPath !== null) {\n record.nodes = lookup(\"nodesPath\", nodesPath);\n }\n if (edgesPath !== null) {\n record[pathEdgesKey(json, edgesPath)] = lookup(\"edgesPath\", edgesPath);\n }\n return record;\n}\n\n/**\n * A value with the entry at a path of object keys removed; undefined when the path is empty (the\n * value itself goes) or nothing but that entry is left.\n * @param value - the value\n * @param segments - the keys down to the entry\n * @returns the value without the entry\n */\nfunction withoutPath(value: unknown, segments: readonly string[]): unknown {\n if (segments.length === 0) {\n return undefined;\n }\n const [head, ...tail] = segments;\n if (!isJsonObject(value) || !hasKey(value, head)) {\n return value;\n }\n // a parsed JSON value is never undefined, so undefined marks the entries to drop\n const entries = Object.entries(value)\n .map(([key, v]) => [key, key === head ? withoutPath(v, tail) : v] as const)\n .filter(([, v]) => v !== undefined);\n return entries.length === 0 ? undefined : Object.fromEntries(entries);\n}\n\n/**\n * The key applyPaths() stores the edge array under: the caller's edgesKey, else \"links\" when\n * edgesPath ends in links (so the d3 sniff still sees it), else \"edges\".\n * @param json - the resolved options\n * @param edgesPath - the edgesPath segments\n * @returns the key\n */\nfunction pathEdgesKey(json: ResolvedJsonOptions, edgesPath: readonly string[]): string {\n return json.edgesKey ?? (edgesPath[edgesPath.length - 1] === \"links\" ? \"links\" : \"edges\");\n}\n\n/**\n * The dialect of a graph record built from nodesPath / edgesPath: the forced one, else the shape\n * rule over the record, else node-link.\n * @param record - the graph record\n * @param forced - the caller's dialect option\n * @param placedEdges - whether edgesPath placed the record's edge array (under links or edges)\n * @returns the dialect\n */\nfunction pathDialect(record: unknown, forced: JsonImportDialect | \"auto\", placedEdges: boolean): JsonImportDialect {\n if (forced !== \"auto\") {\n return forced;\n }\n // edgesPath puts the edge array under links only so a bare d3 document stays d3; under edges,\n // vis and graphology edges are told apart from NetworkX links again. A links key the document\n // itself holds is NetworkX's and settles node-link.\n if (placedEdges && isJsonObject(record) && hasKey(record, \"links\") && !hasKey(record, \"edges\")) {\n const { links, ...rest } = record;\n const asEdges = sniffJsonDialect({ ...rest, edges: links });\n if (asEdges === \"vis\" || asEdges === \"graphology\") {\n return asEdges;\n }\n }\n const sniffed = sniffJsonDialect(record);\n return sniffed !== null && PATH_DIALECTS.has(sniffed) ? sniffed : \"node-link\";\n}\n\n/**\n * The document to read and its dialect: the graph record of nodesPath / edgesPath when either is\n * given, the document itself otherwise.\n * @param parsed - the parsed document\n * @param json - the resolved options\n * @param report - the report\n * @returns the root and its dialect\n */\nfunction documentOf(\n parsed: unknown,\n json: ResolvedJsonOptions,\n report: ImportReportBuilder,\n): { readonly root: unknown; readonly dialect: JsonImportDialect } {\n if (json.nodesPath === null && json.edgesPath === null) {\n return { root: parsed, dialect: detectDialect(parsed, json.dialect, report) };\n }\n const root = applyPaths(parsed, json, report);\n const dialect = pathDialect(root, json.dialect, json.edgesPath !== null);\n // vis and graphology read their edges from the edges key only\n if (json.edgesPath !== null && (dialect === \"vis\" || dialect === \"graphology\") && isJsonObject(root)) {\n const key = pathEdgesKey(json, json.edgesPath);\n const renamed = Object.fromEntries(Object.entries(root).map(([k, v]) => [k === key ? \"edges\" : k, v]));\n return { root: renamed, dialect };\n }\n return { root, dialect };\n}\n\n/**\n * Check a key-valued option.\n * @param name - the option name\n * @param value - the caller's value\n * @returns the key, or null when absent\n */\nfunction keyOption(name: string, value: unknown): string | null {\n if (value === undefined) {\n return null;\n }\n if (typeof value !== \"string\" || value.length === 0) {\n throw unsupportedOption(name, value, [\"a non-empty key\"]);\n }\n return value;\n}\n\n/**\n * The E_UNSUPPORTED error of a bad format-specific option (the core's convention, as in the common\n * option module).\n * @param name - the option name\n * @param found - the value\n * @param supported - what is accepted\n * @returns the error\n */\nfunction unsupportedOption(name: string, found: unknown, supported: readonly string[]): GraphFormatError {\n return new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option ${name}: ${describe(found)} is not one of ${supported.join(\", \")}`,\n {\n option: name,\n found: typeof found === \"string\" ? found : typeof found,\n supported: [...supported],\n },\n );\n}\n\n/**\n * A short description of a value for messages.\n * @param value - the value\n * @returns JSON for primitives, \"array\" or the type name otherwise\n */\nfunction describe(value: unknown): string {\n if (value === null) {\n return \"null\";\n }\n if (Array.isArray(value)) {\n return \"array\";\n }\n switch (typeof value) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return JSON.stringify(value);\n default:\n return typeof value;\n }\n}\n\n// ============================================================ attribute writer\n\n/**\n * Writes inferred attribute cells for one table, caching the handle of every column after its\n * first write so the hot loop never looks a column up by name twice. Names that collide with a\n * structural column declared up front are suffixed deterministically (design section 5.6).\n */\nclass AttributeWriter {\n private readonly sink: GraphSink;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly handles = new Map<string, ColumnHandle>();\n\n private readonly reservedNames = new Set<string>();\n\n private readonly report: ImportReportBuilder;\n\n /** Column names written only with null so far (NetworkX writes None as null). */\n private readonly nullOnly = new Set<string>();\n\n /**\n * Create a writer.\n * @param sink - the sink\n * @param domain - node or edge\n * @param report - where a refused cell is recorded\n */\n constructor(sink: GraphSink, domain: \"node\" | \"edge\", report: ImportReportBuilder) {\n this.sink = sink;\n this.domain = domain;\n this.report = report;\n }\n\n /**\n * Declare a structural column up front; attribute keys with its name are suffixed from now on.\n * @param decl - the declaration\n * @returns the handle\n */\n declare(decl: ColumnDecl): ColumnHandle {\n this.reservedNames.add(decl.name);\n const handle = this.domain === \"node\" ? this.sink.declareNodeColumn(decl) : this.sink.declareEdgeColumn(decl);\n this.handles.set(decl.name, handle);\n return handle;\n }\n\n /**\n * Declare a structural column only when the file uses it.\n * @param decl - the declaration\n * @param present - whether any element carries the field\n * @returns the handle, or INVALID_INDEX when not declared\n */\n declareIf(decl: ColumnDecl, present: boolean): ColumnHandle {\n return present ? this.declare(decl) : (INVALID_INDEX as ColumnHandle);\n }\n\n /**\n * Whether a name is taken in the sink's table (for the deterministic rename rule).\n * @param name - the column name\n * @returns true when a column of that name exists\n */\n taken(name: string): boolean {\n return this.lookup(name) !== INVALID_INDEX;\n }\n\n /**\n * Write one attribute cell by its source key; null and undefined leave the row unset. A cell the\n * sink refuses is recorded and skipped, so the element's other keys are still written.\n * @param row - the node or edge index\n * @param key - the source key\n * @param value - the JSON value\n * @param suffix - the suffix applied when the key collides with a structural column\n * @param element - the element name for an issue\n */\n write(row: number, key: string, value: unknown, suffix: string, element: string): void {\n if (value === undefined) {\n return;\n }\n const name = this.reservedNames.has(key) ? `${key}${suffix}` : key;\n if (value === null) {\n this.nullOnly.add(name);\n return;\n }\n try {\n const cached = this.handles.get(name);\n if (cached !== undefined) {\n this.set(cached, row, value);\n return;\n }\n this.set(name, row, value);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n this.report.recordError(err, { element: `${element}.${key}` });\n return;\n }\n const handle = this.lookup(name);\n if (handle !== INVALID_INDEX) {\n this.handles.set(name, handle);\n }\n }\n\n /**\n * Report the keys that were null on every element that had them: they made no column, so a\n * round trip loses them (W_EMPTY_COLUMN_DROPPED, one warning per table).\n */\n reportNullOnly(): void {\n const names = [...this.nullOnly].filter((name) => this.lookup(name) === INVALID_INDEX);\n if (names.length > 0) {\n this.report.warning(\n \"missing-value\",\n EMPTY_COLUMN_DROPPED_CODE,\n `${this.domain} key${plural(names.length)} ${names.map((n) => JSON.stringify(n)).join(\", \")} ${agree(names.length, \"is\", \"are\")} null wherever they appear; no column is made for them`,\n { element: names[0] },\n );\n }\n }\n\n /**\n * Write through a handle or a name.\n * @param column - the handle or name\n * @param row - the row\n * @param value - the value\n */\n set(column: ColumnHandle | string, row: number, value: unknown): void {\n if (this.domain === \"node\") {\n this.sink.setNodeValue(column, row, value);\n } else {\n this.sink.setEdgeValue(column, row, value);\n }\n }\n\n /**\n * Look a column up by name.\n * @param name - the column name\n * @returns the handle, or INVALID_INDEX\n */\n private lookup(name: string): ColumnHandle {\n return this.domain === \"node\" ? this.sink.nodeColumn(name) : this.sink.edgeColumn(name);\n }\n}\n\n// ============================================================ the import context\n\n/**\n * Everything one import call shares between the dialect readers.\n * @category Plugin helpers\n */\nexport class ImportContext {\n readonly sink: GraphSink;\n\n readonly report: ImportReportBuilder;\n\n readonly options: ResolvedImportOptions;\n\n readonly json: ResolvedJsonOptions;\n\n readonly ids: IdCoercer;\n\n readonly direction: DirectionResolver;\n\n readonly nodes: AttributeWriter;\n\n readonly edges: AttributeWriter;\n\n /** Whether the caller passed `defaultDirected` explicitly (then it beats the dialect's convention). */\n readonly explicitDefaultDirected: boolean;\n\n /** Nodes and edges pushed since the signal was last checked. */\n private elementsSinceCheck = 0;\n\n /**\n * Create the context.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param json - the resolved format options\n * @param explicitDefaultDirected - whether the caller passed defaultDirected\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n json: ResolvedJsonOptions,\n explicitDefaultDirected: boolean,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.json = json;\n this.ids = new IdCoercer(options.ids);\n this.direction = new DirectionResolver(sink, report, options.onMixedDirection);\n this.nodes = new AttributeWriter(sink, \"node\", report);\n this.edges = new AttributeWriter(sink, \"edge\", report);\n this.explicitDefaultDirected = explicitDefaultDirected;\n }\n\n /**\n * Report a `nodeIdFrom` other than \"id\" for a dialect whose ids are unambiguous.\n * @param dialect - the dialect\n * @param idField - where the dialect's ids come from, for the message\n */\n reportNodeIdFrom(dialect: JsonImportDialect, idField: string): void {\n if (this.options.nodeIdFrom !== \"id\") {\n this.report.warning(\n \"unsupported\",\n JSON_ISSUE.OPTION_IGNORED,\n `nodeIdFrom \"${this.options.nodeIdFrom}\" does not apply to ${dialect}; ids are read from ${idField}`,\n { element: \"nodeIdFrom\" },\n );\n }\n }\n\n /**\n * The direction assumed when the file declares none: the caller's `defaultDirected` when given,\n * else the dialect's convention.\n * @param dialect - the dialect\n * @returns the direction\n */\n defaultDirected(dialect: JsonImportDialect): boolean {\n return this.explicitDefaultDirected ? this.options.defaultDirected : DIALECT_DEFAULT_DIRECTED[dialect];\n }\n\n /** The direction the file declares (or the default), set by setHeader(). */\n private fileDirected = false;\n\n /**\n * Rule 1 of design section 8.4: set the sink's direction from the file's header (or the\n * dialect's default) before the first edge, remembering the file's direction for uniformKind().\n * @param directed - the file's direction\n */\n setHeader(directed: boolean): void {\n this.fileDirected = directed;\n this.direction.setHeader(directed);\n }\n\n /**\n * The edge kind every edge of a dialect without per-edge direction has: the file's direction\n * (the resolver expands it when the sink's direction differs).\n * @returns the kind\n */\n uniformKind(): EdgeKind {\n return this.fileDirected ? \"directed\" : \"undirected\";\n }\n\n /**\n * Coerce a node id value per the `ids` option, reporting what cannot be an id. A JSON boolean or\n * null is `unsupported` unless `ids` is \"string\" (design section 8.5); anything the rule rejects\n * is recorded through the per-element catch.\n * @param raw - the JSON value; undefined when the record has no id key\n * @param element - the element name for the issue\n * @returns the id, or null when the value was reported and the element must be skipped\n */\n coerceId(raw: unknown, element: string): NodeId | null {\n if (raw === undefined) {\n this.report.error(\"missing-value\", JSON_ISSUE.MISSING_ID, `${element} has no id`, { element });\n return null;\n }\n if ((typeof raw === \"boolean\" || raw === null) && this.options.ids !== \"string\") {\n const kind = raw === null ? \"null\" : \"boolean\";\n this.report.error(\n \"unsupported\",\n JSON_ISSUE.UNSUPPORTED_ID,\n `${element}: a JSON ${kind} is not a node id (pass ids: \"string\" to coerce it)`,\n { element },\n );\n return null;\n }\n let id: NodeId;\n try {\n id = this.ids.value(this.options.ids === \"string\" && typeof raw === \"number\" ? String(raw) : raw);\n } catch (err) {\n this.report.recordError(err, { element });\n return null;\n }\n const merge = this.ids.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n JSON_ISSUE.ID_MERGED,\n `id text ${JSON.stringify(merge.text)} merged with ${JSON.stringify(merge.previousText)} as ${merge.id}`,\n { element },\n );\n }\n return id;\n }\n\n /**\n * Coerce an id that must be valid for the caller to proceed (hyperedge members): the rejections\n * of coerceId() are thrown instead of recorded.\n * @param raw - the JSON value\n * @param element - the element name\n * @returns the id\n */\n requireId(raw: unknown, element: string): NodeId {\n if ((typeof raw === \"boolean\" || raw === null) && this.options.ids !== \"string\") {\n const kind = raw === null ? \"null\" : \"boolean\";\n throw new GraphFormatError(\"E_INVALID_ID\", `${element}: a JSON ${kind} is not a node id`, {\n reason: \"unsupported id\",\n });\n }\n return this.ids.value(this.options.ids === \"string\" && typeof raw === \"number\" ? String(raw) : raw);\n }\n\n /**\n * Add a node, counting it or recording the failure.\n * @param id - the node id\n * @param element - the element name\n * @param why - more about a repeated id, for the duplicate warning\n * @returns the node index, or -1 when the sink refused the node\n */\n pushNode(id: NodeId, element: string, why = \"\"): number {\n this.checkAbort();\n const existing = this.sink.indexOf(id);\n if (existing !== INVALID_INDEX) {\n this.report.warning(\n \"merged\",\n JSON_ISSUE.DUPLICATE_NODE,\n `${element}: node ${JSON.stringify(id)} already exists${why}; its attributes are merged (the later values win)`,\n { element },\n );\n return existing;\n }\n let index: number;\n try {\n index = this.sink.addNode(id);\n } catch (err) {\n this.skip(err, \"node\", element);\n return -1;\n }\n this.report.counts.nodes++;\n return index;\n }\n\n /**\n * Push one edge through the direction resolver, counting every logical edge the sink gained\n * (both halves of an expanded edge, and the mirrors of an in-place expansion).\n * @param source - the source id\n * @param target - the target id\n * @param kind - the edge's direction in the file\n * @param weight - the weight, or undefined\n * @param element - the element name for issues\n * @returns the primary edge index\n */\n pushEdge(source: NodeId, target: NodeId, kind: EdgeKind, weight: number | undefined, element: string): number {\n this.checkAbort();\n const before = this.sink.edgeCount;\n // endpoints the sink creates (addMissingNodes) count as nodes too, and are reported\n const missingSource = this.sink.indexOf(source) === INVALID_INDEX;\n const missingTarget = source !== target && this.sink.indexOf(target) === INVALID_INDEX;\n const edge = this.direction.addEdge(source, target, kind, weight, { element });\n this.report.counts.edges += this.sink.edgeCount - before;\n if (missingSource) {\n this.dangling(source);\n }\n if (missingTarget) {\n this.dangling(target);\n }\n return edge;\n }\n\n /** Endpoints that named no node and became placeholder nodes, the first few kept for the message. */\n private readonly danglingIds: NodeId[] = [];\n\n private danglingCount = 0;\n\n /** Set when the document has no node section: every node comes from an edge (E_MISSING_SECTION says so). */\n nodesFromEdges = false;\n\n /** Dangling endpoints whose id, as the other JSON type, is a node (`\"1\"` next to the node 1). */\n private readonly nearMatches: NodeId[] = [];\n\n /**\n * Count a placeholder node an edge endpoint created.\n * @param id - the endpoint\n */\n private dangling(id: NodeId): void {\n this.report.counts.nodes++;\n this.danglingCount++;\n if (this.danglingIds.length < DANGLING_SHOWN) {\n this.danglingIds.push(id);\n }\n const other = typeof id === \"number\" ? String(id) : Number(id);\n if (\n this.nearMatches.length < DANGLING_SHOWN &&\n (typeof other === \"string\" || String(other) === id) &&\n this.sink.indexOf(other) !== INVALID_INDEX\n ) {\n this.nearMatches.push(id);\n }\n }\n\n /**\n * Report the edge endpoints that named no node (the shared W_DANGLING_REFERENCE, once with the\n * count): each became a placeholder node, which is rarely what the file meant.\n */\n reportDangling(): void {\n if (this.danglingCount === 0 || this.nodesFromEdges) {\n return;\n }\n const shown = this.danglingIds.map((id) => JSON.stringify(id)).join(\", \");\n const near =\n this.nearMatches.length > 0\n ? `; ${this.nearMatches.map((id) => JSON.stringify(id)).join(\", \")} ${agree(this.nearMatches.length, \"names\", \"name\")} a node id of another JSON type (a string next to a number), which is a different id`\n : \"\";\n this.report.warning(\n \"validation-error\",\n JSON_ISSUE.DANGLING_REFERENCE,\n `${this.danglingCount} edge endpoint${plural(this.danglingCount)} ${agree(this.danglingCount, \"names\", \"name\")} no node and became placeholder nodes: ${shown}${this.danglingCount > DANGLING_SHOWN ? \", ...\" : \"\"}${near}`,\n { element: String(this.danglingIds[0]) },\n );\n }\n\n /**\n * Check the cancellation signal every ABORT_CHECK_INTERVAL pushed elements, so an abort raised\n * while the whole in-memory document is being walked rejects promptly.\n */\n checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * Record a per-element failure and count the skipped element.\n * @param err - the thrown value\n * @param domain - which counter to bump\n * @param element - the element name\n */\n skip(err: unknown, domain: \"node\" | \"edge\", element: string): void {\n this.report.recordError(err, { element });\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * Report an element that is not an object and count it as skipped.\n * @param domain - node or edge\n * @param element - the element name\n * @param what - what was expected\n */\n badElement(domain: \"node\" | \"edge\", element: string, what = \"an object\"): void {\n this.report.error(\"validation-error\", JSON_ISSUE.BAD_ELEMENT, `${element} is not ${what}`, { element });\n this.countSkipped(domain);\n }\n\n /**\n * Count a skipped element whose issue was already recorded.\n * @param domain - node or edge\n */\n countSkipped(domain: \"node\" | \"edge\"): void {\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * Report an edge record without an endpoint and count it as skipped.\n * @param element - the element name\n * @param field - the missing field\n */\n missingEndpoint(element: string, field: string): void {\n this.report.error(\"missing-value\", JSON_ISSUE.MISSING_ENDPOINT, `${element} has no ${field}`, { element });\n this.report.counts.skippedEdges++;\n }\n\n /**\n * Record the shape metadata, the source format and further metadata fields in one setMeta()\n * call (the sink replaces `extra` as a whole).\n * @param shape - the shape record\n * @param patch - further metadata fields\n */\n setMeta(shape: JsonShapeMeta, patch: GraphMetaPatch = {}): void {\n const extra: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n if (value !== undefined) {\n extra[key] = value;\n }\n }\n this.sink.setMeta({ sourceFormat: \"json\", ...patch, extra: { [META_KEY]: extra } });\n }\n\n /**\n * Record which source field the weight came from, so the exporter writes it back under the same\n * key (design section 3.7, `meta.weightOrigin`).\n * @returns the metadata patch, empty for an unweighted import\n */\n weightOriginPatch(): GraphMetaPatch {\n const { weightFrom } = this.options;\n if (weightFrom === null) {\n return {};\n }\n return { weightOrigin: { format: \"json\", id: weightFrom, title: null, type: null, namespace: null } };\n }\n\n /**\n * Write the graph-level attributes of a dict (NetworkX `graph`, JGF `metadata`, graphology\n * `attributes`, Cytoscape `data`), one column per key.\n * @param dict - the dict, or anything else (then reported)\n * @param what - the dict's name for the issue\n */\n writeGraphDict(dict: unknown, what: string): void {\n if (dict === undefined || dict === null) {\n return;\n }\n if (!isJsonObject(dict)) {\n this.report.warning(\"validation-error\", JSON_ISSUE.BAD_FLAG, `${what} is not an object; ignored`, {\n element: what,\n });\n return;\n }\n for (const key of Object.keys(dict)) {\n const value = dict[key];\n if (value === undefined || value === null) {\n continue;\n }\n try {\n this.sink.setGraphValue(key, value);\n } catch (err) {\n this.report.recordError(err, { element: `${what}.${key}` });\n }\n }\n }\n\n /**\n * Read the weight field of an edge record.\n * @param record - the record holding the attributes\n * @returns the weight, or undefined when absent or null; E_INVALID_WEIGHT otherwise\n */\n weightOf(record: JsonRecord): number | undefined {\n const { weightFrom } = this.options;\n if (weightFrom === null || !hasKey(record, weightFrom)) {\n return undefined;\n }\n return weightFromValue(record[weightFrom]);\n }\n\n /**\n * Write the attributes of a nested dict plus the element-level keys the dialect does not\n * define (kept with the `#element` suffix).\n * @param writer - the table writer\n * @param row - the row\n * @param record - the element record\n * @param dict - the nested attribute dict\n * @param structural - the element keys that are not attributes\n * @param weightFrom - the weight key to skip in the dict, or null\n * @param element - the element name for issues\n */\n writeNested(\n writer: AttributeWriter,\n row: number,\n record: JsonRecord,\n dict: JsonRecord,\n structural: ReadonlySet<string>,\n weightFrom: string | null,\n element: string,\n ): void {\n for (const key of Object.keys(dict)) {\n if (key !== weightFrom) {\n writer.write(row, key, dict[key], SUFFIX.data, element);\n }\n }\n for (const key of Object.keys(record)) {\n if (!structural.has(key)) {\n writer.write(row, `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);\n }\n }\n }\n\n /**\n * Write a spec-typed string field (JGF label / relation), reporting a value of another type.\n * @param writer - the table writer\n * @param column - the declared column, or INVALID_INDEX when the file has no such field\n * @param row - the row\n * @param value - the value\n * @param field - the field name\n * @param element - the element name\n */\n writeStringField(\n writer: AttributeWriter,\n column: ColumnHandle,\n row: number,\n value: unknown,\n field: string,\n element: string,\n ): void {\n if (column === INVALID_INDEX || value === undefined || value === null) {\n return;\n }\n if (typeof value !== \"string\") {\n this.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: ${field} must be a string, found ${describe(value)}`,\n { element },\n );\n return;\n }\n writer.set(column, row, value);\n }\n\n /**\n * Declare an edge id column with role \"id\" from a scan of the file's edge ids: f64 when every\n * id is a number, string otherwise (numbers are then stored as their text and reported once).\n * @param edges - the edge records\n * @param read - how to read an edge's raw id\n * @param name - the column name\n * @param unique - whether uniqueness is enforced at freeze\n * @returns the column, or null when no edge has an id\n */\n declareEdgeIds(\n edges: readonly unknown[],\n read: (edge: JsonRecord) => unknown,\n name: string,\n unique: boolean,\n ): EdgeIdColumn | null {\n let numbers = 0;\n let strings = 0;\n let others = 0;\n for (const edge of edges) {\n if (!isJsonObject(edge)) {\n continue;\n }\n const raw = read(edge);\n if (typeof raw === \"number\") {\n numbers++;\n } else if (typeof raw === \"string\") {\n strings++;\n } else if (raw !== undefined && raw !== null) {\n others++;\n }\n }\n if (numbers + strings + others === 0) {\n return null;\n }\n // ids of no usable type still get a column, so edgeIdValue() reports each instead of dropping it\n const dtype = strings === 0 && numbers > 0 ? \"f64\" : \"string\";\n const columnName = uniqueColumnName(name, \"id\", (candidate) => this.edges.taken(candidate));\n const handle = this.edges.declare({ name: columnName, dtype, role: \"id\", nullable: true, unique });\n const stringify = strings > 0 && numbers > 0;\n const seen = unique ? new Set<string>() : null;\n if (stringify) {\n this.report.warning(\n \"coercion\",\n JSON_ISSUE.EDGE_ID_STRINGIFIED,\n `edge ids mix numbers and strings; ${numbers} numeric id${plural(numbers)} stored as text`,\n { element: columnName },\n );\n }\n return { handle, stringify, seen };\n }\n\n /**\n * The value an edge id column stores for a raw id, checked BEFORE the edge is pushed so a bad\n * id skips the edge without touching the sink (design section 11.1).\n * @param column - the column, or null when the file has no edge ids\n * @param raw - the raw id value\n * @returns the value to store, or null when there is nothing to store\n */\n edgeIdValue(column: EdgeIdColumn | null, raw: unknown): string | number | null {\n if (column === null || raw === undefined || raw === null) {\n return null;\n }\n let value: string | number;\n if (typeof raw === \"number\") {\n value = column.stringify ? String(raw) : raw;\n } else if (typeof raw === \"string\") {\n value = raw;\n } else {\n throw new GraphFormatError(\n \"E_COLUMN_TYPE\",\n `an edge id must be a string or a number, found ${describe(raw)}`,\n { found: typeof raw },\n );\n }\n if (column.seen !== null) {\n const text = String(value);\n if (column.seen.has(text)) {\n throw new GraphFormatError(\n JSON_ISSUE.DUPLICATE_EDGE_ID,\n `edge id ${JSON.stringify(value)} is declared more than once; the edge is skipped`,\n { id: value },\n );\n }\n column.seen.add(text);\n }\n return value;\n }\n\n /**\n * Write an edge id value from edgeIdValue().\n * @param column - the column, or null\n * @param edge - the edge index\n * @param value - the value, or null for none\n */\n setEdgeId(column: EdgeIdColumn | null, edge: number, value: string | number | null): void {\n if (column !== null && value !== null) {\n this.edges.set(column.handle, edge, value);\n }\n }\n}\n\n// ============================================================ document level\n\n/**\n * Parse the whole text; syntax errors and empty input abort the import. A key repeated in one\n * object (which JSON.parse silently reduces to its last value) is reported per repetition.\n * @param text - the decoded text\n * @param report - the report\n * @returns the parsed value\n */\nfunction parseDocument(text: string, report: ImportReportBuilder): unknown {\n if (text.trim().length === 0) {\n report.fail(JSON_ISSUE.EMPTY_INPUT, \"the input is empty\");\n }\n let root: unknown;\n let syntaxError: string | null = null;\n // the text the syntax error was found in: the rewrite's when it parsed further than the original\n let errorText = text;\n try {\n root = JSON.parse(text) as unknown;\n } catch (err) {\n syntaxError = err instanceof Error ? err.message : String(err);\n }\n // the fast path: strict JSON without a digit run long enough to be an unsafe integer\n if (syntaxError === null && !MAYBE_UNSAFE_INTEGER.test(text) && !MAYBE_INEXACT_EXPONENT.test(text)) {\n reportDuplicateKeys(text, report);\n return root;\n }\n let scan: ReturnType<typeof rewriteNumbers>;\n try {\n scan = rewriteNumbers(text);\n if (scan.tokens.size > 0 || scan.bigIntegers.length > 0) {\n try {\n root = JSON.parse(scan.text, scan.tokens.size > 0 ? scan.revive : undefined) as unknown;\n syntaxError = null;\n } catch (err) {\n if (err instanceof RangeError) {\n throw err;\n }\n // the rewrite read past the non-standard tokens: its error is the real one\n syntaxError = err instanceof Error ? err.message : String(err);\n errorText = scan.text;\n }\n }\n } catch (err) {\n if (!(err instanceof RangeError)) {\n throw err;\n }\n // the rewrite (quoted big integers, sentinel strings) is longer than one string can hold\n const message = `the document with its numbers rewritten is longer than the most one JavaScript string holds`;\n report.error(\"unsupported\", JSON_ISSUE.TOO_LARGE, message);\n throw report.abort(message, { code: JSON_ISSUE.TOO_LARGE });\n }\n if (syntaxError !== null) {\n return report.fail(JSON_ISSUE.SYNTAX, syntaxMessage(text, syntaxError), {\n line: syntaxLine(errorText, syntaxError),\n });\n }\n reportDuplicateKeys(text, report);\n if (scan.tokens.size > 0) {\n report.warning(\n \"coercion\",\n JSON_ISSUE.NONSTANDARD_NUMBER,\n `the document uses the non-standard token${plural(scan.tokens.size)} ${[...scan.tokens].join(\", \")}, which strict JSON does not allow; read as numbers`,\n );\n }\n if (scan.bigIntegers.length > 0) {\n report.warning(\n \"precision\",\n JSON_ISSUE.BIG_INTEGER,\n `${scan.bigIntegers.length} integer${plural(scan.bigIntegers.length)} beyond 2^53 kept as text so no digit is lost: ${listed(scan.bigIntegers)}`,\n );\n }\n if (scan.inexact.length > 0) {\n report.warning(\n \"precision\",\n JSON_ISSUE.PRECISION,\n `${scan.inexact.length} number literal${plural(scan.inexact.length)} no double holds exactly, read as the nearest double (an infinity beyond the range, 0 below it): ${listed(scan.inexact)}`,\n );\n }\n return root;\n}\n\n/**\n * The first literals of a list for a message, with the count of the rest.\n * @param literals - the literals\n * @returns the text\n */\nfunction listed(literals: readonly string[]): string {\n const more = literals.length - BIG_INTEGERS_SHOWN;\n const shown = literals.slice(0, BIG_INTEGERS_SHOWN).join(\", \");\n return more > 0 ? `${shown} and ${more} more` : shown;\n}\n\n/** How many repeated keys are reported one by one before the rest is summed up. */\nconst DUPLICATE_KEYS_SHOWN = 10;\n\n/**\n * Report every key repeated in one object (JSON.parse keeps the last value, so the earlier one is\n * gone): one warning per repetition up to DUPLICATE_KEYS_SHOWN, then one with the remaining count.\n * @param text - the document text\n * @param report - the report\n */\nfunction reportDuplicateKeys(text: string, report: ImportReportBuilder): void {\n const found = findDuplicateKeys(text);\n let line = 1;\n let counted = 0;\n for (const { key, offset } of found.slice(0, DUPLICATE_KEYS_SHOWN)) {\n line += countLines(text, counted, offset);\n counted = offset;\n report.warning(\n \"merged\",\n JSON_ISSUE.DUPLICATE_ATTRIBUTE,\n `key ${JSON.stringify(key)} appears twice in one object; the earlier value is dropped (JSON.parse keeps the last)`,\n { line, element: key },\n );\n }\n if (found.length > DUPLICATE_KEYS_SHOWN) {\n report.warning(\n \"merged\",\n JSON_ISSUE.DUPLICATE_ATTRIBUTE,\n `${found.length - DUPLICATE_KEYS_SHOWN} more repeated key${plural(found.length - DUPLICATE_KEYS_SHOWN)}; each earlier value is dropped`,\n );\n }\n}\n\n/**\n * The line breaks in a range of the text.\n * @param text - the text\n * @param from - the start offset\n * @param to - the end offset\n * @returns how many \\n the range holds\n */\nfunction countLines(text: string, from: number, to: number): number {\n let lines = 0;\n for (let i = text.indexOf(\"\\n\", from); i >= 0 && i < to; i = text.indexOf(\"\\n\", i + 1)) {\n lines++;\n }\n return lines;\n}\n\n/** The longest text the line of an unpositioned syntax error is searched in (a bisection of JSON.parse calls). */\nconst SYNTAX_SEARCH_LIMIT = 64 * 1024 * 1024;\n\n/**\n * The 1-based line of a JSON.parse error: from the message's \"(line L\" or \"position N\" when the\n * engine gives one, the last line for an unexpected end, else the shortest prefix that fails the\n * same way (V8 names no position for \"Unexpected token\").\n * @param text - the document\n * @param message - the parser's message\n * @returns the line\n */\nfunction syntaxLine(text: string, message: string): number {\n const line = /\\(line (\\d+)/.exec(message);\n if (line !== null) {\n return Number(line[1]);\n }\n const position = /position (\\d+)/.exec(message);\n if (position !== null) {\n return countLines(text, 0, Number(position[1])) + 1;\n }\n if (!message.startsWith(\"Unexpected token\") || text.length > SYNTAX_SEARCH_LIMIT) {\n // ponytail: an unexpected end (or a huge text) is placed on the last line\n return countLines(text, 0, text.length) + 1;\n }\n // the shortest prefix that holds the offending token: shorter prefixes end early instead\n let lo = 0;\n let hi = text.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n let failsOnToken = false;\n try {\n JSON.parse(text.slice(0, mid + 1));\n } catch (err) {\n failsOnToken = err instanceof Error && err.message.startsWith(\"Unexpected token\");\n }\n if (failsOnToken) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return countLines(text, 0, lo) + 1;\n}\n\n/**\n * The E_SYNTAX message: the parser's, with a hint when the text is JSON Lines (one document per\n * line, as apoc.export.json and many loggers write), which this importer does not read.\n * @param text - the document\n * @param message - the parser's message\n * @returns the message\n */\nfunction syntaxMessage(text: string, message: string): string {\n if (looksLikeJsonLines(text)) {\n return `invalid JSON: the input is JSON Lines (one JSON value per line), which is not a graph format graph-io reads; convert it to one JSON document (${message})`;\n }\n return `invalid JSON: ${message}`;\n}\n\n/** How many of the integers kept as text the warning lists. */\nconst BIG_INTEGERS_SHOWN = 10;\n\n/**\n * The dialect to read: the forced one, else the shape rule of sniffJsonDialect(); a document\n * that matches no dialect is a fatal E_JSON_DIALECT.\n * @param root - the parsed document\n * @param forced - the caller's dialect option\n * @param report - the report the failure is recorded in\n * @returns the dialect\n */\nfunction detectDialect(\n root: unknown,\n forced: JsonImportDialect | \"auto\",\n report: ImportReportBuilder,\n): JsonImportDialect {\n if (forced !== \"auto\") {\n return forced;\n }\n const dialect = sniffJsonDialect(root);\n if (dialect !== null) {\n return dialect;\n }\n if (Array.isArray(root)) {\n return report.fail(\n JSON_ISSUE.DIALECT,\n \"a top-level array is only read as Cytoscape elements (objects with a data record)\",\n );\n }\n if (!isJsonObject(root)) {\n return report.fail(JSON_ISSUE.DIALECT, `the document is a JSON ${describe(root)}, not a graph object`);\n }\n return report.fail(\n JSON_ISSUE.DIALECT,\n \"no known dialect: expected nodes / links / edges (node-link), nodes / adjacency (adjacency), children (tree), elements (Cytoscape) or graph (JGF)\",\n );\n}\n\n/**\n * A section that must be an array: fail when it is something else.\n * @param value - the section\n * @param what - its name\n * @param report - the report\n * @returns the array, or null when absent\n */\nfunction arraySection(value: unknown, what: string, report: ImportReportBuilder): readonly unknown[] | null {\n if (value === undefined || value === null) {\n return null;\n }\n if (!Array.isArray(value)) {\n return report.fail(JSON_ISSUE.SHAPE, `${what} must be an array, found ${describe(value)}`, { element: what });\n }\n return value;\n}\n\n/**\n * A boolean flag with a default and a warning when it has another type.\n * @param value - the flag value\n * @param what - its name\n * @param fallback - the default\n * @param report - the report\n * @returns the flag\n */\nfunction flagOf(value: unknown, what: string, fallback: boolean, report: ImportReportBuilder): boolean {\n if (value === undefined || value === null) {\n return fallback;\n }\n if (typeof value === \"boolean\") {\n return value;\n }\n report.warning(\n \"validation-error\",\n JSON_ISSUE.BAD_FLAG,\n `${what} is ${describe(value)}, not a boolean; ${fallback} assumed`,\n { element: what },\n );\n return fallback;\n}\n\n/**\n * The endpoint key and value of an edge record: the explicit key when given, else the first of the\n * default keys the record has (a null value counts as absent).\n * @param record - the edge record\n * @param explicit - the caller's key, or null\n * @param defaults - the default keys\n * @returns the key used (null when none) and its value\n */\nfunction endpointOf(\n record: JsonRecord,\n explicit: string | null,\n defaults: readonly string[],\n): { readonly key: string | null; readonly value: unknown } {\n if (explicit !== null) {\n return { key: present(record, explicit) ? explicit : null, value: record[explicit] };\n }\n for (const key of defaults) {\n if (present(record, key)) {\n return { key, value: record[key] };\n }\n }\n return { key: null, value: undefined };\n}\n\n/**\n * Whether a record has a key with a value other than null: a null endpoint is an absent one.\n * @param record - the record\n * @param key - the key\n * @returns true when the key holds a non-null value\n */\nfunction present(record: JsonRecord, key: string): boolean {\n return hasKey(record, key) && record[key] !== null;\n}\n\n/**\n * Report every key of a record the dialect does not read (W_JSON_UNREAD_KEY): it is dropped.\n * @param ctx - the context\n * @param record - the document or graph record\n * @param known - the keys the dialect reads\n * @param prefix - the record's path for the messages (`\"\"` for the document, `\"graph.\"`)\n */\nfunction reportUnreadKeys(ctx: ImportContext, record: JsonRecord, known: ReadonlySet<string>, prefix: string): void {\n for (const key of Object.keys(record)) {\n if (known.has(key)) {\n continue;\n }\n const value = record[key];\n const entries = Array.isArray(value) && value.length === 1 ? \"entry\" : \"entries\";\n const what = Array.isArray(value) ? `${String(value.length)} ${entries}` : describe(value);\n ctx.report.warning(\n \"unsupported\",\n JSON_ISSUE.UNREAD_KEY,\n `${prefix.length === 0 ? \"top-level key\" : \"key\"} ${prefix}${key} (${what}) is not read; dropped`,\n { element: `${prefix}${key}` },\n );\n }\n}\n\n/** The keys of a vis.js document the reader reads. */\nconst VIS_DOCUMENT_KEYS: ReadonlySet<string> = new Set([\"nodes\", \"edges\"]);\n\n/** The keys of a graphology serialization the reader reads. */\nconst GRAPHOLOGY_DOCUMENT_KEYS: ReadonlySet<string> = new Set([\"nodes\", \"edges\", \"options\", \"attributes\"]);\n\n/** The keys of a JGF graph object the reader reads. */\nconst JGF_GRAPH_KEYS: ReadonlySet<string> = new Set([\n \"id\",\n \"type\",\n \"label\",\n \"directed\",\n \"metadata\",\n \"nodes\",\n \"edges\",\n \"hyperedges\",\n]);\n\n/**\n * Whether any object of an array has a key with a non-null value.\n * @param items - the array\n * @param key - the key\n * @returns true when some element carries the field\n */\nfunction anyHas(items: readonly unknown[], key: string): boolean {\n return items.some((item) => isJsonObject(item) && item[key] !== undefined && item[key] !== null);\n}\n\n/**\n * Whether a value is a non-negative integer below a bound.\n * @param value - the value\n * @param bound - the exclusive bound\n * @returns true for an index\n */\nfunction isIndexBelow(value: unknown, bound: number): boolean {\n return typeof value === \"number\" && Number.isInteger(value) && value >= 0 && value < bound;\n}\n\n// ============================================================ node-link / d3\n\n/**\n * Read a node-link or d3 document.\n * @param ctx - the context\n * @param root - the document\n * @param dialect - \"node-link\" or \"d3\"\n */\nfunction importNodeLink(ctx: ImportContext, root: JsonRecord, dialect: \"node-link\" | \"d3\"): void {\n const { report, json } = ctx;\n let { edgesKey } = json;\n if (edgesKey === null) {\n edgesKey = hasKey(root, \"edges\") || !hasKey(root, \"links\") ? \"edges\" : \"links\";\n }\n const nodes = arraySection(root.nodes, \"nodes\", report);\n const edges = arraySection(root[edgesKey], edgesKey, report);\n if (nodes === null) {\n report.warning(\n \"missing-value\",\n JSON_ISSUE.MISSING_SECTION,\n \"the document has no nodes array; nodes come from the edges\",\n { element: \"nodes\" },\n );\n ctx.nodesFromEdges = true;\n }\n if (edges === null) {\n report.warning(\n \"missing-value\",\n JSON_ISSUE.MISSING_SECTION,\n `the document has no ${edgesKey} array; the graph has no edges`,\n { element: edgesKey },\n );\n }\n const directed = flagOf(root.directed, \"directed\", ctx.defaultDirected(dialect), report);\n const multigraph = hasKey(root, \"multigraph\") ? flagOf(root.multigraph, \"multigraph\", false, report) : null;\n ctx.setHeader(directed);\n ctx.writeGraphDict(root.graph, \"graph\");\n reportUnreadKeys(ctx, root, new Set([\"nodes\", edgesKey, \"directed\", \"multigraph\", \"graph\"]), \"\");\n\n const nodeList = nodes ?? [];\n const edgeList = edges ?? [];\n ctx.sink.reserve(nodeList.length, edgeList.length);\n\n // the id key: the caller's, else \"id\" when any node has it, else \"name\" (d3); nodes without any\n // id key are positional (nodeIdFrom \"index\", or a d3 v3 file whose nodes carry no id at all)\n let { nodeIdKey } = json;\n let positional = ctx.options.nodeIdFrom === \"index\";\n if (!positional && nodeIdKey === null) {\n const candidates = ctx.options.nodeIdFrom === \"label\" ? [\"label\", \"name\", \"id\"] : [\"id\", \"name\"];\n nodeIdKey = candidates.find((key) => anyHas(nodeList, key)) ?? null;\n if (ctx.options.nodeIdFrom === \"label\" && (nodeIdKey === \"id\" || nodeIdKey === \"name\")) {\n report.warning(\n \"unsupported\",\n JSON_ISSUE.OPTION_IGNORED,\n nodeIdKey === \"id\"\n ? 'nodeIdFrom \"label\": no node has a label or name key; ids are read from \"id\"'\n : 'nodeIdFrom \"label\": no node has a \"label\" key; ids are read from \"name\"',\n { element: \"nodeIdFrom\" },\n );\n }\n if (nodeIdKey === null) {\n if (nodeList.length > 0) {\n positional = true;\n report.warning(\n \"missing-value\",\n JSON_ISSUE.POSITIONAL_NODES,\n \"no node has an id or name key; array positions are the node ids\",\n { element: \"nodes\" },\n );\n } else {\n nodeIdKey = \"id\";\n }\n }\n }\n if (positional) {\n nodeIdKey = null;\n }\n let indexLinks: boolean;\n if (positional) {\n indexLinks = true;\n } else if (json.indexLinks === \"auto\") {\n indexLinks = nodeIdKey !== null && looksIndexLinked(nodeList, edgeList, nodeIdKey, json);\n } else {\n ({ indexLinks } = json);\n }\n const positionIds: (NodeId | null)[] | null = indexLinks ? [] : null;\n if (indexLinks && !positional && json.indexLinks === \"auto\" && nodeIdKey !== null) {\n reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);\n }\n\n for (let i = 0; i < nodeList.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodeList[i];\n let pushed: NodeId | null = null;\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n } else {\n let id: NodeId | null;\n if (nodeIdKey === null) {\n id = i;\n } else {\n id = ctx.coerceId(hasKey(record, nodeIdKey) ? record[nodeIdKey] : undefined, element);\n }\n if (id === null) {\n ctx.countSkipped(\"node\");\n } else {\n const index = ctx.pushNode(id, element);\n if (index >= 0) {\n pushed = id;\n writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);\n }\n }\n }\n positionIds?.push(pushed);\n }\n throwIfAborted(ctx.options.signal);\n const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);\n ctx.setMeta(\n {\n dialect,\n edgesKey,\n nodeIdKey,\n indexLinks,\n sourceKey: endpointKeys.source ?? undefined,\n targetKey: endpointKeys.target ?? undefined,\n },\n { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() },\n );\n}\n\n/**\n * Read the node-link / d3 edge records: endpoints by id or array position, the weight, the other\n * keys as attributes.\n * @param ctx - the context\n * @param edgeList - the edge records\n * @param edgesKey - the top-level key they came from, for issues\n * @param positionIds - the ids by array position under index links, or null\n * @param multigraph - the declared multigraph flag, or null when the document has none\n * @returns the source and target keys the first well-formed edge used (null when none did)\n */\nfunction importNodeLinkEdges(\n ctx: ImportContext,\n edgeList: readonly unknown[],\n edgesKey: string,\n positionIds: readonly (NodeId | null)[] | null,\n multigraph: boolean | null,\n): { source: string | null; target: string | null } {\n const { json } = ctx;\n const kind = ctx.uniformKind();\n let sourceKey: string | null = null;\n let targetKey: string | null = null;\n // multigraph false: the pairs seen, to report parallel links; true: the (pair, key) triples, since\n // NetworkX reads a repeated (u, v, key) as one edge\n // ponytail: one string per edge whenever the flag is declared; a hash of the index pair if it shows in profiles\n const pairs = multigraph === null ? null : new Set<string>();\n let parallels = 0;\n for (let i = 0; i < edgeList.length; i++) {\n const element = `${edgesKey}[${i}]`;\n const record = edgeList[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n const source = endpointOf(record, json.sourceKey, NODE_LINK_SOURCE_KEYS);\n const target = endpointOf(record, json.targetKey, NODE_LINK_TARGET_KEYS);\n if (source.key === null || target.key === null) {\n ctx.missingEndpoint(element, source.key === null ? \"source\" : \"target\");\n continue;\n }\n sourceKey ??= source.key;\n targetKey ??= target.key;\n try {\n const u = resolveEndpoint(ctx, source.value, positionIds, element, \"source\");\n const v = resolveEndpoint(ctx, target.value, positionIds, element, \"target\");\n if (u === null || v === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n const weight = ctx.weightOf(record);\n if (pairs !== null) {\n const pair = pairKey(u, v, kind === \"directed\");\n if (multigraph === false) {\n parallels += pairs.has(pair) ? 1 : 0;\n pairs.add(pair);\n } else if (hasKey(record, \"key\")) {\n const triple = `${pair} ${JSON.stringify(record.key)}`;\n if (pairs.has(triple)) {\n throw new GraphFormatError(\n JSON_ISSUE.DUPLICATE_EDGE_ID,\n `${element}: key ${JSON.stringify(record.key)} is repeated for the same pair; NetworkX reads it as the same edge, so it is skipped`,\n { id: String(record.key) },\n );\n }\n pairs.add(triple);\n }\n }\n const edge = ctx.pushEdge(u, v, kind, weight, element);\n const { weightFrom } = ctx.options;\n for (const key of Object.keys(record)) {\n if (key !== source.key && key !== target.key && key !== weightFrom) {\n ctx.edges.write(edge, key, record[key], SUFFIX.data, element);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n if (parallels > 0) {\n ctx.report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `the document declares multigraph false, but ${parallels} link${plural(parallels)} ${agree(parallels, \"repeats\", \"repeat\")} the endpoints of an earlier one; all are kept`,\n { element: edgesKey },\n );\n }\n return { source: sourceKey, target: targetKey };\n}\n\n/**\n * The key of an endpoint pair: ordered for a directed edge, unordered for an undirected one.\n * @param u - the source\n * @param v - the target\n * @param directed - whether the order matters\n * @returns the key\n */\nfunction pairKey(u: NodeId, v: NodeId, directed: boolean): string {\n const a = JSON.stringify(u);\n const b = JSON.stringify(v);\n return directed || a <= b ? `${a} ${b}` : `${b} ${a}`;\n}\n\n/**\n * Warn when indexLinks \"auto\" read integer endpoints as array positions although some also equal\n * a node id's text (`\"2\"`): the file may mean the ids, and the edges are then off by the positions.\n * @param ctx - the context\n * @param nodes - the node records\n * @param edges - the edge records\n * @param nodeIdKey - the node id key\n */\nfunction reportAmbiguousIndexLinks(\n ctx: ImportContext,\n nodes: readonly unknown[],\n edges: readonly unknown[],\n nodeIdKey: string,\n): void {\n const ids = new Set<string>();\n for (const node of nodes) {\n if (isJsonObject(node) && typeof node[nodeIdKey] === \"string\") {\n ids.add(node[nodeIdKey]);\n }\n }\n for (const edge of edges) {\n if (!isJsonObject(edge)) {\n continue;\n }\n for (const value of [\n endpointOf(edge, ctx.json.sourceKey, NODE_LINK_SOURCE_KEYS).value,\n endpointOf(edge, ctx.json.targetKey, NODE_LINK_TARGET_KEYS).value,\n ]) {\n if (typeof value === \"number\" && ids.has(String(value))) {\n ctx.report.warning(\n \"coercion\",\n JSON_ISSUE.INDEX_LINKS,\n `integer endpoints are read as array positions, but ${value} is also a node id; pass indexLinks: false to read the endpoints as ids`,\n { element: \"indexLinks\" },\n );\n return;\n }\n }\n }\n}\n\n/**\n * Write the flat attributes of a node record (every own key the filter keeps).\n * @param writer - the node writer\n * @param index - the node index\n * @param record - the record\n * @param id - the node id, for issues\n * @param keep - which keys are attributes\n */\nfunction writeFlat(\n writer: AttributeWriter,\n index: number,\n record: JsonRecord,\n id: NodeId,\n keep: (key: string) => boolean,\n): void {\n for (const key of Object.keys(record)) {\n if (keep(key)) {\n writer.write(index, key, record[key], SUFFIX.data, String(id));\n }\n }\n}\n\n/**\n * The d3 index-link heuristic: endpoints are array positions when every endpoint is a number, at\n * least one is a non-negative integer, and no node id is a number (a numeric id would make the endpoints ids;\n * research note 07: d3 links reference nodes by array index and are never coerced to ids). An\n * index at or beyond the node count is then E_BAD_INDEX, never a new numeric node.\n * @param nodes - the node records\n * @param edges - the edge records\n * @param nodeIdKey - the node id key\n * @param json - the format options (endpoint keys)\n * @returns true when endpoints are indices\n */\nfunction looksIndexLinked(\n nodes: readonly unknown[],\n edges: readonly unknown[],\n nodeIdKey: string,\n json: ResolvedJsonOptions,\n): boolean {\n if (edges.length === 0 || nodes.length === 0) {\n return false;\n }\n for (const node of nodes) {\n if (isJsonObject(node) && typeof node[nodeIdKey] === \"number\") {\n return false;\n }\n }\n let seen = 0;\n for (const edge of edges) {\n if (!isJsonObject(edge)) {\n continue;\n }\n const s = endpointOf(edge, json.sourceKey, NODE_LINK_SOURCE_KEYS).value;\n const t = endpointOf(edge, json.targetKey, NODE_LINK_TARGET_KEYS).value;\n // a fractional or negative number is a bad index (E_BAD_INDEX), never a reason to read every\n // other endpoint as an id; a missing endpoint is reported on its own\n if ((s !== undefined && typeof s !== \"number\") || (t !== undefined && typeof t !== \"number\")) {\n return false;\n }\n if (isIndexBelow(s, Infinity) || isIndexBelow(t, Infinity)) {\n seen++;\n }\n }\n return seen > 0;\n}\n\n/**\n * Resolve one endpoint: a node id through the coercion rule, or an array position through the\n * ids pushed so far under index links.\n * @param ctx - the context\n * @param raw - the endpoint value\n * @param positionIds - the ids by array position under index links, or null\n * @param element - the edge element name\n * @param field - \"source\" or \"target\"\n * @returns the id, or null when reported\n */\nfunction resolveEndpoint(\n ctx: ImportContext,\n raw: unknown,\n positionIds: readonly (NodeId | null)[] | null,\n element: string,\n field: string,\n): NodeId | null {\n if (positionIds === null) {\n return ctx.coerceId(raw, `${element}.${field}`);\n }\n if (!isIndexBelow(raw, positionIds.length)) {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_INDEX,\n `${element}: ${field} ${describe(raw)} is not a node index below ${positionIds.length}`,\n { element },\n );\n return null;\n }\n const id = positionIds[raw as number];\n if (id === null) {\n ctx.report.error(\"missing-value\", JSON_ISSUE.BAD_INDEX, `${element}: ${field} names a node that was skipped`, {\n element,\n });\n }\n return id;\n}\n\n// ============================================================ vis.js\n\n/**\n * Read a vis.js document: `nodes` with `id`, `edges` with `from` / `to` and an optional `id`.\n * @param ctx - the context\n * @param root - the document\n */\nfunction importVis(ctx: ImportContext, root: JsonRecord): void {\n const { report, json } = ctx;\n const nodes = arraySection(root.nodes, \"nodes\", report) ?? [];\n const edges = arraySection(root.edges, \"edges\", report) ?? [];\n // vis.js options and groups are rendering settings, not graph data\n reportUnreadKeys(ctx, root, VIS_DOCUMENT_KEYS, \"\");\n ctx.setHeader(ctx.defaultDirected(\"vis\"));\n ctx.sink.reserve(nodes.length, edges.length);\n const nodeIdKey = json.nodeIdKey ?? \"id\";\n ctx.reportNodeIdFrom(\"vis\", `the ${JSON.stringify(nodeIdKey)} key`);\n for (let i = 0; i < nodes.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodes[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n continue;\n }\n const id = ctx.coerceId(hasKey(record, nodeIdKey) ? record[nodeIdKey] : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n continue;\n }\n const index = ctx.pushNode(id, element);\n if (index >= 0) {\n writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);\n }\n }\n throwIfAborted(ctx.options.signal);\n const ids = ctx.declareEdgeIds(edges, (edge) => edge.id, \"id\", true);\n const kind = ctx.uniformKind();\n let sourceKey: string | null = null;\n let targetKey: string | null = null;\n for (let i = 0; i < edges.length; i++) {\n const element = `edges[${i}]`;\n const record = edges[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n const source = endpointOf(record, json.sourceKey, VIS_SOURCE_KEYS);\n const target = endpointOf(record, json.targetKey, VIS_TARGET_KEYS);\n if (source.key === null || target.key === null) {\n ctx.missingEndpoint(element, source.key === null ? \"from\" : \"to\");\n continue;\n }\n sourceKey ??= source.key;\n targetKey ??= target.key;\n try {\n const u = ctx.coerceId(source.value, `${element}.from`);\n const v = ctx.coerceId(target.value, `${element}.to`);\n if (u === null || v === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n const idValue = ctx.edgeIdValue(ids, record.id);\n const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(record), element);\n ctx.setEdgeId(ids, edge, idValue);\n const { weightFrom } = ctx.options;\n for (const key of Object.keys(record)) {\n if (key !== source.key && key !== target.key && key !== \"id\" && key !== weightFrom) {\n ctx.edges.write(edge, key, record[key], SUFFIX.data, element);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n // vis.js draws arrows from the `arrows` edge option; the file declares no graph direction, so the\n // arrows stay an attribute and the graph is read as the dialect's default\n const arrows =\n kind === \"undirected\"\n ? edges.filter((e) => isJsonObject(e) && e.arrows !== undefined && e.arrows !== null && e.arrows !== \"\")\n .length\n : 0;\n if (arrows > 0) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `${arrows} edge${plural(arrows)} ${agree(arrows, \"carries\", \"carry\")} vis.js arrows but the graph is read undirected; the arrows are kept as an attribute (pass defaultDirected: true to read the edges as directed)`,\n { element: \"arrows\" },\n );\n }\n ctx.setMeta(\n { dialect: \"vis\", nodeIdKey, sourceKey: sourceKey ?? undefined, targetKey: targetKey ?? undefined },\n ctx.weightOriginPatch(),\n );\n}\n\n// ============================================================ NetworkX adjacency_data / tree_data\n\n/**\n * Read a NetworkX adjacency_data document: `nodes` as in node-link, and `adjacency[i]` the\n * neighbor list of `nodes[i]`, one `{ id, key?, ...attributes }` entry per edge. An undirected\n * file lists every edge from both ends, so an entry whose mirror (the same pair and `key`) was\n * already read is that edge again and is not pushed twice; a self-loop is listed once.\n * @param ctx - the context\n * @param root - the document\n */\nfunction importAdjacency(ctx: ImportContext, root: JsonRecord): void {\n const { report } = ctx;\n const nodes = arraySection(root.nodes, \"nodes\", report) ?? [];\n const adjacency = arraySection(root.adjacency, \"adjacency\", report);\n if (adjacency === null) {\n report.warning(\n \"missing-value\",\n JSON_ISSUE.MISSING_SECTION,\n \"the document has no adjacency array; the graph has no edges\",\n {\n element: \"adjacency\",\n },\n );\n }\n const directed = flagOf(root.directed, \"directed\", ctx.defaultDirected(\"adjacency\"), report);\n const multigraph = hasKey(root, \"multigraph\") ? flagOf(root.multigraph, \"multigraph\", false, report) : null;\n ctx.setHeader(directed);\n // adjacency_data writes the graph dict as a list of [key, value] pairs\n ctx.writeGraphDict(isPairList(root.graph) ? Object.fromEntries(root.graph) : root.graph, \"graph\");\n for (const key of Object.keys(root)) {\n if (key !== \"nodes\" && key !== \"adjacency\" && key !== \"directed\" && key !== \"multigraph\" && key !== \"graph\") {\n report.warning(\n \"unsupported\",\n JSON_ISSUE.UNREAD_KEY,\n `top-level key ${key} (${describe(root[key])}) is not read; dropped`,\n {\n element: key,\n },\n );\n }\n }\n const lists = adjacency ?? [];\n ctx.sink.reserve(\n nodes.length,\n lists.reduce<number>((sum, list) => sum + (Array.isArray(list) ? list.length : 0), 0),\n );\n const idKey = ctx.json.nodeIdKey ?? \"id\";\n ctx.reportNodeIdFrom(\"adjacency\", `the ${JSON.stringify(idKey)} key`);\n const owners: (NodeId | null)[] = [];\n for (let i = 0; i < nodes.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodes[i];\n let pushed: NodeId | null = null;\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n } else {\n const id = ctx.coerceId(hasKey(record, idKey) ? record[idKey] : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n } else {\n const index = ctx.pushNode(id, element);\n if (index >= 0) {\n pushed = id;\n writeFlat(ctx.nodes, index, record, id, (key) => key !== idKey);\n }\n }\n }\n owners.push(pushed);\n }\n throwIfAborted(ctx.options.signal);\n const kind = ctx.uniformKind();\n const { weightFrom } = ctx.options;\n // undirected: entries read once whose mirror is still to come, by pair and key, with their attributes\n const pending = new Map<string, string[]>();\n let disagreeing = 0;\n for (let i = 0; i < lists.length; i++) {\n const element = `adjacency[${i}]`;\n const list = lists[i];\n if (!Array.isArray(list)) {\n report.error(\"validation-error\", JSON_ISSUE.BAD_ELEMENT, `${element} is not an array`, { element });\n continue;\n }\n const source = i < owners.length ? owners[i] : null;\n if (source === null) {\n const why = i < nodes.length ? `nodes[${i}] was skipped` : `there is no nodes[${i}]`;\n report.error(\n \"missing-value\",\n JSON_ISSUE.BAD_INDEX,\n `${element}: ${why}; its ${list.length} edge${plural(list.length)} ${agree(list.length, \"is\", \"are\")} skipped`,\n {\n element,\n },\n );\n report.counts.skippedEdges += list.length;\n continue;\n }\n for (let j = 0; j < list.length; j++) {\n const entry = `${element}[${j}]`;\n const record = list[j];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", entry);\n continue;\n }\n if (!hasKey(record, idKey)) {\n ctx.missingEndpoint(entry, idKey);\n continue;\n }\n try {\n const target = ctx.coerceId(record[idKey], `${entry}.${idKey}`);\n if (target === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n if (!directed) {\n const mirror = mirroredEntry(pending, source, target, record, idKey);\n disagreeing += mirror === \"disagrees\" ? 1 : 0;\n if (mirror !== \"new\") {\n continue;\n }\n }\n const edge = ctx.pushEdge(source, target, kind, ctx.weightOf(record), entry);\n for (const key of Object.keys(record)) {\n if (key !== idKey && key !== weightFrom) {\n ctx.edges.write(edge, key, record[key], SUFFIX.data, element);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", entry);\n }\n }\n }\n reportAdjacencyShape(ctx, nodes.length, adjacency === null ? null : lists.length, disagreeing, pending);\n ctx.setMeta({}, { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() });\n}\n\n/**\n * Report what an adjacency_data document leaves inconsistent: nodes without an adjacency list\n * (NetworkX writes one per node, so the file was cut), undirected edges whose two listings carry\n * different attributes (the first is kept), and undirected entries whose mirror never came.\n * @param ctx - the context\n * @param nodes - the number of node records\n * @param lists - the number of adjacency lists, or null when the section is missing (reported already)\n * @param disagreeing - the mirrors whose attributes differ\n * @param pending - the entries still awaiting their mirror\n */\nfunction reportAdjacencyShape(\n ctx: ImportContext,\n nodes: number,\n lists: number | null,\n disagreeing: number,\n pending: ReadonlyMap<string, readonly string[]>,\n): void {\n const { report } = ctx;\n if (lists !== null && lists < nodes) {\n report.warning(\n \"missing-value\",\n JSON_ISSUE.MISSING_SECTION,\n `${nodes - lists} node${plural(nodes - lists)} from nodes[${lists}] on ${agree(nodes - lists, \"has\", \"have\")} no adjacency list (NetworkX writes one per node); their edges listed elsewhere are kept`,\n { element: \"adjacency\" },\n );\n }\n if (disagreeing > 0) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `the two listings of ${disagreeing} undirected edge${plural(disagreeing)} ${agree(disagreeing, \"disagrees\", \"disagree\")} on their attributes; the first listing is kept`,\n { element: \"adjacency\" },\n );\n }\n let unmatched = 0;\n for (const waiting of pending.values()) {\n unmatched += waiting.length;\n }\n if (unmatched > 0) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `${unmatched} undirected adjacency entr(ies) have no mirror in the other node's list; each is read as one edge`,\n { element: \"adjacency\" },\n );\n }\n}\n\n/**\n * A JSON.stringify replacer that writes every object's keys in sorted order.\n * @param _key - the key\n * @param value - the value\n * @returns the value, an object with its keys sorted\n */\nfunction sortedKeys(_key: string, value: unknown): unknown {\n return isJsonObject(value) ? Object.fromEntries(Object.entries(value).sort(([x], [y]) => (x < y ? -1 : 1))) : value;\n}\n\n/**\n * Whether an undirected adjacency entry is the mirror of one already read (the same unordered pair\n * and key), consuming it; otherwise the entry is remembered as awaiting its mirror. A self-loop is\n * listed once and never awaits one.\n * @param pending - the entries awaiting their mirror, by owner, other end and key: their attributes\n * @param source - the owner of the list\n * @param target - the entry's node\n * @param record - the entry\n * @param idKey - the entry's id key (not an attribute)\n * @returns \"new\" for an entry to push, \"mirror\" for the second listing of one read, \"disagrees\"\n * for a second listing with other attributes\n */\nfunction mirroredEntry(\n pending: Map<string, string[]>,\n source: NodeId,\n target: NodeId,\n record: JsonRecord,\n idKey: string,\n): \"new\" | \"mirror\" | \"disagrees\" {\n const a = JSON.stringify(source);\n const b = JSON.stringify(target);\n if (a === b) {\n return \"new\";\n }\n const k = JSON.stringify(record.key ?? null);\n // key order is not part of a JSON object, so two listings in another order still agree\n const attributes = JSON.stringify(\n Object.fromEntries(Object.entries(record).filter(([key]) => key !== idKey)),\n sortedKeys,\n );\n // an entry is the mirror of one listed by the other end, never of a parallel entry of its own list\n const waiting = pending.get(`${b} ${a} ${k}`);\n if (waiting !== undefined && waiting.length > 0) {\n const first = waiting.shift();\n return first === attributes ? \"mirror\" : \"disagrees\";\n }\n const own = `${a} ${b} ${k}`;\n const list = pending.get(own);\n if (list === undefined) {\n pending.set(own, [attributes]);\n } else {\n list.push(attributes);\n }\n return \"new\";\n}\n\n/**\n * Whether a value is a list of [string, value] pairs, the shape adjacency_data gives the graph dict.\n * @param value - the value\n * @returns true for an array whose items are all two-element arrays with a string first\n */\nfunction isPairList(value: unknown): value is [string, unknown][] {\n return Array.isArray(value) && value.every((p) => Array.isArray(p) && p.length === 2 && typeof p[0] === \"string\");\n}\n\n/**\n * Read a NetworkX tree_data document: a nested record with the node id, its attributes and a\n * `children` array of records of the same shape; every child gets a directed edge from its parent.\n * Walked depth first in document order with an explicit stack. A record without a usable id is\n * reported and skipped, and its children are still read (as roots, without an edge).\n * @param ctx - the context\n * @param root - the root record\n */\nfunction importTree(ctx: ImportContext, root: JsonRecord): void {\n const idKey = ctx.json.nodeIdKey ?? \"id\";\n ctx.setHeader(ctx.defaultDirected(\"tree\"));\n ctx.reportNodeIdFrom(\"tree\", `the ${JSON.stringify(idKey)} key`);\n const kind = ctx.uniformKind();\n const stack: { record: unknown; element: string; parent: NodeId | null }[] = [\n { record: root, element: \"root\", parent: null },\n ];\n for (let item = stack.pop(); item !== undefined; item = stack.pop()) {\n const { record, element, parent } = item;\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n continue;\n }\n let id = ctx.coerceId(hasKey(record, idKey) ? record[idKey] : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n } else if (ctx.pushNode(id, element) < 0) {\n id = null;\n } else {\n writeFlat(ctx.nodes, ctx.sink.indexOf(id), record, id, (key) => key !== idKey && key !== \"children\");\n if (parent !== null) {\n try {\n ctx.pushEdge(parent, id, kind, undefined, element);\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n }\n const { children } = record;\n if (Array.isArray(children)) {\n for (let k = children.length - 1; k >= 0; k--) {\n stack.push({ record: children[k], element: `${element}.children[${k}]`, parent: id });\n }\n } else if (children !== undefined && children !== null) {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: children must be an array, found ${describe(children)}`,\n { element },\n );\n }\n }\n ctx.setMeta({});\n}\n\n// ============================================================ graphology\n\n/**\n * Read a graphology serialization: `options.type` decides the header direction (\"mixed\" or absent:\n * from the edges' `undirected` flags), `options.multi` the declared multigraph flag, node `key`\n * the id, `attributes` the columns, edge `key` the edge id.\n * @param ctx - the context\n * @param root - the document\n */\nfunction importGraphology(ctx: ImportContext, root: JsonRecord): void {\n const { report } = ctx;\n const nodes = arraySection(root.nodes, \"nodes\", report) ?? [];\n const edges = arraySection(root.edges, \"edges\", report) ?? [];\n reportUnreadKeys(ctx, root, GRAPHOLOGY_DOCUMENT_KEYS, \"\");\n const options = isJsonObject(root.options) ? root.options : {};\n if (hasKey(root, \"options\") && !isJsonObject(root.options)) {\n report.warning(\"validation-error\", JSON_ISSUE.BAD_FLAG, \"options is not an object; ignored\", {\n element: \"options\",\n });\n }\n let type: \"directed\" | \"undirected\" | \"mixed\";\n if (options.type === \"directed\" || options.type === \"undirected\" || options.type === \"mixed\") {\n ({ type } = options);\n } else {\n if (options.type !== undefined && options.type !== null) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.BAD_FLAG,\n `options.type ${describe(options.type)} is not directed, undirected or mixed; mixed assumed`,\n { element: \"options.type\" },\n );\n }\n type = \"mixed\";\n }\n let directed: boolean;\n if (type === \"mixed\") {\n const objects = edges.filter((edge) => isJsonObject(edge)) as JsonRecord[];\n const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;\n directed = objects.length === 0 ? ctx.defaultDirected(\"graphology\") : undirectedEdges < objects.length;\n } else {\n directed = type === \"directed\";\n }\n ctx.setHeader(directed);\n const multi = hasKey(options, \"multi\") ? flagOf(options.multi, \"options.multi\", false, report) : null;\n const allowSelfLoops = hasKey(options, \"allowSelfLoops\")\n ? flagOf(options.allowSelfLoops, \"options.allowSelfLoops\", true, report)\n : undefined;\n ctx.writeGraphDict(root.attributes, \"attributes\");\n ctx.reportNodeIdFrom(\"graphology\", \"the node key\");\n ctx.sink.reserve(nodes.length, edges.length);\n\n for (let i = 0; i < nodes.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodes[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n continue;\n }\n const id = ctx.coerceId(hasKey(record, \"key\") ? record.key : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n continue;\n }\n pushNestedNode(ctx, id, record, \"attributes\", GRAPHOLOGY_NODE_KEYS, element);\n }\n throwIfAborted(ctx.options.signal);\n\n const ids = ctx.declareEdgeIds(edges, (edge) => edge.key, \"key\", true);\n // what the edges do against the declared options: graphology itself refuses such a document\n const violations = { selfLoops: 0, parallels: 0, flags: 0 };\n const pairs = multi === false ? new Set<string>() : null;\n for (let i = 0; i < edges.length; i++) {\n const element = `edges[${i}]`;\n const record = edges[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n if (!present(record, \"source\") || !present(record, \"target\")) {\n ctx.missingEndpoint(element, present(record, \"source\") ? \"target\" : \"source\");\n continue;\n }\n try {\n const u = ctx.coerceId(record.source, `${element}.source`);\n const v = ctx.coerceId(record.target, `${element}.target`);\n if (u === null || v === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n let kind: EdgeKind;\n if (type === \"mixed\") {\n kind = flagOf(record.undirected, `${element}.undirected`, false, report) ? \"undirected\" : \"directed\";\n } else {\n kind = type;\n if (typeof record.undirected === \"boolean\" && record.undirected !== (type === \"undirected\")) {\n violations.flags++;\n }\n }\n const { attributes: rawAttributes } = record;\n if (rawAttributes !== undefined && rawAttributes !== null && !isJsonObject(rawAttributes)) {\n report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: attributes must be an object, found ${describe(rawAttributes)}`,\n { element },\n );\n }\n const attributes = isJsonObject(rawAttributes) ? rawAttributes : {};\n const idValue = ctx.edgeIdValue(ids, record.key);\n const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);\n ctx.setEdgeId(ids, edge, idValue);\n ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);\n if (allowSelfLoops === false && u === v) {\n violations.selfLoops++;\n }\n if (pairs !== null) {\n const pair = `${kind} ${pairKey(u, v, kind === \"directed\")}`;\n violations.parallels += pairs.has(pair) ? 1 : 0;\n pairs.add(pair);\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n reportGraphologyViolations(ctx, violations, type);\n ctx.setMeta({ dialect: \"graphology\", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });\n}\n\n/**\n * Report the edges that contradict a graphology document's declared options (W_JSON_INCONSISTENT,\n * one warning per kind); they are kept.\n * @param ctx - the context\n * @param violations - the counts\n * @param violations.selfLoops - self-loops under allowSelfLoops false\n * @param violations.parallels - parallel edges under multi false\n * @param violations.flags - per-edge undirected flags against options.type\n * @param type - options.type\n */\nfunction reportGraphologyViolations(\n ctx: ImportContext,\n violations: { readonly selfLoops: number; readonly parallels: number; readonly flags: number },\n type: string,\n): void {\n const notes: string[] = [];\n if (violations.selfLoops > 0) {\n notes.push(\n `options.allowSelfLoops is false, but ${violations.selfLoops} self-loop${plural(violations.selfLoops)} ${agree(violations.selfLoops, \"is\", \"are\")} listed`,\n );\n }\n if (violations.parallels > 0) {\n notes.push(\n `options.multi is false, but ${violations.parallels} parallel edge${plural(violations.parallels)} ${agree(violations.parallels, \"is\", \"are\")} listed`,\n );\n }\n if (violations.flags > 0) {\n notes.push(\n `options.type is ${type}, but ${violations.flags} edge${plural(violations.flags)} ${agree(violations.flags, \"carries\", \"carry\")} the other undirected flag; read as ${type}`,\n );\n }\n for (const note of notes) {\n ctx.report.warning(\"validation-error\", JSON_ISSUE.INCONSISTENT, `${note}; every edge is kept`, {\n element: \"options\",\n });\n }\n}\n\n/**\n * Push a node whose attributes live in a nested dict (graphology `attributes`, JGF `metadata`);\n * element-level keys the dialect does not define are kept with the `#element` suffix.\n * @param ctx - the context\n * @param id - the node id\n * @param record - the element record\n * @param dictKey - the key of the nested dict\n * @param structural - the element keys that are not attributes\n * @param element - the element name\n * @returns the node index, or -1 when skipped\n */\nfunction pushNestedNode(\n ctx: ImportContext,\n id: NodeId,\n record: JsonRecord,\n dictKey: string,\n structural: ReadonlySet<string>,\n element: string,\n): number {\n const index = ctx.pushNode(id, element);\n if (index < 0) {\n return index;\n }\n try {\n const dict = record[dictKey];\n if (dict !== undefined && dict !== null && !isJsonObject(dict)) {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: ${dictKey} must be an object, found ${describe(dict)}`,\n { element },\n );\n }\n ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, null, element);\n } catch (err) {\n ctx.report.recordError(err, { element: String(id) });\n }\n return index;\n}\n\n// ============================================================ JSON Graph Format\n\n/**\n * Read a JGF v2 document (`graph` or `graphs[graphIndex]`): nodes keyed by id (or a v1 array with\n * `id`), `label` with role \"label\", `metadata` as columns, edges with `id` / `relation` /\n * `directed` / `label` / `metadata`, hyperedges per the `hyperedges` option.\n * @param ctx - the context\n * @param root - the document\n */\nfunction importJgf(ctx: ImportContext, root: JsonRecord): void {\n const { report } = ctx;\n const graph = jgfGraphOf(ctx, root);\n const edges = arraySection(graph.edges, \"graph.edges\", report) ?? [];\n const hyperedges = arraySection(graph.hyperedges, \"graph.hyperedges\", report) ?? [];\n const nodesRaw: unknown = graph.nodes;\n if (nodesRaw !== undefined && nodesRaw !== null && !isJsonObject(nodesRaw) && !Array.isArray(nodesRaw)) {\n report.fail(\n JSON_ISSUE.SHAPE,\n `graph.nodes must be an object keyed by id or an array, found ${describe(nodesRaw)}`,\n );\n }\n const nodeRecords: readonly unknown[] = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});\n\n let directed: boolean;\n if (typeof graph.directed === \"boolean\") {\n ({ directed } = graph);\n } else if (ctx.explicitDefaultDirected) {\n directed = ctx.options.defaultDirected;\n } else {\n if (graph.directed !== undefined && graph.directed !== null) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.BAD_FLAG,\n `graph.directed is ${describe(graph.directed)}, not a boolean`,\n { element: \"graph.directed\" },\n );\n }\n // the spec default is true; a file whose every edge says directed: false is read as undirected\n const objects = edges.filter((edge) => isJsonObject(edge)) as JsonRecord[];\n directed = objects.length === 0 || !objects.every((edge) => edge.directed === false);\n }\n ctx.setHeader(directed);\n ctx.writeGraphDict(graph.metadata, \"graph.metadata\");\n const shape: JsonShapeMeta = {\n dialect: \"jgf\",\n id: typeof graph.id === \"string\" ? graph.id : undefined,\n type: typeof graph.type === \"string\" ? graph.type : undefined,\n };\n const label = typeof graph.label === \"string\" ? graph.label : null;\n\n ctx.reportNodeIdFrom(\"jgf\", \"the node keys\");\n ctx.sink.reserve(nodeRecords.length, edges.length);\n const labelColumn = ctx.nodes.declareIf(\n { name: \"label\", dtype: \"string\", role: \"label\", nullable: true },\n anyHas(nodeRecords, \"label\"),\n );\n if (isJsonObject(nodesRaw)) {\n for (const key of Object.keys(nodesRaw)) {\n const element = `nodes[${JSON.stringify(key)}]`;\n const record = nodesRaw[key];\n if (record !== null && !isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n continue;\n }\n const id = ctx.coerceId(key, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n continue;\n }\n if (record !== null && hasKey(record, \"id\") && record.id !== key) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `${element}: the inner id ${describe(record.id)} differs from the key; the key is the id, the inner one is kept as id${SUFFIX.element}`,\n { element },\n );\n }\n pushJgfNode(ctx, id, record ?? {}, labelColumn, element);\n }\n } else {\n for (let i = 0; i < nodeRecords.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodeRecords[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n continue;\n }\n const id = ctx.coerceId(hasKey(record, \"id\") ? record.id : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n continue;\n }\n pushJgfNode(ctx, id, record, labelColumn, element);\n }\n }\n throwIfAborted(ctx.options.signal);\n\n const ids = ctx.declareEdgeIds([...edges, ...hyperedges], (edge) => edge.id, \"id\", false);\n const relationColumn = ctx.edges.declareIf(\n { name: \"relation\", dtype: \"string\", role: \"kind\", nullable: true },\n anyHas(edges, \"relation\") || anyHas(hyperedges, \"relation\"),\n );\n const edgeLabelColumn = ctx.edges.declareIf(\n { name: \"label\", dtype: \"string\", role: \"label\", nullable: true },\n anyHas(edges, \"label\") || anyHas(hyperedges, \"label\"),\n );\n const writeJgfEdge = (\n record: JsonRecord,\n u: NodeId,\n v: NodeId,\n kind: EdgeKind,\n element: string,\n structural: ReadonlySet<string> = JGF_EDGE_KEYS,\n ): void => {\n const { metadata } = record;\n const dict = isJsonObject(metadata) ? metadata : {};\n const idValue = ctx.edgeIdValue(ids, record.id);\n const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(dict), element);\n ctx.setEdgeId(ids, edge, idValue);\n ctx.writeStringField(ctx.edges, relationColumn, edge, record.relation, \"relation\", element);\n ctx.writeStringField(ctx.edges, edgeLabelColumn, edge, record.label, \"label\", element);\n if (metadata !== undefined && metadata !== null && !isJsonObject(metadata)) {\n report.error(\"validation-error\", JSON_ISSUE.BAD_VALUE, `${element}: metadata must be an object`, {\n element,\n });\n }\n ctx.writeNested(ctx.edges, edge, record, dict, structural, ctx.options.weightFrom, element);\n };\n\n for (let i = 0; i < edges.length; i++) {\n const element = `edges[${i}]`;\n const record = edges[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n if (!present(record, \"source\") || !present(record, \"target\")) {\n ctx.missingEndpoint(element, present(record, \"source\") ? \"target\" : \"source\");\n continue;\n }\n try {\n const u = ctx.coerceId(record.source, `${element}.source`);\n const v = ctx.coerceId(record.target, `${element}.target`);\n if (u === null || v === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n const edgeDirected = flagOf(record.directed, `${element}.directed`, directed, report);\n writeJgfEdge(record, u, v, edgeDirected ? \"directed\" : \"undirected\", element);\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n\n importHyperedges(ctx, hyperedges, directed, writeJgfEdge);\n ctx.setMeta(shape, { name: label, ...ctx.weightOriginPatch() });\n}\n\n/**\n * The graph object of a JGF document: `graph`, or the graph of `graphs` that graphIndex /\n * graphName choose (chooseGraph()).\n * @param ctx - the context\n * @param root - the document\n * @returns the graph object; the import fails when there is none\n */\nfunction jgfGraphOf(ctx: ImportContext, root: JsonRecord): JsonRecord {\n const single = isJsonObject(root.graph);\n // a document with both graph and graphs is read by its graph; the graphs are not\n reportUnreadKeys(ctx, root, new Set([single ? \"graph\" : \"graphs\"]), \"\");\n const graph = single ? (root.graph as JsonRecord) : chosenGraph(ctx, root, \"JGF\");\n const prefix = single ? \"graph.\" : `graphs[${(root.graphs as unknown[]).indexOf(graph)}].`;\n reportUnreadKeys(ctx, graph, JGF_GRAPH_KEYS, prefix);\n for (const key of [\"id\", \"type\", \"label\"]) {\n if (graph[key] !== undefined && graph[key] !== null && typeof graph[key] !== \"string\") {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${prefix}${key} must be a string, found ${describe(graph[key])}; ignored`,\n { element: `${prefix}${key}` },\n );\n }\n }\n return graph;\n}\n\n/**\n * The graph of a `graphs` array (JGF, OBO Graphs) that graphIndex / graphName choose, with\n * W_MULTIPLE_GRAPHS when the others are skipped; importAll() reads graphs[graphIndex].\n * @param ctx - the context\n * @param root - the document\n * @param what - the dialect's name, for the messages\n * @returns the graph object; the import fails when there is none\n * @category Plugin helpers\n */\nexport function chosenGraph(ctx: ImportContext, root: JsonRecord, what: string): JsonRecord {\n const { report } = ctx;\n const graphs = arraySection(root.graphs, \"graphs\", report) ?? [];\n if (graphs.length === 0) {\n report.fail(JSON_ISSUE.SHAPE, `a ${what} document needs a graph object or a non-empty graphs array`);\n }\n const index =\n ctx.json.all === true ? ctx.json.graphIndex : chooseGraph(graphs.map(graphNameOf), ctx.json.choice, report);\n if (graphs.length > 1 && ctx.json.all !== true && !graphChosen(ctx.json.choice)) {\n report.warning(\n \"unsupported\",\n JSON_ISSUE.MULTIPLE_GRAPHS,\n `the document holds ${graphs.length} graphs; only graphs[${index}] is read (${graphs.length - 1} skipped); importAllGraphs() reads every one`,\n { element: \"graphs\" },\n );\n }\n const graph = graphs[index];\n if (!isJsonObject(graph)) {\n if (ctx.json.all !== true) {\n return report.fail(JSON_ISSUE.SHAPE, `graphs[${index}] is not an object`);\n }\n // importAll(): one bad graph is that graph's error, read as empty; the others are still read\n report.error(\"validation-error\", JSON_ISSUE.SHAPE, `graphs[${index}] is not an object; it is read as empty`, {\n element: `graphs[${index}]`,\n });\n return {};\n }\n return graph;\n}\n\n/**\n * The name a graph of a `graphs` array is listed and chosen by: its `id`, else its `label` (JGF)\n * or `lbl` (OBO Graphs).\n * @param graph - the graph\n * @returns the name, or null\n */\nfunction graphNameOf(graph: unknown): string | null {\n if (!isJsonObject(graph)) {\n return null;\n }\n for (const key of [\"id\", \"label\", \"lbl\"]) {\n if (typeof graph[key] === \"string\") {\n return graph[key];\n }\n }\n return null;\n}\n\n/**\n * How many elements a nodes or edges section holds: an array's length, an object's key count, 0\n * when absent, null for anything else.\n * @param section - the section\n * @returns the count, or null\n */\nfunction countOf(section: unknown): number | null {\n if (section === undefined || section === null) {\n return 0;\n }\n if (Array.isArray(section)) {\n return section.length;\n }\n return isJsonObject(section) ? Object.keys(section).length : null;\n}\n\n/**\n * The graphs of a parsed document, for listGraphs(): each entry of a JGF or OBO Graphs `graphs`\n * array with its name and counts; any other document holds one graph.\n * @param root - the parsed document\n * @param dialect - its dialect\n * @returns the listings\n */\nfunction listingsOf(root: unknown, dialect: JsonImportDialect): GraphListing[] {\n if ((dialect === \"jgf\" || dialect === \"obographs\") && isJsonObject(root)) {\n if (Array.isArray(root.graphs) && !isJsonObject(root.graph)) {\n return root.graphs.map((graph: unknown, index) => ({\n index,\n name: graphNameOf(graph),\n nodes: isJsonObject(graph) ? countOf(graph.nodes) : null,\n edges: isJsonObject(graph) ? countOf(graph.edges) : null,\n }));\n }\n if (isJsonObject(root.graph)) {\n const { graph } = root;\n return [{ index: 0, name: graphNameOf(graph), nodes: countOf(graph.nodes), edges: countOf(graph.edges) }];\n }\n }\n return [{ index: 0, name: null, nodes: null, edges: null }];\n}\n\n/**\n * Whether a text that is not one JSON document is JSON Lines / NDJSON: its first two non-blank\n * lines are each a JSON object or array.\n * @param text - the document\n * @returns true for JSON Lines\n */\nfunction looksLikeJsonLines(text: string): boolean {\n const lines = text\n .slice(0, 64 * 1024)\n .split(/\\r?\\n/)\n .filter((line) => line.trim().length > 0)\n .slice(0, 2);\n return (\n lines.length === 2 &&\n lines.every((line) => {\n try {\n const value: unknown = JSON.parse(line);\n return typeof value === \"object\" && value !== null;\n } catch {\n return false;\n }\n })\n );\n}\n\n/**\n * Push a JGF node: `label` into the declared column, `metadata` as attributes.\n * @param ctx - the context\n * @param id - the node id\n * @param record - the node record\n * @param labelColumn - the label column handle, or INVALID_INDEX\n * @param element - the element name\n */\nfunction pushJgfNode(\n ctx: ImportContext,\n id: NodeId,\n record: JsonRecord,\n labelColumn: ColumnHandle,\n element: string,\n): void {\n const index = ctx.pushNode(id, element);\n if (index < 0) {\n return;\n }\n try {\n ctx.writeStringField(ctx.nodes, labelColumn, index, record.label, \"label\", element);\n const { metadata } = record;\n if (metadata !== undefined && metadata !== null && !isJsonObject(metadata)) {\n ctx.report.error(\"validation-error\", JSON_ISSUE.BAD_VALUE, `${element}: metadata must be an object`, {\n element,\n });\n }\n ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, null, element);\n } catch (err) {\n ctx.report.recordError(err, { element: String(id) });\n }\n}\n\n/**\n * JGF hyperedges per the `hyperedges` option: \"error\" aborts, \"skip\" (default) records a warning\n * and a loss note, \"star\" and \"clique\" expand an undirected `{ nodes }` hyperedge into edges from\n * its first node (star) or between every pair (clique); a directed `{ source, target }` hyperedge\n * becomes every source -> target edge under both policies. Every expanded edge carries the\n * hyperedge's id, relation, label and metadata.\n * @param ctx - the context\n * @param hyperedges - the hyperedge records\n * @param directed - the graph's direction\n * @param push - the edge writer of the JGF reader\n */\nfunction importHyperedges(\n ctx: ImportContext,\n hyperedges: readonly unknown[],\n directed: boolean,\n push: (\n record: JsonRecord,\n u: NodeId,\n v: NodeId,\n kind: EdgeKind,\n element: string,\n structural: ReadonlySet<string>,\n ) => void,\n): void {\n if (hyperedges.length === 0) {\n return;\n }\n const { report } = ctx;\n const policy = ctx.options.hyperedges;\n if (policy === \"error\") {\n report.error(\n \"unsupported\",\n JSON_ISSUE.HYPEREDGE,\n `${hyperedges.length} hyperedge${plural(hyperedges.length)} (hyperedges: \"error\")`,\n {\n element: \"hyperedges\",\n },\n );\n throw report.abort(\"hyperedges refused\", { code: JSON_ISSUE.HYPEREDGE, count: hyperedges.length });\n }\n if (policy === \"skip\") {\n report.warning(\n \"unsupported\",\n JSON_ISSUE.HYPEREDGES_SKIPPED,\n `${hyperedges.length} hyperedge${plural(hyperedges.length)} skipped`,\n {\n element: \"hyperedges\",\n },\n );\n report.loss(\n JSON_ISSUE.HYPEREDGES_SKIPPED,\n `${hyperedges.length} hyperedge${plural(hyperedges.length)} ${agree(hyperedges.length, \"was\", \"were\")} not imported`,\n null,\n hyperedges.length,\n );\n return;\n }\n // each expanded edge is pushed on its own, so one the sink refuses is reported and counted\n // while the others stay\n const expand = (\n record: JsonRecord,\n pairs: readonly (readonly [NodeId, NodeId])[],\n kind: EdgeKind,\n element: string,\n ): void => {\n for (const [u, v] of pairs) {\n try {\n push(record, u, v, kind, element, JGF_HYPEREDGE_KEYS);\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n };\n // the edges expanded so far: the cap is on the whole import, so many hyperedges just under it\n // cannot amplify without bound either\n const budget = { used: 0 };\n for (let i = 0; i < hyperedges.length; i++) {\n const element = `hyperedges[${i}]`;\n const record = hyperedges[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n try {\n if (Array.isArray(record.nodes)) {\n const members = distinctMembers(\n ctx,\n record.nodes.map((raw) => ctx.requireId(raw, element)),\n element,\n );\n if (members.length < 2) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${element}: an undirected hyperedge needs two or more nodes`,\n { reason: \"hyperedge shape\" },\n );\n }\n const n = members.length;\n checkExpansion(policy === \"star\" ? n - 1 : (n * (n - 1)) / 2, budget, element);\n const pairs: [NodeId, NodeId][] = [];\n if (policy === \"star\") {\n for (let k = 1; k < n; k++) {\n pairs.push([members[0], members[k]]);\n }\n } else {\n for (let a = 0; a < n; a++) {\n for (let b = a + 1; b < n; b++) {\n pairs.push([members[a], members[b]]);\n }\n }\n }\n expand(record, pairs, directed ? \"directed\" : \"undirected\", element);\n } else if (Array.isArray(record.source) && Array.isArray(record.target)) {\n const sources = record.source.map((raw) => ctx.requireId(raw, element));\n const targets = record.target.map((raw) => ctx.requireId(raw, element));\n if (sources.length === 0 || targets.length === 0) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${element}: a directed hyperedge needs sources and targets`,\n { reason: \"hyperedge shape\" },\n );\n }\n checkExpansion(sources.length * targets.length, budget, element);\n expand(\n record,\n sources.flatMap((s) => targets.map((t) => [s, t] as const)),\n \"directed\",\n element,\n );\n } else {\n report.error(\n \"validation-error\",\n JSON_ISSUE.HYPEREDGE_SHAPE,\n `${element} has neither a nodes array nor source / target arrays`,\n { element },\n );\n ctx.countSkipped(\"edge\");\n }\n } catch (err) {\n if (err instanceof ExpansionRefused) {\n // one hyperedge over the cap is skipped; the shared E_TOO_LARGE rule would stop the import\n report.error(\"unsupported\", err.code, err.message, { element });\n ctx.countSkipped(\"edge\");\n } else {\n ctx.skip(err, \"edge\", element);\n }\n }\n }\n}\n\n/** A hyperedge whose expansion would pass MAX_HYPEREDGE_EXPANSION: that hyperedge alone is skipped. */\nclass ExpansionRefused extends GraphFormatError {}\n\n/** The most edges the hyperedges of one import expand into; a 20k-member clique would be 200M edges. */\n// ponytail: a fixed cap; make it an option if a real file needs more\nconst MAX_HYPEREDGE_EXPANSION = 1_000_000;\n\n/**\n * Refuse an expansion that would take the import beyond MAX_HYPEREDGE_EXPANSION expanded edges,\n * before any of it is pushed; otherwise count it against the budget.\n * @param count - the number of edges the expansion makes\n * @param budget - the edges the import's hyperedges expanded into so far\n * @param budget.used - that count, updated\n * @param element - the hyperedge's name\n */\nfunction checkExpansion(count: number, budget: { used: number }, element: string): void {\n if (budget.used + count > MAX_HYPEREDGE_EXPANSION) {\n throw new ExpansionRefused(\n \"E_TOO_LARGE\",\n `${element}: the expansion makes ${count} edges, which with the ${budget.used} already expanded is more than ${MAX_HYPEREDGE_EXPANSION}; the hyperedge is skipped`,\n { count, used: budget.used, limit: MAX_HYPEREDGE_EXPANSION },\n );\n }\n budget.used += count;\n}\n\n/**\n * The members of an undirected hyperedge with repeats removed (a repeat would expand into a\n * self-loop and parallel edges), each repeat reported as E_HYPEREDGE_SHAPE.\n * @param ctx - the context\n * @param members - the members as listed\n * @param element - the hyperedge's name\n * @returns the distinct members in first-listed order\n */\nfunction distinctMembers(ctx: ImportContext, members: readonly NodeId[], element: string): NodeId[] {\n const distinct = [...new Set(members)];\n if (distinct.length < members.length) {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.HYPEREDGE_SHAPE,\n `${element} lists ${members.length - distinct.length} member${plural(members.length - distinct.length)} more than once; each is read once`,\n { element },\n );\n }\n return distinct;\n}\n\n// ============================================================ Cytoscape\n\n/**\n * Read Cytoscape.js elements: `elements.nodes` / `elements.edges`, a flat `elements` array (group\n * from `group` or from the presence of source / target), or a top-level array. `data.id` is the id,\n * `data.parent` the parent (resolved after every node is known), `position` the position column,\n * `classes` the classes list; the other `data` keys are attributes and the element-level keys\n * (selected, locked, ...) are columns of the same name.\n * @param ctx - the context\n * @param root - the document\n */\nfunction importCytoscape(ctx: ImportContext, root: unknown): void {\n const { report } = ctx;\n let elements: unknown;\n let extra: Record<string, unknown> | undefined;\n if (Array.isArray(root)) {\n elements = root;\n } else if (isJsonObject(root)) {\n ({ elements } = root);\n ctx.writeGraphDict(root.data, \"data\");\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(root)) {\n if (key !== \"elements\" && key !== \"data\") {\n rest[key] = root[key];\n }\n }\n if (Object.keys(rest).length > 0) {\n extra = rest;\n }\n } else {\n report.fail(JSON_ISSUE.SHAPE, `a Cytoscape document must be an object or an array, found ${describe(root)}`);\n }\n const { nodes, edges } = cytoscapeSections(ctx, elements);\n ctx.setHeader(ctx.defaultDirected(\"cytoscape\"));\n ctx.reportNodeIdFrom(\"cytoscape\", \"data.id\");\n ctx.sink.reserve(nodes.length, edges.length);\n\n const dataHas = (items: readonly unknown[], key: string): boolean =>\n items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== undefined);\n const positionColumn = ctx.nodes.declareIf(\n {\n name: POSITION_COLUMN,\n dtype: \"f64\",\n components: 3,\n role: \"position\",\n mutable: true,\n nullable: true,\n // 3D layouts written by Cytoscape-compatible tools carry a z\n extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: \"file\" },\n origin: { format: \"json\", namespace: \"cytoscape\" },\n },\n anyHas(nodes, \"position\"),\n );\n const classesColumn = ctx.nodes.declareIf(\n { name: CLASSES_COLUMN, dtype: \"list\", itemDtype: \"string\", role: \"classes\", nullable: true },\n anyHas(nodes, \"classes\"),\n );\n const parentColumn = ctx.nodes.declareIf(\n { name: PARENT_COLUMN, dtype: \"u32\", role: \"parent\", refersTo: \"node\", nullable: true },\n dataHas(nodes, \"parent\"),\n );\n const edgeClassesColumn = ctx.edges.declareIf(\n { name: CLASSES_COLUMN, dtype: \"list\", itemDtype: \"string\", role: \"classes\", nullable: true },\n anyHas(edges, \"classes\"),\n );\n const parents: { index: number; parent: NodeId; element: string }[] = [];\n const point: [number, number, number] = [0, 0, 0];\n\n for (let i = 0; i < nodes.length; i++) {\n const element = `nodes[${i}]`;\n const record = nodes[i];\n if (!isJsonObject(record) || !isJsonObject(record.data)) {\n ctx.badElement(\"node\", element, \"an element with a data object\");\n continue;\n }\n const { data } = record;\n const id = ctx.coerceId(hasKey(data, \"id\") ? data.id : undefined, element);\n if (id === null) {\n ctx.countSkipped(\"node\");\n continue;\n }\n const index = ctx.pushNode(id, element);\n if (index < 0) {\n continue;\n }\n if (present(data, \"source\") && present(data, \"target\")) {\n report.warning(\n \"validation-error\",\n JSON_ISSUE.INCONSISTENT,\n `${element} has data.source and data.target, the shape of an edge, but its section or group says node; read as a node`,\n { element },\n );\n }\n try {\n for (const key of Object.keys(data)) {\n if (key === \"id\") {\n continue;\n }\n if (key === \"parent\") {\n const raw = data.parent;\n if (raw !== undefined && raw !== null) {\n const parent = ctx.coerceId(raw, `${element}.data.parent`);\n if (parent !== null) {\n parents.push({ index, parent, element });\n }\n }\n continue;\n }\n ctx.nodes.write(index, key, data[key], SUFFIX.data, element);\n }\n const { position } = record;\n if (position !== undefined && position !== null) {\n const z = isJsonObject(position) ? (position.z ?? 0) : 0;\n if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {\n point[0] = position.x;\n // Cytoscape's y grows downward; positions are stored y-up (the exporter flips back)\n point[1] = flipY(position.y);\n point[2] = z;\n ctx.nodes.set(positionColumn, index, point);\n } else {\n report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: position must be an object with numeric x and y (and z) that are finite numbers`,\n { element },\n );\n }\n }\n writeClasses(ctx, ctx.nodes, classesColumn, index, record.classes, element);\n writeElementKeys(ctx.nodes, index, record, element);\n } catch (err) {\n report.recordError(err, { element: String(id) });\n }\n }\n resolveCytoscapeParents(ctx, parents, parentColumn);\n throwIfAborted(ctx.options.signal);\n\n importCytoscapeEdges(ctx, edges, edgeClassesColumn);\n ctx.setMeta({ dialect: \"cytoscape\", cytoscape: extra }, ctx.weightOriginPatch());\n}\n\n/** One Cytoscape parent link: the parent's index and id, its document order and element name. */\ninterface ParentLink {\n readonly parent: number;\n readonly id: NodeId;\n readonly order: number;\n readonly element: string;\n}\n\n/**\n * Set the parent of each Cytoscape node once every node is known (a parent may come later): an\n * unknown parent is E_UNKNOWN_PARENT, a link that would make a node its own ancestor E_PARENT_CYCLE\n * (Cytoscape.js refuses those too); either link is dropped and the node kept.\n * @param ctx - the context\n * @param parents - the parent links in document order\n * @param parentColumn - the parent column\n */\nfunction resolveCytoscapeParents(\n ctx: ImportContext,\n parents: readonly { readonly index: number; readonly parent: NodeId; readonly element: string }[],\n parentColumn: ColumnHandle,\n): void {\n const { report } = ctx;\n // the last link per child (a duplicate node's later parent wins), child -> its link\n const linkOf = new Map<number, ParentLink>();\n for (let order = 0; order < parents.length; order++) {\n const { index, parent, element } = parents[order];\n const parentIndex = ctx.sink.indexOf(parent);\n if (parentIndex === INVALID_INDEX) {\n report.error(\n \"missing-value\",\n JSON_ISSUE.UNKNOWN_PARENT,\n `${element}: parent ${JSON.stringify(parent)} is not a node`,\n { element },\n );\n continue;\n }\n linkOf.set(index, { parent: parentIndex, id: parent, order, element });\n }\n // one walk per chain, each node visited once: on a cycle the link that came last in the document\n // (the one that closed it) is dropped\n const done = new Set<number>();\n for (const start of linkOf.keys()) {\n const path: number[] = [];\n const onPath = new Set<number>();\n let node: number | undefined = start;\n while (node !== undefined && !done.has(node) && !onPath.has(node)) {\n path.push(node);\n onPath.add(node);\n node = linkOf.get(node)?.parent;\n }\n if (node !== undefined && onPath.has(node)) {\n dropClosingLink(report, linkOf, path.slice(path.indexOf(node)));\n }\n for (const member of path) {\n done.add(member);\n }\n }\n for (const [index, { parent }] of linkOf) {\n ctx.nodes.set(parentColumn, index, parent);\n }\n}\n\n/**\n * Drop the link of a parent cycle that came last in the document (the one that closed it).\n * @param report - the report\n * @param linkOf - the links by child, the dropped one removed\n * @param cycle - the nodes of the cycle\n */\nfunction dropClosingLink(report: ImportReportBuilder, linkOf: Map<number, ParentLink>, cycle: readonly number[]): void {\n let closing: [number, ParentLink] | null = null;\n for (const member of cycle) {\n const link = linkOf.get(member);\n if (link !== undefined && (closing === null || link.order > closing[1].order)) {\n closing = [member, link];\n }\n }\n if (closing === null) {\n return;\n }\n const { id, element } = closing[1];\n report.error(\n \"validation-error\",\n JSON_ISSUE.PARENT_CYCLE,\n `${element}: parent ${JSON.stringify(id)} would make the node its own ancestor; the link is dropped`,\n { element },\n );\n linkOf.delete(closing[0]);\n}\n\n/**\n * Read the Cytoscape edge elements: `data.id`, `data.source` / `data.target`, the weight, the\n * other data keys as attributes, `classes` and the element-level keys.\n * @param ctx - the context\n * @param edges - the edge elements\n * @param edgeClassesColumn - the edge classes column, or INVALID_INDEX\n */\nfunction importCytoscapeEdges(ctx: ImportContext, edges: readonly unknown[], edgeClassesColumn: ColumnHandle): void {\n const ids = ctx.declareEdgeIds(edges, (edge) => (isJsonObject(edge.data) ? edge.data.id : undefined), \"id\", true);\n const kind = ctx.uniformKind();\n for (let i = 0; i < edges.length; i++) {\n const element = `edges[${i}]`;\n const record = edges[i];\n if (!isJsonObject(record) || !isJsonObject(record.data)) {\n ctx.badElement(\"edge\", element, \"an element with a data object\");\n continue;\n }\n const { data } = record;\n if (!present(data, \"source\") || !present(data, \"target\")) {\n ctx.missingEndpoint(element, `data.${present(data, \"source\") ? \"target\" : \"source\"}`);\n continue;\n }\n try {\n const u = ctx.coerceId(data.source, `${element}.data.source`);\n const v = ctx.coerceId(data.target, `${element}.data.target`);\n if (u === null || v === null) {\n ctx.countSkipped(\"edge\");\n continue;\n }\n const idValue = ctx.edgeIdValue(ids, data.id);\n const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(data), element);\n ctx.setEdgeId(ids, edge, idValue);\n const { weightFrom } = ctx.options;\n for (const key of Object.keys(data)) {\n if (key !== \"id\" && key !== \"source\" && key !== \"target\" && key !== weightFrom) {\n ctx.edges.write(edge, key, data[key], SUFFIX.data, element);\n }\n }\n writeClasses(ctx, ctx.edges, edgeClassesColumn, edge, record.classes, element);\n writeElementKeys(ctx.edges, edge, record, element);\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n}\n\n/**\n * The node and edge element arrays of a Cytoscape `elements` value: an object with `nodes` /\n * `edges`, a flat array split by isNodeElement(), or nothing (reported).\n * @param ctx - the context\n * @param elements - the `elements` value\n * @returns the two arrays; the import fails when elements has another type\n */\nfunction cytoscapeSections(\n ctx: ImportContext,\n elements: unknown,\n): { readonly nodes: readonly unknown[]; readonly edges: readonly unknown[] } {\n const { report } = ctx;\n if (Array.isArray(elements)) {\n const nodes: unknown[] = [];\n const edges: unknown[] = [];\n elements.forEach((item: unknown, i) => {\n if (isJsonObject(item) && item.group !== undefined && item.group !== \"nodes\" && item.group !== \"edges\") {\n report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `elements[${i}]: group ${describe(item.group)} is neither \"nodes\" nor \"edges\"; classed by its endpoints`,\n { element: `elements[${i}]` },\n );\n }\n // a non-object item stays with the nodes, whose reader reports it as E_BAD_ELEMENT\n (isJsonObject(item) && !isNodeElement(item) ? edges : nodes).push(item);\n });\n return { nodes, edges };\n }\n if (isJsonObject(elements)) {\n return {\n nodes: arraySection(elements.nodes, \"elements.nodes\", report) ?? [],\n edges: arraySection(elements.edges, \"elements.edges\", report) ?? [],\n };\n }\n if (elements === undefined || elements === null) {\n report.warning(\"missing-value\", JSON_ISSUE.MISSING_SECTION, \"the document has no elements\", {\n element: \"elements\",\n });\n return { nodes: [], edges: [] };\n }\n return report.fail(JSON_ISSUE.SHAPE, `elements must be an object or an array, found ${describe(elements)}`);\n}\n\n/**\n * Whether a Cytoscape element's position has a numeric z.\n * @param element - the element\n * @returns true when position.z is a number\n */\nfunction hasPositionZ(element: unknown): boolean {\n return isJsonObject(element) && isJsonObject(element.position) && typeof element.position.z === \"number\";\n}\n\n/**\n * Whether a value is a coordinate the position column holds: a finite number.\n * @param value - the value\n * @returns true for a storable coordinate\n */\nfunction isCoordinate(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\n/**\n * Whether a flat Cytoscape element is a node: `group: \"nodes\"`, or no source / target in its data.\n * @param element - the element\n * @returns true for a node\n */\nfunction isNodeElement(element: JsonRecord): boolean {\n if (element.group === \"nodes\") {\n return true;\n }\n if (element.group === \"edges\") {\n return false;\n }\n const { data } = element;\n return !(isJsonObject(data) && hasKey(data, \"source\") && hasKey(data, \"target\"));\n}\n\n/**\n * Write the classes of an element: a space-separated string or an array of strings.\n * @param ctx - the context\n * @param writer - the table writer\n * @param column - the classes column, or INVALID_INDEX when no element has classes\n * @param row - the row\n * @param raw - the `classes` value\n * @param element - the element name\n */\nfunction writeClasses(\n ctx: ImportContext,\n writer: AttributeWriter,\n column: ColumnHandle,\n row: number,\n raw: unknown,\n element: string,\n): void {\n if (column === INVALID_INDEX || raw === undefined || raw === null) {\n return;\n }\n let classes: string[];\n if (typeof raw === \"string\") {\n classes = raw.split(/\\s+/).filter((c) => c.length > 0);\n } else if (Array.isArray(raw) && raw.every((c) => typeof c === \"string\")) {\n classes = raw;\n } else {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n `${element}: classes must be a string or an array of strings`,\n { element },\n );\n return;\n }\n writer.set(column, row, classes);\n}\n\n/**\n * Write the element-level keys of a Cytoscape element other than the structural ones: the known\n * keys under their own name, unknown ones with the `#element` suffix.\n * @param writer - the table writer\n * @param row - the row\n * @param record - the element\n * @param element - the element name for issues\n */\nfunction writeElementKeys(writer: AttributeWriter, row: number, record: JsonRecord, element: string): void {\n for (const key of Object.keys(record)) {\n if (CYTOSCAPE_STRUCTURAL_KEYS.has(key)) {\n continue;\n }\n const name = CYTOSCAPE_ELEMENT_KEYS.has(key) ? key : `${key}${SUFFIX.element}`;\n writer.write(row, name, record[key], SUFFIX.data, element);\n }\n}\n\n// ============================================================ the plugin\n\n/**\n * The JSON importer plugin.\n * @category Built-in formats\n */\nexport const jsonImporter: GraphImporter<JsonImportOptions> = Object.freeze({\n format: \"json\",\n options: Object.freeze([\n \"dialect\",\n \"edgesKey\",\n \"edgesPath\",\n \"indexLinks\",\n \"nodeIdKey\",\n \"nodesPath\",\n \"oboIds\",\n \"sourceKey\",\n \"targetKey\",\n \"typedefs\",\n ]),\n extensions: Object.freeze([\".json\"]),\n mimeTypes: Object.freeze([\"application/json\"]),\n\n /**\n * Confidence that the head is a JSON graph document: 0 unless it starts with `{` or `[`, 0.5\n * for any JSON, 0.9 when a graph key (nodes, links, edges, elements, graph, graphs) appears in\n * the head.\n * @param head - the first bytes\n * @returns the confidence\n */\n sniff(head: Uint8Array): number {\n // headBytes transcodes a UTF-16 head with a BOM, which import() decodes too\n const text = new TextDecoder(\"utf-8\").decode(headBytes(head).subarray(0, SNIFF_BYTES));\n const trimmed = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return 0;\n }\n const score = SNIFF_KEYS.some((key) => trimmed.includes(key)) ? 0.9 : 0.5;\n // a top-level array is a graph only as Cytoscape.js elements (`[{\"data\": ...}]`): a CX or\n // CX2 document (`[{\"metaData\": ...}]`, `[{\"CXVersion\": ...}]`) is another format's\n return trimmed.startsWith(\"[\") && sniffJsonDialectHead(trimmed) !== \"cytoscape\" ? Math.min(score, 0.3) : score;\n },\n\n /**\n * Read a JSON graph document into the sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the import report; ImportError on a fatal error or beyond the error limit\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: JsonImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const json = resolveJsonOptions(options);\n const report = new ImportReportBuilder(\"json\", resolved.errorLimit);\n const text = await readText(input, report, { ...resolved, bomlessUtf16: true });\n const { root, dialect } = documentOf(parseDocument(text, report), json, report);\n readGraph(root, dialect, sink, report, resolved, json, options);\n return report.finish();\n },\n\n /**\n * List the graphs of a JSON document without importing them: each entry of a JGF or OBO\n * Graphs `graphs` array with its name (`id`, else its label) and node and edge counts; any\n * other document holds one graph.\n * @param input - the text, bytes or stream\n * @param options - format-specific and common options\n * @returns one listing per graph\n */\n async listGraphs(\n input: ImportInput,\n options?: JsonImportOptions & CommonImportOptions,\n ): Promise<readonly GraphListing[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const json = resolveJsonOptions(options);\n const report = new ImportReportBuilder(\"json\", resolved.errorLimit);\n const text = await readText(input, report, { ...resolved, bomlessUtf16: true });\n const { root, dialect } = documentOf(parseDocument(text, report), json, report);\n return listingsOf(root, dialect);\n },\n\n /**\n * Read every graph of a JSON document: each entry of a JGF `graphs` array into its own sink;\n * any other document holds one graph.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: JsonImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const json = resolveJsonOptions(options);\n const first = new ImportReportBuilder(\"json\", resolved.errorLimit);\n const text = await readText(input, first, { ...resolved, bomlessUtf16: true });\n const { root, dialect } = documentOf(parseDocument(text, first), json, first);\n const graphs = listingsOf(root, dialect).length;\n const reports: ImportReport[] = [];\n for (let i = 0; i < Math.max(graphs, 1); i++) {\n const report = i === 0 ? first : new ImportReportBuilder(\"json\", resolved.errorLimit);\n readGraph(root, dialect, sinkFor(i), report, resolved, { ...json, graphIndex: i, all: true }, options);\n reports.push(report.finish());\n }\n return reports;\n },\n});\n\n/**\n * Read one graph of a parsed document into a sink.\n * @param root - the parsed document\n * @param dialect - its dialect\n * @param sink - the sink\n * @param report - the graph's report\n * @param resolved - the resolved common options\n * @param json - the resolved JSON options (graphIndex picks the JGF graph)\n * @param options - the caller's options, for the sink and unused-option checks\n */\nfunction readGraph(\n root: unknown,\n dialect: JsonImportDialect,\n sink: GraphSink,\n report: ImportReportBuilder,\n resolved: ResolvedImportOptions,\n json: ResolvedJsonOptions,\n options: (JsonImportOptions & CommonImportOptions) | undefined,\n): void {\n const ctx = new ImportContext(sink, report, resolved, json, options?.defaultDirected !== undefined);\n // the obographs reader refuses missing endpoints itself, so addMissingNodes false holds on any sink\n reportSinkOptions(sink, options, report, dialect === \"obographs\");\n reportUnusedOptions(options, report, USED_OPTIONS);\n readDialect(ctx, root, dialect);\n ctx.reportDangling();\n ctx.nodes.reportNullOnly();\n ctx.edges.reportNullOnly();\n throwIfAborted(resolved.signal);\n}\n\n/**\n * Read one graph with the reader of its dialect.\n * @param ctx - the import context\n * @param root - the parsed document\n * @param dialect - its dialect\n */\nfunction readDialect(ctx: ImportContext, root: unknown, dialect: JsonImportDialect): void {\n if (dialect === \"cytoscape\") {\n importCytoscape(ctx, root);\n return;\n }\n const doc = isJsonObject(root)\n ? root\n : ctx.report.fail(JSON_ISSUE.SHAPE, `a ${dialect} document must be a JSON object, found ${describe(root)}`);\n switch (dialect) {\n case \"node-link\":\n case \"d3\":\n importNodeLink(ctx, doc, dialect);\n break;\n case \"jgf\":\n importJgf(ctx, doc);\n break;\n case \"graphology\":\n importGraphology(ctx, doc);\n break;\n case \"vis\":\n importVis(ctx, doc);\n break;\n case \"adjacency\":\n importAdjacency(ctx, doc);\n break;\n case \"tree\":\n importTree(ctx, doc);\n break;\n case \"obographs\":\n importObographs(ctx, doc);\n break;\n default: {\n const name: string = dialect;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dialect ${name}`, {\n option: \"dialect\",\n found: name,\n });\n }\n }\n}\n","/**\n * The `obographs` dialect of the JSON importer (design sections 1.6 and 4.6): OBO Graphs JSON,\n * the form in which the Gene Ontology and every OBO Foundry ontology publish a ready-made graph\n * (`{ \"graphs\": [{ \"nodes\": [...], \"edges\": [{ \"sub\", \"pred\", \"obj\" }] }] }`).\n *\n * Nodes and their `meta` fill the OBO column vocabulary of src/common/ontology.ts, the same\n * columns the OBO importer gives the `.obo` file of the same ontology; ids are compacted from IRIs\n * to the identifiers the `.obo` writes (`oboIds: \"curie\"`, the default), and a relation is named by\n * its shorthand (`part_of`, not `http://purl.obolibrary.org/obo/BFO_0000050`). PROPERTY nodes and\n * the edges between properties are metadata unless `typedefs: \"nodes\"`, as `[Typedef]` frames are.\n * The axiom arrays and the graph and document metadata are kept verbatim in\n * `meta.extra.obographs`.\n */\n\nimport { type ColumnHandle, INVALID_INDEX, type NodeId } from \"@graphty/graph-format\";\n\nimport { declareResolved } from \"../../common/attributes.js\";\nimport {\n compactOboIri,\n OBO_NODE_COLUMNS,\n oboColumnDecl,\n OBOGRAPHS_PREDICATE_TAGS,\n PLACEHOLDER_COLUMN,\n synonymScopeOf,\n} from \"../../common/ontology.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { hasKey, isJsonObject } from \"./dialect.js\";\nimport { chosenGraph, type ImportContext, JSON_ISSUE, type JsonRecord } from \"./importer.js\";\n\n/**\n * The node keys the schema defines; any other key goes to `obo.unrecognized`.\n * @category Plugin helpers\n */\nexport const NODE_KEYS: ReadonlySet<string> = new Set([\"id\", \"lbl\", \"type\", \"propertyType\", \"meta\"]);\n\n/**\n * The `meta` keys mapped onto columns; any other key goes to `obo.unrecognized` as `meta.<key>`.\n * @category Plugin helpers\n */\nexport const META_KEYS: ReadonlySet<string> = new Set([\n \"definition\",\n \"comments\",\n \"subsets\",\n \"xrefs\",\n \"synonyms\",\n \"basicPropertyValues\",\n \"deprecated\",\n]);\n\n/**\n * The OBO frame type of an OBO Graphs node type.\n * @category Plugin helpers\n */\nexport const FRAME_TYPES: Readonly<Record<string, string>> = Object.freeze({\n CLASS: \"Term\",\n INDIVIDUAL: \"Instance\",\n PROPERTY: \"Typedef\",\n});\n\n/**\n * The OBO name of the predicates OBO Graphs writes without an IRI.\n * @category Plugin helpers\n */\nexport const BUILTIN_PREDICATES: Readonly<Record<string, string>> = Object.freeze({\n is_a: \"is_a\",\n subPropertyOf: \"is_a\",\n type: \"instance_of\",\n inverseOf: \"inverse_of\",\n});\n\n/**\n * Predicates that relate two properties (metadata under typedefs \"metadata\").\n * @category Plugin helpers\n */\nexport const PROPERTY_PREDICATES: ReadonlySet<string> = new Set([\"subPropertyOf\", \"inverseOf\"]);\n\n/** Writes the OBO vocabulary columns, declaring each on first use. */\nclass ColumnWriter {\n private readonly ctx: ImportContext;\n\n private readonly handles = new Map<string, ColumnHandle>();\n\n /**\n * Create a writer.\n * @param ctx - the import context\n */\n constructor(ctx: ImportContext) {\n this.ctx = ctx;\n }\n\n /**\n * Write a node cell of the vocabulary.\n * @param name - the column\n * @param row - the node index\n * @param value - the value\n */\n node(name: string, row: number, value: unknown): void {\n this.ctx.sink.setNodeValue(this.handle(\"node\", name), row, value);\n }\n\n /**\n * Write an edge cell of the vocabulary.\n * @param name - the column\n * @param row - the edge index\n * @param value - the value\n */\n edge(name: string, row: number, value: unknown): void {\n this.ctx.sink.setEdgeValue(this.handle(\"edge\", name), row, value);\n }\n\n /**\n * The handle of a column, declared on first use.\n * @param domain - node or edge\n * @param name - the column\n * @returns the handle\n */\n private handle(domain: \"node\" | \"edge\", name: string): ColumnHandle {\n const key = `${domain}:${name}`;\n const cached = this.handles.get(key);\n if (cached !== undefined) {\n return cached;\n }\n const { handle } = declareResolved(this.ctx.sink, domain, oboColumnDecl(domain, name), this.ctx.report);\n this.handles.set(key, handle);\n return handle;\n }\n}\n\n/** One import's view of the graph's ids and properties. */\ninterface Vocabulary {\n /** An IRI as the node id or relation name the snapshot uses. */\n readonly id: (iri: string) => string;\n /** A predicate as the relation name the edge column holds. */\n readonly relation: (pred: string) => string;\n /** Whether an IRI names a PROPERTY node and no node of another type. */\n readonly isProperty: (iri: string) => boolean;\n /** Whether an IRI names a node that is not a PROPERTY (a class, an individual). */\n readonly isClass: (iri: string) => boolean;\n /** The PROPERTY nodes kept as metadata, by IRI (a null-prototype record: an IRI may be `__proto__`). */\n readonly properties: Record<string, unknown>;\n /** The first id as written of each node id as read (two ids may meet only after IRI compaction). */\n readonly written: Map<string, string>;\n}\n\n/** The axiom sections of an OBO Graphs graph, each an array (kept verbatim in the metadata). */\nconst AXIOM_KEYS: readonly string[] = [\n \"logicalDefinitionAxioms\",\n \"equivalentNodesSets\",\n \"domainRangeAxioms\",\n \"propertyChainAxioms\",\n];\n\n/** The edge keys the schema defines (`subj` is the README's outdated spelling of `sub`). */\nconst EDGE_KEYS: ReadonlySet<string> = new Set([\"sub\", \"subj\", \"pred\", \"obj\", \"meta\"]);\n\n/**\n * The id rule and the property table of one graph: PROPERTY nodes are found first, so an edge's\n * predicate is named by the shorthand of the property it names wherever that property stands.\n * @param nodes - the graph's node records\n * @param oboIds - \"curie\" or \"iri\"\n * @returns the vocabulary\n */\nfunction vocabularyOf(nodes: readonly unknown[], oboIds: \"curie\" | \"iri\"): Vocabulary {\n const shorthands = new Map<string, string>();\n const propertyIds = new Set<string>();\n const classIds = new Set<string>();\n for (const node of nodes) {\n if (!isJsonObject(node) || typeof node.id !== \"string\") {\n continue;\n }\n if (node.type !== \"PROPERTY\") {\n classIds.add(node.id);\n continue;\n }\n propertyIds.add(node.id);\n const shorthand = basicValues(node.meta).find((pv) => OBOGRAPHS_PREDICATE_TAGS.get(pv.pred) === \"shorthand\");\n if (shorthand !== undefined) {\n shorthands.set(node.id, shorthand.val);\n }\n }\n const compact = (iri: string): string => (oboIds === \"curie\" ? compactOboIri(iri) : iri);\n return {\n id: (iri) => (oboIds === \"curie\" ? (shorthands.get(iri) ?? compactOboIri(iri)) : iri),\n relation: (pred) => BUILTIN_PREDICATES[pred] ?? shorthands.get(pred) ?? compact(pred),\n isProperty: (iri) => propertyIds.has(iri) && !classIds.has(iri),\n isClass: (iri) => classIds.has(iri),\n properties: Object.create(null) as Record<string, unknown>,\n written: new Map(),\n };\n}\n\n/** One `basicPropertyValues` entry. */\ninterface PropertyValue {\n readonly pred: string;\n readonly val: string;\n readonly meta?: unknown;\n}\n\n/**\n * The well-formed `basicPropertyValues` of a node's meta, each malformed entry reported when a\n * context is given (the vocabulary pre-pass reads them silently; writeMeta reports them).\n * @param meta - the node's meta, or anything\n * @param ctx - the context to report through, or null\n * @param element - the node's name in messages\n * @returns the entries with a string pred and val\n */\nfunction basicValues(meta: unknown, ctx: ImportContext | null = null, element = \"\"): PropertyValue[] {\n if (!isJsonObject(meta) || meta.basicPropertyValues === undefined || meta.basicPropertyValues === null) {\n return [];\n }\n const path = `${element}.meta.basicPropertyValues`;\n if (!Array.isArray(meta.basicPropertyValues)) {\n if (ctx !== null) {\n badValue(ctx, `${path} must be an array; it is dropped`, path);\n }\n return [];\n }\n const out: PropertyValue[] = [];\n meta.basicPropertyValues.forEach((pv: unknown, j: number) => {\n if (isJsonObject(pv) && typeof pv.pred === \"string\" && typeof pv.val === \"string\") {\n out.push(pv as unknown as PropertyValue);\n } else if (ctx !== null) {\n badValue(ctx, `${path}[${j}] needs a string pred and a string val; it is dropped`, `${path}[${j}]`);\n }\n });\n return out;\n}\n\n/**\n * The strings of an array, or of an array of `{ val }` records, each item that is neither\n * reported (E_BAD_VALUE) and dropped, and a value that is not an array reported whole.\n * @param ctx - the context\n * @param value - the array, or anything (undefined and null: none)\n * @param path - the field's path in messages\n * @returns the strings\n */\nfunction strings(ctx: ImportContext, value: unknown, path: string): string[] {\n if (value === undefined || value === null) {\n return [];\n }\n if (!Array.isArray(value)) {\n badValue(ctx, `${path} must be an array; it is dropped`, path);\n return [];\n }\n const out: string[] = [];\n value.forEach((item: unknown, j: number) => {\n if (typeof item === \"string\") {\n out.push(item);\n } else if (isJsonObject(item) && typeof item.val === \"string\") {\n out.push(item.val);\n } else {\n badValue(ctx, `${path}[${j}] is not a string or a { val } record; it is dropped`, `${path}[${j}]`);\n }\n });\n return out;\n}\n\n/**\n * Read the chosen graph of an OBO Graphs document into the sink.\n * @param ctx - the import context\n * @param root - the document\n * @category Plugin helpers\n */\nexport function importObographs(ctx: ImportContext, root: JsonRecord): void {\n const graph = chosenGraph(ctx, root, \"OBO Graphs\");\n const nodes = sectionOf(ctx, graph, \"nodes\");\n const edges = sectionOf(ctx, graph, \"edges\");\n const vocabulary = vocabularyOf(nodes, ctx.json.oboIds);\n const columns = new ColumnWriter(ctx);\n ctx.reportNodeIdFrom(\"obographs\", \"the node ids\");\n ctx.setHeader(true);\n ctx.sink.reserve(nodes.length, edges.length);\n for (let i = 0; i < nodes.length; i++) {\n readNode(ctx, columns, vocabulary, nodes[i], `nodes[${i}]`);\n }\n const propertyEdges = readEdges(ctx, columns, vocabulary, edges);\n const graphMeta: JsonRecord = {};\n for (const key of Object.keys(graph)) {\n if (key !== \"nodes\" && key !== \"edges\") {\n graphMeta[key] = graph[key];\n }\n }\n for (const key of AXIOM_KEYS) {\n const axioms = graph[key];\n if (axioms !== undefined && axioms !== null && !Array.isArray(axioms)) {\n badValue(ctx, `the graph's ${key} must be an array; it is kept as written`, key);\n }\n }\n const document: JsonRecord = {};\n for (const key of Object.keys(root)) {\n if (key !== \"graphs\") {\n document[key] = root[key];\n }\n }\n const label = typeof graph.lbl === \"string\" ? graph.lbl : null;\n const name = label ?? (typeof graph.id === \"string\" ? graph.id : null);\n ctx.sink.setMeta({\n sourceFormat: \"json\",\n name,\n extra: {\n json: { dialect: \"obographs\" },\n obographs: {\n ids: ctx.json.oboIds,\n graph: graphMeta,\n document,\n properties: vocabulary.properties,\n propertyEdges,\n },\n },\n });\n}\n\n/**\n * A `nodes` or `edges` section: an array, absent (empty), or a fatal E_JSON_SHAPE.\n * @param ctx - the context\n * @param graph - the graph\n * @param key - the section\n * @returns the elements\n */\nfunction sectionOf(ctx: ImportContext, graph: JsonRecord, key: string): readonly unknown[] {\n const value = graph[key];\n if (value === undefined || value === null) {\n return [];\n }\n if (!Array.isArray(value)) {\n return ctx.report.fail(JSON_ISSUE.SHAPE, `an OBO Graphs graph's ${key} must be an array`, { element: key });\n }\n return value;\n}\n\n/**\n * Read one node: a PROPERTY into the metadata (typedefs \"metadata\"), anything else into the sink\n * with its OBO columns.\n * @param ctx - the context\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param record - the node record\n * @param element - its name in messages\n */\nfunction readNode(\n ctx: ImportContext,\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n record: unknown,\n element: string,\n): void {\n if (!isJsonObject(record)) {\n ctx.badElement(\"node\", element);\n return;\n }\n if (typeof record.id !== \"string\" || record.id.length === 0) {\n if (record.id === undefined) {\n ctx.coerceId(undefined, element);\n } else if (record.id === \"\") {\n ctx.report.error(\"missing-value\", JSON_ISSUE.MISSING_ID, `${element} has an empty id; it is skipped`, {\n element,\n });\n } else {\n badValue(ctx, `${element}.id must be a string; the node is skipped`);\n }\n ctx.countSkipped(\"node\");\n return;\n }\n if (typeof record.type === \"string\" && FRAME_TYPES[record.type] === undefined) {\n ctx.report.warnOnce(\n \"unsupported\",\n JSON_ISSUE.UNKNOWN_ELEMENT,\n `${element}: node type ${JSON.stringify(record.type)} is not CLASS, INDIVIDUAL or PROPERTY; kept as written`,\n { element: record.type },\n `${JSON_ISSUE.UNKNOWN_ELEMENT}:type:${record.type}`,\n );\n }\n if (record.type === \"PROPERTY\" && ctx.json.typedefs === \"metadata\") {\n readProperty(ctx, vocabulary, record, record.id, element);\n return;\n }\n const compacted = vocabulary.id(record.id);\n const id = ctx.coerceId(compacted, element);\n // two ids that differ only by IRI compaction (the PURL and its CURIE) meet here\n const earlier = vocabulary.written.get(compacted);\n if (earlier === undefined) {\n vocabulary.written.set(compacted, record.id);\n }\n const why =\n earlier === undefined || earlier === record.id\n ? \"\"\n : ` (${earlier} and ${record.id} meet only after IRI compaction; oboIds \"iri\" keeps them apart)`;\n const row = id === null ? -1 : ctx.pushNode(id, element, why);\n if (row < 0) {\n return;\n }\n try {\n writeNode(ctx, columns, vocabulary, record, row, element);\n } catch (err) {\n ctx.report.recordError(err, { element: record.id });\n }\n}\n\n/**\n * Keep a PROPERTY node in the metadata (typedefs \"metadata\"), the first of a repeated id.\n * @param ctx - the context\n * @param vocabulary - the graph's vocabulary\n * @param record - the node record\n * @param iri - its id\n * @param element - its name in messages\n */\nfunction readProperty(\n ctx: ImportContext,\n vocabulary: Vocabulary,\n record: JsonRecord,\n iri: string,\n element: string,\n): void {\n if (Object.hasOwn(vocabulary.properties, iri)) {\n ctx.report.warning(\n \"merged\",\n JSON_ISSUE.DUPLICATE_NODE,\n `${element}: property ${JSON.stringify(iri)} is declared again; the first declaration is kept`,\n { element },\n );\n return;\n }\n const shorthand = vocabulary.id(iri) === iri ? undefined : vocabulary.id(iri);\n const entry: JsonRecord = {};\n for (const [key, value] of Object.entries({\n lbl: record.lbl,\n propertyType: record.propertyType,\n shorthand,\n meta: record.meta,\n })) {\n if (value !== undefined) {\n entry[key] = value;\n }\n }\n vocabulary.properties[iri] = entry;\n}\n\n/**\n * Write a node's fields and meta onto the OBO columns.\n * @param ctx - the context\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param record - the node record\n * @param row - the node index\n * @param element - its name in messages\n */\nfunction writeNode(\n ctx: ImportContext,\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n record: JsonRecord,\n row: number,\n element: string,\n): void {\n const unrecognized: JsonRecord = {};\n const text = (key: string, column: string): void => {\n const value = record[key];\n if (typeof value === \"string\") {\n columns.node(column, row, column === \"type\" ? (FRAME_TYPES[value] ?? value) : value);\n } else if (value !== undefined && value !== null) {\n badValue(ctx, `${element}.${key} must be a string`);\n }\n };\n text(\"type\", \"type\");\n text(\"lbl\", \"name\");\n text(\"propertyType\", \"propertyType\");\n for (const key of Object.keys(record)) {\n if (!NODE_KEYS.has(key)) {\n unrecognized[key] = record[key];\n }\n }\n const { meta } = record;\n if (isJsonObject(meta)) {\n writeMeta(ctx, columns, vocabulary, meta, row, unrecognized, element);\n } else if (meta !== undefined && meta !== null) {\n badValue(ctx, `${element}.meta must be an object`);\n }\n if (Object.keys(unrecognized).length > 0) {\n columns.node(\"obo.unrecognized\", row, unrecognized);\n }\n}\n\n/**\n * Write a node's `meta` onto the OBO columns (design 4.6): definition, comments, subsets, xrefs,\n * synonyms, deprecated, and the basicPropertyValues mapped back to the OBO tag they came from. A\n * field of the wrong JSON type is reported and dropped; a nested `meta` (axiom annotations) of\n * a definition or a property value is kept in `obo.unrecognized`.\n * @param ctx - the context\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param meta - the meta record\n * @param row - the node index\n * @param unrecognized - where keys without a column go\n * @param element - the node's name in messages\n */\nfunction writeMeta(\n ctx: ImportContext,\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n meta: JsonRecord,\n row: number,\n unrecognized: JsonRecord,\n element: string,\n): void {\n const path = `${element}.meta`;\n const { definition } = meta;\n if (isJsonObject(definition)) {\n const xrefs = strings(ctx, definition.xrefs, `${path}.definition.xrefs`);\n if (typeof definition.val === \"string\") {\n columns.node(\"def\", row, definition.val);\n columns.node(\"def.xrefs\", row, xrefs);\n } else {\n badValue(ctx, `${path}.definition has no string val; it is dropped`, `${path}.definition.val`);\n }\n if (definition.meta !== undefined) {\n unrecognized[\"meta.definition.meta\"] = definition.meta;\n }\n } else if (definition !== undefined && definition !== null) {\n badValue(ctx, `${path}.definition must be an object with a val; it is dropped`, `${path}.definition`);\n }\n const comments = strings(ctx, meta.comments, `${path}.comments`);\n if (comments.length > 0) {\n columns.node(\"comment\", row, comments.join(\"\\n\"));\n }\n const subsets = strings(ctx, meta.subsets, `${path}.subsets`).map((s) => vocabulary.id(s));\n if (subsets.length > 0) {\n columns.node(\"subset\", row, subsets);\n }\n const xrefs = strings(ctx, meta.xrefs, `${path}.xrefs`);\n if (xrefs.length > 0) {\n columns.node(\"xref\", row, xrefs);\n }\n const synonyms = synonymsOf(ctx, vocabulary, meta.synonyms, `${path}.synonyms`);\n if (synonyms.length > 0) {\n columns.node(\"synonym\", row, synonyms);\n }\n if (typeof meta.deprecated === \"boolean\") {\n columns.node(\"is_obsolete\", row, meta.deprecated);\n } else if (meta.deprecated !== undefined && meta.deprecated !== null) {\n badValue(ctx, `${path}.deprecated must be a boolean; it is dropped`, `${path}.deprecated`);\n }\n writePropertyValues(ctx, columns, vocabulary, meta, row, unrecognized, element);\n for (const key of Object.keys(meta)) {\n if (!META_KEYS.has(key)) {\n unrecognized[`meta.${key}`] = meta[key];\n }\n }\n}\n\n/**\n * The synonyms of a node's meta as the OBO `synonym` items: each entry that is not an object or\n * has no string val reported and dropped, a predicate that is not one of the four scopes kept with\n * scope null (W_UNKNOWN_ELEMENT once per predicate), a nested `meta` kept on the item.\n * @param ctx - the context\n * @param vocabulary - the graph's vocabulary\n * @param value - the `synonyms` field\n * @param path - its path in messages\n * @returns the items\n */\nfunction synonymsOf(ctx: ImportContext, vocabulary: Vocabulary, value: unknown, path: string): JsonRecord[] {\n if (value === undefined || value === null) {\n return [];\n }\n if (!Array.isArray(value)) {\n badValue(ctx, `${path} must be an array; it is dropped`, path);\n return [];\n }\n const out: JsonRecord[] = [];\n value.forEach((s: unknown, j: number) => {\n const at = `${path}[${j}]`;\n if (!isJsonObject(s)) {\n badValue(ctx, `${at} is not an object; it is dropped`, at);\n return;\n }\n if (typeof s.val !== \"string\") {\n badValue(ctx, `${at} has no string val; it is dropped`, `${at}.val`);\n return;\n }\n const scope = typeof s.pred === \"string\" ? synonymScopeOf(s.pred) : null;\n if (scope === null && typeof s.pred === \"string\") {\n ctx.report.warnOnce(\n \"unsupported\",\n JSON_ISSUE.UNKNOWN_ELEMENT,\n `${at}: synonym predicate ${JSON.stringify(s.pred)} is not one of the four scopes; kept with scope null`,\n { element: s.pred },\n `${JSON_ISSUE.UNKNOWN_ELEMENT}:pred:${s.pred}`,\n );\n }\n const item: JsonRecord = { text: s.val, scope, type: null, xrefs: strings(ctx, s.xrefs, `${at}.xrefs`) };\n if (typeof s.synonymType === \"string\") {\n item.type = vocabulary.id(s.synonymType);\n } else if (s.synonymType !== undefined && s.synonymType !== null) {\n badValue(ctx, `${at}.synonymType must be a string; it is dropped`, `${at}.synonymType`);\n }\n if (s.meta !== undefined) {\n item.meta = s.meta;\n }\n out.push(item);\n });\n return out;\n}\n\n/**\n * Write the basicPropertyValues: the ones an OBO tag maps to onto that tag's column (lists for\n * alt_id, replaced_by, consider; the first value of a single-valued tag, a repeat warned as the\n * .obo importer warns it), the rest into `property_value`.\n * @param ctx - the context\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param meta - the node's meta\n * @param row - the node index\n * @param unrecognized - where the nested meta of a mapped value goes\n * @param element - the node's name in messages\n */\nfunction writePropertyValues(\n ctx: ImportContext,\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n meta: JsonRecord,\n row: number,\n unrecognized: JsonRecord,\n element: string,\n): void {\n const lists = new Map<string, string[]>();\n const singles = new Map<string, string>();\n const others: JsonRecord[] = [];\n const values = basicValues(meta, ctx, element);\n values.forEach(({ pred, val, meta: nested }, j) => {\n const tag = OBOGRAPHS_PREDICATE_TAGS.get(pred);\n if (tag === \"shorthand\") {\n return;\n }\n if (tag === undefined) {\n const item: JsonRecord = { relation: vocabulary.id(pred), value: val, datatype: null };\n if (nested !== undefined) {\n item.meta = nested;\n }\n others.push(item);\n return;\n }\n if (nested !== undefined) {\n unrecognized[`meta.basicPropertyValues[${j}].meta`] = nested;\n }\n if (OBO_NODE_COLUMNS[tag].dtype === \"list\") {\n const list = lists.get(tag) ?? [];\n list.push(tag === \"alt_id\" ? val : vocabulary.id(val));\n lists.set(tag, list);\n } else if (singles.get(tag) === val) {\n // an identical value counts once, as an identical .obo clause does\n } else if (singles.has(tag)) {\n ctx.report.warning(\n \"validation-error\",\n JSON_ISSUE.DUPLICATE_ATTRIBUTE,\n `${element}: a second ${tag} (${JSON.stringify(val)}); the first is kept`,\n { element: tag },\n );\n } else {\n singles.set(tag, val);\n columns.node(tag, row, val);\n }\n });\n for (const [tag, list] of lists) {\n columns.node(tag, row, list);\n }\n if (others.length > 0) {\n columns.node(\"property_value\", row, others);\n }\n}\n\n/**\n * Report a field of the wrong JSON type (the field is left unset, the element kept).\n * @param ctx - the context\n * @param message - what is wrong\n * @param element - the field's path, when known\n */\nfunction badValue(ctx: ImportContext, message: string, element?: string): void {\n ctx.report.error(\n \"validation-error\",\n JSON_ISSUE.BAD_VALUE,\n message,\n element === undefined ? undefined : { element },\n );\n}\n\n/**\n * An edge's subject: `sub`, else the README's outdated `subj` (warned once), and a warning when\n * both are present and differ; every key outside the schema warned once per key name.\n * @param ctx - the context\n * @param record - the edge record\n * @param element - its name in messages\n * @returns the subject value, unchecked\n */\nfunction subjectOf(ctx: ImportContext, record: JsonRecord, element: string): unknown {\n const { report } = ctx;\n for (const key of Object.keys(record)) {\n if (!EDGE_KEYS.has(key)) {\n report.warnOnce(\n \"unsupported\",\n JSON_ISSUE.UNREAD_KEY,\n `${element}: the key ${JSON.stringify(key)} is not part of an OBO Graphs edge; it is not read`,\n { element: `${element}.${key}` },\n `${JSON_ISSUE.UNREAD_KEY}:edge:${key}`,\n );\n }\n }\n if (!hasKey(record, \"sub\")) {\n if (hasKey(record, \"subj\")) {\n report.warnOnce(\n \"coercion\",\n JSON_ISSUE.OBOGRAPHS_SUBJ,\n `${element} uses the outdated key subj; read as sub`,\n {\n element,\n },\n );\n }\n return record.subj;\n }\n if (hasKey(record, \"subj\") && record.subj !== record.sub) {\n report.warning(\n \"coercion\",\n JSON_ISSUE.OBOGRAPHS_SUBJ,\n `${element} has both sub and the outdated subj, which differ; sub is read and subj ignored`,\n { element },\n );\n }\n return record.sub;\n}\n\n/**\n * Read the edges: the ones between properties into the metadata (typedefs \"metadata\"), the rest\n * into the sink, making a placeholder node for an endpoint missing from `nodes`.\n * @param ctx - the context\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param edges - the edge records\n * @returns the property edges kept as metadata\n */\nfunction readEdges(\n ctx: ImportContext,\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n edges: readonly unknown[],\n): unknown[] {\n const { report, sink } = ctx;\n const propertyEdges: unknown[] = [];\n const dangling: string[] = [];\n let dropped = 0;\n const endpoint = (raw: string, element: string): NodeId | null => {\n const id = ctx.coerceId(vocabulary.id(raw), element);\n if (id === null || sink.indexOf(id) !== INVALID_INDEX) {\n return id;\n }\n dangling.push(raw);\n if (!ctx.options.addMissingNodes) {\n return null;\n }\n const row = ctx.pushNode(id, element);\n if (row >= 0) {\n columns.node(PLACEHOLDER_COLUMN, row, true);\n }\n return id;\n };\n for (let i = 0; i < edges.length; i++) {\n const element = `edges[${i}]`;\n const record = edges[i];\n if (!isJsonObject(record)) {\n ctx.badElement(\"edge\", element);\n continue;\n }\n const sub = subjectOf(ctx, record, element);\n const { obj, pred } = record;\n if (typeof sub !== \"string\" || typeof obj !== \"string\" || sub.length === 0 || obj.length === 0) {\n ctx.missingEndpoint(element, typeof sub === \"string\" && sub.length > 0 ? \"obj\" : \"sub\");\n continue;\n }\n // only an edge between two properties is property metadata; one that touches a class stays\n const between =\n (vocabulary.isProperty(sub) && vocabulary.isProperty(obj)) ||\n (typeof pred === \"string\" &&\n PROPERTY_PREDICATES.has(pred) &&\n !vocabulary.isClass(sub) &&\n !vocabulary.isClass(obj));\n if (between && ctx.json.typedefs === \"metadata\") {\n propertyEdges.push(record);\n continue;\n }\n try {\n const u = endpoint(sub, `${element}.sub`);\n const v = endpoint(obj, `${element}.obj`);\n if (u === null || v === null) {\n dropped++;\n ctx.countSkipped(\"edge\");\n continue;\n }\n const edge = ctx.pushEdge(u, v, \"directed\", undefined, element);\n if (typeof pred === \"string\") {\n columns.edge(\"relation\", edge, vocabulary.relation(pred));\n } else {\n badValue(ctx, `${element} has no pred; its relation is unset`);\n }\n if (isJsonObject(record.meta)) {\n columns.edge(\"meta\", edge, record.meta);\n } else if (record.meta !== undefined && record.meta !== null) {\n badValue(ctx, `${element}.meta must be an object; it is dropped`, `${element}.meta`);\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n if (dangling.length > 0) {\n const shown = [...new Set(dangling)].slice(0, 5).join(\", \");\n const action = ctx.options.addMissingNodes\n ? \"each became a placeholder node (graphty.placeholder)\"\n : `${dropped} edge${plural(dropped)} to them ${agree(dropped, \"was\", \"were\")} dropped (addMissingNodes false)`;\n report.warning(\n \"validation-error\",\n JSON_ISSUE.DANGLING_REFERENCE,\n `${new Set(dangling).size} edge endpoint${plural(new Set(dangling).size)} missing from nodes: ${shown}; ${action}`,\n { element: dangling[0] },\n );\n }\n return propertyEdges;\n}\n","/**\n * The `obographs` dialect of the JSON exporter: writes a snapshot as an OBO Graphs document\n * (`{ \"graphs\": [{ \"id\", \"meta\", \"nodes\", \"edges\", ... }] }`), the JSON form the Gene Ontology and\n * the OBO Foundry publish, and the form the JSON importer's `obographs` dialect reads back.\n *\n * Nodes carry `lbl` from the label column, `type` from the `type` column (Term as CLASS, Instance\n * as INDIVIDUAL, Typedef as PROPERTY) and a `meta` built from the OBO vocabulary columns\n * (src/common/ontology.ts: definition, comments, subsets, xrefs, synonyms, deprecated, and the\n * basicPropertyValues of namespace, alt_id, created_by, creation_date, replaced_by, consider and\n * property_value); any other node column becomes basicPropertyValues named after the column. Edges\n * are `{ sub, pred, obj }` with the edge's `meta` column and its other columns in `meta`. Ids are\n * written as IRIs (`GO:0008150` as `http://purl.obolibrary.org/obo/GO_0008150`, a relation by the\n * IRI of the property whose shorthand it is) whenever the importer compacts the IRI back to the\n * same id. The graph metadata, the PROPERTY nodes, the property edges and the axioms an OBO Graphs\n * import kept in `meta.extra.obographs` are written back.\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, type NodeId } from \"@graphty/graph-format\";\n\nimport {\n COLUMN_AS_PROPERTY_VALUE_CODE,\n DIRECTION_DROPPED_CODE,\n GRAPH_COLUMN_AS_METADATA_CODE,\n NODE_ORDER_CODE,\n NONFINITE_AS_NULL_CODE,\n RELATION_ASSUMED_CODE,\n TYPEDEF_NODES_CODE,\n} from \"../../common/codes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { LOSS } from \"../../common/export.js\";\nimport {\n compactOboIri,\n OBO_IN_OWL,\n OBO_NODE_COLUMNS,\n OBO_PURL,\n OBOGRAPHS_PREDICATE_TAGS,\n PLACEHOLDER_COLUMN,\n SYNONYM_SCOPES,\n} from \"../../common/ontology.js\";\nimport {\n capabilityNotes,\n cellOf,\n emptyColumnNotes,\n fitsVocabulary,\n framelessNodes,\n movedNodes,\n type NoteFn,\n notePropertyColumn,\n slotColumn,\n textOf,\n UNWRITTEN_ROLES,\n valuesOf,\n} from \"../../common/ontology-export.js\";\nimport { type ResolvedExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { type LossNote } from \"../../types.js\";\nimport { dialectCapabilities, exponentIfUnsafe, isJsonObject } from \"./dialect.js\";\nimport { BUILTIN_PREDICATES, FRAME_TYPES, META_KEYS, NODE_KEYS, PROPERTY_PREDICATES } from \"./obographs.js\";\n\n/**\n * The loss codes only the `obographs` dialect records.\n * @category Built-in formats\n */\nexport const OBOGRAPHS_LOSS = Object.freeze({\n /** An edge column (or the explicit weights) is written into the edge's `meta` and reads back inside the `meta` column. */\n EDGE_COLUMN_AS_META: \"W_OBOGRAPHS_EDGE_COLUMN_AS_META\",\n /** A node id or relation is written as an IRI the importer's default `oboIds: \"curie\"` reads back as a different id. */\n ID_CHANGED: \"W_OBOGRAPHS_ID_CHANGED\",\n /** A `property_value` with an xsd datatype: basicPropertyValues have no datatype, so it reads back without one. */\n DATATYPE_DROPPED: \"W_OBOGRAPHS_DATATYPE_DROPPED\",\n /** A graph without a node `type` column is written with CLASS nodes and reads back with a `type` column holding Term. */\n TYPE_GAINED: \"W_OBOGRAPHS_TYPE_GAINED\",\n});\n\n/**\n * The codes the dialect shares with the other exporters, under the names JSON_LOSS gives them.\n * @category Built-in formats\n */\nexport const OBOGRAPHS_SHARED_LOSS = Object.freeze({\n /** A node column outside the OBO vocabulary reads back inside the `property_value` column. */\n COLUMN_AS_PROPERTY_VALUE: COLUMN_AS_PROPERTY_VALUE_CODE,\n /** An edge without a relation is written with the predicate `is_a`. */\n RELATION_ASSUMED: RELATION_ASSUMED_CODE,\n /** Typedef nodes are written as PROPERTY nodes, which read back as nodes only under `typedefs: \"nodes\"`. */\n TYPEDEF_NODES: TYPEDEF_NODES_CODE,\n /** A graph attribute is written into the graph's `meta` and reads back in `snapshot.meta.extra.obographs`. */\n GRAPH_COLUMN_AS_METADATA: GRAPH_COLUMN_AS_METADATA_CODE,\n});\n\n/** The settings of one export. */\ninterface ObographsSettings {\n readonly common: ResolvedExportOptions;\n readonly indent: string;\n /** The ontology IRI unprefixed ids are written under, or null for the kept or derived one. */\n readonly ontologyIri: string | null;\n}\n\n/** A planned export: the notes and the writer. */\ninterface ObographsPlan {\n readonly notes: LossNote[];\n /** The document's text parts. */\n write(): Generator<string, void, undefined>;\n}\n\n/** The node type of each OBO frame type. */\nconst NODE_TYPES: Readonly<Record<string, string>> = Object.freeze({\n Term: \"CLASS\",\n Instance: \"INDIVIDUAL\",\n Typedef: \"PROPERTY\",\n});\n\n/** The basicPropertyValues predicate of each OBO tag (the reverse of OBOGRAPHS_PREDICATE_TAGS). */\nconst TAG_PREDICATES: ReadonlyMap<string, string> = new Map(\n [...OBOGRAPHS_PREDICATE_TAGS].map(([pred, tag]) => [tag, pred] as const),\n);\n\n/** The OBO Graphs pred of the relations the importer reads from a built-in pred. */\nconst REVERSE_PREDICATES: Readonly<Record<string, string>> = Object.freeze({ is_a: \"is_a\", instance_of: \"type\" });\n\n/** The vocabulary columns the dialect has a place for; every other node column is property values. */\nconst PLACED: ReadonlySet<string> = new Set([\n \"type\",\n \"propertyType\",\n \"def\",\n \"def.xrefs\",\n \"comment\",\n \"subset\",\n \"xref\",\n \"synonym\",\n \"is_obsolete\",\n \"namespace\",\n \"created_by\",\n \"creation_date\",\n \"alt_id\",\n \"replaced_by\",\n \"consider\",\n \"property_value\",\n \"obo.unrecognized\",\n]);\n\n/** The basicPropertyValues columns, in the order they are written. */\nconst PROPERTY_TAGS: readonly string[] = [\n \"namespace\",\n \"alt_id\",\n \"created_by\",\n \"creation_date\",\n \"replaced_by\",\n \"consider\",\n];\n\n/** An IRI with a scheme. */\nconst IRI = /^[A-Za-z][A-Za-z0-9+.-]*:\\/\\//;\n\n/** A CURIE whose prefix the OBO PURL mapping keeps (no underscore). */\nconst CURIE = /^([A-Za-z][A-Za-z0-9.-]*):(.+)$/;\n\n/** The keyed OBO Graphs records an import kept. */\ninterface Kept {\n readonly ids: \"curie\" | \"iri\";\n readonly graph: Record<string, unknown>;\n readonly document: Record<string, unknown>;\n readonly properties: Record<string, Record<string, unknown>>;\n readonly propertyEdges: unknown[];\n}\n\n/**\n * The records an OBO Graphs import kept under `meta.extra.obographs`.\n * @param snapshot - the snapshot\n * @returns the records, empty when the snapshot did not come from OBO Graphs\n */\nfunction keptOf(snapshot: GraphSnapshot): Kept {\n const raw = snapshot.meta.extra.obographs;\n const r = isJsonObject(raw) ? raw : {};\n const properties: Record<string, Record<string, unknown>> = {};\n if (isJsonObject(r.properties)) {\n for (const [iri, entry] of Object.entries(r.properties)) {\n if (isJsonObject(entry)) {\n properties[iri] = entry;\n }\n }\n }\n return {\n ids: r.ids === \"iri\" ? \"iri\" : \"curie\",\n graph: isJsonObject(r.graph) ? r.graph : {},\n document: isJsonObject(r.document) ? r.document : {},\n properties,\n propertyEdges: Array.isArray(r.propertyEdges) ? r.propertyEdges : [],\n };\n}\n\n/**\n * The shorthand a property's meta declares (the importer names the property by it).\n * @param meta - the property's meta\n * @returns the shorthand, or null\n */\nfunction shorthandOf(meta: unknown): string | null {\n if (!isJsonObject(meta) || !Array.isArray(meta.basicPropertyValues)) {\n return null;\n }\n for (const pv of meta.basicPropertyValues) {\n if (\n isJsonObject(pv) &&\n typeof pv.pred === \"string\" &&\n OBOGRAPHS_PREDICATE_TAGS.get(pv.pred) === \"shorthand\" &&\n typeof pv.val === \"string\"\n ) {\n return pv.val;\n }\n }\n return null;\n}\n\n/**\n * The ontology IRI unprefixed ids are written under: the option, the kept graph id, else the OBO\n * PURL of the ontology id (the kept OBO header's, or the graph name's).\n * @param snapshot - the snapshot\n * @param kept - the kept records\n * @param option - the ontologyIri option, or null\n * @returns the IRI\n */\nfunction ontologyIriOf(snapshot: GraphSnapshot, kept: Kept, option: string | null): string {\n if (option !== null) {\n return option;\n }\n if (typeof kept.graph.id === \"string\") {\n return kept.graph.id;\n }\n const { obo } = snapshot.meta.extra;\n const header = isJsonObject(obo) && isJsonObject(obo.header) ? obo.header : {};\n const ontology =\n Array.isArray(header.ontology) && typeof header.ontology[0] === \"string\" ? header.ontology[0].trim() : null;\n const name = ontology ?? snapshot.meta.name;\n const id = name === null || name.length === 0 ? \"graph\" : name.replaceAll(/[^A-Za-z0-9_.\\-/]/g, \"_\");\n return `${OBO_PURL}${id}.owl`;\n}\n\n/**\n * JSON text of a value with -0 kept and the non-finite numbers written as null (counted).\n * @param value - the value\n * @param nonfinite - the counter\n * @param nonfinite.count - the count\n * @returns the JSON text\n */\nfunction json(value: unknown, nonfinite: { count: number }): string {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n nonfinite.count++;\n return \"null\";\n }\n return Object.is(value, -0) ? \"-0\" : exponentIfUnsafe(JSON.stringify(value));\n }\n if (Array.isArray(value)) {\n return `[${value.map((v: unknown) => json(v, nonfinite)).join(\",\")}]`;\n }\n if (isJsonObject(value)) {\n return `{${Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${JSON.stringify(k)}:${json(v, nonfinite)}`)\n .join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n\n/**\n * Whether a value is a non-empty array of strings.\n * @param value - the value\n * @param empty - whether an empty array is allowed\n * @returns true for such an array\n */\nfunction strings(value: unknown, empty = false): value is string[] {\n return Array.isArray(value) && (empty || value.length > 0) && value.every((v) => typeof v === \"string\");\n}\n\n/** A synonym as the vocabulary holds it. */\ninterface Synonym {\n readonly text: string | null;\n readonly scope: string | null;\n readonly type: string | null;\n readonly xrefs: string[];\n /** The synonym's own `meta`, kept by the importer as it was. */\n readonly meta?: unknown;\n}\n\n/** One OBO Graphs export: the plan (ids, columns, notes) and the writer. */\n/**\n * The basicPropertyValue texts a property column gives one node: one per item of a list, JSON text\n * for nested values, none when unset.\n * @param column - the column\n * @param i - the node\n * @returns the texts\n */\nfunction propertyTexts(column: Column, i: number): string[] {\n const v = cellOf(column, i);\n if (v === undefined) {\n return [];\n }\n if (column.dtype === \"list\") {\n return (v as readonly unknown[]).map((item) => textOf(item, column.child.dtype));\n }\n const nested = column.dtype === \"json\" || column.meta.components > 1;\n return [nested ? (JSON.stringify(v) ?? \"null\") : textOf(v, column.dtype)];\n}\n\n/**\n * The graph columns as basicPropertyValues of the graph's meta.\n * @param snapshot - the snapshot\n * @returns one record per value\n */\nfunction graphPropertyValues(snapshot: GraphSnapshot): { pred: string; val: string }[] {\n const values: { pred: string; val: string }[] = [];\n for (const column of snapshot.graph) {\n const dtype = column.dtype === \"list\" ? column.child.dtype : column.dtype;\n for (const item of valuesOf(cellOf(column, 0))) {\n values.push({ pred: column.meta.name, val: typeof item === \"string\" ? item : textOf(item, dtype) });\n }\n }\n return values;\n}\n\n/**\n * Note a placed node column whose dtype reads back as another.\n * @param note - records a note\n * @param want - the dtype the column reads back as\n * @param column - the column\n */\nfunction dtypeNote(note: NoteFn, want: string, column: Column): void {\n const listItems = column.dtype === \"list\" && column.child.dtype !== \"string\";\n if (((want === \"string\" || want === \"dict\") && column.dtype !== want) || listItems) {\n note(\n LOSS.DTYPE,\n `node column \"${column.meta.name}\" holds ${listItems ? \"non-string items\" : column.dtype}; it reads back as ${listItems ? \"string items\" : want}`,\n column.meta.name,\n column.length - column.nullCount,\n );\n }\n}\n\n/**\n * The property values of the written nodes that carry an xsd datatype.\n * @param pv - the property_value column\n * @param rows - the written nodes\n * @returns the count\n */\nfunction countDatatypes(pv: Column, rows: readonly number[]): number {\n let datatypes = 0;\n for (const i of rows) {\n for (const item of (cellOf(pv, i) ?? []) as { datatype: unknown }[]) {\n datatypes += item.datatype === null ? 0 : 1;\n }\n }\n return datatypes;\n}\n\nclass ObographsExport {\n readonly notes: LossNote[] = [];\n\n private readonly note: NoteFn = (code, message, column = null, count = null) => {\n this.notes.push(Object.freeze({ code, message, column, count }));\n };\n\n private readonly kept: Kept;\n\n private readonly ontologyIri: string;\n\n /** IRI to the shorthand the importer names it by. */\n private readonly shorthands = new Map<string, string>();\n\n /** Shorthand to the IRI of its property. */\n private readonly shorthandIris = new Map<string, string>();\n\n /** The IRI written for each node. */\n private readonly iris: string[] = [];\n\n /** The nodes whose IRI reads back as another id. */\n private readonly changedRows = new Set<number>();\n\n /** The Typedef nodes written with a shorthand, by node. */\n private readonly typedefShorthands = new Map<number, string>();\n\n private readonly written: number[] = [];\n\n private rows: number[] = [];\n\n private frameless: Uint8Array = new Uint8Array(0);\n\n private label: Column | null = null;\n\n private readonly placed = new Map<string, Column>();\n\n private readonly properties: Column[] = [];\n\n private metaColumn: Column | null = null;\n\n private readonly edgeColumns: Column[] = [];\n\n private readonly preds = new Map<number, string>();\n\n private readonly weights: ExplicitWeights;\n\n private readonly folding: PairFolding;\n\n private readonly fatal: GraphFormatError | null;\n\n private readonly nonfinite = { count: 0 };\n\n private readonly indent: string;\n\n /** The edges' endpoints. */\n private readonly ends: { readonly src: ArrayLike<number>; readonly dst: ArrayLike<number> };\n\n /**\n * Plan the export.\n * @param snapshot - the snapshot\n * @param settings - the resolved settings\n */\n constructor(\n private readonly snapshot: GraphSnapshot,\n settings: ObographsSettings,\n ) {\n this.kept = keptOf(snapshot);\n this.ontologyIri = ontologyIriOf(snapshot, this.kept, settings.ontologyIri);\n this.indent = settings.indent !== \"\" ? `\\n${settings.indent}` : \"\";\n for (const [iri, entry] of Object.entries(this.kept.properties)) {\n const shorthand = shorthandOf(entry.meta);\n if (shorthand !== null) {\n this.shorthands.set(iri, shorthand);\n this.shorthandIris.set(shorthand, iri);\n }\n }\n this.folding = pairFolding(snapshot);\n this.ends = snapshot.edgeList();\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!this.folding.folded(e)) {\n this.written.push(e);\n }\n }\n this.weights = explicitWeights(snapshot);\n this.planIds();\n this.planNodes();\n this.fatal =\n capabilityNotes(snapshot, settings.common, {\n caps: dialectCapabilities(\"obographs\"),\n label: this.label,\n labelAssumed: slotColumn(snapshot.nodes, \"label\", \"name\").assumed,\n edgeSlot: \"edge meta\",\n note: this.note,\n }) ?? this.emptyIdError();\n this.planColumnNotes();\n this.planEdges(settings.common);\n emptyColumnNotes(snapshot, this.rows, this.frameless, this.written, this.note);\n // a dry run counts the non-finite numbers the document writes as null\n if (this.fatal === null) {\n const parts = this.write();\n while (parts.next().done !== true) {\n // only the counts the writing leaves behind are wanted\n }\n }\n if (this.nonfinite.count > 0) {\n this.note(\n NONFINITE_AS_NULL_CODE,\n `${this.nonfinite.count} NaN or infinite value${plural(this.nonfinite.count)} ${agree(this.nonfinite.count, \"is\", \"are\")} written as null`,\n null,\n this.nonfinite.count,\n );\n }\n }\n\n /**\n * The id the importer reads an IRI back as: the shorthand of the property it names, else the\n * compacted IRI.\n * @param iri - the IRI\n * @returns the id\n */\n private reread(iri: string): string {\n return this.shorthands.get(iri) ?? compactOboIri(iri);\n }\n\n /**\n * An id as an IRI: an IRI as it is, a CURIE as its OBO PURL, anything else under the\n * ontology IRI.\n * @param id - the id\n * @returns the IRI\n */\n private expand(id: string): string {\n if (IRI.test(id)) {\n return id;\n }\n const curie = CURIE.exec(id);\n if (curie !== null && !curie[1].includes(\"_\")) {\n return `${OBO_PURL}${curie[1]}_${curie[2]}`;\n }\n return `${this.ontologyIri}#${id}`;\n }\n\n /**\n * The IRI to write for an id: the first form that reads back as the id (the property of a\n * shorthand, the expanded IRI, the id itself); the id as it stands for a snapshot read with\n * oboIds \"iri\".\n * @param id - the id\n * @returns the IRI and whether it reads back as the id\n */\n private iriOf(id: string): { iri: string; exact: boolean } {\n const candidates =\n this.kept.ids === \"iri\"\n ? [id]\n : [this.shorthandIris.get(id), this.expand(id), id].filter((c): c is string => c !== undefined);\n const found = candidates.find((c) => this.reread(c) === id);\n return found === undefined ? { iri: candidates[0], exact: false } : { iri: found, exact: true };\n }\n\n /**\n * The pred to write for a relation: `is_a`, `type` for instance_of, the property of a\n * shorthand, the expanded IRI or the relation itself, whichever reads back as the relation.\n * @param r - the relation\n * @returns the pred and whether it reads back as the relation\n */\n private predOf(r: string): { pred: string; exact: boolean } {\n const reverse = REVERSE_PREDICATES[r];\n const candidates = [reverse, this.shorthandIris.get(r), this.expand(r), r].filter(\n (c): c is string => c !== undefined && !PROPERTY_PREDICATES.has(c),\n );\n const reread = (c: string): string => BUILTIN_PREDICATES[c] ?? this.shorthands.get(c) ?? compactOboIri(c);\n const found =\n this.kept.ids === \"iri\"\n ? candidates.find((c) => c === r && reread(c) === r)\n : candidates.find((c) => reread(c) === r);\n if (found !== undefined) {\n return { pred: found, exact: true };\n }\n return { pred: this.kept.ids === \"iri\" ? r : candidates[0], exact: false };\n }\n\n /**\n * An empty node id: OBO Graphs gives every node a non-empty id, and the importer skips a node\n * without one, so the export is refused.\n * @returns the error, or null when every id has text\n */\n private emptyIdError(): GraphFormatError | null {\n const { snapshot } = this;\n let count = 0;\n let first = -1;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n if (String(snapshot.ids.idOf(i)) === \"\") {\n count++;\n first = first < 0 ? i : first;\n }\n }\n if (count === 0) {\n return null;\n }\n const message = `${count} node id${plural(count)} ${agree(count, \"is\", \"are\")} empty; an OBO Graphs node needs an id, so the save fails`;\n this.note(LOSS.ID_CHARSET, message, null, count);\n return new GraphFormatError(\"E_INVALID_ID\", message, { reason: \"charset\", count, id: \"\", index: first });\n }\n\n /** The IRI of every node, the Typedefs named by a shorthand, and the numeric-id note. */\n private planIds(): void {\n const { snapshot } = this;\n const typeColumn = snapshot.nodes.get(\"type\");\n let numeric = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id: NodeId = snapshot.ids.idOf(i);\n numeric += typeof id === \"number\" ? 1 : 0;\n const text = String(id);\n let { iri, exact } = this.iriOf(text);\n const typedef = typeColumn !== null && typeColumn.isSet(i) && typeColumn.value(i) === \"Typedef\";\n if (!exact && typedef && !IRI.test(text) && this.kept.ids === \"curie\") {\n // a Typedef named by its shorthand: written under an IRI with the shorthand declared\n iri = this.expand(text);\n this.shorthands.set(iri, text);\n this.shorthandIris.set(text, iri);\n this.typedefShorthands.set(i, text);\n exact = true;\n }\n this.iris.push(iri);\n if (!exact) {\n this.changedRows.add(i);\n }\n }\n if (numeric > 0) {\n this.note(\n LOSS.ID_TEXT_TYPE,\n `${numeric} numeric node id${plural(numeric)} ${agree(numeric, \"is\", \"are\")} written as text and read back as strings`,\n null,\n numeric,\n );\n }\n }\n\n /** The written nodes (placeholders aside), the node order, and the columns with a place. */\n private planNodes(): void {\n const { snapshot } = this;\n const { src, dst } = this.ends;\n this.frameless = framelessNodes(snapshot, this.written, {\n outgoingAllowed: true,\n changed: (i) => this.changedRows.has(i),\n });\n const moved = movedNodes(\n this.frameless,\n this.written.flatMap((e) => [src[e], dst[e]]),\n );\n if (moved > 0) {\n this.note(\n NODE_ORDER_CODE,\n `${moved} node${plural(moved)} ${agree(moved, \"reads\", \"read\")} back at another position: placeholder nodes are not written and read back after the written nodes`,\n null,\n moved,\n );\n }\n this.rows = [];\n for (let i = 0; i < snapshot.nodeCount; i++) {\n if (this.frameless[i] === 0) {\n this.rows.push(i);\n }\n }\n this.label = slotColumn(snapshot.nodes, \"label\", \"name\").column;\n this.placeColumns();\n this.planProperties();\n }\n\n /** The node columns written in their own places of a node (def, synonyms, xrefs...), not as property values. */\n private placeColumns(): void {\n const { snapshot } = this;\n const reproducible = (id: unknown): boolean => typeof id === \"string\" && this.iriOf(id).exact;\n for (const name of PLACED) {\n const column = snapshot.nodes.get(name);\n if (\n column !== null &&\n column !== this.label &&\n column.meta.role === null &&\n carries(name, column, this.rows, reproducible)\n ) {\n this.placed.set(name, column);\n }\n }\n const def = this.placed.get(\"def\");\n const defXrefs = this.placed.get(\"def.xrefs\");\n if (\n defXrefs !== undefined &&\n (def === undefined || this.rows.some((i) => def.isSet(i) !== defXrefs.isSet(i)))\n ) {\n this.placed.delete(\"def.xrefs\");\n }\n if (def !== undefined && !this.placed.has(\"def.xrefs\") && snapshot.nodes.get(\"def.xrefs\") !== null) {\n this.placed.delete(\"def\");\n }\n }\n\n /** The node columns written as property values, each with its note. */\n private planProperties(): void {\n const { snapshot } = this;\n const slotted = new Set<Column>([...this.placed.values(), ...(this.label === null ? [] : [this.label])]);\n for (const column of snapshot.nodes) {\n const { role, name } = column.meta;\n if (slotted.has(column) || (role !== null && UNWRITTEN_ROLES.has(role))) {\n continue;\n }\n if (name === PLACEHOLDER_COLUMN && this.rows.every((i) => !column.isSet(i))) {\n continue;\n }\n this.properties.push(column);\n notePropertyColumn(this.note, column, this.rows, `basicPropertyValues (pred ${JSON.stringify(name)})`);\n }\n }\n\n /** The notes about node and graph columns: Typedef nodes, dtypes, datatypes, graph columns. */\n private planColumnNotes(): void {\n const { snapshot, rows, label, note } = this;\n const type = this.placed.get(\"type\");\n const typedefs =\n type === undefined ? 0 : rows.filter((i) => type.isSet(i) && type.value(i) === \"Typedef\").length;\n if (rows.length > 0 && snapshot.nodes.get(\"type\") === null) {\n note(\n OBOGRAPHS_LOSS.TYPE_GAINED,\n `${rows.length} node${plural(rows.length)} ${agree(rows.length, \"is\", \"are\")} written with the type CLASS and ${agree(rows.length, \"reads\", \"read\")} back with the type Term in a new node column \"type\"`,\n null,\n rows.length,\n );\n }\n if (typedefs > 0) {\n note(\n TYPEDEF_NODES_CODE,\n `${typedefs} node${plural(typedefs)} ${agree(typedefs, \"is\", \"are\")} written as PROPERTY nodes; they read back as nodes only when imported with typedefs: \"nodes\", and then their edges with them`,\n \"type\",\n typedefs,\n );\n }\n for (const [name, column] of [...this.placed, ...(label === null ? [] : ([[\"name\", label]] as const))]) {\n dtypeNote(note, name === \"name\" ? \"string\" : OBO_NODE_COLUMNS[name].dtype, column);\n }\n const pv = this.placed.get(\"property_value\");\n const datatypes = pv === undefined ? 0 : countDatatypes(pv, rows);\n if (datatypes > 0) {\n note(\n OBOGRAPHS_LOSS.DATATYPE_DROPPED,\n `${datatypes} property value${plural(datatypes)} ${agree(datatypes, \"carries\", \"carry\")} an xsd datatype; OBO Graphs basicPropertyValues have none, so they read back without it`,\n \"property_value\",\n datatypes,\n );\n }\n for (const column of snapshot.graph) {\n note(\n GRAPH_COLUMN_AS_METADATA_CODE,\n `graph column \"${column.meta.name}\" is written as a basicPropertyValue of the graph's meta and reads back in meta.extra.obographs, not as a column`,\n column.meta.name,\n column.length - column.nullCount,\n );\n }\n }\n\n /**\n * The edges' preds, meta and other columns, and their notes (relation, direction, ids that\n * change).\n * @param common - the common options\n */\n private planEdges(common: ResolvedExportOptions): void {\n const { snapshot, written, note } = this;\n const slot = slotColumn(snapshot.edges, \"kind\", \"relation\");\n const relation = slot.column;\n if (slot.assumed && relation !== null) {\n note(\n LOSS.ROLE_ASSUMED,\n `edge column \"relation\" has no role, so it is taken as the relation of each edge: it is written as each edge's pred, and reads back with the relation role (\"kind\")`,\n \"relation\",\n relation.length - relation.nullCount,\n );\n }\n const meta = snapshot.edges.get(\"meta\");\n const metaOk =\n meta !== null &&\n meta.dtype === \"json\" &&\n meta.meta.role === null &&\n written.every((e) => !meta.isSet(e) || isJsonObject(cellOf(meta, e)));\n this.metaColumn = metaOk ? meta : null;\n for (const column of snapshot.edges) {\n const { role } = column.meta;\n if (\n column === relation ||\n column === this.metaColumn ||\n role === \"id\" ||\n (role !== null && UNWRITTEN_ROLES.has(role))\n ) {\n continue;\n }\n this.edgeColumns.push(column);\n const count = written.filter((e) => column.isSet(e)).length;\n if (count > 0) {\n note(\n OBOGRAPHS_LOSS.EDGE_COLUMN_AS_META,\n `edge column \"${column.meta.name}\" is written into each edge's meta and reads back inside the meta column`,\n column.meta.name,\n count,\n );\n }\n }\n const { weights } = this;\n const weighted = weights.weighted ? written.filter((e) => weights.isExplicit(e)).length : 0;\n if (weighted > 0) {\n note(\n OBOGRAPHS_LOSS.EDGE_COLUMN_AS_META,\n `${weighted} explicit edge weight${plural(weighted)} ${agree(weighted, \"is\", \"are\")} written as \"weight\" in each edge's meta and read back inside the meta column, not as weights`,\n snapshot.edges.byRole(\"weight\")?.meta.name ?? null,\n weighted,\n );\n }\n this.planPreds(relation);\n this.directionNotes(common);\n }\n\n /**\n * The pred of every written edge, with the relation and id notes.\n * @param relation - the relation column, or null\n */\n private planPreds(relation: Column | null): void {\n let assumed = 0;\n let relationChanges = 0;\n for (const e of this.written) {\n const value = relation === null ? undefined : cellOf(relation, e);\n if (typeof value !== \"string\") {\n assumed++;\n this.preds.set(e, \"is_a\");\n continue;\n }\n const { pred, exact } = this.predOf(value);\n this.preds.set(e, pred);\n relationChanges += exact ? 0 : 1;\n }\n if (assumed > 0) {\n this.note(\n RELATION_ASSUMED_CODE,\n `${assumed} edge${plural(assumed)} ${agree(assumed, \"has\", \"have\")} no relation; written with the pred is_a (an ontology reads is_a as subclassing)`,\n relation?.meta.name ?? null,\n assumed,\n );\n }\n const idChanges = this.rows.filter((i) => this.changedRows.has(i)).length;\n if (idChanges + relationChanges > 0) {\n this.note(\n OBOGRAPHS_LOSS.ID_CHANGED,\n `${idChanges} node id${plural(idChanges)} and ${relationChanges} relation${plural(relationChanges)} are written as IRIs the importer reads back as other ids under its default oboIds \"curie\"`,\n null,\n idChanges + relationChanges,\n );\n }\n }\n\n /**\n * The direction notes: every OBO Graphs edge is directed.\n * @param common - the common options\n */\n private directionNotes(common: ResolvedExportOptions): void {\n const { snapshot, written, folding, note } = this;\n if (!snapshot.directed) {\n note(\n DIRECTION_DROPPED_CODE,\n `the snapshot is undirected; OBO Graphs edges are directed and read back directed (${written.length} edge${plural(written.length)})`,\n null,\n written.length,\n );\n } else if (common.onMixedDirection !== \"error\") {\n const undirected = written.filter((e) => !folding.sourceDirected(e)).length;\n if (undirected > 0) {\n note(\n DIRECTION_DROPPED_CODE,\n `${undirected} undirected edge${plural(undirected)} ${agree(undirected, \"is\", \"are\")} written as one directed edge each`,\n null,\n undirected,\n );\n }\n }\n if (folding.mutualCount > 0) {\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n }\n\n /**\n * A placed column's cell.\n * @param name - the vocabulary name\n * @param i - the node\n * @returns the value, or undefined\n */\n private at(name: string, i: number): unknown {\n const column = this.placed.get(name);\n return column === undefined ? undefined : cellOf(column, i);\n }\n\n /**\n * One node record as JSON.\n * @param i - the node\n * @returns the JSON text\n */\n private nodeRecord(i: number): string {\n const node: Record<string, unknown> = { id: this.iris[i] };\n const lbl = this.label === null ? undefined : cellOf(this.label, i);\n if (typeof lbl === \"string\") {\n node.lbl = lbl;\n }\n // without a type column every node is a class; the type also marks the document as OBO Graphs\n const untyped = this.snapshot.nodes.get(\"type\") === null ? \"Term\" : undefined;\n const type = this.placed.has(\"type\") ? this.at(\"type\", i) : untyped;\n if (typeof type === \"string\") {\n node.type = NODE_TYPES[type] ?? type;\n }\n const propertyType = this.at(\"propertyType\", i);\n if (propertyType !== undefined) {\n node.propertyType = propertyType;\n }\n const meta = this.nodeMeta(i);\n const extra = this.at(\"obo.unrecognized\", i);\n if (isJsonObject(extra)) {\n for (const [key, value] of Object.entries(extra)) {\n if (key.startsWith(\"meta.\")) {\n meta[key.slice(5)] = value;\n } else {\n node[key] = value;\n }\n }\n }\n if (Object.keys(meta).length > 0) {\n node.meta = meta;\n }\n return json(node, this.nonfinite);\n }\n\n /**\n * One node's meta: definition, comments, subsets, xrefs, synonyms, deprecated and the\n * basicPropertyValues.\n * @param i - the node\n * @returns the meta record\n */\n private nodeMeta(i: number): Record<string, unknown> {\n const meta: Record<string, unknown> = {};\n const def = this.at(\"def\", i);\n if (typeof def === \"string\") {\n meta.definition = { val: def, xrefs: this.at(\"def.xrefs\", i) ?? [] };\n }\n const comment = this.at(\"comment\", i);\n if (typeof comment === \"string\") {\n meta.comments = [comment];\n }\n const subsets = this.at(\"subset\", i);\n if (Array.isArray(subsets)) {\n meta.subsets = subsets.map((s) => this.iriOf(String(s)).iri);\n }\n const xrefs = this.at(\"xref\", i);\n if (Array.isArray(xrefs)) {\n meta.xrefs = xrefs.map((val) => ({ val }));\n }\n const synonyms = this.at(\"synonym\", i);\n if (Array.isArray(synonyms)) {\n meta.synonyms = (synonyms as Synonym[]).map((s) => this.synonymRecord(s));\n }\n const obsolete = this.at(\"is_obsolete\", i);\n if (typeof obsolete === \"boolean\") {\n meta.deprecated = obsolete;\n }\n const values = this.propertyValues(i);\n if (values.length > 0) {\n meta.basicPropertyValues = values;\n }\n return meta;\n }\n\n /**\n * One synonym record.\n * @param s - the synonym\n * @returns the record\n */\n private synonymRecord(s: Synonym): Record<string, unknown> {\n const out: Record<string, unknown> = {\n pred: s.scope === null ? \"hasSynonym\" : `has${s.scope[0]}${s.scope.slice(1).toLowerCase()}Synonym`,\n };\n if (s.text !== null) {\n out.val = s.text;\n }\n if (s.xrefs.length > 0) {\n out.xrefs = s.xrefs;\n }\n if (s.type !== null) {\n out.synonymType = this.iriOf(s.type).iri;\n }\n if (s.meta !== undefined) {\n out.meta = s.meta;\n }\n return out;\n }\n\n /**\n * One node's basicPropertyValues: the tags OBO Graphs writes as annotations, the Typedef\n * shorthand, the property values, then the columns outside the vocabulary.\n * @param i - the node\n * @returns the records\n */\n private propertyValues(i: number): Record<string, unknown>[] {\n const values: Record<string, unknown>[] = [];\n for (const tag of PROPERTY_TAGS) {\n const v = this.at(tag, i);\n const pred = TAG_PREDICATES.get(tag) ?? tag;\n for (const item of valuesOf(v)) {\n const text = String(item);\n values.push({ pred, val: tag === \"replaced_by\" || tag === \"consider\" ? this.iriOf(text).iri : text });\n }\n }\n const shorthand = this.typedefShorthands.get(i);\n if (shorthand !== undefined) {\n values.push({ pred: `${OBO_IN_OWL}shorthand`, val: shorthand });\n }\n for (const item of (this.at(\"property_value\", i) ?? []) as { relation: string; value: string }[]) {\n values.push({ pred: this.iriOf(item.relation).iri, val: item.value });\n }\n for (const column of this.properties) {\n for (const val of propertyTexts(column, i)) {\n values.push({ pred: column.meta.name, val });\n }\n }\n return values;\n }\n\n /**\n * One edge record as JSON.\n * @param e - the edge\n * @returns the JSON text\n */\n private edgeRecord(e: number): string {\n const { src, dst } = this.ends;\n const edge: Record<string, unknown> = {\n sub: this.iris[src[e]],\n pred: this.preds.get(e),\n obj: this.iris[dst[e]],\n };\n const base = this.metaColumn === null ? undefined : cellOf(this.metaColumn, e);\n const meta: Record<string, unknown> = isJsonObject(base) ? { ...base } : {};\n for (const column of this.edgeColumns) {\n const v = cellOf(column, e);\n if (v !== undefined) {\n meta[column.meta.name] = v;\n }\n }\n if (this.weights.weighted && this.weights.isExplicit(e)) {\n meta.weight = this.weights.value(e);\n }\n if (Object.keys(meta).length > 0 || base !== undefined) {\n edge.meta = meta;\n }\n return json(edge, this.nonfinite);\n }\n\n /**\n * The graph record up to its nodes: the id, the label and the meta (the graph columns as\n * basicPropertyValues).\n * @returns the JSON text without its closing brace\n */\n private graphHead(): string {\n const { kept, snapshot } = this;\n const graph: Record<string, unknown> = {\n id: typeof kept.graph.id === \"string\" ? kept.graph.id : this.ontologyIri,\n };\n const named = snapshot.meta.name !== null && kept.graph.id === undefined;\n const lbl = kept.graph.lbl ?? (named ? snapshot.meta.name : undefined);\n if (lbl !== undefined) {\n graph.lbl = lbl;\n }\n const meta: Record<string, unknown> = isJsonObject(kept.graph.meta) ? { ...kept.graph.meta } : {};\n const values: unknown[] = Array.isArray(meta.basicPropertyValues)\n ? [...(meta.basicPropertyValues as unknown[])]\n : [];\n values.push(...graphPropertyValues(snapshot));\n if (values.length > 0) {\n meta.basicPropertyValues = values;\n }\n if (Object.keys(meta).length > 0) {\n graph.meta = meta;\n }\n return json(graph, this.nonfinite).slice(0, -1);\n }\n\n /**\n * The graph keys after the edges (the kept axioms and other keys).\n * @returns the JSON text from the comma to the closing brace\n */\n private graphTail(): string {\n const rest: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(this.kept.graph)) {\n if (key !== \"id\" && key !== \"lbl\" && key !== \"meta\" && key !== \"nodes\" && key !== \"edges\") {\n rest[key] = value;\n }\n }\n const text = json(rest, this.nonfinite);\n return text === \"{}\" ? \"}\" : `,${text.slice(1)}`;\n }\n\n /**\n * The kept PROPERTY nodes no written node stands for.\n * @returns their JSON texts\n */\n private propertyNodes(): string[] {\n const writtenIris = new Set(this.rows.map((i) => this.iris[i]));\n const out: string[] = [];\n for (const [iri, entry] of Object.entries(this.kept.properties)) {\n if (writtenIris.has(iri)) {\n continue;\n }\n const node: Record<string, unknown> = { id: iri, lbl: entry.lbl, type: \"PROPERTY\" };\n node.propertyType = entry.propertyType;\n node.meta = entry.meta;\n out.push(json(node, this.nonfinite));\n }\n return out;\n }\n\n /**\n * The document's text parts.\n * @yields the graph head, one part per node and edge, the tail\n * @returns nothing\n */\n *write(): Generator<string, void, undefined> {\n if (this.fatal !== null) {\n throw this.fatal;\n }\n const { indent } = this;\n yield `{\"graphs\":[${this.graphHead()},\"nodes\":[`;\n let first = true;\n const item = (text: string): string => {\n const out = `${first ? \"\" : \",\"}${indent}${text}`;\n first = false;\n return out;\n };\n for (const i of this.rows) {\n yield item(this.nodeRecord(i));\n }\n for (const node of this.propertyNodes()) {\n yield item(node);\n }\n yield `],\"edges\":[`;\n first = true;\n for (const e of this.written) {\n yield item(this.edgeRecord(e));\n }\n for (const edge of this.kept.propertyEdges) {\n yield item(json(edge, this.nonfinite));\n }\n yield `]${this.graphTail()}]`;\n const document = json(this.kept.document, this.nonfinite);\n yield document === \"{}\" ? \"}\\n\" : `,${document.slice(1)}\\n`;\n }\n}\n\n/**\n * Plan an OBO Graphs export.\n * @param snapshot - the snapshot\n * @param settings - the resolved settings\n * @returns the notes and the writer\n * @category Plugin helpers\n */\nexport function planObographs(snapshot: GraphSnapshot, settings: ObographsSettings): ObographsPlan {\n const plan = new ObographsExport(snapshot, settings);\n return { notes: plan.notes, write: () => plan.write() };\n}\n\n/**\n * Whether a vocabulary column is written into its OBO Graphs place and read back unchanged on\n * every written node.\n * @param name - the column name (a PLACED name)\n * @param column - the column\n * @param rows - the written nodes\n * @param reproducible - whether an id is written as an IRI that reads back as itself\n * @returns true when the place carries the column\n */\nfunction carries(\n name: string,\n column: Column,\n rows: readonly number[],\n reproducible: (id: unknown) => boolean,\n): boolean {\n const spec = OBO_NODE_COLUMNS[name];\n if (!fitsVocabulary(spec.dtype, column) || column.meta.components > 1) {\n return false;\n }\n const valid = (v: unknown): boolean => {\n switch (name) {\n case \"type\":\n return typeof v === \"string\" && !Object.hasOwn(FRAME_TYPES, v);\n case \"propertyType\":\n case \"def\":\n case \"comment\":\n case \"namespace\":\n case \"created_by\":\n case \"creation_date\":\n return typeof v === \"string\";\n case \"is_obsolete\":\n return typeof v === \"boolean\";\n case \"def.xrefs\":\n return strings(v, true);\n case \"xref\":\n case \"alt_id\":\n return strings(v);\n case \"subset\":\n case \"replaced_by\":\n case \"consider\":\n return strings(v) && v.every(reproducible);\n case \"synonym\":\n return (\n Array.isArray(v) &&\n v.length > 0 &&\n v.every(\n (s) =>\n isJsonObject(s) &&\n Object.keys(s).length === (\"meta\" in s ? 5 : 4) &&\n (s.text === null || typeof s.text === \"string\") &&\n (s.scope === null || (typeof s.scope === \"string\" && SYNONYM_SCOPES.has(s.scope))) &&\n (s.type === null || reproducible(s.type)) &&\n strings(s.xrefs, true),\n )\n );\n case \"property_value\":\n return (\n Array.isArray(v) &&\n v.length > 0 &&\n v.every(\n (x) =>\n isJsonObject(x) &&\n Object.keys(x).length === 3 &&\n reproducible(x.relation) &&\n !OBOGRAPHS_PREDICATE_TAGS.has(String(x.relation)) &&\n typeof x.value === \"string\" &&\n (x.datatype === null || typeof x.datatype === \"string\"),\n )\n );\n case \"obo.unrecognized\":\n return (\n isJsonObject(v) &&\n Object.keys(v).every((key) =>\n key.startsWith(\"meta.\") ? !META_KEYS.has(key.slice(5)) && key.length > 5 : !NODE_KEYS.has(key),\n )\n );\n default:\n return false;\n }\n };\n return rows.every((i) => !column.isSet(i) || valid(cellOf(column, i)));\n}\n","/**\n * The JSON exporter (design section 8.5): one GraphExporter with a `dialect` option writing\n * NetworkX node-link (the default), d3 (`links`, optional index endpoints), JSON Graph Format v2,\n * Cytoscape.js elements, graphology serialization or vis.js. The dialect defaults to the one the\n * importer recorded under `meta.extra.json` so a JSON file re-exported as JSON keeps its shape,\n * and to node-link for a snapshot from any other source.\n *\n * check() runs the generic capability pre-flight against the dialect's table and appends the\n * dialect-specific notes (non-finite numbers written as null, JGF id stringification / collisions\n * / node order, direction dropped by Cytoscape and vis, mutual pairs expanded, reserved key\n * collisions, positions written as plain attributes, a Cytoscape `parents` column) before anything\n * is written; the same column plan drives write(), so the notes and the output agree.\n *\n * Every column without a structural slot in the dialect is written as a plain attribute under its\n * column name; an f32 value is written as the shortest decimal that round-trips through\n * Math.fround (design section 3.7); a multi-component value is an array; a list is an array; a json\n * value is its JSON text; an unset row writes no key (design section 5.3). Non-finite numbers,\n * which JSON cannot carry, become null and are reported.\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, INVALID_INDEX, type NodeId } from \"@graphty/graph-format\";\n\nimport { DIRECTION_DROPPED_CODE, NODE_ORDER_CODE, NONFINITE_AS_NULL_CODE } from \"../../common/codes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { checkCapabilities, countMixedEdges, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64 } from \"../../common/format.js\";\nimport { flipY } from \"../../common/json-elements.js\";\nimport { otherFormatDialect, type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, indentUnit, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n CYTOSCAPE_ELEMENT_KEYS,\n DIALECT_DEFAULT_DIRECTED,\n dialectCapabilities,\n exponentIfUnsafe,\n isJsonDialect,\n JSON_DIALECTS,\n type JsonDialect,\n type JsonShapeMeta,\n shapeMetaOf,\n SUFFIX,\n} from \"./dialect.js\";\nimport { OBOGRAPHS_LOSS, OBOGRAPHS_SHARED_LOSS, planObographs } from \"./obographs-export.js\";\n\n/**\n * The format-specific options of the JSON exporter.\n * @category Built-in formats\n */\nexport interface JsonExportOptions extends CommonExportOptions {\n /**\n * The dialect to write. The default is the dialect a JSON import read, else \"node-link\".\n * Attributes are written under their own names; vis.js shows the `label` attribute, so rename\n * the attribute you want shown to `label` first (`snapshot.nodes.rename(\"name\", \"label\")`). A CSV\n * dialect name (\"gephi\", \"generic\"), from an options object shared with CSV saves, is ignored.\n * @defaultValue as read, else \"node-link\"\n */\n dialect?: JsonDialect | undefined;\n /**\n * The indentation of one level: a number of spaces, or the text itself (spaces or tabs, such as\n * \"\\t\"). 0 or \"\" writes compact JSON on one line.\n * @defaultValue 0\n */\n indent?: number | string | undefined;\n /**\n * node-link and d3: the key of the edge array. The default is the key a JSON import read, else\n * \"edges\" (\"links\" for d3).\n * @defaultValue as read, else \"edges\"\n */\n edgesKey?: string | undefined;\n /**\n * node-link, d3 and vis: the node id key. The default is the key a JSON import read, else \"id\".\n * @defaultValue as read, else \"id\"\n */\n nodeIdKey?: string | undefined;\n /**\n * node-link and d3: write edge ends as positions in the node array instead of ids. The default\n * is what a JSON import read, else false.\n * @defaultValue as read, else false\n */\n indexLinks?: boolean | undefined;\n /**\n * node-link, d3 and vis: the source key. The default is the key a JSON import read, else\n * \"source\" (\"from\" for vis). graph-io finds \"source\", \"src\" and \"from\" by itself; for another\n * key, read the file back with the same `sourceKey` import option. Without it every edge is an\n * `E_MISSING_ENDPOINT` error and is skipped, and a file with more edges than `errorLimit` (100 by\n * default) fails to load with an `ImportError`. `checkExport()` does not warn about this.\n * @defaultValue as read, else \"source\"\n */\n sourceKey?: string | undefined;\n /**\n * node-link, d3 and vis: the target key. The default is the key a JSON import read, else\n * \"target\" (\"to\" for vis). graph-io finds \"target\", \"dst\" and \"to\" by itself; for another key,\n * read the file back with the same `targetKey` import option, as for `sourceKey`.\n * @defaultValue as read, else \"target\"\n */\n targetKey?: string | undefined;\n /**\n * The key the weight is written under, in every dialect but OBO Graphs, which always writes the\n * weight as \"weight\" in each edge's `meta` (checkExport() then returns W_OBOGRAPHS_EDGE_COLUMN_AS_META).\n * The default is the key a JSON import read the weights from, else \"weight\". For another key,\n * read the file back with `weightFrom` set to it, or the weights come back as a plain edge\n * attribute.\n * @defaultValue as read, else \"weight\"\n */\n weightKey?: string | undefined;\n /**\n * OBO Graphs: the graph id written when the graph has none. A graph read from an OBO Graphs\n * document keeps its own graph id, which this option does not change. Node ids are written in\n * the form graph-io reads back as the same id: an IRI as it is, a prefixed id such as\n * `GO:0008150` as its OBO address, and an id without a prefix (`a`) under the default OBO\n * address (`http://purl.obolibrary.org/obo/graph.owl#a`), or as it is when you pass another IRI\n * here. The default is `http://purl.obolibrary.org/obo/<ontology>.owl`.\n * @defaultValue the ontology's OBO address\n */\n ontologyIri?: string | undefined;\n}\n\n/**\n * The LossNote codes of the JSON exporter's check(): the dialect-specific ones and, aliased, the\n * shared ones it records (`LOSS` holds the rest of the generic pre-flight's codes). A key is the\n * code without its severity prefix.\n * @category Built-in formats\n */\nexport const JSON_LOSS = Object.freeze({\n /** Non-finite numbers (columns, weights) are written as null. */\n NONFINITE_AS_NULL: NONFINITE_AS_NULL_CODE,\n /**\n * The file cannot record direction: an undirected graph's edges read back as directed, or the whole graph reads\n * back with the importer's default direction.\n */\n DIRECTION_DROPPED: DIRECTION_DROPPED_CODE,\n /** GEXF mutual pairs are written as two directed edges. */\n MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,\n /**\n * JGF keys its nodes by text, so number ids read back as text, unless you read the file with `ids: \"canonical\"`.\n */\n NUMERIC_IDS_STRINGIFIED: \"W_NUMERIC_IDS_STRINGIFIED\",\n /**\n * Two node ids would be written as the same text (the number 5 and the text \"5\"); the save fails with\n * E_INVALID_ID.\n */\n ID_TEXT_COLLISION: LOSS.ID_TEXT_COLLISION,\n /** The nodes read back in a different order. */\n NODE_ORDER: NODE_ORDER_CODE,\n /** A column named like a reserved key of the dialect (id, source, target, ...) is skipped. */\n RESERVED_KEY: \"W_RESERVED_KEY\",\n /**\n * An attribute without the weight role is named like the key weights are written under; it reads back as the edge\n * weight, or is not written when the graph has weights of its own.\n */\n WEIGHT_KEY_CLASH: LOSS.WEIGHT_KEY_CLASH,\n /** A position column without a slot (every dialect but Cytoscape) is a plain array attribute; the role is lost. */\n POSITIONS_DROPPED: LOSS.POSITIONS,\n /** Cytoscape positions are 2D; non-zero z values are dropped. */\n POSITION_Z_DROPPED: \"W_POSITION_Z_DROPPED\",\n /** Cytoscape has a single parent; a `parents` list column cannot be written. */\n PARENTS_DROPPED: LOSS.PARENTS,\n /** Node-link / d3 have no edge id slot; the id column is written as a plain attribute. */\n EDGE_IDS_DROPPED: LOSS.EDGE_IDS_DROPPED,\n /**\n * A number attribute whose values are all whole numbers reads back as integers, because the format does not record\n * the type.\n */\n INTEGRAL_F64_AS_I32: LOSS.INTEGRAL_F64,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: LOSS.ROLE,\n /** A column without a set cell is not written (JSON declares no columns). */\n EMPTY_COLUMN_DROPPED: LOSS.EMPTY_COLUMN,\n /**\n * Obographs: an edge column (or the explicit weights) is written into each edge's meta and reads back inside the\n * meta column.\n */\n OBOGRAPHS_EDGE_COLUMN_AS_META: OBOGRAPHS_LOSS.EDGE_COLUMN_AS_META,\n /**\n * Obographs: a node id or relation is written as an IRI the importer's default oboIds \"curie\" reads back as\n * another id.\n */\n OBOGRAPHS_ID_CHANGED: OBOGRAPHS_LOSS.ID_CHANGED,\n /** Obographs: a property_value's xsd datatype has no place in basicPropertyValues and reads back unset. */\n OBOGRAPHS_DATATYPE_DROPPED: OBOGRAPHS_LOSS.DATATYPE_DROPPED,\n /** Obographs: a graph without a node type column is written with CLASS nodes and reads back with a type column holding Term. */\n OBOGRAPHS_TYPE_GAINED: OBOGRAPHS_LOSS.TYPE_GAINED,\n /** Obographs: a node column outside the OBO vocabulary reads back inside the property_value column. */\n COLUMN_AS_PROPERTY_VALUE: OBOGRAPHS_SHARED_LOSS.COLUMN_AS_PROPERTY_VALUE,\n /** Obographs: an edge without a relation is written with the pred is_a. */\n RELATION_ASSUMED: OBOGRAPHS_SHARED_LOSS.RELATION_ASSUMED,\n /**\n * Obographs: Typedef nodes are written as PROPERTY nodes, which read back as nodes only under typedefs: \"nodes\".\n */\n TYPEDEF_NODES: OBOGRAPHS_SHARED_LOSS.TYPEDEF_NODES,\n /**\n * OBO Graphs: a graph attribute is written into the graph's `meta` and reads back in\n * `snapshot.meta.extra.obographs`.\n */\n GRAPH_COLUMN_AS_METADATA: OBOGRAPHS_SHARED_LOSS.GRAPH_COLUMN_AS_METADATA,\n /** Obographs: numeric node ids are written as text and read back as strings. */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /**\n * An attribute without a role is written where the format keeps a role (for example, a `name` column as the label), and\n * reads back with that role.\n */\n ROLE_ASSUMED: LOSS.ROLE_ASSUMED,\n /**\n * An attribute with a role (for example, the label) is written where the format keeps that role, and reads back under the\n * name the format's importer gives it.\n */\n COLUMN_NAME_CHANGED: LOSS.COLUMN_NAME_CHANGED,\n /**\n * OBO Graphs: an OBO attribute stored as text where graph-io uses a dictionary (or the other way round); it reads\n * back with graph-io's usual type. The values are the same.\n */\n DTYPE_UNSUPPORTED: LOSS.DTYPE,\n});\n\n/** The roles each dialect has a slot for (every other role column is a plain attribute, reported by checkCapabilities()). */\nconst SLOT_ROLES: Readonly<Record<JsonDialect, ReadonlySet<string>>> = Object.freeze({\n \"node-link\": new Set<string>(),\n d3: new Set<string>(),\n jgf: new Set([\"label\", \"kind\"]),\n cytoscape: new Set([\"classes\"]),\n graphology: new Set<string>(),\n vis: new Set<string>(),\n obographs: new Set([\"label\", \"kind\"]),\n});\n\n/** The element domains. */\ntype Domain = \"node\" | \"edge\" | \"graph\";\n\n/** A note-recording callback. */\ntype NoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/** The roles the pre-flight treats structurally; never written as attributes. */\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n]);\n\n/** The roles no JSON dialect can carry; skipped (checkCapabilities reports them). */\nconst TEMPORAL_ROLES: ReadonlySet<string> = new Set([\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** The dialects whose attributes live in a nested dict (data / metadata / attributes). */\nconst NESTED_DIALECTS: ReadonlySet<JsonDialect> = new Set([\"jgf\", \"cytoscape\", \"graphology\"]);\n\n/** A mutable counter of the non-finite numbers written as null. */\ninterface Counter {\n count: number;\n}\n\n/** How one column is written. */\ntype Slot = \"attribute\" | \"element\" | \"position\" | \"cytoscapePosition\" | \"parent\" | \"classes\" | \"label\" | \"relation\";\n\n/** One column's place in the output. */\ninterface ColumnPlan {\n readonly column: Column;\n /** The output key (attribute or element-level key). */\n readonly key: string;\n readonly slot: Slot;\n}\n\n/** The resolved exporter options. */\ninterface Resolved {\n readonly common: ResolvedExportOptions;\n readonly dialect: JsonDialect;\n readonly indent: string;\n readonly edgesKey: string;\n readonly nodeIdKey: string | null;\n readonly indexLinks: boolean;\n readonly sourceKey: string;\n readonly targetKey: string;\n readonly weightKey: string;\n readonly shape: JsonShapeMeta;\n readonly ontologyIri: string | null;\n}\n\n/** Everything write() needs, computed once by plan(). */\ninterface Plan {\n readonly resolved: Resolved;\n readonly notes: LossNote[];\n readonly nodes: readonly ColumnPlan[];\n readonly edges: readonly ColumnPlan[];\n readonly graph: readonly ColumnPlan[];\n /** The id-role edge column, or null. */\n readonly edgeIds: Column | null;\n /** The weight of an edge as JSON text, or null when the edge has no explicit weight. */\n readonly weights: (e: number) => string | null;\n /** The pair folding (design section 3.6): mirrors skipped, source directions. */\n readonly folding: PairFolding;\n /** The file-level direction. */\n readonly directed: boolean;\n /** Whether the file declares a multigraph. */\n readonly multigraph: boolean;\n}\n\n/**\n * Resolve the options against the snapshot's recorded shape.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for a bad value\n */\nfunction resolve(snapshot: GraphSnapshot, options: (JsonExportOptions & CommonExportOptions) | undefined): Resolved {\n const o = options ?? {};\n const common = resolveExportOptions(options);\n const shape = shapeMetaOf(snapshot.meta);\n let dialect: JsonDialect;\n if (o.dialect === undefined || otherFormatDialect(\"json\", o.dialect)) {\n // no dialect, or another format's (a CSV \"generic\" in a shared options object)\n dialect = shape.dialect ?? \"node-link\";\n } else if (isJsonDialect(o.dialect)) {\n ({ dialect } = o);\n } else {\n throw unsupported(\"dialect\", o.dialect, JSON_DIALECTS);\n }\n const indent = indentUnit(o.indent, \"\");\n const sameDialect = shape.dialect === dialect;\n const recorded = <T>(value: T | undefined, fallback: T): T =>\n sameDialect && value !== undefined ? value : fallback;\n const edgesKey =\n keyOption(\"edgesKey\", o.edgesKey) ?? recorded(shape.edgesKey, dialect === \"d3\" ? \"links\" : \"edges\");\n let nodeIdKey: string | null;\n if (o.nodeIdKey !== undefined) {\n nodeIdKey = keyOption(\"nodeIdKey\", o.nodeIdKey);\n } else if (sameDialect && shape.nodeIdKey !== undefined) {\n ({ nodeIdKey } = shape);\n } else {\n nodeIdKey = \"id\";\n }\n let indexLinks = o.indexLinks ?? recorded(shape.indexLinks, false);\n if (typeof indexLinks !== \"boolean\") {\n throw unsupported(\"indexLinks\", indexLinks, [\"true\", \"false\"]);\n }\n if (nodeIdKey === null) {\n // positional nodes have no id to write; endpoints must be positions\n indexLinks = true;\n }\n const sourceKey =\n keyOption(\"sourceKey\", o.sourceKey) ?? recorded(shape.sourceKey, dialect === \"vis\" ? \"from\" : \"source\");\n const targetKey =\n keyOption(\"targetKey\", o.targetKey) ?? recorded(shape.targetKey, dialect === \"vis\" ? \"to\" : \"target\");\n const { weightOrigin } = snapshot.meta;\n const weightKey =\n keyOption(\"weightKey\", o.weightKey) ??\n (weightOrigin !== null && weightOrigin.format === \"json\" && weightOrigin.id !== null\n ? weightOrigin.id\n : \"weight\");\n const ontologyIri = keyOption(\"ontologyIri\", o.ontologyIri);\n return {\n common,\n dialect,\n indent,\n edgesKey,\n nodeIdKey,\n indexLinks,\n sourceKey,\n targetKey,\n weightKey,\n shape,\n ontologyIri,\n };\n}\n\n/**\n * Check a key-valued option.\n * @param name - the option name\n * @param value - the caller's value\n * @returns the key, or null when absent\n */\nfunction keyOption(name: string, value: unknown): string | null {\n if (value === undefined) {\n return null;\n }\n if (typeof value !== \"string\" || value.length === 0) {\n throw unsupported(name, value, [\"a non-empty key\"]);\n }\n return value;\n}\n\n/**\n * The E_UNSUPPORTED error of a bad option.\n * @param name - the option name\n * @param found - the value\n * @param supported - what is accepted\n * @returns the error\n */\nfunction unsupported(name: string, found: unknown, supported: readonly string[]): GraphFormatError {\n const shown = typeof found === \"string\" ? JSON.stringify(found) : String(found);\n return new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: ${shown} is not one of ${supported.join(\", \")}`, {\n option: name,\n found: typeof found === \"string\" || typeof found === \"number\" ? found : typeof found,\n supported: [...supported],\n });\n}\n\n// ============================================================ value formatting\n\n/**\n * The JSON text of a finite or non-finite number; non-finite values become null and are counted.\n * @param value - the number\n * @param f32 - whether the value came from an f32 store (shortest fround-round-trip text)\n * @param nonfinite - the counter of null-ed values\n * @returns the JSON text\n */\nfunction numberText(value: number, f32: boolean, nonfinite: Counter): string {\n if (!Number.isFinite(value)) {\n nonfinite.count++;\n return \"null\";\n }\n // -0 is a JSON number too (\"-0\"); JSON.parse reads it back as -0\n return exponentIfUnsafe(f32 ? formatF32(value) : formatF64(value));\n}\n\n/**\n * The JSON text of any cell value: a number per its dtype, a boolean, a string, an array (a\n * multi-component subarray or a list row), or a json value.\n * @param value - the value\n * @param f32 - whether numbers come from an f32 store\n * @param nonfinite - the counter of null-ed values\n * @returns the JSON text\n */\nfunction valueText(value: unknown, f32: boolean, nonfinite: Counter): string {\n switch (typeof value) {\n case \"number\":\n return numberText(value, f32, nonfinite);\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"string\":\n return JSON.stringify(value);\n case \"undefined\":\n return \"null\";\n default:\n break;\n }\n if (value === null) {\n return \"null\";\n }\n if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n const items = Array.from(value as ArrayLike<unknown>, (item) => valueText(item, f32, nonfinite));\n return `[${items.join(\",\")}]`;\n }\n // ponytail: numbers nested in a json object are written by JSON.stringify, so an integral one\n // beyond 2^53 re-imports as its digit text; walk the object here if that ever matters\n const text = JSON.stringify(value);\n return text === undefined ? \"null\" : text;\n}\n\n/**\n * The JSON text of one set cell.\n * @param column - the column\n * @param row - the row\n * @param ids - the snapshot's id map (for refersTo node columns)\n * @param nonfinite - the counter of null-ed values\n * @returns the JSON text\n */\nfunction cellText(column: Column, row: number, ids: GraphSnapshot[\"ids\"], nonfinite: Counter): string {\n switch (column.dtype) {\n case \"list\":\n return valueText(column.sliceOf(row), column.child.dtype === \"f32\", nonfinite);\n case \"json\":\n return valueText(column.values[row], false, nonfinite);\n case \"u32\":\n if (column.meta.refersTo === \"node\" && column.meta.components === 1) {\n const index = column.data[row];\n return index === INVALID_INDEX ? \"null\" : idText(ids.idOf(index));\n }\n return valueText(column.value(row), false, nonfinite);\n case \"f32\":\n return valueText(column.value(row), true, nonfinite);\n default:\n return valueText(column.value(row), false, nonfinite);\n }\n}\n\n/**\n * How many cells of a column hold a non-finite number (f32 / f64 columns, their components and\n * lists of them).\n * @param column - the column\n * @returns the count\n */\nfunction countNonFinite(column: Column): number {\n let data: ArrayLike<number>;\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n ({ data } = column);\n break;\n case \"list\":\n if (column.child.dtype !== \"f32\" && column.child.dtype !== \"f64\") {\n return 0;\n }\n ({ data } = column.child);\n break;\n default:\n return 0;\n }\n let count = 0;\n for (let i = 0; i < data.length; i++) {\n if (!Number.isFinite(data[i])) {\n count++;\n }\n }\n return count;\n}\n\n// ============================================================ the writer\n\n/**\n * Emits JSON tokens with optional indentation, accumulating text parts the generator yields one\n * element at a time.\n */\nclass JsonWriter {\n private parts: string[] = [];\n\n private depth = 0;\n\n private readonly firstAtDepth: boolean[] = [];\n\n private readonly indent: string;\n\n /**\n * Create a writer.\n * @param indent - the text of one level; \"\" for compact output\n */\n constructor(indent: string) {\n this.indent = indent;\n }\n\n /**\n * Open an object or an array.\n * @param bracket - \"{\" or \"[\"\n */\n open(bracket: \"{\" | \"[\"): void {\n this.parts.push(bracket);\n this.depth++;\n this.firstAtDepth.push(true);\n }\n\n /**\n * Close the innermost object or array.\n * @param bracket - \"}\" or \"]\"\n */\n close(bracket: \"}\" | \"]\"): void {\n const wasEmpty = this.firstAtDepth.pop() ?? true;\n this.depth--;\n if (!wasEmpty) {\n this.parts.push(this.newline());\n }\n this.parts.push(bracket);\n }\n\n /**\n * Start an object member: the separator and the quoted key.\n * @param name - the key\n */\n key(name: string): void {\n this.separator();\n this.parts.push(JSON.stringify(name), this.indent !== \"\" ? \": \" : \":\");\n }\n\n /** Start an array element: the separator only. */\n item(): void {\n this.separator();\n }\n\n /**\n * Append raw JSON text (a value).\n * @param text - the text\n */\n raw(text: string): void {\n this.parts.push(text);\n }\n\n /**\n * Write a member with a value in one call.\n * @param name - the key\n * @param text - the value's JSON text\n */\n member(name: string, text: string): void {\n this.key(name);\n this.parts.push(text);\n }\n\n /**\n * Hand out the text accumulated since the last take.\n * @returns the text\n */\n take(): string {\n const text = this.parts.length === 1 ? this.parts[0] : this.parts.join(\"\");\n this.parts = [];\n return text;\n }\n\n /** The comma and newline before a member or element. */\n private separator(): void {\n const top = this.firstAtDepth.length - 1;\n if (this.firstAtDepth[top]) {\n this.firstAtDepth[top] = false;\n } else {\n this.parts.push(\",\");\n }\n this.parts.push(this.newline());\n }\n\n /**\n * A newline plus the current indentation, or nothing in compact mode.\n * @returns the text\n */\n private newline(): string {\n return this.indent !== \"\" ? `\\n${this.indent.repeat(this.depth)}` : \"\";\n }\n}\n\n// ============================================================ planning\n\n/** What plan() and its helpers share. */\ninterface PlanContext {\n readonly snapshot: GraphSnapshot;\n readonly resolved: Resolved;\n readonly dialect: JsonDialect;\n readonly caps: ExportCapabilities;\n readonly notes: LossNote[];\n readonly note: NoteFn;\n /** The reserved output keys per table. */\n readonly reserved: Readonly<Record<Domain, ReadonlySet<string>>>;\n readonly nonfinite: Counter;\n}\n\n/**\n * Build the column plan and the notes for one dialect.\n * @param snapshot - the snapshot\n * @param resolved - the resolved options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, resolved: Resolved): Plan {\n const { dialect } = resolved;\n const caps = dialectCapabilities(dialect);\n // the generic position and edge-id notes are replaced by planTable()'s (both are written as\n // plain attributes and read back without their role)\n const notes = checkCapabilities(snapshot, caps, resolved.common, {\n roles: SLOT_ROLES[dialect],\n positionDtype: \"f64\",\n }).filter((n) => n.code !== LOSS.POSITIONS && n.code !== LOSS.EDGE_IDS_DROPPED);\n const note: NoteFn = (code, message, column = null, count = null): void => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n const ctx: PlanContext = {\n snapshot,\n resolved,\n dialect,\n caps,\n notes,\n note,\n reserved: reservedKeys(snapshot, resolved),\n nonfinite: { count: 0 },\n };\n const nodes = planTable(ctx, snapshot.nodes, \"node\");\n const edges = planTable(ctx, snapshot.edges, \"edge\");\n const graph = caps.graphAttributes ? planTable(ctx, snapshot.graph, \"graph\") : [];\n withdrawSlotNotes(notes, [...nodes, ...edges]);\n const weights = planWeights(ctx, edges);\n if (ctx.nonfinite.count > 0) {\n note(\n JSON_LOSS.NONFINITE_AS_NULL,\n `${ctx.nonfinite.count} non-finite number${plural(ctx.nonfinite.count)} ${agree(ctx.nonfinite.count, \"is\", \"are\")} written as null`,\n null,\n ctx.nonfinite.count,\n );\n }\n const { folding, directed } = planDirection(ctx);\n const multigraph = snapshot.flags.multigraph || snapshot.meta.declaredMultigraph === true;\n if (dialect === \"jgf\") {\n jgfIdNotes(snapshot, note);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n if (dialect === \"cytoscape\" && edgeIds !== null && edgeIds.nullCount > 0) {\n note(\n LOSS.EDGE_IDS_GENERATED,\n `${edgeIds.nullCount} edge${plural(edgeIds.nullCount)} ${agree(edgeIds.nullCount, \"has\", \"have\")} no id; canonical e<index> ids are generated for them`,\n edgeIds.meta.name,\n edgeIds.nullCount,\n );\n }\n return { resolved, notes, nodes, edges, graph, edgeIds, weights, folding, directed, multigraph };\n}\n\n/**\n * Withdraw the generic list note of a Cytoscape classes column: the slot writes the list as the\n * `classes` string and the importer reads it back as the list it was.\n * @param notes - the notes so far\n * @param plans - the node and edge plans\n */\nfunction withdrawSlotNotes(notes: LossNote[], plans: readonly ColumnPlan[]): void {\n for (const plan of plans) {\n if (plan.slot !== \"classes\") {\n continue;\n }\n const at = notes.findIndex((n) => n.code === LOSS.LIST && n.column === plan.column.meta.name);\n if (at >= 0) {\n notes.splice(at, 1);\n }\n }\n}\n\n/**\n * The output keys each dialect reserves for its structure (a column of that name cannot be\n * written as an attribute): the id and endpoint keys, and the weight key of a weighted snapshot.\n * @param snapshot - the snapshot\n * @param resolved - the resolved options\n * @returns the reserved keys per table\n */\nfunction reservedKeys(snapshot: GraphSnapshot, resolved: Resolved): Readonly<Record<Domain, ReadonlySet<string>>> {\n const { dialect } = resolved;\n const node = new Set<string>();\n const edge = new Set<string>(snapshot.flags.weighted ? [resolved.weightKey] : []);\n const graph = new Set<string>();\n switch (dialect) {\n case \"node-link\":\n case \"d3\":\n if (resolved.nodeIdKey !== null) {\n node.add(resolved.nodeIdKey);\n }\n edge.add(resolved.sourceKey).add(resolved.targetKey);\n break;\n case \"vis\":\n node.add(resolved.nodeIdKey ?? \"id\");\n edge.add(resolved.sourceKey).add(resolved.targetKey);\n break;\n case \"cytoscape\":\n node.add(\"id\").add(\"parent\");\n edge.add(\"id\").add(\"source\").add(\"target\");\n break;\n case \"jgf\":\n case \"graphology\":\n break;\n default: {\n const name: string = dialect;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dialect ${name}`, { option: \"dialect\", found: name });\n }\n }\n return { node, edge, graph };\n}\n\n/**\n * Classify the columns of one table: the slot each is written into and what it loses on the way\n * (JSON declares no types, so the notes name what the importer's inference reads back).\n * @param ctx - the plan context\n * @param table - the table\n * @param domain - its domain\n * @returns the plans of the written columns, in declaration order\n */\nfunction planTable(ctx: PlanContext, table: Iterable<Column>, domain: Domain): ColumnPlan[] {\n const { dialect, note } = ctx;\n const plans: ColumnPlan[] = [];\n const reserved = ctx.reserved[domain];\n const used = new Set<string>();\n for (const column of table) {\n const { meta } = column;\n const { role } = meta;\n const setRows = column.length - column.nullCount;\n if (role !== null && (STRUCTURAL_ROLES.has(role) || TEMPORAL_ROLES.has(role))) {\n continue;\n }\n if (domain !== \"graph\") {\n ctx.nonfinite.count += countNonFinite(column);\n }\n const slotted = planSlot(ctx, column, domain);\n if (slotted !== null) {\n if (slotted !== SKIPPED) {\n plans.push(slotted);\n }\n continue;\n }\n let key = meta.name;\n let slot: Slot = \"attribute\";\n if (NESTED_DIALECTS.has(dialect) && domain !== \"graph\") {\n if (key.endsWith(SUFFIX.element)) {\n key = key.slice(0, -SUFFIX.element.length);\n slot = \"element\";\n } else if (dialect === \"cytoscape\" && CYTOSCAPE_ELEMENT_KEYS.has(key)) {\n slot = \"element\";\n } else if (key.endsWith(SUFFIX.data)) {\n key = key.slice(0, -SUFFIX.data.length);\n }\n }\n if (slot === \"attribute\" && reserved.has(key)) {\n note(\n JSON_LOSS.RESERVED_KEY,\n `${domain} column \"${meta.name}\" cannot be written: \"${key}\" is a reserved key of ${dialect}`,\n meta.name,\n setRows,\n );\n continue;\n }\n const slotKey = `${slot}:${key}`;\n if (used.has(slotKey)) {\n note(\n JSON_LOSS.RESERVED_KEY,\n `${domain} column \"${meta.name}\" cannot be written: key \"${key}\" is already used by another column`,\n meta.name,\n setRows,\n );\n continue;\n }\n used.add(slotKey);\n if (setRows === 0 && domain !== \"graph\") {\n note(\n LOSS.EMPTY_COLUMN,\n `${domain} column \"${meta.name}\" has no set cell and is not written: JSON writes values, never declarations`,\n meta.name,\n 0,\n );\n }\n inferenceNotes(ctx, column, domain, setRows);\n plans.push({ column, key, slot });\n }\n return plans;\n}\n\n/** planSlot()'s answer for a role column handled (or dropped) without a plan of its own. */\nconst SKIPPED = Symbol(\"skipped\");\n\n/**\n * The structural slot of a role column in the dialect, when it has one: Cytoscape's parent,\n * position and classes, JGF's label and relation; the id-role edge column is written\n * structurally (data.id / key / id) where the dialect has an edge id and as a plain attribute\n * elsewhere; a position column without a slot is a plain array attribute.\n * @param ctx - the plan context\n * @param column - the column\n * @param domain - its domain\n * @returns the plan, SKIPPED for a column written structurally or dropped, null for a plain attribute\n */\nfunction planSlot(ctx: PlanContext, column: Column, domain: Domain): ColumnPlan | typeof SKIPPED | null {\n const { dialect, note } = ctx;\n const { meta } = column;\n const { role } = meta;\n const setRows = column.length - column.nullCount;\n if (role === \"parent\" || role === \"parents\") {\n if (dialect === \"cytoscape\" && domain === \"node\") {\n if (role === \"parent\" && column.dtype === \"u32\" && meta.refersTo === \"node\") {\n return { column, key: \"parent\", slot: \"parent\" };\n }\n note(\n LOSS.PARENTS,\n `node column \"${meta.name}\" (${role}) cannot be written: Cytoscape has a single parent`,\n meta.name,\n setRows,\n );\n }\n return SKIPPED;\n }\n if (role === \"position\" && domain === \"node\") {\n if (dialect === \"cytoscape\" && (column.dtype === \"f32\" || column.dtype === \"f64\") && meta.components >= 2) {\n const z = countNonZeroZ(column);\n if (z > 0) {\n note(\n JSON_LOSS.POSITION_Z_DROPPED,\n `${z} position${plural(z)} ${agree(z, \"has\", \"have\")} a non-zero z; Cytoscape positions are 2D`,\n meta.name,\n z,\n );\n }\n return { column, key: \"position\", slot: \"cytoscapePosition\" };\n }\n note(\n LOSS.POSITIONS,\n `node column \"${meta.name}\" (position) is written as a plain array attribute; its role is lost on re-import`,\n meta.name,\n setRows,\n );\n return { column, key: meta.name, slot: \"position\" };\n }\n if (role === \"id\" && domain === \"edge\") {\n if (dialect === \"node-link\" || dialect === \"d3\") {\n note(\n LOSS.EDGE_IDS_DROPPED,\n `edge column \"${meta.name}\" (id) is written as a plain attribute; ${dialect} has no edge id`,\n meta.name,\n setRows,\n );\n return null;\n }\n return SKIPPED;\n }\n if (dialect === \"cytoscape\" && role === \"classes\" && column.dtype === \"list\" && column.child.dtype === \"string\") {\n return { column, key: \"classes\", slot: \"classes\" };\n }\n if (dialect === \"jgf\" && role === \"label\" && (column.dtype === \"string\" || column.dtype === \"dict\")) {\n return { column, key: \"label\", slot: \"label\" };\n }\n if (\n dialect === \"jgf\" &&\n role === \"kind\" &&\n domain === \"edge\" &&\n (column.dtype === \"string\" || column.dtype === \"dict\")\n ) {\n return { column, key: \"relation\", slot: \"relation\" };\n }\n return null;\n}\n\n/**\n * What the importer's inference (design section 5.1: JSON numbers are i32 when integral, else\n * f64; strings are strings; arrays and objects are json) changes about a written attribute\n * column beyond what checkCapabilities() already reported for its dtype: an f64 column whose set\n * finite values are all integers reads back as i32 (its non-finite values are written as null).\n * @param ctx - the plan context\n * @param column - the column\n * @param domain - its domain\n * @param setRows - the set rows\n */\nfunction inferenceNotes(ctx: PlanContext, column: Column, domain: Domain, setRows: number): void {\n if (column.dtype !== \"f64\" || column.meta.components > 1 || setRows === 0) {\n return;\n }\n const { data } = column;\n let finite = 0;\n for (let r = 0; r < column.length; r++) {\n // a non-finite value is written as null and reads back unset, so it does not keep the column f64\n if (column.isSet(r) && Number.isFinite(data[r])) {\n if (!Number.isInteger(data[r])) {\n return;\n }\n finite++;\n }\n }\n if (finite === 0) {\n return;\n }\n ctx.note(\n LOSS.INTEGRAL_F64,\n `${domain} column \"${column.meta.name}\" is f64 with integral values only; JSON declares no types and it reads back as i32`,\n column.meta.name,\n setRows,\n );\n}\n\n/**\n * The explicit weights and their JSON text (non-finite values become null and are counted).\n * @param ctx - the plan context\n * @param edges - the edge column plans (for the weight-key clash note)\n * @returns the weight text function\n */\nfunction planWeights(ctx: PlanContext, edges: readonly ColumnPlan[]): (e: number) => string | null {\n const { snapshot, nonfinite } = ctx;\n const weights = explicitWeights(snapshot);\n if (!weights.weighted) {\n const clash = edges.find((p) => p.slot === \"attribute\" && p.key === ctx.resolved.weightKey);\n if (clash !== undefined) {\n ctx.note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${clash.column.meta.name}\" is written under \"${clash.key}\", the key the importer reads edge weights from; it reads back as the weight, not as a column`,\n clash.column.meta.name,\n clash.column.length - clash.column.nullCount,\n );\n }\n return (): null => null;\n }\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (weights.isExplicit(e) && !Number.isFinite(weights.value(e))) {\n nonfinite.count++;\n }\n }\n return (e: number): string | null => {\n if (!weights.isExplicit(e)) {\n return null;\n }\n const text = Number.isFinite(weights.value(e)) ? weights.text(e) : \"null\";\n return text === null ? null : exponentIfUnsafe(text);\n };\n}\n\n/**\n * The direction decisions: the pair folding (mutual pairs are written as two directed edges and\n * reported), the file-level direction under the onMixedDirection policy of a dialect without a\n * per-edge flag, and the note of the dialects that carry no direction at all.\n * @param ctx - the plan context\n * @returns the folding and the file-level direction\n */\nfunction planDirection(ctx: PlanContext): { readonly folding: PairFolding; readonly directed: boolean } {\n const { snapshot, dialect, caps, note } = ctx;\n const folding = pairFolding(snapshot);\n if (folding.mutualCount > 0) {\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two directed edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n let { directed } = snapshot;\n if (\n !caps.mixedDirection &&\n countMixedEdges(snapshot) > 0 &&\n ctx.resolved.common.onMixedDirection === \"undirected\"\n ) {\n directed = false;\n }\n if (dialect === \"cytoscape\" || dialect === \"vis\" || dialect === \"d3\") {\n const assumed = DIALECT_DEFAULT_DIRECTED[dialect];\n if (directed !== assumed) {\n note(\n JSON_LOSS.DIRECTION_DROPPED,\n `${dialect} has no direction flag; the ${directed ? \"directed\" : \"undirected\"} graph re-imports as ${assumed ? \"directed\" : \"undirected\"} unless defaultDirected is passed`,\n );\n }\n }\n return { folding, directed };\n}\n\n/**\n * How many rows of a position column have a non-zero third component.\n * @param column - an f32 / f64 column with at least two components\n * @returns the count\n */\nfunction countNonZeroZ(column: Column): number {\n if ((column.dtype !== \"f32\" && column.dtype !== \"f64\") || column.meta.components < 3) {\n return 0;\n }\n const { components } = column.meta;\n let count = 0;\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && column.data[r * components + 2] !== 0) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * The JGF id notes: numeric ids become string keys, colliding texts are refused, and integer-like\n * keys are enumerated first and ascending by every JSON parser so the node order may change.\n * @param snapshot - the snapshot\n * @param note - the recorder\n */\nfunction jgfIdNotes(\n snapshot: GraphSnapshot,\n note: (code: string, message: string, column?: string | null, count?: number | null) => void,\n): void {\n const { ids } = snapshot;\n const seen = new Set<string>();\n let numeric = 0;\n let collisions = 0;\n let indexLike = 0;\n let lastIndex = -1;\n let ordered = true;\n let sawOther = false;\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n const text = String(id);\n if (typeof id === \"number\") {\n numeric++;\n }\n if (seen.has(text)) {\n collisions++;\n }\n seen.add(text);\n if (isArrayIndexKey(text)) {\n indexLike++;\n const n = Number(text);\n if (sawOther || n <= lastIndex) {\n ordered = false;\n }\n lastIndex = n;\n } else {\n sawOther = true;\n }\n }\n if (numeric > 0) {\n note(\n JSON_LOSS.NUMERIC_IDS_STRINGIFIED,\n `${numeric} numeric node id${plural(numeric)} ${agree(numeric, \"becomes\", \"become\")} JGF object keys (strings); pass ids: \"canonical\" on re-import`,\n null,\n numeric,\n );\n }\n if (collisions > 0) {\n note(\n JSON_LOSS.ID_TEXT_COLLISION,\n `${collisions} node id${plural(collisions)} ${agree(collisions, \"shares\", \"share\")} their text with another id; the save fails`,\n null,\n collisions,\n );\n }\n if (!ordered) {\n note(\n JSON_LOSS.NODE_ORDER,\n `${indexLike} integer-like node id${plural(indexLike)} ${agree(indexLike, \"is\", \"are\")} enumerated first and ascending by JSON parsers; node order changes on re-import`,\n null,\n indexLike,\n );\n }\n}\n\n/**\n * Whether a key is an array index in the JS sense (enumerated before other keys, ascending).\n * @param text - the key\n * @returns true for canonical integer text below 2^32 - 1\n */\nfunction isArrayIndexKey(text: string): boolean {\n return /^(0|[1-9]\\d*)$/.test(text) && Number(text) < 4294967295;\n}\n\n// ============================================================ writing\n\n/**\n * The text parts of the document.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields one part per header, node, edge and footer\n * @returns nothing\n */\nfunction* write(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { dialect } = p.resolved;\n if (p.notes.some((n) => n.code === LOSS.MIXED_DIRECTION_ERROR)) {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${dialect} has no mixed direction; pass onMixedDirection \"directed\" or \"undirected\"`,\n { reason: \"mixed direction\", dialect },\n );\n }\n if (p.notes.some((n) => n.code === JSON_LOSS.ID_TEXT_COLLISION)) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"two node ids have the same text; JGF keys nodes by text\", {\n reason: \"collision\",\n });\n }\n switch (dialect) {\n case \"node-link\":\n case \"d3\":\n yield* writeNodeLink(snapshot, p);\n return;\n case \"vis\":\n yield* writeVis(snapshot, p);\n return;\n case \"graphology\":\n yield* writeGraphology(snapshot, p);\n return;\n case \"jgf\":\n yield* writeJgf(snapshot, p);\n return;\n case \"cytoscape\":\n yield* writeCytoscape(snapshot, p);\n return;\n default: {\n const name: string = dialect;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dialect ${name}`, { option: \"dialect\", found: name });\n }\n }\n}\n\n/** The shared per-row state of the writers. */\ninterface Cursor {\n readonly w: JsonWriter;\n readonly ids: GraphSnapshot[\"ids\"];\n readonly nonfinite: Counter;\n}\n\n/**\n * Write the members of one row's planned columns into the current object, attributes only.\n * @param c - the cursor\n * @param plans - the table plan\n * @param row - the row\n * @param slots - which slots to write\n */\nfunction writeSlots(c: Cursor, plans: readonly ColumnPlan[], row: number, slots: ReadonlySet<Slot>): void {\n for (const item of plans) {\n if (!slots.has(item.slot) || !item.column.isSet(row)) {\n continue;\n }\n let text: string;\n switch (item.slot) {\n case \"position\": {\n const value = item.column.value(row);\n const dims = dimsOf(item.column);\n const values = Array.from(value as ArrayLike<number>).slice(0, dims);\n text = valueText(values, item.column.dtype === \"f32\", c.nonfinite);\n break;\n }\n case \"classes\":\n text = JSON.stringify((item.column as Extract<Column, { dtype: \"list\" }>).sliceOf(row).join(\" \"));\n break;\n default:\n text = cellText(item.column, row, c.ids, c.nonfinite);\n break;\n }\n c.w.member(item.key, text);\n }\n}\n\nconst ATTRIBUTE_SLOTS: ReadonlySet<Slot> = new Set([\"attribute\", \"position\"]);\nconst ELEMENT_SLOTS: ReadonlySet<Slot> = new Set([\"element\", \"classes\"]);\n\n/**\n * The number of components a position column writes: `extra.sourceDims` when recorded, else all.\n * @param column - the position column\n * @returns 2 or 3 (or the component count)\n */\nfunction dimsOf(column: Column): number {\n const dims: unknown = column.meta.extra.sourceDims;\n if (typeof dims === \"number\" && dims >= 1 && dims <= column.meta.components) {\n return dims;\n }\n return column.meta.components;\n}\n\n/**\n * Whether any planned column of a slot set has a value in a row (to omit an empty nested dict).\n * @param plans - the table plan\n * @param row - the row\n * @param slots - the slots\n * @returns true when something would be written\n */\nfunction anySet(plans: readonly ColumnPlan[], row: number, slots: ReadonlySet<Slot>): boolean {\n return plans.some((item) => slots.has(item.slot) && item.column.isSet(row));\n}\n\n/**\n * The JSON text of a node id.\n * @param id - the id\n * @returns the text\n */\nfunction idText(id: NodeId): string {\n if (typeof id === \"number\") {\n return Object.is(id, -0) ? \"0\" : exponentIfUnsafe(String(id));\n }\n return JSON.stringify(id);\n}\n\n/**\n * The edge id text of an edge, or null when none is set.\n * @param p - the plan\n * @param e - the edge\n * @param c - the cursor\n * @returns the text, or null\n */\nfunction edgeIdText(p: Plan, e: number, c: Cursor): string | null {\n const column = p.edgeIds;\n if (column === null || !column.isSet(e)) {\n return null;\n }\n return cellText(column, e, c.ids, c.nonfinite);\n}\n\n/**\n * Whether an edge is written, and as which kind, under the plan's direction policy.\n * @param p - the plan\n * @param e - the edge\n * @returns \"skip\" for a folded mirror, \"undirected\" for a pair primary, \"directed\" otherwise\n */\nfunction edgeDisposition(p: Plan, e: number): \"skip\" | \"undirected\" | \"directed\" {\n const { folding } = p;\n if (folding.folded(e)) {\n return \"skip\";\n }\n if (!p.directed) {\n return \"undirected\";\n }\n if (folding.sourceDirected(e)) {\n return \"directed\";\n }\n // a source-undirected edge (pair primary or expanded self-loop): a dialect with a per-edge flag\n // keeps it; one without writes it per the policy (the pair folds to one directed edge)\n if (dialectCapabilities(p.resolved.dialect).mixedDirection) {\n return \"undirected\";\n }\n return p.resolved.common.onMixedDirection === \"directed\" ? \"directed\" : \"undirected\";\n}\n\n/**\n * The graph-level attribute object.\n * @param c - the cursor\n * @param p - the plan\n */\nfunction writeGraphObject(c: Cursor, p: Plan): void {\n c.w.open(\"{\");\n for (const item of p.graph) {\n if (item.column.isSet(0)) {\n c.w.member(item.key, cellText(item.column, 0, c.ids, c.nonfinite));\n }\n }\n c.w.close(\"}\");\n}\n\n/**\n * The endpoint texts of an edge: ids, or array positions under index links.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @param e - the edge\n * @returns the source and target texts\n */\nfunction endpoints(snapshot: GraphSnapshot, p: Plan, e: number): [string, string] {\n const list = snapshot.edgeList();\n const u = list.src[e];\n const v = list.dst[e];\n if (p.resolved.indexLinks) {\n return [String(u), String(v)];\n }\n return [idText(snapshot.ids.idOf(u)), idText(snapshot.ids.idOf(v))];\n}\n\n/**\n * Write a node-link / d3 document.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the parts\n * @returns nothing\n */\nfunction* writeNodeLink(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { resolved } = p;\n const c: Cursor = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };\n const { w } = c;\n w.open(\"{\");\n if (resolved.dialect !== \"d3\") {\n // d3 is the bare shape: no direction, multigraph or graph keys (the importer sniffs it by their absence)\n w.member(\"directed\", p.directed ? \"true\" : \"false\");\n w.member(\"multigraph\", p.multigraph ? \"true\" : \"false\");\n w.key(\"graph\");\n writeGraphObject(c, p);\n }\n w.key(\"nodes\");\n w.open(\"[\");\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.item();\n w.open(\"{\");\n if (resolved.nodeIdKey !== null) {\n w.member(resolved.nodeIdKey, idText(snapshot.ids.idOf(i)));\n }\n writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.key(resolved.edgesKey);\n w.open(\"[\");\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const disposition = edgeDisposition(p, e);\n if (disposition === \"skip\") {\n continue;\n }\n const [s, t] = endpoints(snapshot, p, e);\n w.item();\n w.open(\"{\");\n w.member(resolved.sourceKey, s);\n w.member(resolved.targetKey, t);\n const weight = p.weights(e);\n if (weight !== null) {\n w.member(resolved.weightKey, weight);\n }\n writeSlots(c, p.edges, e, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.close(\"}\");\n yield w.take();\n}\n\n/**\n * Write a vis.js document.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the parts\n * @returns nothing\n */\nfunction* writeVis(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { resolved } = p;\n const c: Cursor = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };\n const { w } = c;\n const nodeIdKey = resolved.nodeIdKey ?? \"id\";\n w.open(\"{\");\n w.key(\"nodes\");\n w.open(\"[\");\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.item();\n w.open(\"{\");\n w.member(nodeIdKey, idText(snapshot.ids.idOf(i)));\n writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.key(\"edges\");\n w.open(\"[\");\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (edgeDisposition(p, e) === \"skip\") {\n continue;\n }\n const list = snapshot.edgeList();\n w.item();\n w.open(\"{\");\n const id = edgeIdText(p, e, c);\n if (id !== null) {\n w.member(\"id\", id);\n }\n w.member(resolved.sourceKey, idText(snapshot.ids.idOf(list.src[e])));\n w.member(resolved.targetKey, idText(snapshot.ids.idOf(list.dst[e])));\n const weight = p.weights(e);\n if (weight !== null) {\n w.member(resolved.weightKey, weight);\n }\n writeSlots(c, p.edges, e, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.close(\"}\");\n yield w.take();\n}\n\n/**\n * Write a graphology serialization.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the parts\n * @returns nothing\n */\nfunction* writeGraphology(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { resolved } = p;\n const c: Cursor = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };\n const { w } = c;\n let type: string;\n if (!p.directed) {\n type = \"undirected\";\n } else {\n type = countMixedEdges(snapshot) > 0 ? \"mixed\" : \"directed\";\n }\n w.open(\"{\");\n w.key(\"attributes\");\n writeGraphObject(c, p);\n w.key(\"options\");\n w.open(\"{\");\n w.member(\"type\", JSON.stringify(type));\n // the shape the importer read is written back as read: `multi` and `allowSelfLoops` only when\n // the source declared them (or the graph needs them)\n if (snapshot.meta.declaredMultigraph !== null || p.multigraph) {\n w.member(\"multi\", p.multigraph ? \"true\" : \"false\");\n }\n if (resolved.shape.allowSelfLoops !== undefined) {\n w.member(\"allowSelfLoops\", !resolved.shape.allowSelfLoops && snapshot.selfLoopCount === 0 ? \"false\" : \"true\");\n }\n w.close(\"}\");\n w.key(\"nodes\");\n w.open(\"[\");\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.item();\n w.open(\"{\");\n w.member(\"key\", idText(snapshot.ids.idOf(i)));\n if (anySet(p.nodes, i, ATTRIBUTE_SLOTS)) {\n w.key(\"attributes\");\n w.open(\"{\");\n writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n }\n writeSlots(c, p.nodes, i, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.key(\"edges\");\n w.open(\"[\");\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const disposition = edgeDisposition(p, e);\n if (disposition === \"skip\") {\n continue;\n }\n const list = snapshot.edgeList();\n w.item();\n w.open(\"{\");\n const id = edgeIdText(p, e, c);\n if (id !== null) {\n w.member(\"key\", id);\n }\n w.member(\"source\", idText(snapshot.ids.idOf(list.src[e])));\n w.member(\"target\", idText(snapshot.ids.idOf(list.dst[e])));\n if (type === \"mixed\" && disposition === \"undirected\") {\n w.member(\"undirected\", \"true\");\n }\n const weight = p.weights(e);\n if (weight !== null || anySet(p.edges, e, ATTRIBUTE_SLOTS)) {\n w.key(\"attributes\");\n w.open(\"{\");\n if (weight !== null) {\n w.member(resolved.weightKey, weight);\n }\n writeSlots(c, p.edges, e, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n }\n writeSlots(c, p.edges, e, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.close(\"}\");\n yield w.take();\n}\n\n/**\n * Write a JSON Graph Format v2 document.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the parts\n * @returns nothing\n */\nfunction* writeJgf(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { resolved } = p;\n const c: Cursor = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };\n const { w } = c;\n const labelSlots: ReadonlySet<Slot> = new Set([\"label\"]);\n const relationSlots: ReadonlySet<Slot> = new Set([\"relation\"]);\n w.open(\"{\");\n w.key(\"graph\");\n w.open(\"{\");\n if (resolved.shape.id !== undefined) {\n w.member(\"id\", JSON.stringify(resolved.shape.id));\n }\n if (snapshot.meta.name !== null) {\n w.member(\"label\", JSON.stringify(snapshot.meta.name));\n }\n if (resolved.shape.type !== undefined) {\n w.member(\"type\", JSON.stringify(resolved.shape.type));\n }\n w.member(\"directed\", p.directed ? \"true\" : \"false\");\n if (p.graph.some((item) => item.column.isSet(0))) {\n w.key(\"metadata\");\n writeGraphObject(c, p);\n }\n w.key(\"nodes\");\n w.open(\"{\");\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.key(String(snapshot.ids.idOf(i)));\n w.open(\"{\");\n writeSlots(c, p.nodes, i, labelSlots);\n if (anySet(p.nodes, i, ATTRIBUTE_SLOTS)) {\n w.key(\"metadata\");\n w.open(\"{\");\n writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n }\n writeSlots(c, p.nodes, i, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"}\");\n w.key(\"edges\");\n w.open(\"[\");\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const disposition = edgeDisposition(p, e);\n if (disposition === \"skip\") {\n continue;\n }\n const list = snapshot.edgeList();\n w.item();\n w.open(\"{\");\n const id = edgeIdText(p, e, c);\n if (id !== null) {\n w.member(\"id\", id);\n }\n w.member(\"source\", JSON.stringify(String(snapshot.ids.idOf(list.src[e]))));\n w.member(\"target\", JSON.stringify(String(snapshot.ids.idOf(list.dst[e]))));\n writeSlots(c, p.edges, e, relationSlots);\n if (p.directed && disposition === \"undirected\") {\n w.member(\"directed\", \"false\");\n }\n writeSlots(c, p.edges, e, labelSlots);\n const weight = p.weights(e);\n if (weight !== null || anySet(p.edges, e, ATTRIBUTE_SLOTS)) {\n w.key(\"metadata\");\n w.open(\"{\");\n if (weight !== null) {\n w.member(resolved.weightKey, weight);\n }\n writeSlots(c, p.edges, e, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n }\n writeSlots(c, p.edges, e, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.close(\"}\");\n w.close(\"}\");\n yield w.take();\n}\n\n/**\n * Write Cytoscape.js elements.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the parts\n * @returns nothing\n */\nfunction* writeCytoscape(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n const { resolved } = p;\n const c: Cursor = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };\n const { w } = c;\n const parentSlots: ReadonlySet<Slot> = new Set([\"parent\"]);\n const positionSlots: ReadonlySet<Slot> = new Set([\"cytoscapePosition\"]);\n w.open(\"{\");\n w.key(\"elements\");\n w.open(\"{\");\n w.key(\"nodes\");\n w.open(\"[\");\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.item();\n w.open(\"{\");\n w.key(\"data\");\n w.open(\"{\");\n w.member(\"id\", idText(snapshot.ids.idOf(i)));\n writeSlots(c, p.nodes, i, parentSlots);\n writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n for (const item of p.nodes) {\n if (positionSlots.has(item.slot) && item.column.isSet(i)) {\n const value = item.column.value(i) as ArrayLike<number>;\n const f32 = item.column.dtype === \"f32\";\n w.key(\"position\");\n w.open(\"{\");\n w.member(\"x\", numberText(value[0], f32, c.nonfinite));\n // stored y-up; Cytoscape's y grows downward\n w.member(\"y\", numberText(flipY(value[1]), f32, c.nonfinite));\n w.close(\"}\");\n }\n }\n writeSlots(c, p.nodes, i, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.key(\"edges\");\n w.open(\"[\");\n const generated = edgeIdGenerator(snapshot, p);\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (edgeDisposition(p, e) === \"skip\") {\n continue;\n }\n const list = snapshot.edgeList();\n w.item();\n w.open(\"{\");\n w.key(\"data\");\n w.open(\"{\");\n w.member(\"id\", edgeIdText(p, e, c) ?? generated(e));\n w.member(\"source\", idText(snapshot.ids.idOf(list.src[e])));\n w.member(\"target\", idText(snapshot.ids.idOf(list.dst[e])));\n const weight = p.weights(e);\n if (weight !== null) {\n w.member(resolved.weightKey, weight);\n }\n writeSlots(c, p.edges, e, ATTRIBUTE_SLOTS);\n w.close(\"}\");\n writeSlots(c, p.edges, e, ELEMENT_SLOTS);\n w.close(\"}\");\n yield w.take();\n }\n w.close(\"]\");\n w.close(\"}\");\n if (p.graph.some((item) => item.column.isSet(0))) {\n w.key(\"data\");\n writeGraphObject(c, p);\n }\n const extra = resolved.shape.cytoscape;\n if (extra !== undefined) {\n for (const key of Object.keys(extra)) {\n if (key !== \"elements\" && key !== \"data\") {\n w.member(key, valueText(extra[key], false, c.nonfinite));\n }\n }\n }\n w.close(\"}\");\n yield w.take();\n}\n\n/**\n * A generator of canonical `e<index>` edge ids for the edges without one (design section 4.6),\n * skipping any text a node id or an explicit edge id already uses (Cytoscape ids share one\n * namespace).\n * @param snapshot - the snapshot\n * @param p - the plan\n * @returns the id text of an edge without an explicit id\n */\nfunction edgeIdGenerator(snapshot: GraphSnapshot, p: Plan): (e: number) => string {\n const used = new Set<string>();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n used.add(String(snapshot.ids.idOf(i)));\n }\n const column = p.edgeIds;\n if (column !== null) {\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (column.isSet(e)) {\n used.add(String(column.value(e)));\n }\n }\n }\n return (e: number): string => {\n let candidate = `e${e}`;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `e${e}_${k}`;\n }\n used.add(candidate);\n return JSON.stringify(candidate);\n };\n}\n\n// ============================================================ the plugin\n\n/**\n * The text parts of the document in the resolved dialect.\n * @param snapshot - the snapshot\n * @param resolved - the resolved options\n * @returns the parts\n */\nfunction parts(snapshot: GraphSnapshot, resolved: Resolved): Generator<string, void, undefined> {\n return resolved.dialect === \"obographs\"\n ? planObographs(snapshot, resolved).write()\n : write(snapshot, plan(snapshot, resolved));\n}\n\n/**\n * The JSON exporter plugin. `capabilities` is the node-link table (the\n * default dialect); check() applies the table of the dialect actually selected.\n * @category Built-in formats\n */\nexport const jsonExporter: GraphExporter<JsonExportOptions> = Object.freeze({\n format: \"json\",\n options: Object.freeze([\n \"dialect\",\n \"edgesKey\",\n \"indent\",\n \"indexLinks\",\n \"nodeIdKey\",\n \"ontologyIri\",\n \"sourceKey\",\n \"targetKey\",\n \"weightKey\",\n ]),\n capabilities: dialectCapabilities(\"node-link\"),\n\n /**\n * Pre-flight: every loss of the selected dialect, without writing anything.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: JsonExportOptions & CommonExportOptions): readonly LossNote[] {\n const resolved = resolve(snapshot, options);\n const notes =\n resolved.dialect === \"obographs\" ? planObographs(snapshot, resolved).notes : plan(snapshot, resolved).notes;\n return Object.freeze([...notes]);\n },\n\n /**\n * Write the document as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: JsonExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(parts(snapshot, resolve(snapshot, options)));\n },\n\n /**\n * Write the document as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: JsonExportOptions & CommonExportOptions): Promise<string> {\n return joinText(parts(snapshot, resolve(snapshot, options)));\n },\n});\n\n/**\n * The capability table of one dialect, for callers that pick a dialect before check().\n * @param dialect - the dialect\n * @returns the frozen table\n * @category Built-in formats\n */\nexport function jsonCapabilities(dialect: JsonDialect): ExportCapabilities {\n return dialectCapabilities(dialect);\n}\n"],"names":["keyOption","json","present","strings","xrefs","parts","plan"],"mappings":"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"}
|