@graphty/graph-io 0.3.19 → 0.3.21

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.
Files changed (201) hide show
  1. package/README.md +49 -4
  2. package/dist/chunks/{escape-CWExcecC.js → escape-B-tkk_Cl.js} +74 -16
  3. package/dist/chunks/escape-B-tkk_Cl.js.map +1 -0
  4. package/dist/chunks/{writer-DQiKgQJc.js → export-Bh60Dv-n.js} +5 -79
  5. package/dist/chunks/export-Bh60Dv-n.js.map +1 -0
  6. package/dist/chunks/{exporter-CbMZyVt-.js → exporter-BGrsWamJ.js} +7 -6
  7. package/dist/chunks/{exporter-CbMZyVt-.js.map → exporter-BGrsWamJ.js.map} +1 -1
  8. package/dist/chunks/exporter-DIeGJXAZ.js +834 -0
  9. package/dist/chunks/exporter-DIeGJXAZ.js.map +1 -0
  10. package/dist/chunks/{importer-BNFuV1-K.js → importer-BWY2FFc5.js} +28 -7
  11. package/dist/chunks/importer-BWY2FFc5.js.map +1 -0
  12. package/dist/chunks/importer-DD-xv9_Y.js +1471 -0
  13. package/dist/chunks/importer-DD-xv9_Y.js.map +1 -0
  14. package/dist/chunks/{importer-BAP4PrxR.js → importer-DET1tg6s.js} +30 -20
  15. package/dist/chunks/importer-DET1tg6s.js.map +1 -0
  16. package/dist/chunks/{importer-ByPGO-09.js → importer-DEcKhsmQ.js} +2 -2
  17. package/dist/chunks/{importer-ByPGO-09.js.map → importer-DEcKhsmQ.js.map} +1 -1
  18. package/dist/chunks/{importer-BW-Ft2ps.js → importer-DIrbbnAf.js} +6 -5
  19. package/dist/chunks/{importer-BW-Ft2ps.js.map → importer-DIrbbnAf.js.map} +1 -1
  20. package/dist/chunks/importer-D_e7e7LX.js +3055 -0
  21. package/dist/chunks/importer-D_e7e7LX.js.map +1 -0
  22. package/dist/chunks/{importer-Bm1_5vPS.js → importer-eUREhBGj.js} +11 -8
  23. package/dist/chunks/importer-eUREhBGj.js.map +1 -0
  24. package/dist/chunks/{importer-DOepkgnG.js → importer-vi3bSdtw.js} +4 -4
  25. package/dist/chunks/{importer-DOepkgnG.js.map → importer-vi3bSdtw.js.map} +1 -1
  26. package/dist/chunks/{importer-BVGtU1NA.js → importer-zGLo8Dg_.js} +6 -5
  27. package/dist/chunks/{importer-BVGtU1NA.js.map → importer-zGLo8Dg_.js.map} +1 -1
  28. package/dist/chunks/{json-elements-CZY1wiZh.js → json-elements-DDS8N2Dd.js} +2 -2
  29. package/dist/chunks/{json-elements-CZY1wiZh.js.map → json-elements-DDS8N2Dd.js.map} +1 -1
  30. package/dist/chunks/{records-BzNicMsf.js → records-dbRkxwaq.js} +2 -2
  31. package/dist/chunks/{records-BzNicMsf.js.map → records-dbRkxwaq.js.map} +1 -1
  32. package/dist/chunks/{report-BcWboivV.js → report-B1z4WT9e.js} +143 -111
  33. package/dist/chunks/{report-BcWboivV.js.map → report-B1z4WT9e.js.map} +1 -1
  34. package/dist/chunks/{weights-CwISIpCP.js → weights-Dzba96G3.js} +5 -5
  35. package/dist/chunks/{weights-CwISIpCP.js.map → weights-Dzba96G3.js.map} +1 -1
  36. package/dist/chunks/writer-C7flM-Ih.js +77 -0
  37. package/dist/chunks/writer-C7flM-Ih.js.map +1 -0
  38. package/dist/csv.js +6 -5
  39. package/dist/csv.js.map +1 -1
  40. package/dist/cx.js +1 -1
  41. package/dist/cx2.js +2 -2
  42. package/dist/cys.d.ts +1 -0
  43. package/dist/cys.js +6 -0
  44. package/dist/cys.js.map +1 -0
  45. package/dist/dot.js +1 -1
  46. package/dist/gexf.js +5 -4
  47. package/dist/gexf.js.map +1 -1
  48. package/dist/gml.js +12 -14
  49. package/dist/gml.js.map +1 -1
  50. package/dist/graph-io.js +288 -141
  51. package/dist/graph-io.js.map +1 -1
  52. package/dist/graphml.js +1 -1
  53. package/dist/json.js +1 -1
  54. package/dist/neo4j.js +6 -5
  55. package/dist/neo4j.js.map +1 -1
  56. package/dist/obo.js +1 -1
  57. package/dist/pajek.js +1 -1
  58. package/dist/src/common/cell-budget.d.ts +84 -0
  59. package/dist/src/common/cell-budget.d.ts.map +1 -0
  60. package/dist/src/common/cell-budget.js +138 -0
  61. package/dist/src/common/cell-budget.js.map +1 -0
  62. package/dist/src/common/input.d.ts +10 -0
  63. package/dist/src/common/input.d.ts.map +1 -1
  64. package/dist/src/common/input.js +39 -0
  65. package/dist/src/common/input.js.map +1 -1
  66. package/dist/src/common/options.d.ts +6 -0
  67. package/dist/src/common/options.d.ts.map +1 -1
  68. package/dist/src/common/options.js +1 -1
  69. package/dist/src/common/options.js.map +1 -1
  70. package/dist/src/common/xml.d.ts +37 -3
  71. package/dist/src/common/xml.d.ts.map +1 -1
  72. package/dist/src/common/xml.js +86 -6
  73. package/dist/src/common/xml.js.map +1 -1
  74. package/dist/src/common/zip.d.ts +92 -0
  75. package/dist/src/common/zip.d.ts.map +1 -0
  76. package/dist/src/common/zip.js +399 -0
  77. package/dist/src/common/zip.js.map +1 -0
  78. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  79. package/dist/src/formats/cx/importer.js +26 -17
  80. package/dist/src/formats/cx/importer.js.map +1 -1
  81. package/dist/src/formats/cys/constants.d.ts +68 -0
  82. package/dist/src/formats/cys/constants.d.ts.map +1 -0
  83. package/dist/src/formats/cys/constants.js +76 -0
  84. package/dist/src/formats/cys/constants.js.map +1 -0
  85. package/dist/src/formats/cys/importer.d.ts +38 -0
  86. package/dist/src/formats/cys/importer.d.ts.map +1 -0
  87. package/dist/src/formats/cys/importer.js +830 -0
  88. package/dist/src/formats/cys/importer.js.map +1 -0
  89. package/dist/src/formats/cys/index.d.ts +7 -0
  90. package/dist/src/formats/cys/index.d.ts.map +1 -0
  91. package/dist/src/formats/cys/index.js +7 -0
  92. package/dist/src/formats/cys/index.js.map +1 -0
  93. package/dist/src/formats/cys/session.d.ts +132 -0
  94. package/dist/src/formats/cys/session.d.ts.map +1 -0
  95. package/dist/src/formats/cys/session.js +315 -0
  96. package/dist/src/formats/cys/session.js.map +1 -0
  97. package/dist/src/formats/cys/tables.d.ts +90 -0
  98. package/dist/src/formats/cys/tables.d.ts.map +1 -0
  99. package/dist/src/formats/cys/tables.js +293 -0
  100. package/dist/src/formats/cys/tables.js.map +1 -0
  101. package/dist/src/formats/dot/exporter.d.ts +2 -0
  102. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  103. package/dist/src/formats/dot/exporter.js +12 -0
  104. package/dist/src/formats/dot/exporter.js.map +1 -1
  105. package/dist/src/formats/dot/importer.js +6 -2
  106. package/dist/src/formats/dot/importer.js.map +1 -1
  107. package/dist/src/formats/gexf/importer.d.ts +2 -2
  108. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  109. package/dist/src/formats/gexf/importer.js +1 -1
  110. package/dist/src/formats/gexf/importer.js.map +1 -1
  111. package/dist/src/formats/gml/exporter.d.ts +0 -8
  112. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  113. package/dist/src/formats/gml/exporter.js +7 -17
  114. package/dist/src/formats/gml/exporter.js.map +1 -1
  115. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  116. package/dist/src/formats/json/exporter.js +3 -1
  117. package/dist/src/formats/json/exporter.js.map +1 -1
  118. package/dist/src/formats/json/importer.d.ts.map +1 -1
  119. package/dist/src/formats/json/importer.js +3 -2
  120. package/dist/src/formats/json/importer.js.map +1 -1
  121. package/dist/src/formats/xgmml/columns.d.ts +152 -0
  122. package/dist/src/formats/xgmml/columns.d.ts.map +1 -0
  123. package/dist/src/formats/xgmml/columns.js +593 -0
  124. package/dist/src/formats/xgmml/columns.js.map +1 -0
  125. package/dist/src/formats/xgmml/constants.d.ts +196 -0
  126. package/dist/src/formats/xgmml/constants.d.ts.map +1 -0
  127. package/dist/src/formats/xgmml/constants.js +197 -0
  128. package/dist/src/formats/xgmml/constants.js.map +1 -0
  129. package/dist/src/formats/xgmml/document.d.ts +361 -0
  130. package/dist/src/formats/xgmml/document.d.ts.map +1 -0
  131. package/dist/src/formats/xgmml/document.js +695 -0
  132. package/dist/src/formats/xgmml/document.js.map +1 -0
  133. package/dist/src/formats/xgmml/emit.d.ts +341 -0
  134. package/dist/src/formats/xgmml/emit.d.ts.map +1 -0
  135. package/dist/src/formats/xgmml/emit.js +1275 -0
  136. package/dist/src/formats/xgmml/emit.js.map +1 -0
  137. package/dist/src/formats/xgmml/exporter.d.ts +24 -0
  138. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -0
  139. package/dist/src/formats/xgmml/exporter.js +999 -0
  140. package/dist/src/formats/xgmml/exporter.js.map +1 -0
  141. package/dist/src/formats/xgmml/importer.d.ts +58 -0
  142. package/dist/src/formats/xgmml/importer.d.ts.map +1 -0
  143. package/dist/src/formats/xgmml/importer.js +360 -0
  144. package/dist/src/formats/xgmml/importer.js.map +1 -0
  145. package/dist/src/formats/xgmml/index.d.ts +8 -0
  146. package/dist/src/formats/xgmml/index.d.ts.map +1 -0
  147. package/dist/src/formats/xgmml/index.js +8 -0
  148. package/dist/src/formats/xgmml/index.js.map +1 -0
  149. package/dist/src/formats/xgmml/values.d.ts +60 -0
  150. package/dist/src/formats/xgmml/values.d.ts.map +1 -0
  151. package/dist/src/formats/xgmml/values.js +148 -0
  152. package/dist/src/formats/xgmml/values.js.map +1 -0
  153. package/dist/src/index.d.ts +2 -0
  154. package/dist/src/index.d.ts.map +1 -1
  155. package/dist/src/index.js +2 -0
  156. package/dist/src/index.js.map +1 -1
  157. package/dist/src/registry.d.ts +7 -0
  158. package/dist/src/registry.d.ts.map +1 -1
  159. package/dist/src/registry.js +25 -10
  160. package/dist/src/registry.js.map +1 -1
  161. package/dist/src/sniff.d.ts +1 -1
  162. package/dist/src/sniff.d.ts.map +1 -1
  163. package/dist/src/sniff.js +2 -0
  164. package/dist/src/sniff.js.map +1 -1
  165. package/dist/xgmml.d.ts +1 -0
  166. package/dist/xgmml.js +9 -0
  167. package/dist/xgmml.js.map +1 -0
  168. package/package.json +15 -2
  169. package/src/common/cell-budget.ts +170 -0
  170. package/src/common/input.ts +40 -0
  171. package/src/common/options.ts +1 -1
  172. package/src/common/xml.ts +127 -6
  173. package/src/common/zip.ts +472 -0
  174. package/src/formats/cx/importer.ts +27 -19
  175. package/src/formats/cys/constants.ts +99 -0
  176. package/src/formats/cys/importer.ts +1100 -0
  177. package/src/formats/cys/index.ts +7 -0
  178. package/src/formats/cys/session.ts +428 -0
  179. package/src/formats/cys/tables.ts +400 -0
  180. package/src/formats/dot/exporter.ts +17 -0
  181. package/src/formats/dot/importer.ts +6 -2
  182. package/src/formats/gexf/importer.ts +0 -1
  183. package/src/formats/gml/exporter.ts +7 -18
  184. package/src/formats/json/exporter.ts +3 -1
  185. package/src/formats/json/importer.ts +3 -2
  186. package/src/formats/xgmml/columns.ts +747 -0
  187. package/src/formats/xgmml/constants.ts +265 -0
  188. package/src/formats/xgmml/document.ts +975 -0
  189. package/src/formats/xgmml/emit.ts +1563 -0
  190. package/src/formats/xgmml/exporter.ts +1215 -0
  191. package/src/formats/xgmml/importer.ts +491 -0
  192. package/src/formats/xgmml/index.ts +8 -0
  193. package/src/formats/xgmml/values.ts +183 -0
  194. package/src/index.ts +9 -0
  195. package/src/registry.ts +41 -15
  196. package/src/sniff.ts +5 -1
  197. package/dist/chunks/escape-CWExcecC.js.map +0 -1
  198. package/dist/chunks/importer-BAP4PrxR.js.map +0 -1
  199. package/dist/chunks/importer-BNFuV1-K.js.map +0 -1
  200. package/dist/chunks/importer-Bm1_5vPS.js.map +0 -1
  201. package/dist/chunks/writer-DQiKgQJc.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importer-D_e7e7LX.js","sources":["../../src/formats/xgmml/constants.ts","../../src/formats/xgmml/document.ts","../../src/formats/xgmml/values.ts","../../src/formats/xgmml/columns.ts","../../src/formats/xgmml/emit.ts","../../src/formats/xgmml/importer.ts"],"sourcesContent":["/**\n * What the XGMML importer and exporter share: the namespaces, the format facts, the fixed column\n * names, the `meta.extra` key, and the issue and loss code tables (design\n * `design/graph-io/cytoscape-and-obo/design.md` section 1.1).\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n BAD_VALUE_CODE,\n COLUMN_RENAMED_CODE,\n COLUMN_RENAMED_LOSS_CODE,\n DANGLING_REFERENCE_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n EMPTY_INPUT_CODE,\n ENCODING_FALLBACK_CODE,\n EQUATION_AS_TEXT_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n ID_TEXT_TYPE_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MIXED_DIRECTION_CODE,\n MULTIPLE_GRAPHS_CODE,\n MUTUAL_EXPANDED_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PARENT_CYCLE_CODE,\n PARENTS_DROPPED_CODE,\n PRECISION_CODE,\n ROLE_ASSUMED_CODE,\n ROLE_DROPPED_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STORAGE_CLASS_CODE,\n STRAY_TEXT_CODE,\n TEMPORAL_DROPPED_CODE,\n TEMPORAL_TEXT_DROPPED_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ELEMENT_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n WEIGHT_KEY_CLASH_CODE,\n WIDENED_CODE,\n XML_ILLEGAL_CHAR_CODE,\n XML_SYNTAX_CODE,\n} from \"../../common/codes.js\";\n\n/** The format name. */\nexport const FORMAT = \"xgmml\";\n\n/** File extensions (never `.gr`, which DIMACS owns). */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".xgmml\", \".xml\"]);\n\n/** MIME types: the draft's (appendix E) and Cytoscape's. */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/xgmml\", \"text/xgmml\", \"text/xgmml+xml\"]);\n\n/** The XGMML namespace. */\nexport const XGMML_NAMESPACE = \"http://www.cs.rpi.edu/XGMML\";\n\n/** Cytoscape's namespace, bound to the `cy` prefix. */\nexport const CY_NAMESPACE = \"http://www.cytoscape.org\";\n\n/** The XLink namespace. */\nexport const XLINK_NAMESPACE = \"http://www.w3.org/1999/xlink\";\n\n/** The `meta.extra` key the importer writes and the exporter reads. */\nexport const META_KEY = \"xgmml\";\n\n/** The label column (role label) of node and edge `label` attributes. */\nexport const LABEL_COLUMN = \"label\";\n\n/** The edge `id` column (role id, unique). */\nexport const EDGE_ID_COLUMN = \"id\";\n\n/** The node position (f32 x3, role position, y up). */\nexport const POSITION_COLUMN = \"position\";\n\n/** Cytoscape's stacking order (`NODE_Z_LOCATION`), kept out of the position. */\nexport const Z_COLUMN = \"z\";\n\n/** The node, edge and graph json column of a `<graphics>` element's values as written. */\nexport const GRAPHICS_COLUMN = \"graphics\";\n\n/** The containing group node (u32, role parent). */\nexport const PARENT_COLUMN = \"parent\";\n\n/** Every containing group node of a node that is in several groups (list of u32, role parents). */\nexport const PARENTS_COLUMN = \"parents\";\n\n/** The json node column of a group's nested graph id, label and atts. */\nexport const SUBGRAPH_COLUMN = \"xgmml.subgraph\";\n\n/** The string node column naming the network a node's nested-network pointer points to. */\nexport const NESTED_NETWORK_COLUMN = \"cytoscape.nestedNetwork\";\n\n/** The string node column of a nested-network pointer into another file (`file.xgmml#id`). */\nexport const NETWORK_POINTER_COLUMN = \"xgmml.networkPointer\";\n\n/** The list node column of the root-level subgraphs a node belongs to, in a generic document. */\nexport const NETWORKS_COLUMN = \"xgmml.networks\";\n\n/** The edge column of Cytoscape's interaction type. */\nexport const INTERACTION_COLUMN = \"interaction\";\n\n/** The `origin.namespace` of the columns the importer derives from XGMML structure. */\nexport const XGMML_ORIGIN_NAMESPACE = \"xgmml\";\n\n/** The `origin.namespace` of the columns that hold Cytoscape-only data (z, nested networks). */\nexport const CYTOSCAPE_ORIGIN_NAMESPACE = \"cytoscape\";\n\n/**\n * The issue codes the XGMML importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the XGMML-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const XGMML_ISSUE = Object.freeze({\n /** Fatal: the input is not well-formed XML. */\n XML_SYNTAX: XML_SYNTAX_CODE,\n /** Fatal: the input is empty or whitespace only. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** Fatal: the input holds invalid UTF-8. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Fatal: bytes invalid in the encoding a BOM, a declaration or the option chose. */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Undeclared non-UTF-8 bytes were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** Fatal: the root element is not `<graph>` (an XHTML page embedding one, a GraphML file). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** Fatal: a session view document (`cy:view=\"1\"`): view SUIDs and no topology. */\n VIEW_DOCUMENT: \"E_XGMML_VIEW_DOCUMENT\",\n /** A node with neither an id nor a label; it is skipped with its subtree. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without an id; its label is used as the id. */\n ID_FROM_LABEL: \"W_XGMML_ID_FROM_LABEL\",\n /** An edge without a source or a target that no label alias resolves. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** An edge endpoint that names no node (addMissingNodes false); the edge is skipped. */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /** Endpoints resolved through Cytoscape's `\"a (pp) b\"` label aliases; interactions filled from labels. */\n LABEL_ALIAS: \"W_XGMML_LABEL_ALIAS\",\n /** A node id declared twice; the declarations are merged. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id used twice; the second edge is skipped. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /** A meta-edge the 2.x writer repeats inside a group; the copy is dropped. */\n GROUP_DUPLICATE_EDGE: \"W_XGMML_GROUP_DUPLICATE_EDGE\",\n /** A `directed` or `cy:directed` value other than 0 / 1. */\n BAD_DIRECTED: \"W_XGMML_BAD_DIRECTED\",\n /** A `documentVersion` that does not parse; the dialect is chosen from the content. */\n DOCUMENT_VERSION: \"W_XGMML_DOCUMENT_VERSION\",\n /** A root `<graph>` with neither the XGMML namespace nor an XGMML DOCTYPE. */\n NO_NAMESPACE: \"W_XGMML_NO_NAMESPACE\",\n /** A malformed `<att>`: a list with a value, a scalar with child atts, an att with no name. */\n BAD_ATT: \"W_XGMML_BAD_ATT\",\n /** A bare `&` read as `&amp;` under repairBareAmpersands. */\n AMPERSAND_REPAIRED: \"W_XGMML_AMPERSAND_REPAIRED\",\n /** Two surrogate character references joined under pairSurrogateReferences. */\n SURROGATE_PAIRED: \"W_XGMML_SURROGATE_PAIRED\",\n /** An empty list whose element type nothing states; a list of strings is assumed. */\n EMPTY_LIST_TYPE: \"W_XGMML_EMPTY_LIST_TYPE\",\n /** A record list, a list of lists, a 2.x map or foreign XML in an att, kept as json. */\n RECORD_LIST: \"W_XGMML_RECORD_LIST\",\n /** A pointer into another file (`file.xgmml#id`); kept as text. */\n CROSS_FILE_REFERENCE: \"W_XGMML_CROSS_FILE_REFERENCE\",\n /** A graph nested in an edge's att; there is no model for it. */\n EDGE_NESTED_GRAPH: \"W_XGMML_EDGE_NESTED_GRAPH\",\n /** Elements of a session network declared outside every registered subnetwork. */\n ROOT_ONLY_ELEMENTS: \"W_XGMML_ROOT_ONLY_ELEMENTS\",\n /** A value that does not parse as its declared type; the cell is unset. */\n BAD_VALUE: BAD_VALUE_CODE,\n /** A column widened because its values or declared types disagree. */\n WIDENED: WIDENED_CODE,\n /** A long or real beyond what a double holds exactly. */\n PRECISION: PRECISION_CODE,\n /** A reference (xlink:href, nested-network pointer) that names nothing. */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The same attribute twice on one element; the later value wins. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** A group membership naming no node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** A group membership that would close a parent cycle; that link is dropped. */\n PARENT_CYCLE: PARENT_CYCLE_CODE,\n /** A Cytoscape formula kept as its text. */\n EQUATION_AS_TEXT: EQUATION_AS_TEXT_CODE,\n /** An att type XGMML and Cytoscape do not define; kept as text. */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** An element XGMML does not define at that place; skipped with its subtree. */\n UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,\n /** Character data where XGMML allows only elements, or inside an att. */\n STRAY_TEXT: STRAY_TEXT_CODE,\n /** A session network document holds several registered networks; one was read. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** graphIndex / graphName names no network (fatal). */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** graphName names several networks (fatal). */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** A column renamed `<name>#<n>` because its name was taken. */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column declared without its role because the table already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** An option the format has no use for. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n});\n\n/**\n * Loss note codes of the XGMML exporter (check()): the XGMML ones and the shared ones its notes\n * can carry. The generic notes of `checkCapabilities()` (dtypes, components, temporal and visual\n * roles, extension tables) are those of `LOSS`.\n */\nexport const XGMML_LOSS = Object.freeze({\n /** A json or nested-list column written as a string att. */\n JSON_AS_STRING: \"W_XGMML_JSON_AS_STRING\",\n /** A dtype written as a wider Cytoscape type (f32 as Double, u32 above i32 as Long, u8 as Integer, dict as String). */\n WIDENED_TYPE: \"W_XGMML_WIDENED_TYPE\",\n /** A string holding a character XML 1.0 cannot carry; export() throws. */\n XML_ILLEGAL_CHAR: XML_ILLEGAL_CHAR_CODE,\n /** A temporal column written as plain numbers. */\n TEMPORAL_DROPPED: TEMPORAL_DROPPED_CODE,\n /** A temporal text companion written as a plain string att. */\n TEMPORAL_TEXT_DROPPED: TEMPORAL_TEXT_DROPPED_CODE,\n /** A role the format has no slot for, written as a plain att. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /** A parents column not written because the snapshot also has a parent column. */\n PARENTS_DROPPED: PARENTS_DROPPED_CODE,\n /** A mutual pair written as two directed edges. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** Node ids whose text reads back as the other type. */\n ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,\n /** An edge id column of another dtype written as text; it reads back as strings. */\n EDGE_ID_TEXT: \"W_XGMML_EDGE_ID_TEXT\",\n /** Strings holding a literal backslash-n or backslash-t read back as newline / tab (Cytoscape's escapes). */\n BACKSLASH_ESCAPE: \"W_XGMML_BACKSLASH_ESCAPE\",\n /** A position that cannot be written as it is: another shape, a non-finite coordinate, a z read back in the z column. */\n POSITION: \"W_XGMML_POSITION\",\n /** Nodes whose parent chain never reaches a root are written at the top level. */\n PARENT_CYCLE: \"W_XGMML_PARENT_CYCLE\",\n /** A column named like a column the importer owns reads back renamed. */\n COLUMN_NAME_CHANGED: COLUMN_RENAMED_LOSS_CODE,\n /** A role-less column written into a slot reads back with the slot's role. */\n ROLE_ASSUMED: ROLE_ASSUMED_CODE,\n /** A plain `weight` edge column reads back as THE weight. */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /** A string / dict column that reads back as the other storage class. */\n STORAGE_CLASS_CHANGED: STORAGE_CLASS_CODE,\n /** Edge labels shaped `a (i) b` read back with an `interaction` column (Cytoscape's label alias). */\n INTERACTION_FROM_LABEL: \"W_XGMML_INTERACTION_FROM_LABEL\",\n});\n","/**\n * The XGMML document model: one pass of the shared XML tokenizer turns an XGMML document into\n * plain records (graphs, nodes, edges, atts, graphics) that keep everything the file says, with\n * forward references (`xlink:href`, an edge before its nodes) left as ids. The importer\n * (importer.ts) resolves the records into a sink once the outermost `</graph>` has closed, as\n * Cytoscape does, and the `.cys` importer reuses the same records for the network and view files\n * of a session.\n *\n * It recognises the five shapes of `research-xgmml.md` section 2: the 1.0 draft, the Cytoscape\n * 2.x export and session, the 3.x export, the 3.x session network file (root `cy:registered=\"0\"`)\n * and the 3.x session view file (root `cy:view=\"1\"`).\n */\n\nimport { escapeXmlAttribute, escapeXmlText } from \"../../common/escape.js\";\nimport { type ImportReportBuilder } from \"../../common/report.js\";\nimport { isWhitespace, localName, type XmlHandler } from \"../../common/xml.js\";\nimport { XGMML_ISSUE, XGMML_NAMESPACE } from \"./constants.js\";\n\n/** One `<att>` and what it holds. */\nexport interface AttRec {\n /** The `name` (else `label`) attribute, or null. */\n name: string | null;\n /** The XGMML `type` as written, or null. */\n readonly type: string | null;\n /** Cytoscape's `cy:type`, or null. */\n readonly cyType: string | null;\n /** Cytoscape's `cy:elementType` of a list, or null. */\n readonly elementType: string | null;\n /** The `value` attribute, or null when absent. */\n readonly value: string | null;\n /** `cy:hidden` is 1, true or yes. */\n readonly hidden: boolean;\n /** `cy:equation` is 1, true or yes: the value is a formula. */\n readonly equation: boolean;\n /** The child atts (list items, record fields, graphics properties). */\n readonly children: AttRec[];\n /** The XML attributes besides the ones above (a 2.x bend handle's `x` and `y`). */\n readonly extra: Record<string, string>;\n /** Foreign XML inside the att (RDF), serialized, or null. */\n xml: string | null;\n /** Whether the att held a `<graph>`. */\n hasGraph: boolean;\n /** Non-whitespace character data inside the att. */\n text: string;\n /** The line of the `<att`. */\n readonly line: number;\n /** The table namespace of a `.cys` column, or null for an att of the document. */\n readonly namespace?: string | null | undefined;\n}\n\n/** A `<node>`. */\nexport interface NodeRec {\n readonly kind: \"node\";\n /** The id (the label when the id is missing), or null for an `xlink:href` reference. */\n readonly id: string | null;\n /** The `xlink:href` of a reference to a node declared elsewhere, or null. */\n readonly href: string | null;\n /** The `label` attribute (else `name`), or null. */\n readonly label: string | null;\n /** The `name` attribute when a label is also given, or null. */\n readonly name: string | null;\n /** The other XML attributes, as written. */\n readonly xmlAttrs: [string, string][];\n /** The atts, in document order. */\n readonly atts: AttRec[];\n /** The graphics values besides x, y and z, or null without `<graphics>`. */\n graphics: Record<string, unknown> | null;\n /** The x, y and z texts of the graphics (or its `<center>`), or null. */\n x: string | null;\n y: string | null;\n z: string | null;\n /** The graphs nested in the node's atts. */\n readonly nested: GraphRec[];\n /** The graph that declares (or references) the node. */\n readonly graph: GraphRec;\n /** The line of the `<node`. */\n readonly line: number;\n /** A session view's `cy:nodeId`, or null. */\n readonly viewId: string | null;\n}\n\n/** An `<edge>`. */\nexport interface EdgeRec {\n readonly kind: \"edge\";\n /** The id attribute, or null. */\n readonly id: string | null;\n /** The `xlink:href` of a reference to an edge declared elsewhere, or null. */\n readonly href: string | null;\n /** The source and target texts, or null when missing. */\n readonly source: string | null;\n readonly target: string | null;\n /** The label attribute, or null. */\n readonly label: string | null;\n /** The `name` attribute, or null. */\n readonly name: string | null;\n /** The `weight` attribute, or null. */\n readonly weight: string | null;\n /** The `cy:directed` attribute, or null. */\n readonly directed: string | null;\n /** The other XML attributes, as written. */\n readonly xmlAttrs: [string, string][];\n /** The atts, in document order. */\n readonly atts: AttRec[];\n /** The graphics values, or null. */\n graphics: Record<string, unknown> | null;\n /** The graph that declares (or references) the edge. */\n readonly graph: GraphRec;\n /** The line of the `<edge`. */\n readonly line: number;\n /** A session view's `cy:edgeId`, or null. */\n readonly viewId: string | null;\n}\n\n/** A `<graph>`: the root, a subnetwork, a group or a nested-network pointer. */\nexport interface GraphRec {\n /** The id attribute, or null. */\n readonly id: string | null;\n /** The label attribute, or null. */\n readonly label: string | null;\n /** The `xlink:href` of a pointer to a graph written elsewhere, or null. */\n readonly href: string | null;\n /** `cy:registered` as written, or null. */\n readonly registered: string | null;\n /** Every XML attribute, as written. */\n readonly attrs: ReadonlyMap<string, string>;\n /** The graph-level atts. */\n readonly atts: AttRec[];\n /** The graph's `<graphics>` values, or null. */\n graphics: Record<string, unknown> | null;\n /** The node whose att holds this graph, or null. */\n readonly owner: NodeRec | null;\n /** The graph this one is nested in, or null for the root. */\n readonly parent: GraphRec | null;\n /** The nodes and edges directly in this graph (declared or referenced), in document order. */\n readonly members: (NodeRec | EdgeRec)[];\n /** The graphs held by this graph's own atts (subnetworks of the root). */\n readonly subgraphs: GraphRec[];\n /** The line of the `<graph`. */\n readonly line: number;\n}\n\n/** A parsed document. */\nexport interface XgmmlDocument {\n /** The root graph. */\n readonly root: GraphRec;\n /** Every declared node (not references), in document order. */\n readonly nodes: NodeRec[];\n /** Every declared edge, in document order. */\n readonly edges: EdgeRec[];\n /** Every graph, root first. */\n readonly graphs: GraphRec[];\n /** The `cy` prefix is bound, or a `cy:` attribute is used: Cytoscape wrote the file. */\n readonly cytoscape: boolean;\n /** The root is in the XGMML namespace (default or prefixed). */\n readonly xgmmlNamespace: boolean;\n /** The RDF network metadata fields (`dc:title`, ...) by local name. */\n readonly rdf: Record<string, string>;\n /** The serialized `networkMetadata` RDF, or null. */\n readonly rdfXml: string | null;\n}\n\n/** What the parser keeps about one open element. */\ntype Frame =\n | { readonly kind: \"graph\"; readonly graph: GraphRec }\n | { readonly kind: \"node\"; readonly node: NodeRec }\n | { readonly kind: \"edge\"; readonly edge: EdgeRec }\n | { readonly kind: \"att\"; readonly att: AttRec; readonly owner: \"graph\" | \"node\" | \"edge\" | \"graphics\" | \"att\" }\n | { readonly kind: \"graphics\"; readonly target: GraphicsTarget }\n | { readonly kind: \"line\"; readonly points: Record<string, string>[] }\n | { readonly kind: \"capture\"; readonly att: AttRec; depth: number }\n | { readonly kind: \"skip\" };\n\n/** What a `<graphics>` writes into. */\ninterface GraphicsTarget {\n graphics: Record<string, unknown> | null;\n x?: string | null;\n y?: string | null;\n z?: string | null;\n}\n\n/** The XML attributes the parser reads on `<node>`. */\nconst NODE_READ: ReadonlySet<string> = new Set([\"id\", \"label\", \"name\", \"xlink:href\", \"cy:nodeId\"]);\n\n/** The XML attributes the parser reads on `<edge>`. */\nconst EDGE_READ: ReadonlySet<string> = new Set([\n \"id\",\n \"label\",\n \"name\",\n \"source\",\n \"target\",\n \"weight\",\n \"cy:directed\",\n \"xlink:href\",\n \"cy:edgeId\",\n]);\n\n/** The XML attributes an `<att>` uses as its own; any other is kept in `extra`. */\nconst ATT_READ: ReadonlySet<string> = new Set([\n \"name\",\n \"label\",\n \"type\",\n \"value\",\n \"cy:type\",\n \"cy:elementType\",\n \"cy:hidden\",\n \"cy:equation\",\n \"cy:editable\",\n]);\n\n/** Cytoscape's spellings of true (`1`, `true`, `yes`, any case). */\nconst TRUE_TEXT = /^(1|true|yes)$/i;\n\n/**\n * Whether a Cytoscape flag text is true.\n * @param text - the text, or undefined\n * @returns true for 1, true or yes in any case\n */\nexport function isCyTrue(text: string | null | undefined): boolean {\n return text !== null && text !== undefined && TRUE_TEXT.test(text.trim());\n}\n\n/**\n * The name an XML attribute is known by, its `xlink` prefix normalised whatever prefix the file\n * binds XLink to (galFiltered.xgmml uses `ns1`).\n * @param name - the attribute name as written\n * @param xlinkPrefixes - the prefixes bound to the XLink namespace\n * @returns the name with `xlink:` for XLink attributes\n */\nfunction normaliseName(name: string, xlinkPrefixes: ReadonlySet<string>): string {\n const colon = name.indexOf(\":\");\n if (colon > 0 && xlinkPrefixes.has(name.slice(0, colon))) {\n return `xlink:${name.slice(colon + 1)}`;\n }\n return name;\n}\n\n/**\n * The tokenizer handler that builds an XgmmlDocument.\n */\nexport class XgmmlParser implements XmlHandler {\n private readonly report: ImportReportBuilder;\n\n private readonly frames: Frame[] = [];\n\n private readonly xlinkPrefixes = new Set<string>([\"xlink\"]);\n\n private rootGraph: GraphRec | null = null;\n\n private readonly nodes: NodeRec[] = [];\n\n private readonly edges: EdgeRec[] = [];\n\n private readonly graphs: GraphRec[] = [];\n\n private cytoscape = false;\n\n private xgmmlNamespace = false;\n\n /** The prefix of the root element (`xgmml` in `<xgmml:graph>`), or null when it has none. */\n private rootPrefix: string | null = null;\n\n private readonly rdf: Record<string, string> = {};\n\n private rdfXml: string | null = null;\n\n /**\n * Create a parser.\n * @param report - the report issues are recorded in\n */\n constructor(report: ImportReportBuilder) {\n this.report = report;\n }\n\n /**\n * The parsed document.\n * @returns the document; E_NO_GRAPH (fatal) when no root graph was read\n */\n document(): XgmmlDocument {\n const root = this.rootGraph;\n if (root === null) {\n return this.report.fail(XGMML_ISSUE.NO_GRAPH, \"the document has no <graph> element\");\n }\n return {\n root,\n nodes: this.nodes,\n edges: this.edges,\n graphs: this.graphs,\n cytoscape: this.cytoscape,\n xgmmlNamespace: this.xgmmlNamespace,\n rdf: this.rdf,\n rdfXml: this.rdfXml,\n };\n }\n\n /**\n * An element starts.\n * @param rawName - the element name as written\n * @param rawAttrs - its attributes\n * @param line - the line\n */\n start(rawName: string, rawAttrs: ReadonlyMap<string, string>, line: number): void {\n const top = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];\n if (top === null) {\n this.startRoot(rawName, rawAttrs, line);\n return;\n }\n if (top.kind === \"skip\") {\n this.frames.push(top);\n return;\n }\n if (top.kind === \"capture\") {\n this.capture(top, rawName, rawAttrs);\n return;\n }\n const attrs = this.normalise(rawAttrs);\n const name = localName(rawName);\n switch (top.kind) {\n case \"graph\":\n this.startInGraph(top.graph, rawName, name, attrs, line);\n return;\n case \"node\":\n this.startInElement(top.node, rawName, name, attrs, line);\n return;\n case \"edge\":\n this.startInElement(top.edge, rawName, name, attrs, line);\n return;\n case \"att\":\n this.startInAtt(top, rawName, name, attrs, line);\n return;\n case \"graphics\":\n this.startInGraphics(top.target, rawName, name, attrs, line);\n return;\n case \"line\":\n if (name === \"point\") {\n top.points.push(Object.fromEntries(attrs));\n this.frames.push({ kind: \"skip\" });\n return;\n }\n this.unknownElement(rawName, line);\n return;\n default: {\n const kind: never = top;\n throw new Error(`unknown XGMML frame ${String(kind)}`);\n }\n }\n }\n\n /**\n * An element ends.\n * @param name - the element name\n * @param _line - the line\n */\n end(name: string, _line: number): void {\n const frame = this.frames.pop();\n const below = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];\n switch (frame?.kind) {\n case \"capture\":\n frame.att.xml = `${frame.att.xml ?? \"\"}</${name}>`;\n frame.depth--;\n if (frame.depth > 0) {\n this.frames.push(frame);\n } else if (frame.att.name === \"networkMetadata\") {\n this.rdfXml = frame.att.xml;\n }\n this.rdfElement = null;\n return;\n case \"att\":\n if (below?.kind === \"graphics\") {\n this.graphicsAtt(below.target, frame.att);\n }\n return;\n case \"line\":\n if (below?.kind === \"graphics\") {\n below.target.graphics = { ...(below.target.graphics ?? {}), Line: frame.points };\n }\n return;\n default:\n }\n }\n\n /**\n * Character data.\n * @param text - the text\n * @param line - the line\n */\n text(text: string, line: number): void {\n const top = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];\n if (top === null || top.kind === \"skip\") {\n return;\n }\n if (top.kind === \"capture\") {\n top.att.xml = `${top.att.xml ?? \"\"}${escapeXmlText(text)}`;\n this.captureRdfText(text);\n return;\n }\n if (isWhitespace(text)) {\n return;\n }\n if (top.kind === \"att\") {\n top.att.text += text;\n }\n this.report.warnOnce(\n \"validation-error\",\n XGMML_ISSUE.STRAY_TEXT,\n top.kind === \"att\"\n ? \"text inside <att> is ignored; an XGMML value is the value attribute\"\n : \"text where XGMML allows only elements was ignored\",\n { line },\n );\n }\n\n // ------------------------------------------------------------------ structure\n\n /**\n * The XML attribute map with every XLink prefix written `xlink:`.\n * @param attrs - the attributes as written\n * @returns the normalised map\n */\n private normalise(attrs: ReadonlyMap<string, string>): Map<string, string> {\n const out = new Map<string, string>();\n for (const [key, value] of attrs) {\n out.set(normaliseName(key, this.xlinkPrefixes), value);\n }\n return out;\n }\n\n /**\n * The root element: a `<graph>`, else the document is not XGMML.\n * @param rawName - the name as written\n * @param rawAttrs - its attributes\n * @param line - the line\n */\n private startRoot(rawName: string, rawAttrs: ReadonlyMap<string, string>, line: number): void {\n const local = localName(rawName);\n const prefix = rawName.includes(\":\") ? rawName.slice(0, rawName.indexOf(\":\")) : null;\n for (const [key, value] of rawAttrs) {\n if (key.startsWith(\"xmlns:\") && value === \"http://www.w3.org/1999/xlink\") {\n this.xlinkPrefixes.add(key.slice(6));\n }\n if (key === \"xmlns:cy\" || key.startsWith(\"cy:\")) {\n this.cytoscape = true;\n }\n }\n this.rootPrefix = prefix;\n const nsKey = prefix === null ? \"xmlns\" : `xmlns:${prefix}`;\n this.xgmmlNamespace = rawAttrs.get(nsKey) === XGMML_NAMESPACE;\n if (local !== \"graph\") {\n this.report.fail(\n XGMML_ISSUE.NO_GRAPH,\n `the root element is <${rawName}>, not <graph>; an XGMML graph embedded in another document is not read`,\n { line },\n );\n }\n const graph = this.newGraph(this.normalise(rawAttrs), line, null, null);\n this.rootGraph = graph;\n this.frames.push({ kind: \"graph\", graph });\n }\n\n /**\n * A graph record, registered in the document.\n * @param attrs - its attributes\n * @param line - the line\n * @param owner - the node whose att holds it, or null\n * @param parent - the graph it is nested in, or null\n * @returns the record\n */\n private newGraph(\n attrs: ReadonlyMap<string, string>,\n line: number,\n owner: NodeRec | null,\n parent: GraphRec | null,\n ): GraphRec {\n const graph: GraphRec = {\n id: attrs.get(\"id\") ?? null,\n label: attrs.get(\"label\") ?? null,\n href: attrs.get(\"xlink:href\") ?? null,\n registered: attrs.get(\"cy:registered\") ?? null,\n attrs,\n atts: [],\n graphics: null,\n owner,\n parent,\n members: [],\n subgraphs: [],\n line,\n };\n if (!this.cytoscape) {\n for (const key of attrs.keys()) {\n if (key.startsWith(\"cy:\")) {\n this.cytoscape = true;\n }\n }\n }\n this.graphs.push(graph);\n return graph;\n }\n\n /**\n * A child of `<graph>`.\n * @param graph - the graph\n * @param rawName - the name as written\n * @param name - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraph(\n graph: GraphRec,\n rawName: string,\n name: string,\n attrs: Map<string, string>,\n line: number,\n ): void {\n switch (name) {\n case \"node\":\n this.beginNode(graph, attrs, line);\n return;\n case \"edge\":\n this.beginEdge(graph, attrs, line);\n return;\n case \"att\": {\n const att = this.newAtt(attrs, line);\n graph.atts.push(att);\n this.beginAtt(att, attrs, \"graph\");\n return;\n }\n case \"graphics\":\n this.beginGraphics(graph, attrs);\n return;\n default:\n this.unknownElement(rawName, line);\n }\n }\n\n /**\n * A child of `<node>` or `<edge>`.\n * @param element - the node or edge\n * @param rawName - the name as written\n * @param name - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInElement(\n element: NodeRec | EdgeRec,\n rawName: string,\n name: string,\n attrs: Map<string, string>,\n line: number,\n ): void {\n switch (name) {\n case \"att\": {\n const att = this.newAtt(attrs, line);\n element.atts.push(att);\n this.beginAtt(att, attrs, element.kind);\n return;\n }\n case \"graphics\":\n this.beginGraphics(element, attrs);\n return;\n default:\n this.unknownElement(rawName, line);\n }\n }\n\n /**\n * A child of `<att>`: a child att, a nested graph, or foreign XML.\n * @param frame - the att frame\n * @param rawName - the name as written\n * @param name - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInAtt(\n frame: Extract<Frame, { kind: \"att\" }>,\n rawName: string,\n name: string,\n attrs: Map<string, string>,\n line: number,\n ): void {\n const { att } = frame;\n const xgmml = this.isXgmmlName(rawName);\n if (name === \"att\" && xgmml) {\n const child = this.newAtt(attrs, line);\n att.children.push(child);\n this.beginAtt(child, attrs, frame.owner === \"graphics\" ? \"graphics\" : \"att\");\n return;\n }\n if (name === \"graph\" && xgmml) {\n att.hasGraph = true;\n this.beginNestedGraph(frame, attrs, line);\n return;\n }\n // a second foreign element of the same att is appended to the first\n att.xml ??= \"\";\n const capture: Extract<Frame, { kind: \"capture\" }> = { kind: \"capture\", att, depth: 0 };\n this.frames.push(capture);\n this.capture(capture, rawName, attrs);\n }\n\n /**\n * Whether an element name inside an att is XGMML's own (unprefixed, or with the root's prefix,\n * as in a document whose root is `<xgmml:graph>`) rather than foreign XML such as `rdf:RDF`.\n * @param rawName - the name as written\n * @returns true for an XGMML element name\n */\n private isXgmmlName(rawName: string): boolean {\n const colon = rawName.indexOf(\":\");\n return colon < 0 || (this.rootPrefix !== null && rawName.slice(0, colon) === this.rootPrefix);\n }\n\n /**\n * A `<graph>` inside an `<att>`: a subnetwork of the root, a group or nested-network pointer\n * of a node, or (in an edge) a graph with no model.\n * @param frame - the att frame\n * @param attrs - the graph's attributes\n * @param line - the line\n */\n private beginNestedGraph(frame: Extract<Frame, { kind: \"att\" }>, attrs: Map<string, string>, line: number): void {\n const holder = this.attHolder();\n if (holder === null || holder.kind === \"edge\" || frame.owner === \"graphics\") {\n this.report.warnOnce(\n \"unsupported\",\n XGMML_ISSUE.EDGE_NESTED_GRAPH,\n \"a graph nested in an edge's (or a graphics) att has no model and was skipped with its content\",\n { line },\n );\n this.frames.push({ kind: \"skip\" });\n return;\n }\n if (holder.kind === \"node\") {\n const graph = this.newGraph(attrs, line, holder.node, holder.node.graph);\n holder.node.nested.push(graph);\n this.frames.push({ kind: \"graph\", graph });\n return;\n }\n const graph = this.newGraph(attrs, line, null, holder.graph);\n holder.graph.subgraphs.push(graph);\n this.frames.push({ kind: \"graph\", graph });\n }\n\n /**\n * The innermost node, edge or graph frame below the open atts.\n * @returns the frame, or null\n */\n private attHolder(): Extract<Frame, { kind: \"graph\" | \"node\" | \"edge\" }> | null {\n for (let i = this.frames.length - 1; i >= 0; i--) {\n const frame = this.frames[i];\n if (frame.kind === \"graph\" || frame.kind === \"node\" || frame.kind === \"edge\") {\n return frame;\n }\n }\n return null;\n }\n\n /**\n * Report an element XGMML does not define here and skip its subtree.\n * @param rawName - the name as written\n * @param line - the line\n */\n private unknownElement(rawName: string, line: number): void {\n this.report.warnOnce(\n \"unsupported\",\n XGMML_ISSUE.UNKNOWN_ELEMENT,\n `element <${rawName}> is not XGMML here and was skipped with its content`,\n { line, element: rawName },\n `${XGMML_ISSUE.UNKNOWN_ELEMENT}:${rawName}`,\n );\n this.frames.push({ kind: \"skip\" });\n }\n\n // ------------------------------------------------------------------ nodes and edges\n\n /**\n * Open a `<node>`.\n * @param graph - the graph it is in\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginNode(graph: GraphRec, attrs: Map<string, string>, line: number): void {\n const href = attrs.get(\"xlink:href\") ?? null;\n let id = attrs.get(\"id\") ?? null;\n const labelAttr = attrs.get(\"label\") ?? null;\n const nameAttr = attrs.get(\"name\") ?? null;\n const label = labelAttr ?? nameAttr;\n if (href === null && id === null) {\n if (label === null || label.length === 0) {\n this.report.counts.skippedNodes++;\n this.report.error(\"missing-value\", XGMML_ISSUE.MISSING_ID, \"<node> without an id or a label\", {\n line,\n });\n this.frames.push({ kind: \"skip\" });\n return;\n }\n this.report.warning(\n \"validation-error\",\n XGMML_ISSUE.ID_FROM_LABEL,\n `<node> without an id: its label \"${label}\" is used as the id`,\n { line, element: label },\n );\n id = label;\n }\n const node: NodeRec = {\n kind: \"node\",\n id: href === null ? id : null,\n href,\n label,\n name: labelAttr !== null ? nameAttr : null,\n xmlAttrs: otherAttributes(attrs, NODE_READ),\n atts: [],\n graphics: null,\n x: null,\n y: null,\n z: null,\n nested: [],\n graph,\n line,\n viewId: attrs.get(\"cy:nodeId\") ?? null,\n };\n graph.members.push(node);\n if (href === null) {\n this.nodes.push(node);\n }\n this.frames.push({ kind: \"node\", node });\n }\n\n /**\n * Open an `<edge>`.\n * @param graph - the graph it is in\n * @param attrs - its attributes\n * @param line - the line\n */\n private beginEdge(graph: GraphRec, attrs: Map<string, string>, line: number): void {\n const href = attrs.get(\"xlink:href\") ?? null;\n const edge: EdgeRec = {\n kind: \"edge\",\n id: href === null ? (attrs.get(\"id\") ?? null) : null,\n href,\n source: attrs.get(\"source\") ?? null,\n target: attrs.get(\"target\") ?? null,\n label: attrs.get(\"label\") ?? null,\n name: attrs.get(\"name\") ?? null,\n weight: attrs.get(\"weight\") ?? null,\n directed: attrs.get(\"cy:directed\") ?? null,\n xmlAttrs: otherAttributes(attrs, EDGE_READ),\n atts: [],\n graphics: null,\n graph,\n line,\n viewId: attrs.get(\"cy:edgeId\") ?? null,\n };\n graph.members.push(edge);\n if (href === null) {\n this.edges.push(edge);\n }\n this.frames.push({ kind: \"edge\", edge });\n }\n\n // ------------------------------------------------------------------ atts\n\n /**\n * An att record from its XML attributes.\n * @param attrs - the attributes\n * @param line - the line\n * @returns the record\n */\n private newAtt(attrs: Map<string, string>, line: number): AttRec {\n const extra: Record<string, string> = {};\n for (const [key, value] of attrs) {\n if (!ATT_READ.has(key) && key !== \"xmlns\" && !key.startsWith(\"xmlns:\")) {\n extra[key] = value;\n }\n }\n return {\n name: attrs.get(\"name\") ?? attrs.get(\"label\") ?? null,\n type: attrs.get(\"type\") ?? null,\n cyType: attrs.get(\"cy:type\") ?? null,\n elementType: attrs.get(\"cy:elementType\") ?? null,\n value: attrs.get(\"value\") ?? null,\n hidden: isCyTrue(attrs.get(\"cy:hidden\")),\n equation: isCyTrue(attrs.get(\"cy:equation\")),\n children: [],\n extra,\n xml: null,\n hasGraph: false,\n text: \"\",\n line,\n };\n }\n\n /**\n * Open an `<att>`.\n * @param att - the record\n * @param _attrs - its attributes\n * @param owner - what holds it\n */\n private beginAtt(\n att: AttRec,\n _attrs: Map<string, string>,\n owner: \"graph\" | \"node\" | \"edge\" | \"graphics\" | \"att\",\n ): void {\n this.frames.push({ kind: \"att\", att, owner });\n }\n\n /**\n * Serialize one start tag of foreign XML into the capturing att.\n * @param frame - the capture frame\n * @param rawName - the name as written\n * @param attrs - its attributes\n */\n private capture(\n frame: Extract<Frame, { kind: \"capture\" }>,\n rawName: string,\n attrs: ReadonlyMap<string, string>,\n ): void {\n let tag = `<${rawName}`;\n for (const [key, value] of attrs) {\n tag += ` ${key}=\"${escapeXmlAttribute(value)}\"`;\n }\n frame.att.xml = `${frame.att.xml ?? \"\"}${tag}>`;\n frame.depth++;\n if (frame.att.name === \"networkMetadata\") {\n this.rdfElement = localName(rawName);\n }\n }\n\n /** The local name of the RDF element whose text is being read, or null. */\n private rdfElement: string | null = null;\n\n /**\n * Keep the text of an RDF metadata field.\n * @param text - the text\n */\n private captureRdfText(text: string): void {\n if (this.rdfElement !== null && !isWhitespace(text)) {\n this.rdf[this.rdfElement] = (this.rdf[this.rdfElement] ?? \"\") + text;\n }\n }\n\n // ------------------------------------------------------------------ graphics\n\n /**\n * Open a `<graphics>`: x, y and z (draft and Cytoscape) are read as coordinates; every other\n * attribute is kept as written, merged key by key with an earlier `<graphics>`.\n * @param target - the node, edge or graph\n * @param attrs - its attributes\n */\n private beginGraphics(target: GraphicsTarget, attrs: Map<string, string>): void {\n const graphics: Record<string, unknown> = { ...(target.graphics ?? {}) };\n for (const [key, value] of attrs) {\n if (\"x\" in target && (key === \"x\" || key === \"y\" || key === \"z\")) {\n target[key] = value;\n } else if (key !== \"xmlns\" && !key.startsWith(\"xmlns:\")) {\n graphics[key] = value;\n }\n }\n target.graphics = graphics;\n this.frames.push({ kind: \"graphics\", target });\n }\n\n /**\n * A child of `<graphics>`: a visual-property att, a `<center>` or a `<Line>`.\n * @param target - the graphics target\n * @param rawName - the name as written\n * @param name - its local name\n * @param attrs - its attributes\n * @param line - the line\n */\n private startInGraphics(\n target: GraphicsTarget,\n rawName: string,\n name: string,\n attrs: Map<string, string>,\n line: number,\n ): void {\n switch (name) {\n case \"att\": {\n this.frames.push({ kind: \"att\", att: this.newAtt(attrs, line), owner: \"graphics\" });\n return;\n }\n case \"center\":\n if (\"x\" in target) {\n target.x ??= attrs.get(\"x\") ?? null;\n target.y ??= attrs.get(\"y\") ?? null;\n target.z ??= attrs.get(\"z\") ?? null;\n }\n this.frames.push({ kind: \"skip\" });\n return;\n case \"Line\":\n case \"line\":\n this.frames.push({ kind: \"line\", points: [] });\n return;\n default:\n this.unknownElement(rawName, line);\n }\n }\n\n /**\n * Keep a visual-property att of a `<graphics>` in its record, as written. A session view's\n * `<att name=\"z\">` repeats z and is read as z when the attributes gave none.\n * @param target - the graphics target\n * @param att - the att\n */\n private graphicsAtt(target: GraphicsTarget, att: AttRec): void {\n if (att.name === \"z\" && \"z\" in target && att.children.length === 0) {\n target.z ??= att.value;\n return;\n }\n if (att.name === null) {\n this.report.warnOnce(\n \"validation-error\",\n XGMML_ISSUE.BAD_ATT,\n \"a graphics <att> without a name was skipped\",\n { line: att.line },\n `${XGMML_ISSUE.BAD_ATT}:graphics-name`,\n );\n return;\n }\n target.graphics = { ...(target.graphics ?? {}), [att.name]: attJson(att) };\n }\n}\n\n/**\n * Whether an att's children are list items rather than named fields: they have no names, repeat\n * the parent's name (Cytoscape 3 lists), or are several that share one name (2.x bend handles).\n * @param att - the att\n * @returns true for a list\n */\nexport function isListLike(att: AttRec): boolean {\n const names = new Set(att.children.map((c) => c.name));\n if (names.size !== 1) {\n return false;\n }\n const [only] = names;\n return only === null || only === att.name || att.children.length > 1;\n}\n\n/**\n * A graphics att as plain data, values as written: an att with children is an array when they\n * are list items (isListLike), else a record by name; a childless att is its value,\n * else its other XML attributes (a 2.x bend handle's x and y), else null.\n * @param att - the att\n * @returns the value\n */\nexport function attJson(att: AttRec): unknown {\n if (att.children.length === 0) {\n if (att.value !== null) {\n return att.value;\n }\n return Object.keys(att.extra).length > 0 ? { ...att.extra } : null;\n }\n if (isListLike(att)) {\n return att.children.map(attJson);\n }\n const out: Record<string, unknown> = {};\n for (const child of att.children) {\n out[child.name ?? \"\"] = attJson(child);\n }\n return out;\n}\n\n/**\n * The XML attributes of an element the parser does not read itself, without namespace\n * declarations.\n * @param attrs - the attributes\n * @param read - the names the parser reads\n * @returns the others, in document order\n */\nfunction otherAttributes(attrs: ReadonlyMap<string, string>, read: ReadonlySet<string>): [string, string][] {\n const out: [string, string][] = [];\n for (const [key, value] of attrs) {\n if (!read.has(key) && key !== \"xmlns\" && !key.startsWith(\"xmlns:\")) {\n out.push([key, value]);\n }\n }\n return out;\n}\n","/**\n * XGMML attribute types and values (`research-xgmml.md` sections 3.6, 3.8 and 4.3): which kind an\n * `<att>` declares (Cytoscape's `cy:type` before the draft's `type`, case-insensitively), and the\n * lexical rules of each kind as Cytoscape writes them. A value that does not parse is never\n * guessed at: the caller records E_BAD_VALUE and leaves the cell unset.\n */\n\nimport { type AttRec } from \"./document.js\";\n\n/** The scalar kinds of a column, in widening order (string beats everything). */\nexport type ScalarKind = \"bool\" | \"int\" | \"long\" | \"real\" | \"string\";\n\n/** What one att declares. */\ntype DeclaredKind = ScalarKind | \"list\" | \"map\";\n\n/** The declared kind of an att and the type text to keep in `origin.type`. */\ninterface AttType {\n /** The kind. */\n readonly kind: DeclaredKind;\n /** The type as declared (`cy:type` when given, else `type`), or null for an untyped att. */\n readonly declared: string | null;\n /** The type text no kind matched (kept as text, W_UNKNOWN_ATTR_TYPE), or null. */\n readonly unknown: string | null;\n}\n\n/** Cytoscape's `cy:type` names (3.3+), lower-cased. */\nconst CY_TYPES: Readonly<Record<string, DeclaredKind>> = {\n string: \"string\",\n double: \"real\",\n integer: \"int\",\n long: \"long\",\n boolean: \"bool\",\n list: \"list\",\n};\n\n/** The XGMML draft's types, Cytoscape's `boolean` and the 2.x `map`, lower-cased. */\nconst XGMML_TYPES: Readonly<Record<string, DeclaredKind>> = {\n string: \"string\",\n real: \"real\",\n integer: \"int\",\n boolean: \"bool\",\n list: \"list\",\n map: \"map\",\n};\n\n/**\n * The kind an att declares: `cy:type` first, then `type`, both case-insensitive; no type is a\n * string; an unknown type is a string the caller reports. An untyped-by-Cytoscape `integer` att\n * whose name ends in `.SUID` is a long (Cytoscape keeps SUID references as Long).\n * @param att - the att\n * @returns the declared kind\n */\nexport function attType(att: AttRec): AttType {\n let kind: DeclaredKind | undefined;\n let declared: string | null = null;\n if (att.cyType !== null && att.cyType.length > 0) {\n kind = CY_TYPES[att.cyType.trim().toLowerCase()];\n declared = att.cyType;\n }\n if (kind === undefined && att.type !== null && att.type.length > 0) {\n kind = XGMML_TYPES[att.type.trim().toLowerCase()];\n declared = att.type;\n }\n if (kind === undefined) {\n const unknown = declared ?? null;\n return { kind: \"string\", declared, unknown };\n }\n if (kind === \"int\" && att.cyType === null && att.name?.endsWith(\".SUID\") === true) {\n // pre-3.3 Cytoscape wrote its Long SUID references as \"integer\"; a real one stays real\n // (Cytoscape writes Double.toString forms such as \"21.0\", which no integer rule reads)\n kind = \"long\";\n }\n return { kind, declared, unknown: null };\n}\n\n/**\n * The scalar kind a list element type names (`cy:elementType`), or null when it names none.\n * @param text - the element type text\n * @returns the kind, or null\n */\nexport function elementKind(text: string | null): ScalarKind | null {\n if (text === null) {\n return null;\n }\n const kind = CY_TYPES[text.trim().toLowerCase()] ?? XGMML_TYPES[text.trim().toLowerCase()];\n return kind === undefined || kind === \"list\" || kind === \"map\" ? null : kind;\n}\n\n/**\n * The wider of two scalar kinds (design section 5.1): int and long widen to long, any two numbers\n * to real, a boolean and a number to string, anything and a string to string.\n * @param a - one kind\n * @param b - the other\n * @returns the kind both fit\n */\nexport function widenScalar(a: ScalarKind, b: ScalarKind): ScalarKind {\n if (a === b) {\n return a;\n }\n if (a === \"string\" || b === \"string\" || a === \"bool\" || b === \"bool\") {\n return \"string\";\n }\n if (a === \"real\" || b === \"real\") {\n return \"real\";\n }\n return \"long\";\n}\n\nconst INTEGER_TEXT = /^[+-]?[0-9]+$/;\n\n/** Java's Double.valueOf forms that Cytoscape writes: no hex, no `d` / `f` suffix. */\nconst REAL_TEXT = /^[+-]?(NaN|Infinity|([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE][+-]?[0-9]+)?)$/;\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/** A parsed scalar and what parsing it found. */\ninterface ParsedScalar {\n /** The value. */\n readonly value: boolean | number | string;\n /** An integer beyond i32 (the column widens), or a long / real beyond what a double holds exactly. */\n readonly overflow?: \"i32\" | \"precision\" | undefined;\n}\n\n/**\n * Parse one value text by its declared scalar kind. Numbers and booleans are trimmed; strings\n * never are. Booleans accept 1 / 0 / true / false / yes / no in any case.\n * @param text - the value text\n * @param kind - the declared kind\n * @param unescape - decode Cytoscape's two-character `\\n` and `\\t` in strings\n * @returns the value, or null when the text does not parse as the kind\n */\nexport function parseScalar(text: string, kind: ScalarKind, unescape: boolean): ParsedScalar | null {\n switch (kind) {\n case \"string\":\n return { value: unescape ? unescapeCytoscape(text) : text };\n case \"bool\": {\n const t = text.trim().toLowerCase();\n if (t === \"1\" || t === \"true\" || t === \"yes\") {\n return { value: true };\n }\n if (t === \"0\" || t === \"false\" || t === \"no\") {\n return { value: false };\n }\n return null;\n }\n case \"int\":\n case \"long\": {\n const t = text.trim();\n if (!INTEGER_TEXT.test(t)) {\n return null;\n }\n const n = Number(t);\n if (kind === \"int\" && (n < I32_MIN || n > I32_MAX)) {\n return { value: n, overflow: Number.isSafeInteger(n) ? \"i32\" : \"precision\" };\n }\n return { value: n, overflow: Number.isSafeInteger(n) ? undefined : \"precision\" };\n }\n case \"real\": {\n const t = text.trim();\n if (!REAL_TEXT.test(t)) {\n return null;\n }\n const n = Number(t);\n // only a finite spelling that overflows (1e400) loses precision; NaN and the infinities are exact\n const overflow = !Number.isFinite(n) && !/Infinity|NaN/.test(t) ? \"precision\" : undefined;\n return { value: n, overflow };\n }\n default: {\n const name: never = kind;\n throw new Error(`unknown scalar kind ${String(name)}`);\n }\n }\n}\n\n/**\n * Decode the two-character escapes the Cytoscape writer uses for newline and tab.\n * @param text - the text\n * @returns the text with `\\n` and `\\t` decoded\n */\nfunction unescapeCytoscape(text: string): string {\n return text.includes(\"\\\\\") ? text.replace(/\\\\t/g, \"\\t\").replace(/\\\\n/g, \"\\n\") : text;\n}\n","/**\n * The attribute columns of one XGMML (or `.cys`) import: every att and every untyped XML\n * attribute is parsed by its own declared kind when it is read, then each column's dtype is\n * decided once over all its values (design section 5.1 widening: int and long to f64, numbers\n * and booleans to string, lists and scalars to json), and only then declared on the sink, so a\n * column is never re-typed after rows were written and a caller's sink needs no widening call.\n */\n\nimport { type ColumnDecl, type Dtype, type GraphSink, type ScalarDtype } from \"@graphty/graph-format\";\n\nimport { declareResolved, DictHeuristic, uniqueColumnName } from \"../../common/attributes.js\";\nimport { type ImportReportBuilder, type IssueLocation } from \"../../common/report.js\";\nimport { inferTextDtype, parseTextCell } from \"../../common/text.js\";\nimport { CYTOSCAPE_ORIGIN_NAMESPACE, FORMAT, XGMML_ISSUE } from \"./constants.js\";\nimport { type AttRec, isListLike } from \"./document.js\";\nimport { attType, elementKind, parseScalar, type ScalarKind, widenScalar } from \"./values.js\";\n\n/** A table of the snapshot. */\ntype Domain = \"node\" | \"edge\" | \"graph\";\n\n/** One item of a list cell. */\ninterface Item {\n readonly value: boolean | number | string;\n readonly text: string;\n}\n\n/** One parsed value. */\ninterface Cell {\n /** The kind the value was parsed as. */\n readonly kind: ScalarKind | \"list\" | \"json\";\n /** A scalar's value, a json value, or null for a list. */\n readonly value: unknown;\n /** A scalar's text as written (what a column widened to string keeps). */\n readonly text: string;\n /** A list's items. */\n readonly items: readonly Item[];\n /** A list's item kind, or null for an empty list whose type nothing states. */\n readonly itemKind: ScalarKind | null;\n /** The kind came from a declared type (not the text grammar of an XML attribute). */\n readonly typed: boolean;\n}\n\n/** One column being collected. */\ninterface Plan {\n readonly name: string;\n readonly namespace: string | null;\n readonly cells: Map<number, Cell>;\n readonly declared: Set<string>;\n readonly lines: Map<number, number>;\n declaredType: string | null;\n hidden: boolean;\n equation: boolean;\n suid: boolean;\n overflow: boolean;\n precision: boolean;\n}\n\n/** Options of a column set. */\ninterface ColumnSetOptions {\n /** Decode Cytoscape's `\\n` / `\\t` escapes in string values. */\n readonly unescape: boolean;\n /** The importer's `long` option. */\n readonly long: \"f64\" | \"string\";\n /** The column names the importer's own columns hold; an att of one of these names is renamed. */\n readonly reserved: ReadonlySet<string>;\n}\n\n/** The dtype of each scalar kind. */\nconst DTYPES: Readonly<Record<ScalarKind, ScalarDtype>> = {\n bool: \"bool\",\n int: \"i32\",\n long: \"f64\",\n real: \"f64\",\n string: \"string\",\n};\n\n/**\n * Collects the attribute values of one table, then declares and writes the columns.\n */\nexport class ColumnSet {\n private readonly domain: Domain;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ColumnSetOptions;\n\n private readonly plans = new Map<string, Plan>();\n\n /**\n * Create a column set.\n * @param domain - the table\n * @param report - the report\n * @param options - the options\n */\n constructor(domain: Domain, report: ImportReportBuilder, options: ColumnSetOptions) {\n this.domain = domain;\n this.report = report;\n this.options = options;\n }\n\n /**\n * Whether a column of that name (any namespace) was collected.\n * @param name - the name\n * @returns true when some row has a value or the column was declared\n */\n has(name: string): boolean {\n return this.plans.has(key(null, name));\n }\n\n /**\n * Add one att of a row: parse it by its declared kind (E_BAD_VALUE for a value that does not\n * parse; the cell stays unset). A second value of the same column on one row wins with\n * W_DUPLICATE_ATTRIBUTE.\n * @param row - the row\n * @param att - the att\n * @param where - the element, for issues\n */\n addAtt(row: number, att: AttRec, where: IssueLocation): void {\n const { name } = att;\n if (name === null || name.length === 0) {\n this.badAtt(\"an <att> without a name was skipped\", att, \"name\");\n return;\n }\n const plan = this.plan(name, att.namespace ?? null);\n const type = attType(att);\n plan.hidden ||= att.hidden;\n plan.suid ||= name.endsWith(\".SUID\");\n if (type.declared !== null) {\n plan.declaredType ??= type.declared;\n }\n const at = { line: att.line, element: where.element ?? name };\n if (type.unknown !== null) {\n this.report.warnOnce(\n \"unsupported\",\n XGMML_ISSUE.UNKNOWN_ATTR_TYPE,\n `att type \"${type.unknown}\" of \"${name}\" is not an XGMML or Cytoscape type; its values are kept as text`,\n at,\n `${XGMML_ISSUE.UNKNOWN_ATTR_TYPE}:${this.domain}:${name}`,\n );\n }\n let cell: Cell | null;\n if (att.equation) {\n plan.equation = true;\n this.report.warnOnce(\n \"unsupported\",\n XGMML_ISSUE.EQUATION_AS_TEXT,\n `\"${name}\" holds Cytoscape formulas; each is kept as its text, never evaluated`,\n at,\n `${XGMML_ISSUE.EQUATION_AS_TEXT}:${this.domain}:${name}`,\n );\n cell = att.value === null ? null : scalarCell(\"string\", att.value, att.value, true);\n if (cell !== null) {\n plan.declared.add(\"string\");\n }\n } else if (type.kind === \"list\") {\n cell = this.listCell(att, name, plan, at);\n plan.declared.add(\"list\");\n } else if (type.kind === \"map\") {\n cell = jsonCell(recordOf(att));\n this.recordList(`\"${name}\" is a 2.x map; it is kept as a json record`, at);\n plan.declared.add(\"json\");\n } else {\n cell = this.scalarAtt(att, type.kind, plan, at);\n }\n if (cell !== null) {\n this.set(plan, row, cell, at);\n }\n }\n\n /**\n * Add one value read by the 5.1 text grammar (an XML attribute of an element).\n * @param row - the row\n * @param name - the column name\n * @param text - the text\n * @param where - the element, for issues\n */\n addText(row: number, name: string, text: string, where: IssueLocation): void {\n const plan = this.plan(name, null);\n const value = parseTextCell(text);\n const kind = textKind(inferTextDtype(text));\n this.set(plan, row, { kind, value, text, items: [], itemKind: null, typed: false }, where);\n }\n\n /**\n * Add one value of a known kind (a typed table cell of a session).\n * @param row - the row\n * @param name - the column name\n * @param value - the value\n * @param where - the element, for issues\n */\n addJson(row: number, name: string, value: unknown, where: IssueLocation): void {\n this.set(this.plan(name, null), row, jsonCell(value), where);\n }\n\n /**\n * Declare every collected column on the sink and write its values.\n * @param sink - the sink\n * @param rowIndex - the sink index of a row (node or edge index), or -1 when the row was not added\n */\n write(sink: GraphSink, rowIndex: (row: number) => number): void {\n const taken = new Set<string>(this.options.reserved);\n const ordered = [...this.plans.values()].sort(\n (a, b) => Number(a.namespace !== null) - Number(b.namespace !== null),\n );\n for (const plan of ordered) {\n let { name } = plan;\n if (taken.has(name)) {\n name = uniqueColumnName(plan.name, plan.namespace, (n) => taken.has(n));\n this.report.warning(\n \"coercion\",\n XGMML_ISSUE.COLUMN_RENAMED,\n `${this.domain} attribute \"${plan.name}\" renamed to \"${name}\": the name was taken`,\n { element: plan.name },\n );\n }\n taken.add(name);\n this.writePlan(sink, plan, name, rowIndex);\n }\n }\n\n // ------------------------------------------------------------------ cells\n\n /**\n * The plan of a column, created on first use.\n * @param name - the attribute name\n * @param namespace - the table namespace, or null\n * @returns the plan\n */\n private plan(name: string, namespace: string | null): Plan {\n const k = key(namespace, name);\n let plan = this.plans.get(k);\n if (plan === undefined) {\n plan = {\n name,\n namespace,\n cells: new Map(),\n declared: new Set(),\n lines: new Map(),\n declaredType: null,\n hidden: false,\n equation: false,\n suid: false,\n overflow: false,\n precision: false,\n };\n this.plans.set(k, plan);\n }\n return plan;\n }\n\n /**\n * Store a cell, reporting a second value on the same row.\n * @param plan - the column\n * @param row - the row\n * @param cell - the cell\n * @param where - the location\n */\n private set(plan: Plan, row: number, cell: Cell, where: IssueLocation): void {\n if (plan.cells.has(row)) {\n this.report.warning(\n \"validation-error\",\n XGMML_ISSUE.DUPLICATE_ATTRIBUTE,\n `\"${plan.name}\" is given twice on one ${this.domain}; the later value is kept`,\n { line: where.line ?? null, element: where.element ?? plan.name },\n );\n }\n plan.cells.set(row, cell);\n if (where.line !== undefined && where.line !== null) {\n plan.lines.set(row, where.line);\n }\n }\n\n /**\n * Parse a scalar att.\n * @param att - the att\n * @param kind - the declared kind\n * @param plan - the column\n * @param at - the location\n * @returns the cell, or null when unset or invalid\n */\n private scalarAtt(att: AttRec, kind: ScalarKind, plan: Plan, at: IssueLocation): Cell | null {\n if (att.children.length > 0) {\n this.badAtt(`the ${kind} att \"${att.name ?? \"\"}\" holds child atts; they are ignored`, att, \"children\");\n }\n if (att.xml !== null) {\n this.recordList(`\"${att.name ?? \"\"}\" holds foreign XML; it is kept as text in a json column`, at);\n plan.declared.add(\"json\");\n return jsonCell(att.xml);\n }\n if (att.value === null) {\n plan.declared.add(kind);\n return null;\n }\n const parsed = parseScalar(att.value, kind, this.options.unescape);\n if (parsed === null || (parsed.overflow !== undefined && kind === \"int\" && exactInteger(att.cyType))) {\n this.badValue(att.value, kind, at);\n return null;\n }\n plan.declared.add(kind);\n if (parsed.overflow === \"i32\") {\n plan.overflow = true;\n } else if (parsed.overflow === \"precision\") {\n plan.precision = true;\n plan.overflow ||= kind === \"int\";\n }\n return scalarCell(kind, parsed.value, att.value, true);\n }\n\n /**\n * Parse a list att: items by `cy:elementType`, else by the widened kinds of the children.\n * A list of lists, a list with records, or a list of named fields is a json value.\n * @param att - the att\n * @param name - the column name\n * @param plan - the column (an item beyond i32 widens it, as a scalar does)\n * @param at - the location\n * @returns the cell\n */\n private listCell(att: AttRec, name: string, plan: Plan, at: IssueLocation): Cell | null {\n if (att.value !== null) {\n this.badAtt(`the list att \"${name}\" has a value; it is ignored`, att, \"list-value\");\n }\n const { children } = att;\n const names = new Set(children.map((c) => c.name).filter((n): n is string => n !== null && n !== name));\n if (names.size > 1 || children.some((c) => c.children.length > 0 || c.xml !== null)) {\n this.recordList(`\"${name}\" is a record or a list of lists; it is kept as json`, at);\n return jsonCell(names.size > 1 ? recordOf(att) : children.map(jsonOfAtt));\n }\n let itemKind = elementKind(att.elementType);\n if (itemKind === null) {\n const kinds = new Set<ScalarKind>();\n for (const child of children) {\n const type = attType(child);\n const kind: ScalarKind = type.kind === \"list\" || type.kind === \"map\" ? \"string\" : type.kind;\n kinds.add(kind);\n itemKind = itemKind === null ? kind : widenScalar(itemKind, kind);\n }\n if (kinds.size > 1) {\n this.report.warnOnce(\n \"coercion\",\n XGMML_ISSUE.WIDENED,\n `the items of list \"${name}\" declare different types; they are read as ${itemKind ?? \"string\"}`,\n at,\n `${XGMML_ISSUE.WIDENED}:${this.domain}:${name}`,\n );\n }\n }\n const items: Item[] = [];\n for (const child of children) {\n if (child.value === null) {\n continue;\n }\n const parsed = parseScalar(child.value, itemKind ?? \"string\", this.options.unescape);\n const exact = exactInteger(att.elementType) || exactInteger(child.cyType);\n if (parsed === null || (parsed.overflow !== undefined && itemKind === \"int\" && exact)) {\n this.badValue(child.value, itemKind ?? \"string\", { line: child.line, element: at.element });\n continue;\n }\n if (parsed.overflow === \"i32\") {\n plan.overflow = true;\n } else if (parsed.overflow === \"precision\") {\n plan.precision = true;\n plan.overflow ||= itemKind === \"int\";\n }\n items.push({ value: parsed.value, text: child.value });\n }\n return { kind: \"list\", value: null, text: \"\", items, itemKind, typed: true };\n }\n\n // ------------------------------------------------------------------ decision and writing\n\n /**\n * Decide one column's dtype, declare it and write its values.\n * @param sink - the sink\n * @param plan - the column\n * @param name - the name to declare it under\n * @param rowIndex - the row to sink index map\n */\n private writePlan(sink: GraphSink, plan: Plan, name: string, rowIndex: (row: number) => number): void {\n const cells = [...plan.cells.values()];\n const decision = this.decide(plan, cells);\n const decl: ColumnDecl = {\n name,\n dtype: decision.dtype,\n nullable: true,\n origin: {\n format: FORMAT,\n id: null,\n title: name === plan.name ? null : plan.name,\n type: originType(plan, decision),\n namespace: plan.namespace ?? (plan.hidden ? CYTOSCAPE_ORIGIN_NAMESPACE : null),\n },\n };\n if (decision.itemDtype !== null) {\n decl.itemDtype = decision.itemDtype;\n }\n const extra: Record<string, unknown> = {};\n if (plan.hidden) {\n extra.hidden = true;\n }\n if (plan.suid) {\n extra.suidReference = true;\n }\n if (plan.equation) {\n extra.equation = true;\n }\n if (Object.keys(extra).length > 0) {\n decl.extra = extra;\n }\n const where = { element: name };\n if (this.domain === \"graph\") {\n const cell = plan.cells.get(0);\n try {\n sink.setGraphValue(name, cell === undefined ? undefined : convert(cell, decision), decl);\n } catch (err) {\n this.report.recordError(err, where);\n }\n return;\n }\n let handle;\n try {\n ({ handle } = declareResolved(sink, this.domain, decl, this.report, where));\n } catch (err) {\n this.report.recordError(err, where);\n return;\n }\n for (const [row, cell] of plan.cells) {\n const index = rowIndex(row);\n if (index < 0) {\n continue;\n }\n const value = convert(cell, decision);\n try {\n if (this.domain === \"node\") {\n sink.setNodeValue(handle, index, value);\n } else {\n sink.setEdgeValue(handle, index, value);\n }\n } catch (err) {\n this.report.recordError(err, { line: plan.lines.get(row) ?? null, element: name });\n }\n }\n }\n\n /**\n * The dtype of a column from its cells, with the widening and precision warnings.\n * @param plan - the column\n * @param cells - its cells\n * @returns the decision\n */\n private decide(plan: Plan, cells: readonly Cell[]): Decision {\n const where = { element: plan.name };\n const typedKinds = new Set(cells.filter((c) => c.typed).map((c) => c.kind));\n let widened = typedKinds.size > 1 || plan.declared.size > 1;\n let decision: Decision;\n if (\n cells.some((c) => c.kind === \"json\") ||\n (cells.some((c) => c.kind === \"list\") && cells.some((c) => c.kind !== \"list\"))\n ) {\n decision = { dtype: \"json\", itemDtype: null, scalar: null, item: null, long: false };\n } else if (cells.length > 0 && cells.every((c) => c.kind === \"list\")) {\n let item: ScalarKind | null = null;\n for (const cell of cells) {\n if (cell.itemKind !== null) {\n widened ||= item !== null && item !== cell.itemKind;\n item = item === null ? cell.itemKind : widenScalar(item, cell.itemKind);\n }\n }\n if (item === null) {\n this.report.warnOnce(\n \"coercion\",\n XGMML_ISSUE.EMPTY_LIST_TYPE,\n `list \"${plan.name}\" has no element type and no items; it is a list of strings`,\n where,\n `${XGMML_ISSUE.EMPTY_LIST_TYPE}:${this.domain}:${plan.name}`,\n );\n item = \"string\";\n }\n if (plan.overflow && item === \"int\") {\n item = \"real\";\n widened = true;\n }\n decision = { dtype: \"list\", itemDtype: DTYPES[item], scalar: null, item, long: item === \"long\" };\n } else {\n decision = this.decideScalar(plan, cells);\n widened ||= plan.overflow && decision.scalar === \"real\" && plan.declared.has(\"int\");\n }\n if (widened) {\n this.report.warnOnce(\n \"coercion\",\n XGMML_ISSUE.WIDENED,\n `${this.domain} column \"${plan.name}\" was widened to ${decision.dtype}: its values or declared types disagree`,\n where,\n `${XGMML_ISSUE.WIDENED}:${this.domain}:${plan.name}`,\n );\n }\n if (plan.precision) {\n this.report.warnOnce(\n \"precision\",\n XGMML_ISSUE.PRECISION,\n `values of \"${plan.name}\" beyond what a double holds exactly are stored as the nearest double (or infinity)`,\n where,\n `${XGMML_ISSUE.PRECISION}:${this.domain}:${plan.name}`,\n );\n }\n return decision;\n }\n\n /**\n * The scalar decision of a column.\n * @param plan - the column\n * @param cells - its cells\n * @returns the decision\n */\n private decideScalar(plan: Plan, cells: readonly Cell[]): Decision {\n let scalar: ScalarKind | null = null;\n for (const cell of cells) {\n const kind = cell.kind as ScalarKind;\n scalar = scalar === null ? kind : widenScalar(scalar, kind);\n }\n if (scalar === null) {\n const declared = [...plan.declared].find((k): k is ScalarKind => k in DTYPES);\n scalar = declared ?? \"string\";\n }\n if (scalar === \"int\" && plan.overflow) {\n scalar = \"real\";\n }\n const long = scalar === \"long\";\n if (long && this.options.long === \"string\") {\n return { dtype: \"string\", itemDtype: null, scalar: \"string\", item: null, long: true };\n }\n let dtype: Dtype = DTYPES[scalar];\n if (scalar === \"string\") {\n const heuristic = new DictHeuristic();\n for (const cell of cells) {\n if (heuristic.observe(cell.text)) {\n break;\n }\n }\n dtype = heuristic.decide();\n }\n return { dtype, itemDtype: null, scalar, item: null, long };\n }\n\n /**\n * Report a malformed att, once per kind of defect.\n * @param message - the message\n * @param att - the att\n * @param kind - the defect, for the once key\n */\n private badAtt(message: string, att: AttRec, kind: string): void {\n this.report.warnOnce(\n \"parse-error\",\n XGMML_ISSUE.BAD_ATT,\n message,\n { line: att.line, element: att.name },\n `${XGMML_ISSUE.BAD_ATT}:${kind}`,\n );\n }\n\n /**\n * Report a value that does not parse as its declared kind (an error; the cell stays unset).\n * @param text - the value\n * @param kind - the kind\n * @param at - the location\n */\n private badValue(text: string, kind: ScalarKind, at: IssueLocation): void {\n this.report.error(\n \"validation-error\",\n XGMML_ISSUE.BAD_VALUE,\n `value ${JSON.stringify(text)} is not a valid ${KIND_NAMES[kind]}; the cell is left unset`,\n at,\n );\n }\n\n /**\n * Report a record list, list of lists, map or foreign XML kept as json, once.\n * @param message - the message\n * @param at - the location\n */\n private recordList(message: string, at: IssueLocation): void {\n this.report.warnOnce(\"coercion\", XGMML_ISSUE.RECORD_LIST, message, at);\n }\n}\n\n/**\n * Whether a Cytoscape type names Java's Integer exactly (`cy:type=\"Integer\"`, a CyCSV\n * `java.lang.Integer` column): a value beyond i32 is then not an Integer at all (Cytoscape cannot\n * write one), where the XGMML `integer` of pre-3.3 Cytoscape also carried Longs and widens.\n * @param cyType - the Cytoscape type, or null\n * @returns true for Integer\n */\nfunction exactInteger(cyType: string | null): boolean {\n return cyType?.trim().toLowerCase() === \"integer\";\n}\n\n/** A column's decided storage. */\ninterface Decision {\n readonly dtype: Dtype;\n readonly itemDtype: ScalarDtype | null;\n readonly scalar: ScalarKind | null;\n readonly item: ScalarKind | null;\n /** The column is a declared long (origin.type \"long\"). */\n readonly long: boolean;\n}\n\n/**\n * The `origin.type` of a column: \"equation\" for formulas, \"long\" for a declared long, else the\n * declared type text.\n * @param plan - the column\n * @param decision - its decision\n * @returns the type text, or null\n */\nfunction originType(plan: Plan, decision: Decision): string | null {\n if (plan.equation) {\n return \"equation\";\n }\n return decision.long ? \"long\" : plan.declaredType;\n}\n\n/** How a kind is named in messages. */\nconst KIND_NAMES: Readonly<Record<ScalarKind, string>> = {\n bool: \"boolean (1, 0, true, false, yes, no)\",\n int: \"integer\",\n long: \"long integer\",\n real: \"real number\",\n string: \"string\",\n};\n\n/**\n * The plans key of a column.\n * @param namespace - the namespace, or null\n * @param name - the name\n * @returns the key\n */\nfunction key(namespace: string | null, name: string): string {\n return namespace === null ? name : `${namespace}\\u0000${name}`;\n}\n\n/**\n * The scalar kind of a text grammar dtype.\n * @param dtype - the dtype\n * @returns the kind\n */\nfunction textKind(dtype: \"bool\" | \"i32\" | \"f64\" | \"string\"): ScalarKind {\n switch (dtype) {\n case \"bool\":\n return \"bool\";\n case \"i32\":\n return \"int\";\n case \"f64\":\n return \"real\";\n default:\n return \"string\";\n }\n}\n\n/**\n * A scalar cell.\n * @param kind - its kind\n * @param value - its value\n * @param text - its text as written\n * @param typed - whether a declared type gave the kind\n * @returns the cell\n */\nfunction scalarCell(kind: ScalarKind, value: unknown, text: string, typed: boolean): Cell {\n return { kind, value, text, items: [], itemKind: null, typed };\n}\n\n/**\n * A json cell.\n * @param value - the value\n * @returns the cell\n */\nfunction jsonCell(value: unknown): Cell {\n return { kind: \"json\", value, text: JSON.stringify(value), items: [], itemKind: null, typed: true };\n}\n\n/**\n * An att with named children as a record of name to value.\n * @param att - the att\n * @returns the record\n */\nfunction recordOf(att: AttRec): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const child of att.children) {\n out[child.name ?? \"\"] = jsonOfAtt(child);\n }\n return out;\n}\n\n/**\n * An att as a json value: its value text, its children as an array or a record, or its XML.\n * @param att - the att\n * @returns the value\n */\nfunction jsonOfAtt(att: AttRec): unknown {\n if (att.xml !== null) {\n return att.xml;\n }\n if (att.children.length === 0) {\n return att.value;\n }\n return isListLike(att) ? att.children.map(jsonOfAtt) : recordOf(att);\n}\n\n/**\n * A cell as the value its column's dtype stores.\n * @param cell - the cell\n * @param decision - the column's decision\n * @returns the value\n */\nfunction convert(cell: Cell, decision: Decision): unknown {\n if (decision.dtype === \"json\") {\n if (cell.kind === \"json\") {\n return cell.value;\n }\n return cell.kind === \"list\" ? cell.items.map((i) => i.value) : cell.value;\n }\n if (decision.dtype === \"list\") {\n return cell.items.map((item) => convertScalar(item.value, item.text, decision.item ?? \"string\"));\n }\n return convertScalar(\n cell.value,\n cell.text,\n decision.long && decision.dtype === \"string\" ? \"string\" : (decision.scalar ?? \"string\"),\n );\n}\n\n/**\n * A scalar as the kind its column stores.\n * @param value - the parsed value\n * @param text - its text as written\n * @param kind - the column's kind\n * @returns the value\n */\nfunction convertScalar(value: unknown, text: string, kind: ScalarKind): unknown {\n switch (kind) {\n case \"bool\":\n return value;\n case \"int\":\n case \"long\":\n case \"real\":\n return Number(value);\n default:\n return typeof value === \"string\" ? value : text;\n }\n}\n","/**\n * Resolving a parsed XGMML document (document.ts) into a sink: which nodes and edges a graph\n * holds, their ids, endpoints, direction, weights, containment, positions, graphics and attribute\n * columns. The `.cys` importer calls the same code with the session's tables and views merged into\n * the records first, so both readers share every rule.\n */\n\nimport { type ColumnDecl, type ColumnHandle, type GraphSink, INVALID_INDEX, type NodeId } from \"@graphty/graph-format\";\n\nimport { declareResolved } from \"../../common/attributes.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { throwIfAborted } from \"../../common/input.js\";\nimport { type ResolvedImportOptions } from \"../../common/options.js\";\nimport { type ImportReportBuilder, type IssueLocation } from \"../../common/report.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport { ColumnSet } from \"./columns.js\";\nimport {\n CYTOSCAPE_ORIGIN_NAMESPACE,\n EDGE_ID_COLUMN,\n FORMAT,\n GRAPHICS_COLUMN,\n INTERACTION_COLUMN,\n LABEL_COLUMN,\n META_KEY,\n NESTED_NETWORK_COLUMN,\n NETWORK_POINTER_COLUMN,\n NETWORKS_COLUMN,\n PARENT_COLUMN,\n PARENTS_COLUMN,\n POSITION_COLUMN,\n SUBGRAPH_COLUMN,\n XGMML_ISSUE,\n XGMML_ORIGIN_NAMESPACE,\n Z_COLUMN,\n} from \"./constants.js\";\nimport {\n attJson,\n type AttRec,\n type EdgeRec,\n type GraphRec,\n isCyTrue,\n type NodeRec,\n type XgmmlDocument,\n} from \"./document.js\";\n\n/** The XGMML-specific options, resolved. */\nexport interface XgmmlSettings {\n /** Resolve missing or unknown endpoints through `\"a (pp) b\"` edge labels. */\n readonly labelAliases: boolean;\n /** Decode Cytoscape's `\\n` / `\\t` in strings. */\n readonly cytoscapeEscapes: boolean;\n /** Where Cytoscape's z goes. */\n readonly zAs: \"column\" | \"position\";\n}\n\n/** What a session adds to the document's own rules. */\nexport interface EmitExtras {\n /** Ids of nodes the session's group bookkeeping lists as groups. */\n readonly groupNodes?: ReadonlySet<string> | undefined;\n /** The network name a cross-file pointer (`file.xgmml#id`) names, or null when unknown. */\n readonly resolvePointer?: ((href: string) => string | null) | undefined;\n /** Graph-level attributes and the graph name come from elsewhere: skip the graph's own. */\n readonly graphName?: string | null | undefined;\n /** Extra json graph columns. */\n readonly graphJson?: Readonly<Record<string, unknown>> | undefined;\n /** Extra entries of `meta.extra`. */\n readonly metaExtra?: Readonly<Record<string, unknown>> | undefined;\n /** The format name the report and metadata carry (\"cys\"). */\n readonly sourceFormat?: string | undefined;\n /** Prefix of every issue message (the session entry name). */\n readonly entry?: string | undefined;\n /**\n * A group member that is not in the graph being read (a collapsed group's member in a\n * session): the session records it instead of E_UNKNOWN_PARENT.\n */\n readonly onMissingMember?: ((group: string, member: string) => void) | undefined;\n}\n\n/** The dialect facts the rules depend on. */\nexport interface Dialect {\n /** The documentVersion as written, or null. */\n readonly versionText: string | null;\n /** The parsed version, or 0 when absent or unparseable. */\n readonly version: number;\n /** Cytoscape wrote the file (the `cy` namespace is in use). */\n readonly cytoscape: boolean;\n /** A Cytoscape 2.x document (Cytoscape dialect with a version below 3). */\n readonly cy2: boolean;\n /** The 3.x session network dialect (root `cy:registered=\"0\"` with registered subnetworks). */\n readonly session: boolean;\n /** A session view document (root `cy:view=\"1\"`). */\n readonly view: boolean;\n}\n\n/** The graph atts that are document metadata, not columns. */\nconst META_ATTS: ReadonlySet<string> = new Set([\"documentVersion\", \"networkMetadata\"]);\n\n/** The root XML attributes that are structure, not graph columns. */\nconst GRAPH_STRUCTURE: ReadonlySet<string> = new Set([\n \"id\",\n \"label\",\n \"directed\",\n \"xlink:href\",\n \"cy:documentVersion\",\n \"cy:view\",\n \"cy:registered\",\n \"cy:networkId\",\n \"cy:visualStyle\",\n \"cy:rendererId\",\n]);\n\n/** Elements between two checks of the cancellation signal. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** Cytoscape's label alias shape: `source (interaction) target`. */\nconst ALIAS_SPLIT = /[()]/;\n\n/**\n * The dialect of a document (`research-xgmml.md` section 2).\n * @param doc - the document\n * @param report - the report the unparseable-version warning goes to\n * @returns the dialect\n */\nexport function dialectOf(doc: XgmmlDocument, report: ImportReportBuilder): Dialect {\n const { root } = doc;\n let versionText = root.attrs.get(\"cy:documentVersion\") ?? null;\n for (const att of root.atts) {\n if (att.name === \"documentVersion\" && att.value !== null) {\n versionText ??= att.value;\n }\n }\n let version = 0;\n if (versionText !== null) {\n version = Number(versionText.trim());\n if (!Number.isFinite(version) || versionText.trim().length === 0) {\n report.warning(\n \"validation-error\",\n XGMML_ISSUE.DOCUMENT_VERSION,\n `documentVersion \"${versionText}\" does not parse; the dialect is chosen from the content`,\n { line: root.line },\n );\n version = 0;\n }\n }\n const registered = root.subgraphs.some((g) => isCyTrue(g.registered));\n return {\n versionText,\n version,\n cytoscape: doc.cytoscape,\n cy2: doc.cytoscape && version < 3,\n session: root.registered !== null && !isCyTrue(root.registered) && registered,\n view: isCyTrue(root.attrs.get(\"cy:view\")),\n };\n}\n\n/**\n * The graphs a document offers: the registered subnetworks of a session network document, else\n * the root.\n * @param doc - the document\n * @param dialect - its dialect\n * @returns the graphs, in document order\n */\nexport function graphsOf(doc: XgmmlDocument, dialect: Dialect): GraphRec[] {\n return dialect.session ? doc.root.subgraphs.filter((g) => isCyTrue(g.registered)) : [doc.root];\n}\n\n/**\n * The id a `#id` reference names, or null for a cross-file or malformed reference.\n * @param href - the xlink:href text\n * @returns the id\n */\nfunction localRef(href: string): string | null {\n return href.startsWith(\"#\") ? href.slice(1) : null;\n}\n\n/**\n * The nodes and edges a graph holds: its direct members, references resolved.\n * @param doc - the document\n * @param graph - the graph (a registered subnetwork), or null for the whole document\n * @returns the declared node and edge records it holds, references resolved, in order\n */\nexport function membersOf(\n doc: XgmmlDocument,\n graph: GraphRec | null,\n): { readonly nodes: NodeRec[]; readonly edges: EdgeRec[]; readonly dangling: number } {\n if (graph === null) {\n return { nodes: doc.nodes, edges: doc.edges, dangling: 0 };\n }\n const nodeById = indexById(doc.nodes);\n const edgeById = indexById(doc.edges);\n const nodes: NodeRec[] = [];\n const edges: EdgeRec[] = [];\n let dangling = 0;\n for (const member of graph.members) {\n if (member.href === null) {\n if (member.kind === \"node\") {\n nodes.push(member);\n } else {\n edges.push(member);\n }\n continue;\n }\n const id = localRef(member.href);\n let target: NodeRec | EdgeRec | undefined;\n if (id !== null) {\n target = member.kind === \"node\" ? nodeById.get(id) : edgeById.get(id);\n }\n if (target === undefined) {\n dangling++;\n } else if (target.kind === \"node\") {\n nodes.push(target);\n } else {\n edges.push(target);\n }\n }\n return { nodes, edges, dangling };\n}\n\n/**\n * The first declaration of each id.\n * @param records - node or edge records\n * @returns id to record\n */\nfunction indexById<T extends NodeRec | EdgeRec>(records: readonly T[]): Map<string, T> {\n const out = new Map<string, T>();\n for (const record of records) {\n if (record.id !== null && !out.has(record.id)) {\n out.set(record.id, record);\n }\n }\n return out;\n}\n\n/** Per-node state while emitting. */\ninterface NodeRow {\n readonly id: string;\n readonly records: NodeRec[];\n index: number;\n readonly row: number;\n}\n\n/**\n * Pushes one graph of a document into a sink.\n */\nexport class XgmmlEmitter {\n private readonly doc: XgmmlDocument;\n\n private readonly dialect: Dialect;\n\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly settings: XgmmlSettings;\n\n private readonly extras: EmitExtras;\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly nodeColumns: ColumnSet;\n\n private readonly edgeColumns: ColumnSet;\n\n private readonly graphColumns: ColumnSet;\n\n private readonly rows = new Map<string, NodeRow>();\n\n private readonly rowList: NodeRow[] = [];\n\n private readonly edgeIndex: number[] = [];\n\n private sinceCheck = 0;\n\n private aliasResolved = 0;\n\n private aliasInteractions = 0;\n\n private weighted = false;\n\n /**\n * Create an emitter for one graph.\n * @param doc - the document\n * @param dialect - its dialect\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param settings - the XGMML options\n * @param extras - what a session adds\n */\n constructor(\n doc: XgmmlDocument,\n dialect: Dialect,\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n settings: XgmmlSettings,\n extras: EmitExtras = {},\n ) {\n this.doc = doc;\n this.dialect = dialect;\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.settings = settings;\n this.extras = extras;\n this.coercer = new IdCoercer(options.ids);\n this.direction = new DirectionResolver(sink, report, options.onMixedDirection);\n const base = { unescape: settings.cytoscapeEscapes, long: options.long };\n this.nodeColumns = new ColumnSet(\"node\", report, {\n ...base,\n reserved: new Set([\n LABEL_COLUMN,\n POSITION_COLUMN,\n Z_COLUMN,\n GRAPHICS_COLUMN,\n PARENT_COLUMN,\n PARENTS_COLUMN,\n SUBGRAPH_COLUMN,\n NESTED_NETWORK_COLUMN,\n NETWORK_POINTER_COLUMN,\n NETWORKS_COLUMN,\n ]),\n });\n this.edgeColumns = new ColumnSet(\"edge\", report, {\n ...base,\n reserved: new Set([EDGE_ID_COLUMN, LABEL_COLUMN, GRAPHICS_COLUMN]),\n });\n this.graphColumns = new ColumnSet(\"graph\", report, { ...base, reserved: new Set([GRAPHICS_COLUMN]) });\n }\n\n /**\n * Push the graph: nodes, containment, positions, edges, columns, metadata.\n * @param graph - the subnetwork, or null for the whole document\n */\n emit(graph: GraphRec | null): void {\n const members = membersOf(this.doc, graph);\n if (members.dangling > 0) {\n this.report.warning(\n \"validation-error\",\n XGMML_ISSUE.DANGLING_REFERENCE,\n `${this.prefix()}${members.dangling} xlink:href member reference(s) name no node or edge of the document`,\n { line: graph?.line ?? null },\n );\n }\n const header = this.headerDirected();\n this.direction.setHeader(this.sinkDirection(members.edges, header), { line: this.doc.root.line });\n this.addNodes(members.nodes);\n if (graph === null) {\n this.checkReferences();\n }\n const containment = new Containment(this);\n containment.resolve(this.rowList, this.groupTest());\n this.writeNodeExtras(graph);\n this.addEdges(members.edges, header);\n this.finishAliases();\n this.writeGraph(graph);\n const nodeIndex = (row: number): number => this.rowList[row].index;\n this.nodeColumns.write(this.sink, nodeIndex);\n this.edgeColumns.write(this.sink, (row) => this.edgeIndex[row] ?? -1);\n containment.write();\n this.writeMeta(graph);\n throwIfAborted(this.options.signal);\n }\n\n // ------------------------------------------------------------------ shared helpers (also used by Containment)\n\n /**\n * The sink.\n * @returns the sink\n */\n get target(): GraphSink {\n return this.sink;\n }\n\n /**\n * The report.\n * @returns the report\n */\n get issues(): ImportReportBuilder {\n return this.report;\n }\n\n /**\n * The row of a node id in this graph.\n * @param id - the id text\n * @returns the row, or undefined\n */\n rowOf(id: string): NodeRow | undefined {\n return this.rows.get(id);\n }\n\n /**\n * The network name a cross-file pointer names, when a session can tell.\n * @param href - the pointer\n * @returns the name, or null\n */\n resolvePointer(href: string): string | null {\n return this.extras.resolvePointer?.(href) ?? null;\n }\n\n /**\n * Hand a group member the graph does not hold to the session, when one is reading.\n * @param group - the group node's id\n * @param member - the member's id\n * @returns true when the session took it\n */\n missingMember(group: string, member: string): boolean {\n if (this.extras.onMissingMember === undefined) {\n return false;\n }\n this.extras.onMissingMember(group, member);\n return true;\n }\n\n /**\n * The first graph of the document with an id.\n * @param id - the id\n * @returns the graph, or undefined\n */\n graphById(id: string): GraphRec | undefined {\n return this.doc.graphs.find((g) => g.id === id);\n }\n\n /**\n * The prefix of every message (the session entry), or \"\".\n * @returns the prefix\n */\n prefix(): string {\n return this.extras.entry === undefined ? \"\" : `${this.extras.entry}: `;\n }\n\n /**\n * Check the cancellation signal every few dozen elements.\n */\n checkAbort(): void {\n if (++this.sinceCheck >= ABORT_CHECK_INTERVAL) {\n this.sinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * Declare a column the importer owns on first use (the 5.6 rename rule applies).\n * @param domain - node or edge\n * @param decl - the declaration\n * @returns the handle, or null when the sink refused it (recorded)\n */\n declare(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle | null {\n try {\n return declareResolved(this.sink, domain, decl, this.report, { element: decl.name }).handle;\n } catch (err) {\n this.report.recordError(err, { element: decl.name });\n return null;\n }\n }\n\n // ------------------------------------------------------------------ nodes\n\n /**\n * The header direction: the root's `directed` (0 by the DTD), else the defaultDirected option.\n * @returns whether the graph is directed by default\n */\n private headerDirected(): boolean {\n const text = this.doc.root.attrs.get(\"directed\");\n if (text === undefined) {\n return this.options.defaultDirected;\n }\n return this.flag(text, this.options.defaultDirected, { line: this.doc.root.line, element: \"directed\" });\n }\n\n /** The direction of each edge, decided once (its warning is recorded once). */\n private readonly directions = new Map<EdgeRec, boolean>();\n\n /**\n * The direction of one edge: its cy:directed, else the header.\n * @param record - the edge\n * @param header - the header direction\n * @returns whether the edge is directed\n */\n private edgeDirection(record: EdgeRec, header: boolean): boolean {\n let directed = this.directions.get(record);\n if (directed === undefined) {\n directed =\n record.directed === null\n ? header\n : this.flag(record.directed, header, { line: record.line, element: record.id ?? record.label });\n this.directions.set(record, directed);\n }\n return directed;\n }\n\n /**\n * The direction the sink starts with: the one every edge has when they all agree (a\n * Cytoscape file writes cy:directed on every edge and may omit the root attribute), else the\n * header, so a graph of one direction is never expanded into a mixed one.\n * @param edges - the edges of the graph\n * @param header - the header direction\n * @returns the sink direction\n */\n private sinkDirection(edges: readonly EdgeRec[], header: boolean): boolean {\n let first: boolean | null = null;\n for (const edge of edges) {\n const directed = this.edgeDirection(edge, header);\n if (first === null) {\n first = directed;\n } else if (first !== directed) {\n return header;\n }\n }\n return first ?? header;\n }\n\n /**\n * A 0 / 1 direction flag: true, false, yes and no are accepted with a warning; anything else\n * falls back.\n * @param text - the text\n * @param fallback - the direction for an unreadable value\n * @param where - the location\n * @returns the direction\n */\n private flag(text: string, fallback: boolean, where: IssueLocation): boolean {\n const t = text.trim();\n if (t === \"1\" || t === \"0\") {\n return t === \"1\";\n }\n const lower = t.toLowerCase();\n const readable = lower === \"true\" || lower === \"yes\" || lower === \"false\" || lower === \"no\";\n this.report.warnOnce(\n \"validation-error\",\n XGMML_ISSUE.BAD_DIRECTED,\n readable\n ? `${this.prefix()}directed=\"${text}\" is not 0 or 1; read as ${lower === \"true\" || lower === \"yes\" ? \"1\" : \"0\"}`\n : `${this.prefix()}directed=\"${text}\" is not 0 or 1; read as ${fallback ? \"directed\" : \"undirected\"}`,\n where,\n `${XGMML_ISSUE.BAD_DIRECTED}:${text}`,\n );\n return readable ? lower === \"true\" || lower === \"yes\" : fallback;\n }\n\n /**\n * Add every node record to the sink (one node per id; later declarations merge).\n * @param records - the node records\n */\n private addNodes(records: readonly NodeRec[]): void {\n for (const record of records) {\n const { id } = record;\n if (id === null) {\n continue;\n }\n const existing = this.rows.get(id);\n if (existing !== undefined) {\n existing.records.push(record);\n this.report.warning(\n \"validation-error\",\n XGMML_ISSUE.DUPLICATE_NODE,\n `${this.prefix()}node \"${id}\" is declared twice; the declarations are merged`,\n { line: record.line, element: id },\n );\n continue;\n }\n // -1 (not INVALID_INDEX, which is positive) marks a node the sink refused\n const row: NodeRow = { id, records: [record], index: -1, row: this.rowList.length };\n try {\n row.index = this.sink.addNode(this.nodeId(id, record.line));\n this.report.counts.nodes++;\n } catch (err) {\n this.report.counts.skippedNodes++;\n this.report.recordError(err, { line: record.line, element: id });\n }\n this.rows.set(id, row);\n this.rowList.push(row);\n this.checkAbort();\n }\n }\n\n /**\n * The coerced id of a node text.\n * @param text - the id text\n * @param line - the line\n * @returns the id\n */\n private nodeId(text: string, line: number): NodeId {\n const id = this.coercer.text(text);\n const merge = this.coercer.lastMerge;\n if (merge !== null) {\n this.report.warning(\n \"coercion\",\n XGMML_ISSUE.ID_MERGED,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n }\n\n /**\n * Whether a node's nested graph is a group (containment) rather than a nested-network\n * pointer: any graph in the 1.0 draft dialect, a 2.x node with `__groupState`, a 3.x node with\n * `__isGroup` true, or a node the session lists.\n * @returns the test\n */\n private groupTest(): (node: NodeRec) => boolean {\n const { groupNodes } = this.extras;\n const { cytoscape } = this.dialect;\n return (node: NodeRec): boolean => {\n if (!cytoscape) {\n return true;\n }\n if (node.id !== null && groupNodes?.has(node.id) === true) {\n return true;\n }\n return node.atts.some((a) => a.name === \"__groupState\" || (a.name === \"__isGroup\" && isCyTrue(a.value)));\n };\n }\n\n /**\n * W_DANGLING_REFERENCE for the `xlink:href` members of a generic document's non-group graphs\n * that name no node or edge (a group's are E_UNKNOWN_PARENT, reported by the containment).\n */\n private checkReferences(): void {\n const isGroup = this.groupTest();\n const edgeIds = new Set(this.doc.edges.map((e) => e.id));\n let dangling = 0;\n for (const graph of this.doc.graphs) {\n if (graph.owner !== null && isGroup(graph.owner)) {\n continue;\n }\n for (const member of graph.members) {\n if (member.href === null) {\n continue;\n }\n const id = localRef(member.href);\n const known = id !== null && (member.kind === \"node\" ? this.rows.has(id) : edgeIds.has(id));\n if (!known) {\n dangling++;\n }\n }\n }\n if (dangling > 0) {\n this.report.warning(\n \"validation-error\",\n XGMML_ISSUE.DANGLING_REFERENCE,\n `${this.prefix()}${dangling} xlink:href reference(s) name no node or edge of the document`,\n );\n }\n }\n\n /**\n * Write the per-node values: label, attributes, XML attributes, graphics, positions, nested\n * network pointers and subgraph memberships.\n * @param graph - the subnetwork, or null\n */\n private writeNodeExtras(graph: GraphRec | null): void {\n const labels: (string | undefined)[] = [];\n const positions = new Positions(this, this.dialect.cytoscape ? this.settings.zAs : \"position\");\n const graphics = new JsonColumn(this, \"node\", GRAPHICS_COLUMN, XGMML_ORIGIN_NAMESPACE, \"graphics\");\n const pointers = new Pointers(this, this.groupTest());\n for (const row of this.rowList) {\n const where = { line: row.records[0].line, element: row.id };\n const seen = new Set<string>();\n for (const record of row.records) {\n labels[row.row] ??= record.label ?? undefined;\n this.addElementColumns(this.nodeColumns, row.row, record, seen, where);\n positions.add(row, record);\n if (record.graphics !== null && Object.keys(record.graphics).length > 0) {\n graphics.set(row.index, record.graphics);\n }\n pointers.add(row, record);\n }\n this.checkAbort();\n }\n this.writeLabels(\"node\", labels, (row) => this.rowList[row].index);\n positions.write();\n pointers.write();\n if (graph === null) {\n this.writeNetworks();\n }\n }\n\n /**\n * Add an element's XML attributes (text grammar) and atts to a column set; atts of a later\n * duplicate declaration only fill names the earlier ones left unset.\n * @param columns - the column set\n * @param row - the row\n * @param record - the node or edge\n * @param seen - the names set by earlier declarations of the same node\n * @param where - the location\n */\n private addElementColumns(\n columns: ColumnSet,\n row: number,\n record: NodeRec | EdgeRec,\n seen: Set<string>,\n where: IssueLocation,\n ): void {\n const merging = seen.size > 0;\n const names = new Set<string>();\n if (record.name !== null) {\n if (!(merging && seen.has(\"name\"))) {\n columns.addText(row, \"name\", record.name, where);\n }\n names.add(\"name\");\n }\n for (const [key, value] of record.xmlAttrs) {\n if (!(merging && seen.has(key))) {\n columns.addText(row, key, value, where);\n }\n names.add(key);\n }\n for (const att of record.atts) {\n if (this.skipAtt(record, att) || (merging && att.name !== null && seen.has(att.name))) {\n continue;\n }\n if (record.kind === \"node\" && att.name === \"__isGroup\" && record.nested.length > 0 && isCyTrue(att.value)) {\n // the group is the containment itself (parent / parents and xgmml.subgraph)\n continue;\n }\n if (att.hasGraph && att.name === null) {\n continue;\n }\n columns.addAtt(row, att, where);\n if (att.name !== null) {\n names.add(att.name);\n }\n }\n for (const name of names) {\n seen.add(name);\n }\n }\n\n /**\n * Whether an att is not a column: an edge's weight att under weightFrom.\n * @param record - the element\n * @param att - the att\n * @returns true to skip it\n */\n private skipAtt(record: NodeRec | EdgeRec, att: AttRec): boolean {\n return record.kind === \"edge\" && record.weight === null && att.name === this.options.weightFrom;\n }\n\n /**\n * Write a label column (role label).\n * @param domain - node or edge\n * @param labels - the label of each row\n * @param index - the sink index of a row\n */\n private writeLabels(\n domain: \"node\" | \"edge\",\n labels: readonly (string | undefined)[],\n index: (row: number) => number,\n ): void {\n if (!labels.some((l) => l !== undefined)) {\n return;\n }\n const handle = this.declare(domain, {\n name: LABEL_COLUMN,\n dtype: \"string\",\n role: \"label\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"label\", namespace: null },\n });\n if (handle === null) {\n return;\n }\n labels.forEach((label, row) => {\n const i = index(row);\n if (label !== undefined && i >= 0) {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, i, label);\n } else {\n this.sink.setEdgeValue(handle, i, label);\n }\n }\n });\n }\n\n /** The `xgmml.networks` membership of nodes in root-level subgraphs of a generic document. */\n private writeNetworks(): void {\n const { subgraphs } = this.doc.root;\n if (subgraphs.length === 0) {\n return;\n }\n const member = new Map<number, string[]>();\n for (const graph of subgraphs) {\n const name = graph.id ?? graph.label ?? \"\";\n for (const m of graph.members) {\n const id = m.kind === \"node\" ? (m.id ?? (m.href === null ? null : localRef(m.href))) : null;\n const row = id === null ? undefined : this.rows.get(id);\n if (row !== undefined && row.index >= 0) {\n const list = member.get(row.index) ?? [];\n list.push(name);\n member.set(row.index, list);\n }\n }\n }\n if (member.size === 0) {\n return;\n }\n const handle = this.declare(\"node\", {\n name: NETWORKS_COLUMN,\n dtype: \"list\",\n itemDtype: \"string\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"graph\", namespace: XGMML_ORIGIN_NAMESPACE },\n });\n if (handle !== null) {\n for (const [index, list] of member) {\n this.sink.setNodeValue(handle, index, list);\n }\n }\n }\n\n // ------------------------------------------------------------------ edges\n\n /**\n * Push every edge record.\n * @param records - the edge records\n * @param header - the header direction\n */\n private addEdges(records: readonly EdgeRec[], header: boolean): void {\n const ids = new Set<string>();\n const dedupe = this.dialect.cy2 && this.doc.nodes.some((n) => n.nested.length > 0) ? new Set<string>() : null;\n const labels: (string | undefined)[] = [];\n const edgeIds: (string | undefined)[] = [];\n const graphics: [number, Record<string, unknown>][] = [];\n let row = 0;\n for (const record of records) {\n const where = { line: record.line, element: record.id ?? record.label };\n const key = record.id ?? record.label;\n if (dedupe !== null && key !== null) {\n if (dedupe.has(key)) {\n this.report.warnOnce(\n \"merged\",\n XGMML_ISSUE.GROUP_DUPLICATE_EDGE,\n `${this.prefix()}the Cytoscape 2.x writer repeats the edges of a group; each repeat is dropped`,\n where,\n );\n continue;\n }\n dedupe.add(key);\n }\n const index = this.addEdge(record, header, ids, where);\n this.checkAbort();\n if (index < 0) {\n continue;\n }\n this.edgeIndex[row] = index;\n labels[row] = record.label ?? undefined;\n edgeIds[row] = record.id ?? undefined;\n this.addElementColumns(this.edgeColumns, row, record, new Set(), where);\n this.fillInteraction(record, row, where);\n if (record.graphics !== null && Object.keys(record.graphics).length > 0) {\n graphics.push([index, record.graphics]);\n }\n row++;\n }\n this.writeEdgeIds(edgeIds);\n this.writeLabels(\"edge\", labels, (r) => this.edgeIndex[r] ?? -1);\n const column = new JsonColumn(this, \"edge\", GRAPHICS_COLUMN, XGMML_ORIGIN_NAMESPACE, \"graphics\");\n for (const [index, value] of graphics) {\n column.set(index, value);\n }\n }\n\n /**\n * Push one edge: endpoints (with label aliases), duplicate id check, direction and weight.\n * @param record - the edge\n * @param header - the header direction\n * @param ids - the edge ids used so far\n * @param where - the location\n * @returns the edge index, or -1 when it was skipped\n */\n private addEdge(record: EdgeRec, header: boolean, ids: Set<string>, where: IssueLocation): number {\n const alias = this.settings.labelAliases ? aliasesOf(record.label) : null;\n let source: NodeId | null;\n let target: NodeId | null;\n try {\n source = this.endpoint(record.source, alias?.[0] ?? null, \"source\", where);\n target = this.endpoint(record.target, alias?.[2] ?? null, \"target\", where);\n } catch (err) {\n // an endpoint the id rule or the sink refuses (ids: \"number\", a caller's sink)\n this.report.counts.skippedEdges++;\n this.report.recordError(err, where);\n return -1;\n }\n if (source === null || target === null) {\n this.report.counts.skippedEdges++;\n return -1;\n }\n if (record.id !== null && ids.has(record.id)) {\n this.report.counts.skippedEdges++;\n this.report.error(\n \"validation-error\",\n XGMML_ISSUE.DUPLICATE_EDGE_ID,\n `${this.prefix()}edge id \"${record.id}\" is used twice; the second edge is skipped`,\n where,\n );\n return -1;\n }\n const directed = this.edgeDirection(record, header);\n const kind: EdgeKind = directed ? \"directed\" : \"undirected\";\n let weight: number | undefined;\n try {\n weight = this.weightOf(record);\n const before = this.sink.edgeCount;\n const e = this.direction.addEdge(source, target, kind, weight, where);\n this.report.counts.edges += this.sink.edgeCount - before;\n if (record.id !== null) {\n ids.add(record.id);\n }\n return e;\n } catch (err) {\n this.report.counts.skippedEdges++;\n this.report.recordError(err, where);\n return -1;\n }\n }\n\n /**\n * The weight of an edge: its `weight` XML attribute (or the att weightFrom names).\n * @param record - the edge\n * @returns the weight, or undefined\n */\n private weightOf(record: EdgeRec): number | undefined {\n const from = this.options.weightFrom;\n if (from === null) {\n return undefined;\n }\n let text: string | null = from === \"weight\" ? record.weight : null;\n if (text === null) {\n text = record.atts.find((a) => a.name === from && a.children.length === 0)?.value ?? null;\n }\n if (text === null) {\n return undefined;\n }\n const weight = parseWeightText(text);\n this.weighted ||= weight !== undefined;\n return weight;\n }\n\n /**\n * Resolve one endpoint: a node of this graph by id, else (under labelAliases) the label alias\n * by id or by unique node label; a missing endpoint is E_MISSING_ENDPOINT, an unknown one\n * E_UNKNOWN_NODE unless addMissingNodes adds it.\n * @param text - the source or target text, or null\n * @param alias - the label alias, or null\n * @param side - which end\n * @param where - the location\n * @returns the node id, or null when the edge cannot be added\n */\n private endpoint(text: string | null, alias: string | null, side: string, where: IssueLocation): NodeId | null {\n if (text !== null) {\n const row = this.rows.get(text);\n if (row !== undefined && row.index >= 0) {\n return this.coercer.text(text);\n }\n }\n if (alias !== null) {\n const resolved = this.aliasRow(alias);\n if (resolved !== null) {\n this.aliasResolved++;\n return this.coercer.text(resolved.id);\n }\n }\n if (text === null) {\n this.report.error(\n \"missing-value\",\n XGMML_ISSUE.MISSING_ENDPOINT,\n `${this.prefix()}<edge> without a ${side}`,\n where,\n );\n return null;\n }\n if (this.options.addMissingNodes) {\n const id = this.coercer.text(text);\n if (this.sink.indexOf(id) === INVALID_INDEX) {\n this.sink.addNode(id);\n this.report.counts.nodes++;\n }\n return id;\n }\n this.report.error(\n \"validation-error\",\n XGMML_ISSUE.UNKNOWN_NODE,\n `${this.prefix()}edge ${side} \"${text}\" is not a node of this graph; the edge is skipped`,\n where,\n );\n return null;\n }\n\n /** Node labels to rows, for label aliases; null marks a label two nodes share. */\n private labelRows: Map<string, NodeRow | null> | null = null;\n\n /**\n * The node a label alias names: by id, else by a label only one node has.\n * @param alias - the alias\n * @returns the row, or null\n */\n private aliasRow(alias: string): NodeRow | null {\n const byId = this.rows.get(alias);\n if (byId !== undefined && byId.index >= 0) {\n return byId;\n }\n if (this.labelRows === null) {\n this.labelRows = new Map();\n for (const row of this.rowList) {\n const { label } = row.records[0];\n if (label !== null && row.index >= 0) {\n this.labelRows.set(label, this.labelRows.has(label) ? null : row);\n }\n }\n }\n return this.labelRows.get(alias) ?? null;\n }\n\n /**\n * Fill the interaction of an edge without one from its label alias, as Cytoscape does.\n * @param record - the edge\n * @param row - the edge row\n * @param where - the location\n */\n private fillInteraction(record: EdgeRec, row: number, where: IssueLocation): void {\n if (\n !this.settings.labelAliases ||\n this.dialect.session ||\n record.atts.some((a) => a.name === INTERACTION_COLUMN)\n ) {\n return;\n }\n const alias = aliasesOf(record.label);\n if (alias !== null) {\n this.edgeColumns.addText(row, INTERACTION_COLUMN, alias[1], where);\n this.aliasInteractions++;\n }\n }\n\n /** Report the label alias uses, once. */\n private finishAliases(): void {\n if (this.aliasResolved === 0 && this.aliasInteractions === 0) {\n return;\n }\n this.report.warning(\n \"coercion\",\n XGMML_ISSUE.LABEL_ALIAS,\n `${this.prefix()}Cytoscape label aliases (\"a (pp) b\"): ${this.aliasResolved} endpoint(s) resolved, ${this.aliasInteractions} interaction(s) filled from edge labels`,\n );\n }\n\n /**\n * Write the edge `id` column (role id, unique).\n * @param ids - the id of each row\n */\n private writeEdgeIds(ids: readonly (string | undefined)[]): void {\n if (!ids.some((id) => id !== undefined)) {\n return;\n }\n const handle = this.declare(\"edge\", {\n name: EDGE_ID_COLUMN,\n dtype: \"string\",\n role: \"id\",\n unique: true,\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"id\", namespace: null },\n });\n if (handle === null) {\n return;\n }\n ids.forEach((id, row) => {\n const e = this.edgeIndex[row];\n if (id !== undefined && e !== undefined) {\n try {\n this.sink.setEdgeValue(handle, e, id);\n } catch (err) {\n this.report.recordError(err, { element: id });\n }\n }\n });\n }\n\n // ------------------------------------------------------------------ graph and metadata\n\n /**\n * The graph table: the graph's atts and other XML attributes, and its graphics.\n * @param graph - the subnetwork, or null for the root\n */\n private writeGraph(graph: GraphRec | null): void {\n const g = graph ?? this.doc.root;\n const where = { line: g.line, element: g.id };\n if (graph === null) {\n for (const [key, value] of g.attrs) {\n if (!GRAPH_STRUCTURE.has(key) && key !== \"xmlns\" && !key.startsWith(\"xmlns:\")) {\n this.graphColumns.addText(0, key, value, where);\n }\n }\n }\n for (const att of g.atts) {\n if (att.name !== null && META_ATTS.has(att.name)) {\n continue;\n }\n if (att.hasGraph && att.name === null) {\n continue;\n }\n this.graphColumns.addAtt(0, att, where);\n }\n this.graphColumns.write(this.sink, () => 0);\n const json: Record<string, unknown> = { ...(this.extras.graphJson ?? {}) };\n if (g.graphics !== null && Object.keys(g.graphics).length > 0) {\n json[GRAPHICS_COLUMN] = g.graphics;\n }\n for (const [name, value] of Object.entries(json)) {\n this.sink.setGraphValue(name, value, {\n name,\n dtype: \"json\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: name, namespace: XGMML_ORIGIN_NAMESPACE },\n });\n }\n }\n\n /**\n * The graph metadata: name, description and date from the RDF metadata, the format, version\n * and what the exporter needs.\n * @param graph - the subnetwork, or null\n */\n private writeMeta(graph: GraphRec | null): void {\n const g = graph ?? this.doc.root;\n const { rdf } = this.doc;\n const name = this.extras.graphName ?? g.label ?? rdf.title ?? g.id ?? undefined;\n this.sink.setMeta({\n name: name ?? undefined,\n description: rdf.description ?? undefined,\n created: rdf.date ?? undefined,\n sourceFormat: this.extras.sourceFormat ?? FORMAT,\n sourceVersion: this.dialect.versionText ?? undefined,\n weightOrigin: this.weighted\n ? { format: FORMAT, id: \"weight\", title: null, type: \"weight\", namespace: null }\n : undefined,\n extra: {\n [META_KEY]: {\n graphId: g.id,\n directed: this.doc.root.attrs.get(\"directed\") ?? null,\n rdf: Object.keys(rdf).length > 0 ? { ...rdf } : null,\n },\n ...(this.extras.metaExtra ?? {}),\n },\n });\n }\n}\n\n/**\n * The three parts of a Cytoscape edge label (`source (interaction) target`).\n * @param label - the label, or null\n * @returns source alias, interaction, target alias; null when the label has another shape\n */\nexport function aliasesOf(label: string | null): [string, string, string] | null {\n if (label === null) {\n return null;\n }\n const parts = label.split(ALIAS_SPLIT);\n return parts.length === 3 ? [parts[0].trim(), parts[1], parts[2].trim()] : null;\n}\n\n/**\n * A json column the importer owns, declared on first value.\n */\nclass JsonColumn {\n private handle: ColumnHandle | null | undefined;\n\n /**\n * Create the column.\n * @param emitter - the emitter\n * @param domain - node or edge\n * @param name - the column name\n * @param namespace - its origin namespace\n * @param type - its origin type\n * @param dtype - json (default) or string\n */\n constructor(\n private readonly emitter: XgmmlEmitter,\n private readonly domain: \"node\" | \"edge\",\n private readonly name: string,\n private readonly namespace: string,\n private readonly type: string,\n private readonly dtype: \"json\" | \"string\" = \"json\",\n ) {}\n\n /**\n * Set one value.\n * @param index - the node or edge index\n * @param value - the value\n */\n set(index: number, value: unknown): void {\n if (index < 0) {\n return;\n }\n if (this.handle === undefined) {\n this.handle = this.emitter.declare(this.domain, {\n name: this.name,\n dtype: this.dtype,\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: this.type, namespace: this.namespace },\n });\n }\n if (this.handle === null) {\n return;\n }\n const sink = this.emitter.target;\n if (this.domain === \"node\") {\n sink.setNodeValue(this.handle, index, value);\n } else {\n sink.setEdgeValue(this.handle, index, value);\n }\n }\n}\n\n/**\n * Node positions: x and y (y negated: Cytoscape's screen y grows down, graph-io's grows up), z\n * as a coordinate in the draft dialect or under zAs \"position\", else as the `z` column.\n */\nclass Positions {\n private readonly values = new Map<number, [number, number, number]>();\n\n private readonly zValues = new Map<number, number>();\n\n private hasZ = false;\n\n /**\n * Create the collector.\n * @param emitter - the emitter\n * @param zAs - where z goes\n */\n constructor(\n private readonly emitter: XgmmlEmitter,\n private readonly zAs: \"column\" | \"position\",\n ) {}\n\n /**\n * Read one node record's coordinates.\n * @param row - the node row\n * @param record - the record\n */\n add(row: NodeRow, record: NodeRec): void {\n if (row.index < 0 || (record.x === null && record.y === null && record.z === null)) {\n return;\n }\n const where = { line: record.line, element: row.id };\n const x = this.number(record.x, where);\n const y = this.number(record.y, where);\n const z = this.number(record.z, where);\n if (z !== null) {\n this.hasZ = true;\n if (this.zAs === \"column\") {\n this.zValues.set(row.index, z);\n }\n }\n if (x !== null && y !== null) {\n const flipped = y === 0 ? 0 : -y;\n this.values.set(row.index, [x, flipped, this.zAs === \"position\" ? (z ?? 0) : 0]);\n }\n }\n\n /**\n * A coordinate.\n * @param text - the text, or null\n * @param where - the location\n * @returns the number, or null when absent or invalid (recorded)\n */\n private number(text: string | null, where: IssueLocation): number | null {\n if (text === null) {\n return null;\n }\n const n = Number(text.trim());\n if (text.trim().length === 0 || !Number.isFinite(n)) {\n this.emitter.issues.error(\n \"validation-error\",\n XGMML_ISSUE.BAD_VALUE,\n `${this.emitter.prefix()}graphics coordinate \"${text}\" is not a number`,\n where,\n );\n return null;\n }\n return n;\n }\n\n /** Declare and write the position and z columns. */\n write(): void {\n const sink = this.emitter.target;\n if (this.values.size > 0) {\n const handle = this.emitter.declare(\"node\", {\n name: POSITION_COLUMN,\n dtype: \"f32\",\n components: 3,\n role: \"position\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"graphics\", namespace: XGMML_ORIGIN_NAMESPACE },\n extra: { sourceDims: this.zAs === \"position\" && this.hasZ ? 3 : 2, units: \"file\" },\n });\n if (handle !== null) {\n for (const [index, xyz] of this.values) {\n sink.setNodeValue(handle, index, xyz);\n }\n }\n }\n if (this.zValues.size > 0) {\n const handle = this.emitter.declare(\"node\", {\n name: Z_COLUMN,\n dtype: \"f64\",\n nullable: true,\n origin: {\n format: FORMAT,\n id: null,\n title: null,\n type: \"graphics\",\n namespace: CYTOSCAPE_ORIGIN_NAMESPACE,\n },\n });\n if (handle !== null) {\n for (const [index, z] of this.zValues) {\n sink.setNodeValue(handle, index, z);\n }\n }\n }\n }\n}\n\n/**\n * Nested-network pointers: a node-nested graph that is not a group names a network.\n */\nclass Pointers {\n private readonly names = new Map<number, string>();\n\n private readonly crossFile = new Map<number, string>();\n\n private dangling = 0;\n\n /**\n * Create the collector.\n * @param emitter - the emitter\n * @param isGroup - the group test\n */\n constructor(\n private readonly emitter: XgmmlEmitter,\n private readonly isGroup: (node: NodeRec) => boolean,\n ) {}\n\n /**\n * Read one node record's pointers.\n * @param row - the node row\n * @param record - the record\n */\n add(row: NodeRow, record: NodeRec): void {\n if (record.nested.length === 0 || this.isGroup(record) || row.index < 0) {\n return;\n }\n for (const graph of record.nested) {\n if (graph.href === null) {\n this.names.set(row.index, graph.label ?? graph.id ?? \"\");\n continue;\n }\n const id = localRef(graph.href);\n if (id === null) {\n const resolved = this.emitter.resolvePointer(graph.href);\n if (resolved !== null) {\n this.names.set(row.index, resolved);\n } else {\n this.crossFile.set(row.index, graph.href);\n }\n continue;\n }\n const target = this.emitter.graphById(id);\n if (target === undefined) {\n this.dangling++;\n } else {\n this.names.set(row.index, target.label ?? target.id ?? id);\n }\n }\n }\n\n /** Write the pointer columns and their warnings. */\n write(): void {\n const prefix = this.emitter.prefix();\n if (this.dangling > 0) {\n this.emitter.issues.warning(\n \"validation-error\",\n XGMML_ISSUE.DANGLING_REFERENCE,\n `${prefix}${this.dangling} nested-network pointer(s) name no graph of the document`,\n );\n }\n const names = new JsonColumn(\n this.emitter,\n \"node\",\n NESTED_NETWORK_COLUMN,\n CYTOSCAPE_ORIGIN_NAMESPACE,\n \"nestedNetwork\",\n \"string\",\n );\n for (const [index, name] of this.names) {\n names.set(index, name);\n }\n if (this.crossFile.size > 0) {\n this.emitter.issues.warning(\n \"unsupported\",\n XGMML_ISSUE.CROSS_FILE_REFERENCE,\n `${prefix}${this.crossFile.size} nested-network pointer(s) point into another file; each is kept as text in ${NETWORK_POINTER_COLUMN}`,\n );\n const column = new JsonColumn(\n this.emitter,\n \"node\",\n NETWORK_POINTER_COLUMN,\n XGMML_ORIGIN_NAMESPACE,\n \"xlink:href\",\n \"string\",\n );\n for (const [index, href] of this.crossFile) {\n column.set(index, href);\n }\n }\n }\n}\n\n/**\n * Group containment: every node (declared or referenced) in a group's nested graph has the group\n * node as a parent; a node in several groups gets the `parents` list instead of `parent`.\n */\nclass Containment {\n private readonly parents = new Map<number, number[]>();\n\n private readonly subgraphs = new Map<number, Record<string, unknown>>();\n\n /**\n * Create the resolver.\n * @param emitter - the emitter\n */\n constructor(private readonly emitter: XgmmlEmitter) {}\n\n /**\n * Collect the memberships of every group node of the graph.\n * @param rows - the node rows\n * @param isGroup - the group test\n */\n resolve(rows: readonly NodeRow[], isGroup: (node: NodeRec) => boolean): void {\n let unknown = 0;\n for (const row of rows) {\n for (const record of row.records) {\n if (row.index < 0 || record.nested.length === 0 || !isGroup(record)) {\n continue;\n }\n for (const graph of record.nested) {\n const atts = graph.atts.filter((a) => a.name !== null);\n if (graph.id !== null || graph.label !== null || atts.length > 0) {\n this.subgraphs.set(row.index, {\n id: graph.id,\n label: graph.label,\n atts: Object.fromEntries(atts.map((a) => [a.name, attJson(a)])),\n });\n }\n for (const member of graph.members) {\n if (member.kind !== \"node\") {\n continue;\n }\n const id = member.id ?? (member.href === null ? null : localRef(member.href));\n const child = id === null ? undefined : this.emitter.rowOf(id);\n if (child === undefined) {\n if (id === null || !this.emitter.missingMember(row.id, id)) {\n unknown++;\n }\n continue;\n }\n if (child.index >= 0) {\n this.link(child.index, row.index, member.line);\n }\n }\n }\n }\n }\n if (unknown > 0) {\n this.emitter.issues.error(\n \"missing-value\",\n XGMML_ISSUE.UNKNOWN_PARENT,\n `${this.emitter.prefix()}${unknown} group member(s) name no node of this graph`,\n );\n }\n }\n\n /**\n * Add one membership unless it closes a parent cycle.\n * @param child - the member's index\n * @param parent - the group node's index\n * @param line - the line\n */\n private link(child: number, parent: number, line: number): void {\n if (child === parent || this.isAncestor(child, parent)) {\n this.emitter.issues.error(\n \"validation-error\",\n XGMML_ISSUE.PARENT_CYCLE,\n `${this.emitter.prefix()}a group membership would make a node its own ancestor; that membership is dropped`,\n { line },\n );\n return;\n }\n const list = this.parents.get(child) ?? [];\n if (!list.includes(parent)) {\n list.push(parent);\n }\n this.parents.set(child, list);\n }\n\n /**\n * Whether a node is an ancestor of another through the memberships so far.\n * @param ancestor - the candidate ancestor\n * @param node - the node\n * @returns true when following parents from node reaches ancestor\n */\n private isAncestor(ancestor: number, node: number): boolean {\n const stack = [node];\n const seen = new Set<number>();\n while (stack.length > 0) {\n const n = stack.pop() as number;\n if (n === ancestor) {\n return true;\n }\n if (seen.has(n)) {\n continue;\n }\n seen.add(n);\n stack.push(...(this.parents.get(n) ?? []));\n }\n return false;\n }\n\n /** Declare and write the parent (or parents) and subgraph columns. */\n write(): void {\n const sink = this.emitter.target;\n if (this.parents.size > 0) {\n const multi = [...this.parents.values()].some((list) => list.length > 1);\n const handle = this.emitter.declare(\"node\", {\n name: multi ? PARENTS_COLUMN : PARENT_COLUMN,\n dtype: multi ? \"list\" : \"u32\",\n itemDtype: multi ? \"u32\" : undefined,\n role: multi ? \"parents\" : \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: { format: FORMAT, id: null, title: null, type: \"graph\", namespace: null },\n });\n if (handle !== null) {\n for (const [child, list] of this.parents) {\n sink.setNodeValue(handle, child, multi ? list : list[0]);\n }\n }\n }\n if (this.subgraphs.size > 0) {\n const column = new JsonColumn(this.emitter, \"node\", SUBGRAPH_COLUMN, XGMML_ORIGIN_NAMESPACE, \"graph\");\n for (const [index, value] of this.subgraphs) {\n column.set(index, value);\n }\n }\n }\n}\n","/**\n * The XGMML importer (design `design/graph-io/cytoscape-and-obo/design.md` section 1.1;\n * `research-xgmml.md`): one reader for the 1.0 draft, the Cytoscape 2.x and 3.x exports and the\n * Cytoscape 3 session network files. The document is read in one pass of the shared XML tokenizer\n * into records (document.ts), and resolved into the sink once the outermost `</graph>` closes\n * (emit.ts), so forward references and edges before their nodes need nothing special.\n *\n * Direction follows the specification: the root `directed` (0 by the DTD, else the\n * `defaultDirected` option), then `cy:directed` per edge, overruling Cytoscape, which ignores the\n * root attribute. Ids are kept as written (`ids: \"keep\"`), so `\"1\"`, `\"01\"` and `\" 1 \"` stay three\n * nodes. Positions are stored y-up (Cytoscape writes screen coordinates). Graphics values are kept\n * as a json column, never interpreted (style import is issue #706).\n */\n\nimport { GraphFormatError, type GraphSink } from \"@graphty/graph-format\";\n\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport {\n chooseGraph,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { isWhitespace, tokenizeXml, xmlDeclaredEncoding, type XmlRepairs, XmlSyntaxError } from \"../../common/xml.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 { EXTENSIONS, FORMAT, MIME_TYPES, XGMML_ISSUE } from \"./constants.js\";\nimport { type GraphRec, type XgmmlDocument, XgmmlParser } from \"./document.js\";\nimport {\n type Dialect,\n dialectOf,\n type EmitExtras,\n graphsOf,\n membersOf,\n XgmmlEmitter,\n type XgmmlSettings,\n} from \"./emit.js\";\n\n/** The format-specific options of the XGMML importer. */\nexport interface XgmmlImportOptions extends GraphChoiceOptions {\n /**\n * Resolve an edge endpoint that is missing or names no node through Cytoscape's\n * `\"source (interaction) target\"` edge label, and fill a missing interaction from it. Default:\n * on for files that use the Cytoscape (`cy`) namespace, off otherwise.\n */\n labelAliases?: boolean | undefined;\n /**\n * Decode Cytoscape's two-character `\\n` and `\\t` escapes in string values. Default: on for\n * files that use the Cytoscape namespace, off otherwise.\n */\n cytoscapeEscapes?: boolean | undefined;\n /** Read an `&` not followed by `;` within 7 characters as `&amp;` (warned per occurrence). Default false. */\n repairBareAmpersands?: boolean | undefined;\n /** Join two surrogate character references into one character (warned per pair). Default false. */\n pairSurrogateReferences?: boolean | undefined;\n /** Where Cytoscape's z (a stacking order) goes: the `z` column (default) or the position. */\n zAs?: \"column\" | \"position\" | undefined;\n}\n\n/** The per-format defaults: ids as written, undirected by the DTD, the edge `weight` attribute. */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = {\n ids: \"keep\",\n defaultDirected: false,\n weightFrom: \"weight\",\n addMissingNodes: false,\n};\n\n/** The common options the XGMML importer reads. */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n \"encoding\",\n]);\n\n/** Bytes inspected by sniff(). */\nconst SNIFF_BYTES = 4096;\n\n/** The head of the document kept for the DOCTYPE check. */\nconst HEAD_CHARS = 2048;\n\n/** An XGMML DOCTYPE (Cytoscape's file filter tests the same). */\nconst XGMML_DOCTYPE = /<!DOCTYPE\\s+graph\\s[^<>]*xgmml\\.dtd/i;\n\n/**\n * The XGMML option values, checked.\n * @param options - the caller's options\n * @param cytoscape - whether the document uses the Cytoscape namespace\n * @returns the settings; E_UNSUPPORTED for a value of the wrong type\n */\nexport function resolveSettings(options: XgmmlImportOptions | undefined, cytoscape: boolean): XgmmlSettings {\n const zAs = options?.zAs ?? \"column\";\n if (zAs !== \"column\" && zAs !== \"position\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option zAs: ${JSON.stringify(zAs)} is not \"column\" or \"position\"`,\n {\n option: \"zAs\",\n found: zAs,\n },\n );\n }\n return {\n labelAliases: booleanOption(\"labelAliases\", options?.labelAliases, cytoscape),\n cytoscapeEscapes: booleanOption(\"cytoscapeEscapes\", options?.cytoscapeEscapes, cytoscape),\n zAs,\n };\n}\n\n/**\n * One boolean option.\n * @param name - the option name\n * @param value - the caller's value\n * @param fallback - the default\n * @returns the value; E_UNSUPPORTED when not a boolean\n */\nfunction booleanOption(name: string, value: unknown, fallback: boolean): boolean {\n if (value === undefined) {\n return fallback;\n }\n if (typeof value !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: ${JSON.stringify(value)} is not a boolean`, {\n option: name,\n found: value,\n });\n }\n return value;\n}\n\n/**\n * Read an XGMML document into records. Fatal conditions (not XML, not a graph, empty) fail the\n * report.\n * @param input - the input\n * @param report - the report\n * @param common - the resolved common options\n * @param options - the XGMML options (for the repairs)\n * @returns the document\n */\nexport async function parseXgmml(\n input: ImportInput,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n options: XgmmlImportOptions | undefined,\n): Promise<XgmmlDocument> {\n const repairs: XmlRepairs = {\n bareAmpersand: booleanOption(\"repairBareAmpersands\", options?.repairBareAmpersands, false)\n ? (line): void => {\n report.warning(\"parse-error\", XGMML_ISSUE.AMPERSAND_REPAIRED, \"a bare & was read as &amp;\", { line });\n }\n : undefined,\n surrogatePair: booleanOption(\"pairSurrogateReferences\", options?.pairSurrogateReferences, false)\n ? (line): void => {\n report.warning(\n \"parse-error\",\n XGMML_ISSUE.SURROGATE_PAIRED,\n \"two surrogate character references were joined into one character\",\n { line },\n );\n }\n : undefined,\n };\n const parser = new XgmmlParser(report);\n const seen = { head: \"\", content: false };\n try {\n await tokenizeXml(\n watch(textChunks(input, report, { ...common, declaredEncoding: xmlDeclaredEncoding }), seen),\n parser,\n repairs,\n );\n } catch (err) {\n if (err instanceof XmlSyntaxError) {\n if (!seen.content) {\n report.fail(XGMML_ISSUE.EMPTY_INPUT, \"the input is empty\");\n }\n report.fail(XGMML_ISSUE.XML_SYNTAX, err.message, { line: err.line });\n }\n throw err;\n }\n const doc = parser.document();\n if (!doc.xgmmlNamespace && !XGMML_DOCTYPE.test(seen.head)) {\n report.warning(\n \"validation-error\",\n XGMML_ISSUE.NO_NAMESPACE,\n \"the root <graph> has neither the XGMML namespace nor an XGMML DOCTYPE; it is read as XGMML\",\n { line: doc.root.line },\n );\n }\n return doc;\n}\n\n/**\n * Pass text chunks through while keeping the head and noting non-whitespace content.\n * @param chunks - the chunks\n * @param seen - where the head and the content flag are kept\n * @param seen.head - the first characters of the document\n * @param seen.content - whether non-whitespace text was seen\n * @yields the chunks unchanged\n * @returns nothing\n */\nasync function* watch(\n chunks: AsyncIterable<string>,\n seen: { head: string; content: boolean },\n): AsyncGenerator<string, void, undefined> {\n for await (const chunk of chunks) {\n if (seen.head.length < HEAD_CHARS) {\n seen.head += chunk.slice(0, HEAD_CHARS - seen.head.length);\n }\n seen.content ||= !isWhitespace(chunk);\n yield chunk;\n }\n}\n\n/** What an import call sets up before it emits. */\ninterface Prepared {\n readonly report: ImportReportBuilder;\n readonly common: ResolvedImportOptions;\n readonly doc: XgmmlDocument;\n readonly dialect: Dialect;\n readonly settings: XgmmlSettings;\n readonly graphs: readonly GraphRec[];\n}\n\n/**\n * Resolve the options, read the document and check it is a graph document.\n * @param input - the input\n * @param sink - the sink, or null for listGraphs\n * @param options - the options\n * @returns what the import needs\n */\nasync function prepare(\n input: ImportInput,\n sink: GraphSink | null,\n options: (XgmmlImportOptions & CommonImportOptions) | undefined,\n): Promise<Prepared> {\n const common = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(FORMAT, common.errorLimit);\n if (sink !== null) {\n reportSinkOptions(sink, options, report, true);\n reportUnusedOptions(options, report, USED_OPTIONS);\n }\n resolveSettings(options, false);\n const doc = await parseXgmml(input, report, common, options);\n const dialect = dialectOf(doc, report);\n if (dialect.view) {\n report.fail(\n XGMML_ISSUE.VIEW_DOCUMENT,\n \"this is a Cytoscape session view file (cy:view): it holds positions keyed by view ids and no topology; open the session (.cys) instead\",\n { line: doc.root.line },\n );\n }\n return {\n report,\n common,\n doc,\n dialect,\n settings: resolveSettings(options, doc.cytoscape),\n graphs: graphsOf(doc, dialect),\n };\n}\n\n/**\n * Emit one graph of a prepared document.\n * @param prepared - the prepared import\n * @param graph - the graph to read\n * @param sink - the sink\n * @param extras - what a session adds\n * @returns the report\n */\nfunction emitOne(prepared: Prepared, graph: GraphRec, sink: GraphSink, extras?: EmitExtras): ImportReport {\n const { doc, dialect, report, common, settings } = prepared;\n const emitter = new XgmmlEmitter(doc, dialect, sink, report, common, settings, extras);\n emitter.emit(dialect.session ? graph : null);\n if (dialect.session) {\n reportRootOnly(prepared);\n }\n throwIfAborted(common.signal);\n return report.finish();\n}\n\n/**\n * W_XGMML_ROOT_ONLY_ELEMENTS: elements of a session network document no registered subnetwork\n * holds (group meta-edges, members of collapsed groups).\n * @param prepared - the prepared import\n */\nfunction reportRootOnly(prepared: Prepared): void {\n const held = new Set<unknown>();\n for (const graph of prepared.graphs) {\n const members = membersOf(prepared.doc, graph);\n members.nodes.forEach((n) => held.add(n));\n members.edges.forEach((e) => held.add(e));\n }\n const nodes = prepared.doc.nodes.filter((n) => !held.has(n)).length;\n const edges = prepared.doc.edges.filter((e) => !held.has(e)).length;\n if (nodes + edges > 0) {\n prepared.report.warning(\n \"unsupported\",\n XGMML_ISSUE.ROOT_ONLY_ELEMENTS,\n `${nodes} node(s) and ${edges} edge(s) belong to no registered network (group meta-edges, collapsed group members) and were not read`,\n );\n }\n}\n\n/**\n * Import one graph of an XGMML document.\n * @param input - the document\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError when the document cannot be read or the error limit is exceeded\n */\nasync function importXgmml(\n input: ImportInput,\n sink: GraphSink,\n options?: XgmmlImportOptions & CommonImportOptions,\n): Promise<ImportReport> {\n const prepared = await prepare(input, sink, options);\n const index = chooseGraph(\n prepared.graphs.map((g) => graphName(g, prepared.doc)),\n options,\n prepared.report,\n );\n if (prepared.graphs.length > 1) {\n prepared.report.warning(\n \"unsupported\",\n XGMML_ISSUE.MULTIPLE_GRAPHS,\n `the session network document holds ${prepared.graphs.length} registered networks; ${prepared.graphs.length - 1} were not read (use importAll, graphIndex or graphName)`,\n );\n }\n return emitOne(prepared, prepared.graphs[index], sink);\n}\n\n/**\n * Import every graph of an XGMML document: each registered subnetwork of a session network\n * document, else the one graph.\n * @param input - the document\n * @param sinkFor - a sink per graph\n * @param options - format-specific and common options\n * @returns one report per graph\n */\nasync function importAllXgmml(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: XgmmlImportOptions & CommonImportOptions,\n): Promise<ImportReport[]> {\n const bytes = await reread(input);\n const first = await prepare(bytes, null, options);\n const reports: ImportReport[] = [];\n for (let i = 0; i < first.graphs.length; i++) {\n const sink = sinkFor(i);\n const prepared = i === 0 ? first : await prepare(bytes, null, options);\n reportSinkOptions(sink, options, prepared.report, true);\n reportUnusedOptions(options, prepared.report, USED_OPTIONS);\n reports.push(emitOne(prepared, prepared.graphs[i], sink));\n }\n return reports;\n}\n\n/**\n * List the graphs of an XGMML document without importing them.\n * @param input - the document\n * @param options - the options\n * @returns one listing per graph\n */\nasync function listXgmmlGraphs(\n input: ImportInput,\n options?: XgmmlImportOptions & CommonImportOptions,\n): Promise<readonly GraphListing[]> {\n const prepared = await prepare(input, null, options);\n return prepared.graphs.map((graph, index) => {\n const members = membersOf(prepared.doc, prepared.dialect.session ? graph : null);\n return Object.freeze({\n index,\n name: graphName(graph, prepared.doc),\n nodes: new Set(members.nodes.map((n) => n.id)).size,\n edges: members.edges.length,\n });\n });\n}\n\n/**\n * The name of a graph: its label, else the RDF title (root only), else its id.\n * @param graph - the graph\n * @param doc - the document\n * @returns the name, or null\n */\nfunction graphName(graph: GraphRec, doc: XgmmlDocument): string | null {\n return graph.label ?? (graph === doc.root ? (doc.rdf.title ?? null) : null) ?? graph.id ?? null;\n}\n\n/**\n * The input in a form that can be read more than once (a stream is read into bytes).\n * @param input - the input\n * @returns the same input when it is a string or bytes, else the collected bytes\n */\nasync function reread(input: ImportInput): Promise<string | Uint8Array> {\n if (typeof input === \"string\" || input instanceof Uint8Array) {\n return input;\n }\n const parts: (string | Uint8Array)[] = [];\n const iterable: AsyncIterable<string | Uint8Array> =\n typeof (input as { getReader?: unknown }).getReader === \"function\"\n ? streamIterable(input as ReadableStream<Uint8Array>)\n : (input as AsyncIterable<string | Uint8Array>);\n for await (const chunk of iterable) {\n parts.push(chunk);\n }\n if (parts.every((p) => typeof p === \"string\")) {\n return parts.join(\"\");\n }\n const bytes = parts.map((p) => (typeof p === \"string\" ? new TextEncoder().encode(p) : p));\n const out = new Uint8Array(bytes.reduce((n, b) => n + b.byteLength, 0));\n let at = 0;\n for (const b of bytes) {\n out.set(b, at);\n at += b.byteLength;\n }\n return out;\n}\n\n/**\n * A ReadableStream as an async iterable.\n * @param stream - the stream\n * @yields its chunks\n * @returns nothing\n */\nasync function* streamIterable(stream: ReadableStream<Uint8Array>): AsyncGenerator<Uint8Array, void, undefined> {\n const reader = stream.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n return;\n }\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Confidence that a head of bytes is XGMML: 0.95 for a root `graph` in the XGMML namespace or an\n * XGMML DOCTYPE (Cytoscape's file filter tests the same two things, and a session view file still\n * scores so its failure names it), 0.5 for a root local name `graph` without either.\n * @param head - the first bytes\n * @returns the confidence\n */\nfunction sniffXgmml(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head.subarray(0, SNIFF_BYTES));\n if (!/^\\uFEFF?\\s*</.test(text)) {\n return 0;\n }\n if (XGMML_DOCTYPE.test(text)) {\n return 0.95;\n }\n const root = /<(?!\\?|!)([A-Za-z_][\\w.-]*:)?([A-Za-z_][\\w.-]*)[\\s/>]/.exec(text.replace(/<!--[\\s\\S]*?-->/g, \"\"));\n if (root === null || root[2] !== \"graph\") {\n return 0;\n }\n const tagEnd = text.indexOf(\">\", root.index);\n const tag = text.slice(root.index, tagEnd < 0 ? undefined : tagEnd);\n return tag.includes(\"http://www.cs.rpi.edu/XGMML\") ? 0.95 : 0.5;\n}\n\n/** The XGMML importer. */\nexport const xgmmlImporter: GraphImporter<XgmmlImportOptions> = Object.freeze({\n format: FORMAT,\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n sniff: sniffXgmml,\n import: importXgmml,\n importAll: importAllXgmml,\n listGraphs: listXgmmlGraphs,\n});\n"],"names":["key","graph"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { aB as resolveExportOptions, ax as pairFolding, ar as declareResolved, af as UNKNOWN_ENCODING_CODE, r as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, U as OPTION_IGNORED_CODE, a2 as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ac as TOO_LARGE_CODE, D as DANGLING_REFERENCE_CODE, A as AMBIGUOUS_GRAPH_NAME_CODE, G as GRAPH_NOT_FOUND_CODE, O as MULTIPLE_GRAPHS_CODE, u as ID_MERGED_CODE, m as DUPLICATE_EDGE_ID_CODE, o as DUPLICATE_NODE_CODE, ag as UNKNOWN_PARENT_CODE, d as BAD_VALUE_CODE, M as MISSING_ENDPOINT_CODE, K as MISSING_ID_CODE, a8 as SYNTAX_CODE, q as EMPTY_INPUT_CODE, aC as resolveImportOptions, I as ImportReportBuilder, ay as readText, aD as textChunks, az as reportSinkOptions, aA as reportUnusedOptions, t as throwIfAborted, F as IdCoercer, p as DirectionResolver, aE as uniqueColumnName, an as chooseGraph } from "./report-BcWboivV.js";
3
- import { c as capabilities, L as LOSS, j as joinText, e as encodeChunks, a as checkCapabilities, g as countMixedEdges } from "./writer-DQiKgQJc.js";
4
- import { e as explicitWeights, a as formatF32, b as formatF64, w as weightFromValue } from "./weights-CwISIpCP.js";
5
- import { M as MAYBE_UNSAFE_INTEGER, e as rewriteNumbers, g as reviveNonstandard } from "./json-elements-CZY1wiZh.js";
2
+ import { V as resolveExportOptions, X as pairFolding, L as declareResolved, q as UNKNOWN_ENCODING_CODE, E as ENCODING_FALLBACK_CODE, r as INVALID_ENCODING_CODE, s as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, an as HYPEREDGE_CODE, T as TOO_LARGE_CODE, j as DANGLING_REFERENCE_CODE, A as AMBIGUOUS_GRAPH_NAME_CODE, G as GRAPH_NOT_FOUND_CODE, M as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, c as DUPLICATE_EDGE_ID_CODE, d as DUPLICATE_NODE_CODE, U as UNKNOWN_PARENT_CODE, B as BAD_VALUE_CODE, e as MISSING_ENDPOINT_CODE, f as MISSING_ID_CODE, t as SYNTAX_CODE, u as EMPTY_INPUT_CODE, v as resolveImportOptions, w as ImportReportBuilder, aG as readText, x as textChunks, F as reportSinkOptions, z as reportUnusedOptions, y as throwIfAborted, K as IdCoercer, J as DirectionResolver, Q as uniqueColumnName, H as chooseGraph } from "./report-B1z4WT9e.js";
3
+ import { c as capabilities, L as LOSS, a as checkCapabilities, d as countMixedEdges } from "./export-Bh60Dv-n.js";
4
+ import { e as explicitWeights, f as formatF32, a as formatF64, w as weightFromValue } from "./weights-Dzba96G3.js";
5
+ import { f as flipY, M as MAYBE_UNSAFE_INTEGER, e as rewriteNumbers, g as reviveNonstandard } from "./json-elements-DDS8N2Dd.js";
6
+ import { j as joinText, e as encodeChunks } from "./writer-C7flM-Ih.js";
6
7
  import { a as OBOGRAPHS_PREDICATE_TAGS, c as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, s as synonymScopeOf, O as OBO_NODE_COLUMNS } from "./ontology-BnrJ4I98.js";
7
8
  const JSON_DIALECTS = Object.freeze([
8
9
  "node-link",
@@ -1265,7 +1266,7 @@ function* writeCytoscape(snapshot, p) {
1265
1266
  w.key("position");
1266
1267
  w.open("{");
1267
1268
  w.member("x", numberText(value[0], f32, c.nonfinite));
1268
- w.member("y", numberText(value[1], f32, c.nonfinite));
1269
+ w.member("y", numberText(flipY(value[1]), f32, c.nonfinite));
1269
1270
  w.close("}");
1270
1271
  }
1271
1272
  }
@@ -1381,9 +1382,11 @@ const GRAPH_FORMATS = Object.freeze([
1381
1382
  "dot",
1382
1383
  "pajek",
1383
1384
  "neo4j",
1385
+ "xgmml",
1384
1386
  "cx2",
1385
1387
  "cx",
1386
- "obo"
1388
+ "obo",
1389
+ "cys"
1387
1390
  ]);
1388
1391
  const SNIFF_HEAD_BYTES = 8192;
1389
1392
  function extensionOf(filename) {
@@ -3895,7 +3898,7 @@ function importCytoscape(ctx, root) {
3895
3898
  if (position !== void 0 && position !== null) {
3896
3899
  if (isJsonObject(position) && typeof position.x === "number" && typeof position.y === "number") {
3897
3900
  point[0] = position.x;
3898
- point[1] = position.y;
3901
+ point[1] = flipY(position.y);
3899
3902
  ctx.nodes.set(positionColumn, index, point);
3900
3903
  } else {
3901
3904
  report.error(
@@ -4164,4 +4167,4 @@ export {
4164
4167
  rankFormats as r,
4165
4168
  sniffFormat as s
4166
4169
  };
4167
- //# sourceMappingURL=importer-Bm1_5vPS.js.map
4170
+ //# sourceMappingURL=importer-eUREhBGj.js.map