@graphty/graph-io 0.3.20 → 0.3.22
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/README.md +7 -5
- package/dist/chunks/{importer-BaQpCEcJ.js → importer-DET1tg6s.js} +26 -16
- package/dist/chunks/importer-DET1tg6s.js.map +1 -0
- package/dist/chunks/{importer-Wv4C4gaF.js → importer-eUREhBGj.js} +4 -4
- package/dist/chunks/importer-eUREhBGj.js.map +1 -0
- package/dist/cx.js +1 -1
- package/dist/graph-io.js +4 -4
- package/dist/json.js +1 -1
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +26 -17
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +3 -1
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +3 -2
- package/dist/src/formats/json/importer.js.map +1 -1
- package/package.json +2 -2
- package/src/formats/cx/importer.ts +27 -19
- package/src/formats/json/exporter.ts +3 -1
- package/src/formats/json/importer.ts +3 -2
- package/dist/chunks/importer-BaQpCEcJ.js.map +0 -1
- package/dist/chunks/importer-Wv4C4gaF.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importer-Wv4C4gaF.js","sources":["../../src/formats/json/dialect.ts","../../src/formats/json/exporter.ts","../../src/sniff.ts","../../src/formats/json/obographs.ts","../../src/formats/json/importer.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 serialisation (`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 } from \"@graphty/graph-format\";\n\nimport { capabilities } from \"../../common/export.js\";\nimport { type ExportCapabilities } from \"../../types.js\";\n\n/** The JSON dialects the plugin reads and writes. */\nexport type JsonDialect = \"node-link\" | \"d3\" | \"jgf\" | \"cytoscape\" | \"graphology\" | \"vis\";\n\n/** Every dialect name, for option checking and messages. */\nexport const JSON_DIALECTS: readonly JsonDialect[] = Object.freeze([\n \"node-link\",\n \"d3\",\n \"jgf\",\n \"cytoscape\",\n \"graphology\",\n \"vis\",\n]);\n\n/**\n * The dialects the importer reads: every JsonDialect plus three it only reads, NetworkX\n * adjacency_data (`nodes` plus one neighbour list per node under `adjacency`), tree_data (a\n * nested `id` / `children` record) and OBO Graphs (`graphs[]` of `sub` / `pred` / `obj` edges, the\n * JSON form of the Gene Ontology and the OBO Foundry ontologies). The exporter writes none of them.\n */\nexport type JsonImportDialect = JsonDialect | \"adjacency\" | \"tree\" | \"obographs\";\n\n/** Every dialect the importer reads, for option checking and messages. */\nexport const JSON_IMPORT_DIALECTS: readonly JsonImportDialect[] = Object.freeze([\n ...JSON_DIALECTS,\n \"adjacency\",\n \"tree\",\n \"obographs\",\n]);\n\n/** The key under `meta.extra` that holds the shape record (design section 8.5). */\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 (design section 8.5). Every field is optional because a snapshot may come from\n * another format or from an older record.\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 * 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 */\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 */\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 */\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 */\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; vis: edges with `from` / `to`; 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 */\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 return isOboGraph(firstJsonObject(root.graphs)) ? \"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 if (firstNode !== null && hasKey(firstNode, \"key\") && !hasKey(firstNode, \"id\")) {\n return \"graphology\";\n }\n if (firstEdge !== null && !hasKey(firstEdge, \"from\")) {\n if (hasKey(firstEdge, \"undirected\") || isJsonObject(firstEdge.attributes)) {\n return \"graphology\";\n }\n }\n if (firstEdge !== null && hasKey(firstEdge, \"from\") && hasKey(firstEdge, \"to\") && !hasKey(firstEdge, \"source\")) {\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 */\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/** The direction a dialect assumes when the file declares none (design section 8.4, `defaultDirected`). */\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});\n\n/**\n * What one dialect can express (design section 8.5): 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 */\nexport function dialectCapabilities(dialect: JsonDialect): ExportCapabilities {\n return TABLES[dialect];\n}\n\n/** The Cytoscape element-level keys (everything else on an element lives under `data`). */\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/** The Cytoscape element keys the importer maps structurally rather than to columns. */\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 */\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/** The default source keys of a node-link edge record, tried in order (as fromRecords does). */\nexport const NODE_LINK_SOURCE_KEYS: readonly string[] = Object.freeze([\"source\", \"src\", \"from\"]);\n\n/** The default target keys of a node-link edge record, tried in order. */\nexport const NODE_LINK_TARGET_KEYS: readonly string[] = Object.freeze([\"target\", \"dst\", \"to\"]);\n\n/** The name of the position column every JSON dialect writes / reads (design section 5.2). */\nexport const POSITION_COLUMN = \"position\";\n\n/** The name of the Cytoscape classes column (a list of strings with role \"classes\"). */\nexport const CLASSES_COLUMN = \"classes\";\n\n/** The name of the Cytoscape parent column (u32 refersTo node, role \"parent\"). */\nexport const PARENT_COLUMN = \"parent\";\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 serialisation 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 { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { checkCapabilities, countMixedEdges, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64 } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, 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 isJsonDialect,\n JSON_DIALECTS,\n type JsonDialect,\n type JsonShapeMeta,\n shapeMetaOf,\n SUFFIX,\n} from \"./dialect.js\";\n\n/** The format-specific options of the JSON exporter. */\nexport interface JsonExportOptions {\n /** The dialect to write; default: the dialect the importer recorded, else \"node-link\". */\n dialect?: JsonDialect | undefined;\n /** Spaces per indentation level; 0 (default) writes compact JSON. */\n indent?: number | undefined;\n /** node-link / d3: the key of the edge array; default: the recorded key, else \"edges\" (d3: \"links\"). */\n edgesKey?: string | undefined;\n /** node-link / d3 / vis: the node id key; default: the recorded key, else \"id\". */\n nodeIdKey?: string | undefined;\n /** node-link / d3: write endpoints as node array positions; default: the recorded flag, else false. */\n indexLinks?: boolean | undefined;\n /** node-link / d3 / vis: the source key; default: the recorded key, else \"source\" (vis: \"from\"). */\n sourceKey?: string | undefined;\n /** node-link / d3 / vis: the target key; default: the recorded key, else \"target\" (vis: \"to\"). */\n targetKey?: string | undefined;\n /** The key the weight is written under; default: the key the JSON importer read it from, else \"weight\". */\n weightKey?: 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 */\nexport const JSON_LOSS = Object.freeze({\n /** Non-finite numbers (columns, weights) are written as null. */\n NONFINITE_AS_NULL: \"W_NONFINITE_AS_NULL\",\n /** Cytoscape, vis and d3 carry no direction; the file re-imports with the dialect's default direction. */\n DIRECTION_DROPPED: \"W_DIRECTION_DROPPED\",\n /** GEXF mutual pairs are written as two directed edges. */\n MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,\n /** JGF keys its nodes by string; numeric ids re-import as text unless ids: \"canonical\". */\n NUMERIC_IDS_STRINGIFIED: \"W_NUMERIC_IDS_STRINGIFIED\",\n /** JGF: two ids have the same text; export() throws E_INVALID_ID. */\n ID_TEXT_COLLISION: LOSS.ID_TEXT_COLLISION,\n /** JGF: integer-like id keys are enumerated first and ascending by JSON parsers; node order changes on re-import. */\n NODE_ORDER: \"W_NODE_ORDER\",\n /** A column named like a reserved key of the dialect (id, source, target, ...) is skipped. */\n RESERVED_KEY: \"W_RESERVED_KEY\",\n /** A plain edge column named like the weight key reads back as THE weight (or is skipped when weights are written). */\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 /** An f64 column of integral values reads back as i32 (JSON declares no types). */\n INTEGRAL_F64_AS_I32: LOSS.INTEGRAL_F64,\n /** A role column the dialect has no slot for is 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\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});\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: number;\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}\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) {\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 = o.indent ?? 0;\n if (!Number.isInteger(indent) || indent < 0 || indent > 16) {\n throw unsupported(\"indent\", indent, [\"an integer 0..16\"]);\n }\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 return { common, dialect, indent, edgesKey, nodeIdKey, indexLinks, sourceKey, targetKey, weightKey, shape };\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 * 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 */\nfunction exponentIfUnsafe(text: string): string {\n const match = /^(-?)([0-9]{16,})$/.exec(text);\n if (match === null || Number.isSafeInteger(Number(text))) {\n return text;\n }\n const [, sign, digits] = match;\n const mantissa = digits.replace(/0+$/, \"\");\n const fraction = mantissa.length > 1 ? `.${mantissa.slice(1)}` : \"\";\n return `${sign}${mantissa[0]}${fraction}e+${digits.length - 1}`;\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: number;\n\n /**\n * Create a writer.\n * @param indent - spaces per level; 0 for compact output\n */\n constructor(indent: number) {\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 > 0 ? \": \" : \":\");\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 > 0 ? `\\n${\" \".repeat(this.depth * this.indent)}` : \"\";\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: \"f32\",\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(s) 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(s) 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(s) 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 THE weight 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(s) 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(s) 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(s) share their text with another id; export() will throw`,\n null,\n collisions,\n );\n }\n if (!ordered) {\n note(\n JSON_LOSS.NODE_ORDER,\n `${indexLike} integer-like node id(s) 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][0-9]*)$/.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 serialisation.\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 w.member(\"y\", numberText(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 JSON exporter plugin (design section 8.5). `capabilities` is the node-link table (the\n * default dialect); check() applies the table of the dialect actually selected.\n */\nexport const jsonExporter: GraphExporter<JsonExportOptions> = Object.freeze({\n format: \"json\",\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 return Object.freeze([...plan(snapshot, resolve(snapshot, options)).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(write(snapshot, plan(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(write(snapshot, plan(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 */\nexport function jsonCapabilities(dialect: JsonDialect): ExportCapabilities {\n return dialectCapabilities(dialect);\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 (design section 8.4); 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 recognises the content (`content > 0`), so a content match always scores at least\n * 0.5 and at most 1;\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/** The format names of the eight built-in importers and exporters. */\nexport type GraphFormatName =\n | \"gexf\"\n | \"graphml\"\n | \"gml\"\n | \"dot\"\n | \"pajek\"\n | \"csv\"\n | \"json\"\n | \"neo4j\"\n | \"xgmml\"\n | \"cx2\"\n | \"cx\"\n | \"obo\"\n | \"cys\";\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 */\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/** How many bytes of the input the sniffers look at; the registry reads no more than this before deciding. */\nexport const SNIFF_HEAD_BYTES = 8192;\n\n/** What is known about an input before it is read. */\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. */\n readonly head?: Uint8Array | string | null | undefined;\n}\n\n/** One ranked candidate of a sniff. */\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 recognised). */\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 * The lower-cased extension of a file name or path, with its dot.\n * @param filename - the name or path\n * @returns the extension (`.gexf`), or null when the name has none\n */\nexport function extensionOf(filename: string): string | null {\n const base = filename.slice(Math.max(filename.lastIndexOf(\"/\"), filename.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 */\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 */\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 the registered importers for an input by the rule of the module comment: every importer\n * whose content confidence is positive or whose extension / MIME type matches is a candidate,\n * ordered by confidence (ties in registration order).\n * @param hints - what is known about the input\n * @param importers - the registered importers, in registration order\n * @returns the candidates, best first; empty when nothing matches\n */\nexport function rankFormats(hints: SniffHints, importers: Iterable<GraphImporter>): 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 candidates: { readonly result: SniffResult; readonly rank: number }[] = [];\n let rank = 0;\n for (const importer of importers) {\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 let content = 0;\n if (head !== null && head.byteLength > 0 && typeof importer.sniff === \"function\") {\n content = clamp(importer.sniff(head));\n }\n let confidence: number;\n if (content > 0) {\n confidence = 0.5 + 0.35 * content + (extensionMatch ? 0.1 : 0) + (mimeMatch ? 0.05 : 0);\n } else if (extensionMatch || mimeMatch) {\n confidence = (extensionMatch ? 0.3 : 0) + (mimeMatch ? 0.1 : 0);\n } else {\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 * The best candidate of rankFormats(), or null when no importer matches.\n * @param hints - what is known about the input\n * @param importers - the registered importers, in registration order\n * @returns the best candidate, or null\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 */\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 root = skeletonOf(trimmed);\n }\n return sniffJsonDialect(root);\n}\n\n/** Where a key was seen while scanning a truncated head. */\ntype KeyPath =\n | \"\"\n | \"graph\"\n | \"options\"\n | \"nodes[0]\"\n | \"edges[0]\"\n | \"links[0]\"\n | \"graphs[0].nodes[]\"\n | \"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 `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 { hasKey, isJsonObject } from \"./dialect.js\";\nimport { chosenGraph, type ImportContext, JSON_ISSUE, type JsonRecord } from \"./importer.js\";\n\n/** The node keys the schema defines; any other key goes to `obo.unrecognized`. */\nconst NODE_KEYS: ReadonlySet<string> = new Set([\"id\", \"lbl\", \"type\", \"propertyType\", \"meta\"]);\n\n/** The `meta` keys mapped onto columns; any other key goes to `obo.unrecognized` as `meta.<key>`. */\nconst META_KEYS: ReadonlySet<string> = new Set([\n \"definition\",\n \"comments\",\n \"subsets\",\n \"xrefs\",\n \"synonyms\",\n \"basicPropertyValues\",\n \"deprecated\",\n]);\n\n/** The OBO frame type of an OBO Graphs node type. */\nconst FRAME_TYPES: Readonly<Record<string, string>> = Object.freeze({\n CLASS: \"Term\",\n INDIVIDUAL: \"Instance\",\n PROPERTY: \"Typedef\",\n});\n\n/** The OBO name of the predicates OBO Graphs writes without an IRI. */\nconst 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/** Predicates that relate two properties (metadata under typedefs \"metadata\"). */\nconst 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. */\n readonly isProperty: (iri: string) => boolean;\n /** The PROPERTY nodes kept as metadata, by IRI. */\n readonly properties: Record<string, unknown>;\n}\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 for (const node of nodes) {\n if (!isJsonObject(node) || typeof node.id !== \"string\" || node.type !== \"PROPERTY\") {\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),\n properties: {},\n };\n}\n\n/** One `basicPropertyValues` entry. */\ninterface PropertyValue {\n readonly pred: string;\n readonly val: string;\n}\n\n/**\n * The well-formed `basicPropertyValues` of a node's meta.\n * @param meta - the node's meta, or anything\n * @returns the entries with a string pred and val\n */\nfunction basicValues(meta: unknown): PropertyValue[] {\n if (!isJsonObject(meta) || !Array.isArray(meta.basicPropertyValues)) {\n return [];\n }\n return meta.basicPropertyValues.filter(\n (pv): pv is PropertyValue => isJsonObject(pv) && typeof pv.pred === \"string\" && typeof pv.val === \"string\",\n );\n}\n\n/**\n * The strings of an array, or of an array of `{ val }` records.\n * @param value - the array, or anything\n * @returns the strings\n */\nfunction strings(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.flatMap((item: unknown) => {\n if (typeof item === \"string\") {\n return [item];\n }\n return isJsonObject(item) && typeof item.val === \"string\" ? [item.val] : [];\n });\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 */\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 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\") {\n if (record.id === undefined) {\n ctx.coerceId(undefined, element);\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 (record.type === \"PROPERTY\" && ctx.json.typedefs === \"metadata\") {\n const shorthand = vocabulary.id(record.id) === record.id ? undefined : vocabulary.id(record.id);\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[record.id] = entry;\n return;\n }\n const id = ctx.coerceId(vocabulary.id(record.id), element);\n const row = id === null ? -1 : ctx.pushNode(id, element);\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 * 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(columns, vocabulary, meta, row, unrecognized);\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.\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 */\nfunction writeMeta(\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n meta: JsonRecord,\n row: number,\n unrecognized: JsonRecord,\n): void {\n const { definition } = meta;\n if (isJsonObject(definition) && typeof definition.val === \"string\") {\n columns.node(\"def\", row, definition.val);\n columns.node(\"def.xrefs\", row, strings(definition.xrefs));\n }\n const comments = strings(meta.comments);\n if (comments.length > 0) {\n columns.node(\"comment\", row, comments.join(\"\\n\"));\n }\n const subsets = strings(meta.subsets).map((s) => vocabulary.id(s));\n if (subsets.length > 0) {\n columns.node(\"subset\", row, subsets);\n }\n const xrefs = strings(meta.xrefs);\n if (xrefs.length > 0) {\n columns.node(\"xref\", row, xrefs);\n }\n if (Array.isArray(meta.synonyms) && meta.synonyms.length > 0) {\n columns.node(\n \"synonym\",\n row,\n meta.synonyms.filter(isJsonObject).map((s) => ({\n text: typeof s.val === \"string\" ? s.val : null,\n scope: typeof s.pred === \"string\" ? synonymScopeOf(s.pred) : null,\n type: typeof s.synonymType === \"string\" ? vocabulary.id(s.synonymType) : null,\n xrefs: strings(s.xrefs),\n })),\n );\n }\n if (typeof meta.deprecated === \"boolean\") {\n columns.node(\"is_obsolete\", row, meta.deprecated);\n }\n writePropertyValues(columns, vocabulary, basicValues(meta), row);\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 * Write the basicPropertyValues: the ones an OBO tag maps to onto that tag's column (lists for\n * alt_id, replaced_by, consider), the rest into `property_value`.\n * @param columns - the column writer\n * @param vocabulary - the graph's vocabulary\n * @param values - the entries\n * @param row - the node index\n */\nfunction writePropertyValues(\n columns: ColumnWriter,\n vocabulary: Vocabulary,\n values: readonly PropertyValue[],\n row: number,\n): void {\n const lists = new Map<string, string[]>();\n const others: JsonRecord[] = [];\n for (const { pred, val } of values) {\n const tag = OBOGRAPHS_PREDICATE_TAGS.get(pred);\n if (tag === \"shorthand\") {\n continue;\n }\n if (tag === undefined) {\n others.push({ relation: vocabulary.id(pred), value: val, datatype: null });\n } else 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 {\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 */\nfunction badValue(ctx: ImportContext, message: string): void {\n ctx.report.error(\"validation-error\", JSON_ISSUE.BAD_VALUE, message);\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 subKey = hasKey(record, \"sub\") ? \"sub\" : \"subj\";\n if (subKey === \"subj\" && 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 const sub = record[subKey];\n const { obj, pred } = record;\n if (typeof sub !== \"string\" || typeof obj !== \"string\") {\n ctx.missingEndpoint(element, typeof sub === \"string\" ? \"obj\" : \"sub\");\n continue;\n }\n const between =\n (typeof pred === \"string\" && PROPERTY_PREDICATES.has(pred)) ||\n vocabulary.isProperty(sub) ||\n vocabulary.isProperty(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 }\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(s) to them were dropped (addMissingNodes false)`;\n report.warning(\n \"validation-error\",\n JSON_ISSUE.DANGLING_REFERENCE,\n `${new Set(dangling).size} edge endpoint(s) missing from nodes: ${shown}; ${action}`,\n { element: dangling[0] },\n );\n }\n return propertyEdges;\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 serialisation (`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 DANGLING_REFERENCE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n EMPTY_INPUT_CODE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n HYPEREDGE_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n OPTION_IGNORED_CODE,\n SYNTAX_CODE,\n TOO_LARGE_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, textChunks, throwIfAborted } from \"../../common/input.js\";\nimport { MAYBE_UNSAFE_INTEGER, reviveNonstandard, rewriteNumbers } from \"../../common/json-elements.js\";\nimport {\n chooseGraph,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n SINK_OPTION_CODE,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { weightFromValue } from \"../../common/weights.js\";\nimport { 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 */\nexport interface JsonImportOptions extends GraphChoiceOptions {\n /** The dialect to read; \"auto\" (default) sniffs the parsed document. */\n dialect?: JsonImportDialect | \"auto\" | undefined;\n /**\n * node-link / d3 / vis / adjacency / tree: the node key holding the id; auto: \"id\" (node-link /\n * d3: \"id\" when any node has it, else \"name\").\n */\n nodeIdKey?: string | undefined;\n /** node-link / d3: the top-level key holding the edges; auto: \"edges\" when present, else \"links\". */\n edgesKey?: string | undefined;\n /** node-link / d3 / vis: the edge key holding the source; auto: \"source\", \"src\" or \"from\" (vis: \"from\"). */\n sourceKey?: string | undefined;\n /** node-link / d3 / vis: the edge key holding the target; auto: \"target\", \"dst\" or \"to\" (vis: \"to\"). */\n targetKey?: string | undefined;\n /**\n * node-link / d3: whether edge endpoints are node array positions; \"auto\" (default) says yes when\n * every endpoint is an integer below the node count and no node id is a number.\n */\n indexLinks?: boolean | \"auto\" | undefined;\n /**\n * obographs: \"curie\" (default) reads `http://purl.obolibrary.org/obo/GO_0008150` as `GO:0008150`\n * and `.../obo/go#regulates` as `regulates`, the identifiers the `.obo` file of the same ontology\n * writes; \"iri\" keeps every IRI as written.\n */\n oboIds?: \"curie\" | \"iri\" | undefined;\n /**\n * obographs: \"metadata\" (default) keeps PROPERTY nodes and their subPropertyOf / inverseOf edges\n * in `meta.extra.obographs`, as the OBO importer keeps `[Typedef]` frames; \"nodes\" makes them\n * nodes and edges.\n */\n typedefs?: \"metadata\" | \"nodes\" | undefined;\n /**\n * node-link / d3 / vis / graphology: where the node array is, as a dotted path of object keys\n * from the document root (`\"data.nodes\"`); the object holding it is read as the graph record\n * (its `directed`, `multigraph`, `graph` and edge keys). \"nodes\" by default. A path that names\n * nothing is an E_MISSING_SECTION issue and the graph has no node records.\n */\n nodesPath?: string | undefined;\n /**\n * node-link / d3 / vis / graphology: where the edge array is, as a dotted path of object keys\n * from the document root (`\"data.links\"`); by default the edges or links key of the object\n * holding the nodes. A path that names nothing is an E_MISSING_SECTION issue and the graph has\n * no edge records.\n */\n edgesPath?: string | undefined;\n}\n\n/**\n * The issue codes the JSON importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the JSON-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const JSON_ISSUE = Object.freeze({\n /** The text is empty or whitespace (fatal). */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** JSON.parse refused the text (fatal). */\n SYNTAX: SYNTAX_CODE,\n /** No dialect matches the document's top-level shape. */\n DIALECT: \"E_JSON_DIALECT\",\n /** A section (nodes, edges, elements, graph) has the wrong JSON type. */\n SHAPE: \"E_JSON_SHAPE\",\n /** A node-link document lacks its nodes or its edges array, or a Cytoscape document its elements. */\n MISSING_SECTION: \"E_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 /** A node id is a JSON boolean or null (legal in NetworkX, not a NodeId); coerced only under ids \"string\". */\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 distinct id texts merged into one number under ids \"number\". */\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 /** A JGF or OBO Graphs `graphs` array holds more than one graph; only the chosen one is read. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** `graphIndex` is beyond the `graphs` array, or `graphName` names none of its graphs (fatal). */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` names more than one graph of the `graphs` array (fatal). */\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 /** obographs: an edge endpoint missing from `nodes` (a placeholder node is made, or the edge dropped under addMissingNodes false). */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The document is longer than one JavaScript string can hold (fatal; category unsupported). */\n TOO_LARGE: TOO_LARGE_CODE,\n /** JGF hyperedges under the \"error\" policy. */\n HYPEREDGE: HYPEREDGE_CODE,\n /** JGF hyperedges skipped under the default \"skip\" policy. */\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 /** A builder-policy option (addMissingNodes, duplicateEdges, selfLoops, weightDtype) differs from the sink's (the shared W_SINK_OPTION). */\n SINK_OPTION: SINK_OPTION_CODE,\n /** A common option the dialect has no use for (nodeIdFrom outside node-link, long, restoreMangledIds). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\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: \"W_JSON_NONSTANDARD_NUMBER\",\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});\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/** 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, or undefined when a step is missing or not an object.\n * @param root - the document\n * @param segments - the keys\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 (!isJsonObject(value) || !hasKey(value, segment)) {\n return undefined;\n }\n value = value[segment];\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.error(\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 * @returns the dialect\n */\nfunction pathDialect(record: unknown, forced: JsonImportDialect | \"auto\"): JsonImportDialect {\n if (forced !== \"auto\") {\n return forced;\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);\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 /**\n * Create a writer.\n * @param sink - the sink\n * @param domain - node or edge\n */\n constructor(sink: GraphSink, domain: \"node\" | \"edge\") {\n this.sink = sink;\n this.domain = domain;\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.\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 */\n write(row: number, key: string, value: unknown, suffix: string): void {\n if (value === undefined || value === null) {\n return;\n }\n const name = this.reservedNames.has(key) ? `${key}${suffix}` : key;\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 const handle = this.lookup(name);\n if (handle !== INVALID_INDEX) {\n this.handles.set(name, handle);\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 */\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\");\n this.edges = new AttributeWriter(sink, \"edge\");\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 * @returns the node index, or -1 when the sink refused the node\n */\n pushNode(id: NodeId, element: string): 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; 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\n let created = this.sink.indexOf(source) === INVALID_INDEX ? 1 : 0;\n if (source !== target && this.sink.indexOf(target) === INVALID_INDEX) {\n created++;\n }\n const edge = this.direction.addEdge(source, target, kind, weight, { element });\n this.report.counts.edges += this.sink.edgeCount - before;\n this.report.counts.nodes += created;\n return edge;\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 */\n writeNested(\n writer: AttributeWriter,\n row: number,\n record: JsonRecord,\n dict: JsonRecord,\n structural: ReadonlySet<string>,\n weightFrom: string | null,\n ): void {\n for (const key of Object.keys(dict)) {\n if (key !== weightFrom) {\n writer.write(row, key, dict[key], SUFFIX.data);\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);\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 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 }\n }\n if (numbers + strings === 0) {\n return null;\n }\n const dtype = strings === 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(s) 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.\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 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)) {\n return root;\n }\n const 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 ? reviveNonstandard : undefined) as unknown;\n syntaxError = null;\n } catch {\n // the rewrite did not make it valid JSON: report the parser's message on the original text\n }\n }\n if (syntaxError !== null) {\n return report.fail(JSON_ISSUE.SYNTAX, `invalid JSON: ${syntaxError}`);\n }\n if (scan.tokens.size > 0) {\n report.warning(\n \"coercion\",\n JSON_ISSUE.NONSTANDARD_NUMBER,\n `the document uses the non-standard token(s) ${[...scan.tokens].join(\", \")}, which strict JSON does not allow; read as numbers`,\n );\n }\n if (scan.bigIntegers.length > 0) {\n const shown = scan.bigIntegers.slice(0, BIG_INTEGERS_SHOWN).join(\", \");\n const more = scan.bigIntegers.length - BIG_INTEGERS_SHOWN;\n report.warning(\n \"precision\",\n JSON_ISSUE.BIG_INTEGER,\n `${scan.bigIntegers.length} integer(s) beyond 2^53 kept as text so no digit is lost: ${shown}${more > 0 ? ` and ${more} more` : \"\"}`,\n );\n }\n return root;\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.\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: hasKey(record, explicit) ? explicit : null, value: record[explicit] };\n }\n for (const key of defaults) {\n if (hasKey(record, key)) {\n return { key, value: record[key] };\n }\n }\n return { key: null, value: undefined };\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.error(\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 }\n if (edges === null) {\n report.error(\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 for (const key of Object.keys(root)) {\n if (key !== \"nodes\" && key !== edgesKey && key !== \"directed\" && key !== \"multigraph\" && key !== \"graph\") {\n const value = root[key];\n const what = Array.isArray(value)\n ? `${String(value.length)} ${value.length === 1 ? \"entry\" : \"entries\"}`\n : describe(value);\n report.warning(\n \"unsupported\",\n JSON_ISSUE.UNREAD_KEY,\n `top-level key ${key} (${what}) is not read; dropped`,\n {\n element: key,\n },\n );\n }\n }\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\") {\n report.warning(\n \"unsupported\",\n JSON_ISSUE.OPTION_IGNORED,\n 'nodeIdFrom \"label\": no node has a label or name key; ids are read from \"id\"',\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\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, 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);\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 * @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): { 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 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 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);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n return { source: sourceKey, target: targetKey };\n}\n\n/**\n * Write the flat attributes of a node record (every own key the filter keeps).\n * @param ctx - the context\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 ctx: ImportContext,\n writer: AttributeWriter,\n index: number,\n record: JsonRecord,\n id: NodeId,\n keep: (key: string) => boolean,\n): void {\n try {\n for (const key of Object.keys(record)) {\n if (keep(key)) {\n writer.write(index, key, record[key], SUFFIX.data);\n }\n }\n } catch (err) {\n ctx.report.recordError(err, { element: String(id) });\n }\n}\n\n/**\n * The d3 index-link heuristic: endpoints are array positions when every endpoint is a\n * 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 if (!isIndexBelow(s, Infinity) || !isIndexBelow(t, Infinity)) {\n return false;\n }\n seen++;\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 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, 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);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", element);\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 * neighbour 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.error(\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, 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\n const pending = new Map<string, number>();\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(s) 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 && isMirroredEntry(pending, source, target, record.key)) {\n continue;\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);\n }\n }\n } catch (err) {\n ctx.skip(err, \"edge\", entry);\n }\n }\n }\n ctx.setMeta({}, { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() });\n}\n\n/**\n * Whether an undirected adjacency entry is the mirror of one already read (the same unordered\n * pair and key), consuming it; otherwise the entry is remembered as awaiting its mirror. A\n * self-loop is listed once and never awaits one.\n * @param pending - the entries awaiting their mirror, by owner, other end and key\n * @param source - the owner of the list\n * @param target - the entry's node\n * @param key - the entry's multigraph key, or undefined\n * @returns true when the entry is a mirror and must not be pushed\n */\nfunction isMirroredEntry(pending: Map<string, number>, source: NodeId, target: NodeId, key: unknown): boolean {\n const a = JSON.stringify(source);\n const b = JSON.stringify(target);\n if (a === b) {\n return false;\n }\n const k = JSON.stringify(key ?? null);\n // an entry is the mirror of one listed by the other end, never of a parallel entry of its own list\n const mirror = `${b} ${a} ${k}`;\n const waiting = pending.get(mirror) ?? 0;\n if (waiting > 0) {\n pending.set(mirror, waiting - 1);\n return true;\n }\n const own = `${a} ${b} ${k}`;\n pending.set(own, (pending.get(own) ?? 0) + 1);\n return false;\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, 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 serialisation: `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 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 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 (!hasKey(record, \"source\") || !hasKey(record, \"target\")) {\n ctx.missingEndpoint(element, hasKey(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 }\n const attributes = isJsonObject(record.attributes) ? record.attributes : {};\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);\n } catch (err) {\n ctx.skip(err, \"edge\", element);\n }\n }\n ctx.setMeta({ dialect: \"graphology\", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });\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);\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 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);\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 (!hasKey(record, \"source\") || !hasKey(record, \"target\")) {\n ctx.missingEndpoint(element, hasKey(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 return isJsonObject(root.graph) ? root.graph : chosenGraph(ctx, root, \"JGF\");\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 */\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) {\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), importAll() reads every one`,\n { element: \"graphs\" },\n );\n }\n const graph = graphs[index];\n if (!isJsonObject(graph)) {\n return report.fail(JSON_ISSUE.SHAPE, `graphs[${index}] is not an object`);\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/** The longest string V8 makes (2^29 - 24 UTF-16 code units); a longer document cannot be one JSON.parse input. */\nconst MAX_TEXT_LENGTH = 2 ** 29 - 24;\n\n/**\n * Read the whole input as one string, failing with E_TOO_LARGE (category unsupported) before the\n * join when it is longer than one JavaScript string can hold (OBO Graphs files such as\n * ncbitaxon.json are; design 7.1 defers streaming the JSON reader).\n * @param input - the input\n * @param report - the report\n * @param options - cancellation, progress and encoding\n * @returns the text\n */\nasync function readJsonText(\n input: ImportInput,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n): Promise<string> {\n if (typeof input === \"string\") {\n return readText(input, report, options);\n }\n const parts: string[] = [];\n let length = 0;\n for await (const chunk of textChunks(input, report, options)) {\n length += chunk.length;\n if (length > MAX_TEXT_LENGTH) {\n const message = `the document is longer than ${MAX_TEXT_LENGTH} characters, 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 parts.push(chunk);\n }\n return parts.length === 1 ? parts[0] : parts.join(\"\");\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);\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(\"unsupported\", JSON_ISSUE.HYPEREDGE, `${hyperedges.length} hyperedge(s) (hyperedges: \"error\")`, {\n element: \"hyperedges\",\n });\n throw report.abort(\"hyperedges refused\", { code: JSON_ISSUE.HYPEREDGE, count: hyperedges.length });\n }\n if (policy === \"skip\") {\n report.warning(\"unsupported\", JSON_ISSUE.HYPEREDGES_SKIPPED, `${hyperedges.length} hyperedge(s) skipped`, {\n element: \"hyperedges\",\n });\n report.loss(\n JSON_ISSUE.HYPEREDGES_SKIPPED,\n `${hyperedges.length} hyperedge(s) were not imported`,\n null,\n hyperedges.length,\n );\n return;\n }\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 = record.nodes.map((raw) => ctx.requireId(raw, element));\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 kind: EdgeKind = directed ? \"directed\" : \"undirected\";\n if (policy === \"star\") {\n for (let k = 1; k < members.length; k++) {\n push(record, members[0], members[k], kind, element, JGF_HYPEREDGE_KEYS);\n }\n } else {\n for (let a = 0; a < members.length; a++) {\n for (let b = a + 1; b < members.length; b++) {\n push(record, members[a], members[b], kind, element, JGF_HYPEREDGE_KEYS);\n }\n }\n }\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 for (const s of sources) {\n for (const t of targets) {\n push(record, s, t, \"directed\", element, JGF_HYPEREDGE_KEYS);\n }\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 ctx.skip(err, \"edge\", element);\n }\n }\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: \"f32\",\n components: 3,\n role: \"position\",\n mutable: true,\n nullable: true,\n extra: { sourceDims: 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 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);\n }\n const { position } = record;\n if (position !== undefined && position !== null) {\n if (isJsonObject(position) && typeof position.x === \"number\" && typeof position.y === \"number\") {\n point[0] = position.x;\n point[1] = position.y;\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`,\n { element },\n );\n }\n }\n writeClasses(ctx, ctx.nodes, classesColumn, index, record.classes, element);\n writeElementKeys(ctx.nodes, index, record);\n } catch (err) {\n report.recordError(err, { element: String(id) });\n }\n }\n for (const { index, parent, element } of parents) {\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 ctx.nodes.set(parentColumn, index, parentIndex);\n }\n throwIfAborted(ctx.options.signal);\n\n importCytoscapeEdges(ctx, edges, edgeClassesColumn);\n ctx.setMeta({ dialect: \"cytoscape\", cytoscape: extra }, ctx.weightOriginPatch());\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 (!hasKey(data, \"source\") || !hasKey(data, \"target\")) {\n ctx.missingEndpoint(element, `data.${hasKey(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);\n }\n }\n writeClasses(ctx, ctx.edges, edgeClassesColumn, edge, record.classes, element);\n writeElementKeys(ctx.edges, edge, record);\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 return {\n nodes: elements.filter((item) => isJsonObject(item) && isNodeElement(item)),\n edges: elements.filter((item) => isJsonObject(item) && !isNodeElement(item)),\n };\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.error(\"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 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 */\nfunction writeElementKeys(writer: AttributeWriter, row: number, record: JsonRecord): 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);\n }\n}\n\n// ============================================================ the plugin\n\n/**\n * The JSON importer plugin (design section 8.4).\n */\nexport const jsonImporter: GraphImporter<JsonImportOptions> = Object.freeze({\n format: \"json\",\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 const text = new TextDecoder(\"utf-8\").decode(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 readJsonText(input, report, resolved);\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 readJsonText(input, report, resolved);\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 readJsonText(input, first, resolved);\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 if (dialect === \"cytoscape\") {\n importCytoscape(ctx, root);\n throwIfAborted(resolved.signal);\n return;\n }\n const doc = isJsonObject(root)\n ? root\n : 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 throwIfAborted(resolved.signal);\n}\n"],"names":["keyOption","plan","strings"],"mappings":"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"}
|