@graphty/graph-io 0.3.18 → 0.3.20

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 (235) hide show
  1. package/README.md +80 -2
  2. package/dist/chunks/{escape-D-gZWO26.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-GAdltGmC.js → export-Bh60Dv-n.js} +7 -252
  5. package/dist/chunks/export-Bh60Dv-n.js.map +1 -0
  6. package/dist/chunks/exporter-BGrsWamJ.js +736 -0
  7. package/dist/chunks/exporter-BGrsWamJ.js.map +1 -0
  8. package/dist/chunks/exporter-DIeGJXAZ.js +834 -0
  9. package/dist/chunks/exporter-DIeGJXAZ.js.map +1 -0
  10. package/dist/chunks/{importer-Br_QeAeE.js → importer-BWY2FFc5.js} +28 -6
  11. package/dist/chunks/importer-BWY2FFc5.js.map +1 -0
  12. package/dist/chunks/importer-BaQpCEcJ.js +2194 -0
  13. package/dist/chunks/importer-BaQpCEcJ.js.map +1 -0
  14. package/dist/chunks/importer-DD-xv9_Y.js +1471 -0
  15. package/dist/chunks/importer-DD-xv9_Y.js.map +1 -0
  16. package/dist/chunks/{importer-aNJfe0qu.js → importer-DEcKhsmQ.js} +2 -2
  17. package/dist/chunks/{importer-aNJfe0qu.js.map → importer-DEcKhsmQ.js.map} +1 -1
  18. package/dist/chunks/{importer-DHagxvDD.js → importer-DIrbbnAf.js} +6 -4
  19. package/dist/chunks/{importer-DHagxvDD.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-Du5crN9l.js → importer-Wv4C4gaF.js} +278 -82
  23. package/dist/chunks/importer-Wv4C4gaF.js.map +1 -0
  24. package/dist/chunks/importer-vi3bSdtw.js +1713 -0
  25. package/dist/chunks/importer-vi3bSdtw.js.map +1 -0
  26. package/dist/chunks/{importer-d0uQxFp6.js → importer-zGLo8Dg_.js} +6 -4
  27. package/dist/chunks/{importer-d0uQxFp6.js.map → importer-zGLo8Dg_.js.map} +1 -1
  28. package/dist/chunks/json-elements-DDS8N2Dd.js +779 -0
  29. package/dist/chunks/json-elements-DDS8N2Dd.js.map +1 -0
  30. package/dist/chunks/{records-Bk9jgodz.js → records-dbRkxwaq.js} +2 -2
  31. package/dist/chunks/{records-Bk9jgodz.js.map → records-dbRkxwaq.js.map} +1 -1
  32. package/dist/chunks/{report-BOk0p5y8.js → report-B1z4WT9e.js} +143 -111
  33. package/dist/chunks/{report-BOk0p5y8.js.map → report-B1z4WT9e.js.map} +1 -1
  34. package/dist/chunks/weights-Dzba96G3.js +176 -0
  35. package/dist/chunks/weights-Dzba96G3.js.map +1 -0
  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 -4
  39. package/dist/csv.js.map +1 -1
  40. package/dist/cx.d.ts +1 -0
  41. package/dist/cx.js +6 -0
  42. package/dist/cx.js.map +1 -0
  43. package/dist/cx2.d.ts +1 -0
  44. package/dist/cx2.js +10 -0
  45. package/dist/cx2.js.map +1 -0
  46. package/dist/cys.d.ts +1 -0
  47. package/dist/cys.js +6 -0
  48. package/dist/cys.js.map +1 -0
  49. package/dist/dot.js +1 -1
  50. package/dist/gexf.js +16 -4
  51. package/dist/gexf.js.map +1 -1
  52. package/dist/gml.js +13 -14
  53. package/dist/gml.js.map +1 -1
  54. package/dist/graph-io.js +302 -399
  55. package/dist/graph-io.js.map +1 -1
  56. package/dist/graphml.js +1 -1
  57. package/dist/json.js +1 -1
  58. package/dist/neo4j.js +6 -4
  59. package/dist/neo4j.js.map +1 -1
  60. package/dist/obo.js +1 -1
  61. package/dist/pajek.js +1 -1
  62. package/dist/src/common/cell-budget.d.ts +84 -0
  63. package/dist/src/common/cell-budget.d.ts.map +1 -0
  64. package/dist/src/common/cell-budget.js +138 -0
  65. package/dist/src/common/cell-budget.js.map +1 -0
  66. package/dist/src/common/input.d.ts +10 -0
  67. package/dist/src/common/input.d.ts.map +1 -1
  68. package/dist/src/common/input.js +39 -0
  69. package/dist/src/common/input.js.map +1 -1
  70. package/dist/src/common/json-elements.d.ts +286 -0
  71. package/dist/src/common/json-elements.d.ts.map +1 -0
  72. package/dist/src/common/json-elements.js +926 -0
  73. package/dist/src/common/json-elements.js.map +1 -0
  74. package/dist/src/common/options.d.ts +6 -0
  75. package/dist/src/common/options.d.ts.map +1 -1
  76. package/dist/src/common/options.js +1 -1
  77. package/dist/src/common/options.js.map +1 -1
  78. package/dist/src/common/xml.d.ts +37 -3
  79. package/dist/src/common/xml.d.ts.map +1 -1
  80. package/dist/src/common/xml.js +86 -6
  81. package/dist/src/common/xml.js.map +1 -1
  82. package/dist/src/common/zip.d.ts +92 -0
  83. package/dist/src/common/zip.d.ts.map +1 -0
  84. package/dist/src/common/zip.js +399 -0
  85. package/dist/src/common/zip.js.map +1 -0
  86. package/dist/src/formats/cx/importer.d.ts +133 -0
  87. package/dist/src/formats/cx/importer.d.ts.map +1 -0
  88. package/dist/src/formats/cx/importer.js +2220 -0
  89. package/dist/src/formats/cx/importer.js.map +1 -0
  90. package/dist/src/formats/cx/index.d.ts +7 -0
  91. package/dist/src/formats/cx/index.d.ts.map +1 -0
  92. package/dist/src/formats/cx/index.js +7 -0
  93. package/dist/src/formats/cx/index.js.map +1 -0
  94. package/dist/src/formats/cx2/exporter.d.ts +59 -0
  95. package/dist/src/formats/cx2/exporter.d.ts.map +1 -0
  96. package/dist/src/formats/cx2/exporter.js +864 -0
  97. package/dist/src/formats/cx2/exporter.js.map +1 -0
  98. package/dist/src/formats/cx2/importer.d.ts +169 -0
  99. package/dist/src/formats/cx2/importer.d.ts.map +1 -0
  100. package/dist/src/formats/cx2/importer.js +1652 -0
  101. package/dist/src/formats/cx2/importer.js.map +1 -0
  102. package/dist/src/formats/cx2/index.d.ts +7 -0
  103. package/dist/src/formats/cx2/index.d.ts.map +1 -0
  104. package/dist/src/formats/cx2/index.js +7 -0
  105. package/dist/src/formats/cx2/index.js.map +1 -0
  106. package/dist/src/formats/cys/constants.d.ts +68 -0
  107. package/dist/src/formats/cys/constants.d.ts.map +1 -0
  108. package/dist/src/formats/cys/constants.js +76 -0
  109. package/dist/src/formats/cys/constants.js.map +1 -0
  110. package/dist/src/formats/cys/importer.d.ts +38 -0
  111. package/dist/src/formats/cys/importer.d.ts.map +1 -0
  112. package/dist/src/formats/cys/importer.js +830 -0
  113. package/dist/src/formats/cys/importer.js.map +1 -0
  114. package/dist/src/formats/cys/index.d.ts +7 -0
  115. package/dist/src/formats/cys/index.d.ts.map +1 -0
  116. package/dist/src/formats/cys/index.js +7 -0
  117. package/dist/src/formats/cys/index.js.map +1 -0
  118. package/dist/src/formats/cys/session.d.ts +132 -0
  119. package/dist/src/formats/cys/session.d.ts.map +1 -0
  120. package/dist/src/formats/cys/session.js +315 -0
  121. package/dist/src/formats/cys/session.js.map +1 -0
  122. package/dist/src/formats/cys/tables.d.ts +90 -0
  123. package/dist/src/formats/cys/tables.d.ts.map +1 -0
  124. package/dist/src/formats/cys/tables.js +293 -0
  125. package/dist/src/formats/cys/tables.js.map +1 -0
  126. package/dist/src/formats/dot/exporter.d.ts +2 -0
  127. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  128. package/dist/src/formats/dot/exporter.js +12 -0
  129. package/dist/src/formats/dot/exporter.js.map +1 -1
  130. package/dist/src/formats/dot/importer.js +6 -2
  131. package/dist/src/formats/dot/importer.js.map +1 -1
  132. package/dist/src/formats/gexf/exporter.d.ts +2 -0
  133. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/gexf/exporter.js +6 -0
  135. package/dist/src/formats/gexf/exporter.js.map +1 -1
  136. package/dist/src/formats/gexf/importer.d.ts +0 -2
  137. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  138. package/dist/src/formats/gexf/importer.js +1 -3
  139. package/dist/src/formats/gexf/importer.js.map +1 -1
  140. package/dist/src/formats/gexf/index.d.ts +1 -1
  141. package/dist/src/formats/gexf/index.js +2 -2
  142. package/dist/src/formats/gexf/index.js.map +1 -1
  143. package/dist/src/formats/gml/exporter.d.ts +0 -8
  144. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  145. package/dist/src/formats/gml/exporter.js +8 -18
  146. package/dist/src/formats/gml/exporter.js.map +1 -1
  147. package/dist/src/formats/json/importer.d.ts.map +1 -1
  148. package/dist/src/formats/json/importer.js +6 -104
  149. package/dist/src/formats/json/importer.js.map +1 -1
  150. package/dist/src/formats/xgmml/columns.d.ts +152 -0
  151. package/dist/src/formats/xgmml/columns.d.ts.map +1 -0
  152. package/dist/src/formats/xgmml/columns.js +593 -0
  153. package/dist/src/formats/xgmml/columns.js.map +1 -0
  154. package/dist/src/formats/xgmml/constants.d.ts +196 -0
  155. package/dist/src/formats/xgmml/constants.d.ts.map +1 -0
  156. package/dist/src/formats/xgmml/constants.js +197 -0
  157. package/dist/src/formats/xgmml/constants.js.map +1 -0
  158. package/dist/src/formats/xgmml/document.d.ts +361 -0
  159. package/dist/src/formats/xgmml/document.d.ts.map +1 -0
  160. package/dist/src/formats/xgmml/document.js +695 -0
  161. package/dist/src/formats/xgmml/document.js.map +1 -0
  162. package/dist/src/formats/xgmml/emit.d.ts +341 -0
  163. package/dist/src/formats/xgmml/emit.d.ts.map +1 -0
  164. package/dist/src/formats/xgmml/emit.js +1275 -0
  165. package/dist/src/formats/xgmml/emit.js.map +1 -0
  166. package/dist/src/formats/xgmml/exporter.d.ts +24 -0
  167. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -0
  168. package/dist/src/formats/xgmml/exporter.js +999 -0
  169. package/dist/src/formats/xgmml/exporter.js.map +1 -0
  170. package/dist/src/formats/xgmml/importer.d.ts +58 -0
  171. package/dist/src/formats/xgmml/importer.d.ts.map +1 -0
  172. package/dist/src/formats/xgmml/importer.js +360 -0
  173. package/dist/src/formats/xgmml/importer.js.map +1 -0
  174. package/dist/src/formats/xgmml/index.d.ts +8 -0
  175. package/dist/src/formats/xgmml/index.d.ts.map +1 -0
  176. package/dist/src/formats/xgmml/index.js +8 -0
  177. package/dist/src/formats/xgmml/index.js.map +1 -0
  178. package/dist/src/formats/xgmml/values.d.ts +60 -0
  179. package/dist/src/formats/xgmml/values.d.ts.map +1 -0
  180. package/dist/src/formats/xgmml/values.js +148 -0
  181. package/dist/src/formats/xgmml/values.js.map +1 -0
  182. package/dist/src/index.d.ts +4 -0
  183. package/dist/src/index.d.ts.map +1 -1
  184. package/dist/src/index.js +4 -0
  185. package/dist/src/index.js.map +1 -1
  186. package/dist/src/registry.d.ts +7 -0
  187. package/dist/src/registry.d.ts.map +1 -1
  188. package/dist/src/registry.js +30 -10
  189. package/dist/src/registry.js.map +1 -1
  190. package/dist/src/sniff.d.ts +1 -1
  191. package/dist/src/sniff.d.ts.map +1 -1
  192. package/dist/src/sniff.js +4 -0
  193. package/dist/src/sniff.js.map +1 -1
  194. package/dist/xgmml.d.ts +1 -0
  195. package/dist/xgmml.js +9 -0
  196. package/dist/xgmml.js.map +1 -0
  197. package/package.json +25 -2
  198. package/src/common/cell-budget.ts +170 -0
  199. package/src/common/input.ts +40 -0
  200. package/src/common/json-elements.ts +1147 -0
  201. package/src/common/options.ts +1 -1
  202. package/src/common/xml.ts +127 -6
  203. package/src/common/zip.ts +472 -0
  204. package/src/formats/cx/importer.ts +2733 -0
  205. package/src/formats/cx/index.ts +7 -0
  206. package/src/formats/cx2/exporter.ts +1036 -0
  207. package/src/formats/cx2/importer.ts +2187 -0
  208. package/src/formats/cx2/index.ts +7 -0
  209. package/src/formats/cys/constants.ts +99 -0
  210. package/src/formats/cys/importer.ts +1100 -0
  211. package/src/formats/cys/index.ts +7 -0
  212. package/src/formats/cys/session.ts +428 -0
  213. package/src/formats/cys/tables.ts +400 -0
  214. package/src/formats/dot/exporter.ts +17 -0
  215. package/src/formats/dot/importer.ts +6 -2
  216. package/src/formats/gexf/exporter.ts +11 -0
  217. package/src/formats/gexf/importer.ts +1 -2
  218. package/src/formats/gexf/index.ts +1 -1
  219. package/src/formats/gml/exporter.ts +8 -19
  220. package/src/formats/json/importer.ts +6 -105
  221. package/src/formats/xgmml/columns.ts +747 -0
  222. package/src/formats/xgmml/constants.ts +265 -0
  223. package/src/formats/xgmml/document.ts +975 -0
  224. package/src/formats/xgmml/emit.ts +1563 -0
  225. package/src/formats/xgmml/exporter.ts +1215 -0
  226. package/src/formats/xgmml/importer.ts +491 -0
  227. package/src/formats/xgmml/index.ts +8 -0
  228. package/src/formats/xgmml/values.ts +183 -0
  229. package/src/index.ts +19 -0
  230. package/src/registry.ts +46 -15
  231. package/src/sniff.ts +18 -1
  232. package/dist/chunks/escape-D-gZWO26.js.map +0 -1
  233. package/dist/chunks/importer-Br_QeAeE.js.map +0 -1
  234. package/dist/chunks/importer-Du5crN9l.js.map +0 -1
  235. package/dist/chunks/writer-GAdltGmC.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importer-DD-xv9_Y.js","sources":["../../src/formats/cys/constants.ts","../../src/common/zip.ts","../../src/formats/cys/session.ts","../../src/formats/cys/tables.ts","../../src/formats/cys/importer.ts"],"sourcesContent":["/**\n * What the Cytoscape session importer's modules share: the format facts, the column and metadata\n * names it adds, and its issue code table (design `design/graph-io/cytoscape-and-obo/design.md`\n * sections 1.4 and 3).\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n DANGLING_REFERENCE_CODE,\n EMPTY_INPUT_CODE,\n GRAPH_NOT_FOUND_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE,\n STYLES_NOT_IMPORTED_CODE,\n TOO_LARGE_CODE,\n} from \"../../common/codes.js\";\nimport { XGMML_ISSUE } from \"../xgmml/constants.js\";\n\n/** The format name. */\nexport const FORMAT = \"cys\";\n\n/** File extensions. */\nexport const EXTENSIONS: readonly string[] = Object.freeze([\".cys\"]);\n\n/** MIME types: Cytoscape declares none, so the generic zip type. */\nexport const MIME_TYPES: readonly string[] = Object.freeze([\"application/zip\"]);\n\n/** The `meta.extra` key of the session facts. */\nexport const META_KEY = \"cytoscape\";\n\n/** The origin namespace of the columns the session importer adds (selection, hidden state). */\nexport const CYTOSCAPE_NAMESPACE = \"cytoscape\";\n\n/** The 2.x selected state (bool node and edge column). */\nexport const SELECTED_COLUMN = \"cytoscape.selected\";\n\n/** The 2.x hidden state (bool node and edge column). */\nexport const HIDDEN_COLUMN = \"cytoscape.hidden\";\n\n/** The prefix of the node columns of a second and further view's positions (`position@2`). */\nexport const VIEW_POSITION_PREFIX = \"position@\";\n\n/** The default total of uncompressed bytes one import may inflate (2 GiB). */\nexport const DEFAULT_MAX_UNCOMPRESSED = 2 * 1024 * 1024 * 1024;\n\n/** The largest uncompressed-to-compressed ratio an entry may have (real sessions reach 30:1). */\nexport const MAX_RATIO = 1000;\n\n/**\n * The XGMML codes the session importer relays from the network and view files inside, keyed as\n * every table is (the code without its `E_` / `W_` prefix).\n */\nconst RELAYED: Readonly<Record<string, string>> = Object.fromEntries(\n Object.values(XGMML_ISSUE).map((code) => [code.replace(/^[EW]_/, \"\"), code]),\n);\n\n/**\n * Issue codes of the Cytoscape session importer: its own, the shared ones it records and the\n * XGMML codes it relays from the files inside (with the entry name in the message).\n */\nexport const CYS_ISSUE = Object.freeze({\n ...RELAYED,\n /** The input is not a zip archive (or is text). */\n NOT_ZIP: \"E_CYS_NOT_ZIP\",\n /** The archive is damaged: no end record, offsets outside the file, a bad CRC, truncated data. */\n CORRUPT: \"E_CYS_CORRUPT\",\n /** A zip without a session marker (`<x.y.z>.version` or `cysession.xml`). */\n NOT_SESSION: \"E_CYS_NOT_SESSION\",\n /** A zip feature the reader does not support: encryption, a compression method, split archives. */\n UNSUPPORTED: \"E_CYS_UNSUPPORTED\",\n /** A session version graph-io cannot read: a major above 3, or the 2011 3.0 pre-release layout. */\n VERSION: \"E_CYS_VERSION\",\n /** A table or a virtual column that cannot be read at all; it is skipped. */\n TABLE: \"E_CYS_TABLE\",\n /** Table rows with too few or too many cells, a repeated key, or a key matching no element. */\n TABLE_ROW: \"W_CYS_TABLE_ROW\",\n /** A collapsed group's members are not in the network; they are recorded in meta.extra. */\n COLLAPSED_GROUP: \"W_CYS_COLLAPSED_GROUP\",\n /** Entries the importer does not read (apps, global tables, properties, images, thumbnails). */\n ENTRY_SKIPPED: \"W_CYS_ENTRY_SKIPPED\",\n /** Two entries with one name; the first is read. */\n DUPLICATE_ENTRY: \"W_CYS_DUPLICATE_ENTRY\",\n /** The archive inflates beyond maxUncompressedBytes, or an entry beyond the ratio limit. */\n TOO_LARGE: TOO_LARGE_CODE,\n /** The session's styles are not applied (issue #706). */\n STYLES_NOT_IMPORTED: STYLES_NOT_IMPORTED_CODE,\n /** A view, table or network the session names but does not hold. */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The input is empty. */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The session holds no network. */\n NO_GRAPH: NO_GRAPH_CODE,\n /** The session holds several 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});\n","/**\n * A zip reader with no dependency (design `design/graph-io/cytoscape-and-obo/design.md` section\n * 3.3; PKWARE APPNOTE 6.3.10, https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT), for\n * the Cytoscape session importer.\n *\n * The whole archive is in memory: every Cytoscape-written entry has a data descriptor and zero\n * sizes in its local header, so the sizes come from the central directory at the end. The end\n * record is searched in the last 65,557 bytes (a comment can be 65,535 bytes long); the zip64\n * locator and the `0x0001` extra field are followed; bytes prepended to the archive (a\n * self-extracting stub) are tolerated by the shift between the directory's stated and actual\n * offsets. Deflate (method 8) is inflated by wrapping the raw deflate bytes in a gzip member\n * (header, data, the directory's CRC-32 and size) and passing it to `DecompressionStream(\"gzip\")`,\n * which every supported runtime has (Node 18, unlike `\"deflate-raw\"`) and which checks the CRC and\n * the length itself; stored entries (method 0) are checked against a CRC-32 table here. Every\n * other method, and encryption, is refused by name. Entry names are decoded by `decodeEntryName()`\n * (the one place bytes become text) and are matching keys only, never paths.\n */\n\nimport { decodeEntryName, throwIfAborted } from \"./input.js\";\n\n/** Why a zip could not be read; the importer maps each kind to its own issue code. */\ntype ZipErrorKind = \"not-zip\" | \"corrupt\" | \"unsupported\" | \"too-large\";\n\n/** A zip that cannot be read, or an entry that cannot be inflated. */\nexport class ZipError extends Error {\n /** What went wrong. */\n readonly kind: ZipErrorKind;\n\n /**\n * Create the error.\n * @param kind - what went wrong\n * @param message - a plain-ASCII message\n */\n constructor(kind: ZipErrorKind, message: string) {\n super(message);\n this.name = \"ZipError\";\n this.kind = kind;\n }\n}\n\n/** One entry of the central directory. */\nexport interface ZipEntry {\n /** The name, decoded, as the central directory spells it. */\n readonly name: string;\n /** The compression method (0 stored, 8 deflate, ...). */\n readonly method: number;\n /** The general purpose bit flags. */\n readonly flags: number;\n /** The CRC-32 of the uncompressed data. */\n readonly crc32: number;\n /** The compressed size in bytes. */\n readonly compressedSize: number;\n /** The uncompressed size in bytes. */\n readonly size: number;\n /** The offset of the local header in the archive bytes (the prepended-data shift applied). */\n readonly localOffset: number;\n /** The name ends in `/`: a directory entry, which holds no data. */\n readonly directory: boolean;\n}\n\n/** How one entry is read. */\nexport interface ReadEntryOptions {\n /** The cancellation signal. */\n readonly signal?: AbortSignal | null | undefined;\n /** Called with the bytes inflated so far by this call. */\n readonly onBytes?: ((inflated: number) => void) | undefined;\n /** The most uncompressed bytes this entry may have (the import's remaining budget). */\n readonly maxBytes: number;\n /** The largest uncompressed-to-compressed ratio allowed (above `RATIO_FLOOR` bytes). */\n readonly maxRatio: number;\n}\n\n/** A per-entry size under which the ratio limit does not apply (tiny entries compress well). */\nexport const RATIO_FLOOR = 1024 * 1024;\n\nconst EOCD_SIGNATURE = 0x06054b50;\nconst ZIP64_LOCATOR_SIGNATURE = 0x07064b50;\nconst ZIP64_EOCD_SIGNATURE = 0x06064b50;\nconst CENTRAL_SIGNATURE = 0x02014b50;\nconst LOCAL_SIGNATURE = 0x04034b50;\nconst EOCD_SIZE = 22;\nconst MAX_COMMENT = 65535;\nconst CENTRAL_SIZE = 46;\nconst LOCAL_SIZE = 30;\nconst ZIP64_EOCD_SIZE = 56;\nconst ZIP64_LOCATOR_SIZE = 20;\nconst U16_MAX = 0xffff;\nconst U32_MAX = 0xffffffff;\n/** Bytes between two cancellation checks while a stored entry's CRC is computed. */\nconst CRC_SLICE = 1024 * 1024;\n\n/** The compression methods other tools write, by number, for the refusal message. */\nconst METHOD_NAMES: Readonly<Record<number, string>> = {\n 1: \"shrink\",\n 6: \"implode\",\n 9: \"deflate64\",\n 12: \"bzip2\",\n 14: \"LZMA\",\n 93: \"zstd\",\n 95: \"xz\",\n 96: \"JPEG\",\n 97: \"WavPack\",\n 98: \"PPMd\",\n 99: \"AES encryption\",\n};\n\n/**\n * Whether bytes start with a local file header signature (`PK\\x03\\x04`).\n * @param bytes - the bytes\n * @returns true for the start of a zip\n */\nexport function startsLikeZip(bytes: Uint8Array): boolean {\n return bytes.byteLength >= 4 && bytes[0] === 0x50 && bytes[1] === 0x4b && bytes[2] === 3 && bytes[3] === 4;\n}\n\n/**\n * Read the central directory.\n * @param bytes - the whole archive\n * @returns the entries in directory order; ZipError \"not-zip\" when there is no end record and the\n * bytes do not start like a zip, \"corrupt\" for an end record or directory that does not fit,\n * \"unsupported\" for a split archive\n */\nexport function readZipDirectory(bytes: Uint8Array): ZipEntry[] {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const eocd = findEndRecord(bytes, view);\n if (eocd < 0) {\n throw startsLikeZip(bytes)\n ? new ZipError(\"corrupt\", \"the archive has no end of central directory record (truncated?)\")\n : new ZipError(\"not-zip\", \"the input is not a zip archive\");\n }\n let disk = view.getUint16(eocd + 4, true);\n let directoryDisk = view.getUint16(eocd + 6, true);\n let count = view.getUint16(eocd + 10, true);\n let directorySize = view.getUint32(eocd + 12, true);\n let directoryOffset = view.getUint32(eocd + 16, true);\n let directoryEnd = eocd;\n const locator = eocd - ZIP64_LOCATOR_SIZE;\n if (locator >= 0 && view.getUint32(locator, true) === ZIP64_LOCATOR_SIGNATURE) {\n const record = zip64EndRecord(view, locator);\n disk = view.getUint32(record + 16, true);\n directoryDisk = view.getUint32(record + 20, true);\n count = readU64(view, record + 32);\n directorySize = readU64(view, record + 40);\n directoryOffset = readU64(view, record + 48);\n directoryEnd = record;\n } else if (count === U16_MAX || directorySize === U32_MAX || directoryOffset === U32_MAX) {\n throw new ZipError(\"corrupt\", \"the end record needs a zip64 record the archive does not have\");\n }\n if (disk !== 0 || directoryDisk !== 0) {\n throw new ZipError(\"unsupported\", \"a split (multi-disk) archive cannot be read\");\n }\n const start = directoryEnd - directorySize;\n if (start < 0 || directoryOffset > bytes.byteLength) {\n throw new ZipError(\"corrupt\", \"the central directory lies outside the archive\");\n }\n // data prepended to the archive moves every offset by the same amount\n const shift = start - directoryOffset;\n if (shift < 0) {\n throw new ZipError(\"corrupt\", \"the central directory offset does not match its position\");\n }\n const entries: ZipEntry[] = [];\n let at = start;\n for (let i = 0; i < count; i++) {\n if (at + CENTRAL_SIZE > directoryEnd || view.getUint32(at, true) !== CENTRAL_SIGNATURE) {\n throw new ZipError(\"corrupt\", `central directory entry ${i + 1} of ${count} is damaged`);\n }\n const nameLength = view.getUint16(at + 28, true);\n const extraLength = view.getUint16(at + 30, true);\n const commentLength = view.getUint16(at + 32, true);\n const next = at + CENTRAL_SIZE + nameLength + extraLength + commentLength;\n if (next > directoryEnd) {\n throw new ZipError(\"corrupt\", `central directory entry ${i + 1} runs past the directory`);\n }\n const name = decodeEntryName(bytes.subarray(at + CENTRAL_SIZE, at + CENTRAL_SIZE + nameLength));\n let compressedSize = view.getUint32(at + 20, true);\n let size = view.getUint32(at + 24, true);\n let localOffset = view.getUint32(at + 42, true);\n if (compressedSize === U32_MAX || size === U32_MAX || localOffset === U32_MAX) {\n ({ compressedSize, size, localOffset } = zip64Extra(view, at + CENTRAL_SIZE + nameLength, extraLength, {\n compressedSize,\n size,\n localOffset,\n }));\n }\n entries.push(\n Object.freeze({\n name,\n method: view.getUint16(at + 10, true),\n flags: view.getUint16(at + 8, true),\n crc32: view.getUint32(at + 16, true),\n compressedSize,\n size,\n localOffset: localOffset + shift,\n directory: name.endsWith(\"/\"),\n }),\n );\n at = next;\n }\n return entries;\n}\n\n/**\n * The position of the end of central directory record: the last signature whose comment length\n * fits the archive, else the last signature at all (an archive with bytes after its comment).\n * @param bytes - the archive\n * @param view - a view of it\n * @returns the offset, or -1\n */\nfunction findEndRecord(bytes: Uint8Array, view: DataView): number {\n const lowest = Math.max(0, bytes.byteLength - EOCD_SIZE - MAX_COMMENT);\n let fallback = -1;\n for (let at = bytes.byteLength - EOCD_SIZE; at >= lowest; at--) {\n if (view.getUint32(at, true) !== EOCD_SIGNATURE) {\n continue;\n }\n if (at + EOCD_SIZE + view.getUint16(at + 20, true) === bytes.byteLength) {\n return at;\n }\n if (fallback < 0) {\n fallback = at;\n }\n }\n return fallback;\n}\n\n/**\n * The zip64 end of central directory record a locator points at (or, when the archive has bytes\n * prepended, the one right before the locator).\n * @param view - the archive\n * @param locator - the locator's offset\n * @returns the record's offset\n */\nfunction zip64EndRecord(view: DataView, locator: number): number {\n const stated = readU64(view, locator + 8);\n for (const at of [stated, locator - ZIP64_EOCD_SIZE]) {\n if (at >= 0 && at + ZIP64_EOCD_SIZE <= locator && view.getUint32(at, true) === ZIP64_EOCD_SIGNATURE) {\n return at;\n }\n }\n throw new ZipError(\"corrupt\", \"the zip64 end record the locator names is missing\");\n}\n\n/**\n * The zip64 extended information extra field (header id 0x0001) of a central entry: the 64-bit\n * values of the fields whose 32-bit slot is 0xFFFFFFFF, in the order APPNOTE 4.5.3 gives.\n * @param view - the archive\n * @param at - the start of the extra field\n * @param length - its length\n * @param fields - the 32-bit values\n * @param fields.compressedSize - the compressed size slot\n * @param fields.size - the uncompressed size slot\n * @param fields.localOffset - the local header offset slot\n * @returns the resolved values\n */\nfunction zip64Extra(\n view: DataView,\n at: number,\n length: number,\n fields: { compressedSize: number; size: number; localOffset: number },\n): { compressedSize: number; size: number; localOffset: number } {\n const out = { ...fields };\n for (let p = at; p + 4 <= at + length; ) {\n const id = view.getUint16(p, true);\n const dataLength = view.getUint16(p + 2, true);\n if (id === 1) {\n let q = p + 4;\n const end = q + dataLength;\n for (const key of [\"size\", \"compressedSize\", \"localOffset\"] as const) {\n if (fields[key] === U32_MAX) {\n if (q + 8 > end) {\n throw new ZipError(\"corrupt\", \"a zip64 extra field is too short\");\n }\n out[key] = readU64(view, q);\n q += 8;\n }\n }\n return out;\n }\n p += 4 + dataLength;\n }\n throw new ZipError(\"corrupt\", \"an entry needs a zip64 extra field it does not have\");\n}\n\n/**\n * An unsigned 64-bit little-endian integer as a number (exact up to 2^53).\n * @param view - the bytes\n * @param at - the offset\n * @returns the value; ZipError \"unsupported\" beyond 2^53\n */\nfunction readU64(view: DataView, at: number): number {\n const high = view.getUint32(at + 4, true);\n if (high >= 0x200000) {\n throw new ZipError(\"unsupported\", \"a zip64 size or offset beyond 2^53 cannot be read\");\n }\n return high * 0x100000000 + view.getUint32(at, true);\n}\n\n/**\n * Read one entry's data: stored entries are sliced and CRC-checked, deflated ones inflated.\n * @param bytes - the whole archive\n * @param entry - the entry\n * @param options - cancellation, progress and the size limits\n * @returns the uncompressed bytes; ZipError for a damaged, encrypted, unsupported or oversized entry\n */\nexport async function readZipEntry(bytes: Uint8Array, entry: ZipEntry, options: ReadEntryOptions): Promise<Uint8Array> {\n if ((entry.flags & 1) !== 0 || entry.method === 99) {\n throw new ZipError(\"unsupported\", `${entry.name}: the entry is encrypted`);\n }\n if (entry.method !== 0 && entry.method !== 8) {\n const name = METHOD_NAMES[entry.method] ?? `method ${entry.method}`;\n throw new ZipError(\n \"unsupported\",\n `${entry.name}: compression ${name} is not supported (only stored and deflate)`,\n );\n }\n if (entry.size > options.maxBytes) {\n throw new ZipError(\n \"too-large\",\n `${entry.name}: ${entry.size} uncompressed bytes exceed the limit of ${options.maxBytes}`,\n );\n }\n if (entry.size > RATIO_FLOOR && entry.size > options.maxRatio * Math.max(entry.compressedSize, 1)) {\n throw new ZipError(\n \"too-large\",\n `${entry.name}: ${entry.size} bytes from ${entry.compressedSize} is a compression ratio above ${options.maxRatio}:1`,\n );\n }\n const data = entryData(bytes, entry);\n if (entry.method === 0) {\n if (data.byteLength !== entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: a stored entry's sizes disagree`);\n }\n let crc = 0xffffffff;\n for (let at = 0; at < data.byteLength; at += CRC_SLICE) {\n throwIfAborted(options.signal);\n crc = crcUpdate(crc, data.subarray(at, Math.min(at + CRC_SLICE, data.byteLength)));\n options.onBytes?.(Math.min(at + CRC_SLICE, data.byteLength));\n }\n if ((crc ^ 0xffffffff) >>> 0 !== entry.crc32) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data does not match its CRC-32`);\n }\n return data;\n }\n return inflate(data, entry, options);\n}\n\n/**\n * The compressed bytes of an entry, located through its local header (whose name and extra\n * lengths can differ from the central directory's).\n * @param bytes - the archive\n * @param entry - the entry\n * @returns exactly compressedSize bytes\n */\nfunction entryData(bytes: Uint8Array, entry: ZipEntry): Uint8Array {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const at = entry.localOffset;\n if (at + LOCAL_SIZE > bytes.byteLength || view.getUint32(at, true) !== LOCAL_SIGNATURE) {\n throw new ZipError(\"corrupt\", `${entry.name}: the local header is missing`);\n }\n const start = at + LOCAL_SIZE + view.getUint16(at + 26, true) + view.getUint16(at + 28, true);\n const end = start + entry.compressedSize;\n if (end > bytes.byteLength) {\n throw new ZipError(\"corrupt\", `${entry.name}: the entry's data runs past the end of the archive (truncated?)`);\n }\n return bytes.subarray(start, end);\n}\n\n/**\n * Inflate a deflate stream through `DecompressionStream(\"gzip\")`, wrapped in a gzip member that\n * carries the directory's CRC-32 and size, so the platform checks both.\n * @param data - the raw deflate bytes\n * @param entry - the entry\n * @param options - cancellation, progress and limits\n * @returns the bytes\n */\nasync function inflate(data: Uint8Array, entry: ZipEntry, options: ReadEntryOptions): Promise<Uint8Array> {\n if (typeof DecompressionStream !== \"function\") {\n throw new ZipError(\n \"unsupported\",\n \"this runtime has no DecompressionStream, so deflated entries cannot be read\",\n );\n }\n const member = new Uint8Array(10 + data.byteLength + 8);\n member.set([0x1f, 0x8b, 8, 0, 0, 0, 0, 0, 0, 0xff]);\n member.set(data, 10);\n const trailer = new DataView(member.buffer, 10 + data.byteLength, 8);\n trailer.setUint32(0, entry.crc32, true);\n trailer.setUint32(4, entry.size % 0x100000000, true);\n const source = new ReadableStream<BufferSource>({\n start(controller): void {\n controller.enqueue(member);\n controller.close();\n },\n });\n const reader = source.pipeThrough(new DecompressionStream(\"gzip\")).getReader();\n const parts: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n throwIfAborted(options.signal);\n let chunk: ReadableStreamReadResult<Uint8Array>;\n try {\n chunk = await reader.read();\n } catch {\n throw new ZipError(\n \"corrupt\",\n `${entry.name}: the deflate data is damaged or does not match its CRC-32 and size`,\n );\n }\n if (chunk.done) {\n break;\n }\n total += chunk.value.byteLength;\n if (total > entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data is longer than its directory size`);\n }\n parts.push(chunk.value);\n options.onBytes?.(total);\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n if (total !== entry.size) {\n throw new ZipError(\"corrupt\", `${entry.name}: the data is shorter than its directory size`);\n }\n if (parts.length === 1) {\n return parts[0];\n }\n const out = new Uint8Array(total);\n let at = 0;\n for (const part of parts) {\n out.set(part, at);\n at += part.byteLength;\n }\n return out;\n}\n\n/** The CRC-32 table (polynomial 0xEDB88320). */\nconst CRC_TABLE = ((): Uint32Array => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = (c & 1) === 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\n/**\n * Continue a CRC-32 over more bytes.\n * @param crc - the running value (start with 0xFFFFFFFF)\n * @param bytes - the bytes\n * @returns the running value (XOR with 0xFFFFFFFF to finish)\n */\nfunction crcUpdate(crc: number, bytes: Uint8Array): number {\n let c = crc;\n for (const byte of bytes) {\n c = CRC_TABLE[(c ^ byte) & 0xff] ^ (c >>> 8);\n }\n return c >>> 0;\n}\n\n/**\n * The CRC-32 of bytes.\n * @param bytes - the bytes\n * @returns the checksum\n */\nexport function crc32(bytes: Uint8Array): number {\n return (crcUpdate(0xffffffff, bytes) ^ 0xffffffff) >>> 0;\n}\n","/**\n * The layout of a Cytoscape session archive (`research-session-and-style.md` sections 2.1 to 2.3;\n * Cytoscape's `Cy3SessionReaderImpl`, `Cy2SessionReaderImpl` and `SessionUtil`): which entries\n * are the version marker, the networks, views, tables, styles and the rest, read from the central\n * directory alone. Entries are inflated one at a time, only when asked for, within the import's\n * byte budget.\n */\n\nimport { readBytes, textChunks } from \"../../common/input.js\";\nimport { type ResolvedImportOptions } from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { tokenizeXml, xmlDeclaredEncoding, XmlSyntaxError } from \"../../common/xml.js\";\nimport { readZipDirectory, readZipEntry, type ZipEntry, ZipError } from \"../../common/zip.js\";\nimport { ImportError, type ImportInput } from \"../../types.js\";\nimport { CYS_ISSUE, FORMAT, MAX_RATIO } from \"./constants.js\";\n\n/** An entry of the session, by its path under the session's root folder. */\nexport interface SessionEntry {\n /** The path under the root folder, as the archive spells it (URL-encoded parts). */\n readonly path: string;\n /** The full entry name, for messages. */\n readonly name: string;\n /** The zip entry. */\n readonly zip: ZipEntry;\n}\n\n/** A 3.x network file: one root network (a collection). */\nexport interface NetworkEntry extends SessionEntry {\n /** The root network's saved SUID. */\n readonly suid: string;\n /** The file name's network name, decoded. */\n readonly title: string;\n}\n\n/** A 3.x view file. */\ninterface ViewEntry extends SessionEntry {\n /** The SUID of the network the view shows. */\n readonly network: string;\n /** The view's SUID. */\n readonly view: string;\n}\n\n/** A 3.x table file. */\nexport interface TableEntry extends SessionEntry {\n /** The path under `tables/` (what `cytables.xml` names). */\n readonly tablePath: string;\n /** The SUID of the network the table belongs to. */\n readonly network: string;\n /** The namespace: LOCAL_ATTRS, SHARED_ATTRS, HIDDEN or an app's. */\n readonly namespace: string;\n /** The element class: CyNode, CyEdge or CyNetwork. */\n readonly element: \"node\" | \"edge\" | \"network\" | null;\n}\n\n/** What a session archive holds, by kind. */\ninterface SessionLayout {\n /** \"3\" for a 3.x session, \"2\" for a 2.x one. */\n readonly era: \"2\" | \"3\";\n /** The version marker as written (`3.0.0`), or the 2.x cysession.xml documentVersion. */\n readonly version: string;\n /** The root folder, with its trailing slash (\"\" when the entries have none). */\n readonly root: string;\n readonly networks: readonly NetworkEntry[];\n readonly views: readonly ViewEntry[];\n readonly tables: readonly TableEntry[];\n /** `tables/cytables.xml`, if present. */\n readonly cytables: SessionEntry | null;\n /** `apps/org.cytoscape.swing-application/network_list.xml`, if present. */\n readonly networkList: SessionEntry | null;\n /** 2.x: `cysession.xml`. */\n readonly cysession: SessionEntry | null;\n /** 2.x: the network files by their path. */\n readonly files: ReadonlyMap<string, SessionEntry>;\n /** The style entries (`session_vizmap.xml`, `session_vizmap.props`). */\n readonly styles: readonly SessionEntry[];\n /** Every entry the importer does not read. */\n readonly skipped: readonly string[];\n}\n\n/** An opened session: its bytes, its layout and an entry reader within the byte budget. */\nexport interface Session {\n readonly layout: SessionLayout;\n /**\n * Inflate one entry.\n * @param entry - the entry\n * @returns its bytes\n */\n read(entry: SessionEntry): Promise<Uint8Array>;\n}\n\n/**\n * Java's `URLDecoder.decode` (UTF-8): `+` is a space, `%XX` a byte; a malformed escape leaves the\n * text as it is.\n * @param text - the encoded text\n * @returns the decoded text\n */\nexport function urlDecode(text: string): string {\n const plus = text.replace(/\\+/g, \" \");\n try {\n return decodeURIComponent(plus);\n } catch {\n return plus;\n }\n}\n\n/**\n * Read the input as a zip and lay out its session entries. Fatal: text input or not a zip\n * (E_CYS_NOT_ZIP), an empty input, a damaged archive (E_CYS_CORRUPT), a split archive\n * (E_CYS_UNSUPPORTED), no session marker (E_CYS_NOT_SESSION), a version graph-io cannot read\n * (E_CYS_VERSION).\n * @param input - the input\n * @param report - the report\n * @param common - cancellation and progress\n * @param maxBytes - the import's uncompressed byte budget\n * @returns the session\n */\nexport async function openSession(\n input: ImportInput,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n maxBytes: number,\n): Promise<Session> {\n const bytes = await readBytes(input, common);\n if (bytes === null) {\n report.fail(\n CYS_ISSUE.NOT_ZIP,\n \"a Cytoscape session is a zip archive; text input cannot hold one (pass the bytes)\",\n );\n }\n if (bytes.byteLength === 0) {\n report.fail(CYS_ISSUE.EMPTY_INPUT, \"the input is empty\");\n }\n let zipEntries: ZipEntry[];\n try {\n zipEntries = readZipDirectory(bytes);\n } catch (err) {\n return zipFailure(err, report);\n }\n const layout = layoutOf(zipEntries, report);\n let budget = maxBytes;\n let inflated = 0;\n const total = zipEntries.reduce((sum, e) => sum + e.size, 0);\n return {\n layout,\n read: async (entry: SessionEntry): Promise<Uint8Array> => {\n const before = inflated;\n try {\n const data = await readZipEntry(bytes, entry.zip, {\n signal: common.signal,\n maxBytes: budget,\n maxRatio: MAX_RATIO,\n onBytes: (n) => common.onProgress?.(before + n, total),\n });\n budget -= data.byteLength;\n inflated += data.byteLength;\n return data;\n } catch (err) {\n return zipFailure(err, report);\n }\n },\n };\n}\n\n/**\n * Fail the import with the fatal issue of a zip error (any other error is rethrown).\n * @param err - the error\n * @param report - the report\n */\nfunction zipFailure(err: unknown, report: ImportReportBuilder): never {\n if (!(err instanceof ZipError)) {\n throw err;\n }\n const code = {\n \"not-zip\": CYS_ISSUE.NOT_ZIP,\n corrupt: CYS_ISSUE.CORRUPT,\n unsupported: CYS_ISSUE.UNSUPPORTED,\n \"too-large\": CYS_ISSUE.TOO_LARGE,\n }[err.kind];\n if (err.kind === \"too-large\") {\n // the size limits are not a parse error: graph-io records E_TOO_LARGE as unsupported\n report.error(\"unsupported\", code, err.message);\n throw report.abort(err.message, { code });\n }\n report.fail(code, err.message);\n}\n\n/** A 3.x network entry name: `<SUID>[-<name>].xgmml`. */\nconst NETWORK_FILE = /^networks\\/(\\d+)(?:-([^/]*))?\\.xgmml$/;\n/** A 3.x view entry name: `<networkSUID>-<viewSUID>[-<title>].xgmml`. */\nconst VIEW_FILE = /^views\\/(\\d+)-(\\d+)(?:-[^/]*)?\\.xgmml$/;\n/** A 3.x table: `tables/<networkSUID>[-<name>]/<namespace>-<class>-<title>.cytable`. */\nconst TABLE_FILE = /^tables\\/((\\d+)(?:-[^/]*)?\\/([^/-]+)-([^/-]+)-[^/]*\\.cytable)$/;\n\n/** Entries of other tools that carry nothing: macOS resource forks and folder metadata. */\nconst NOISE = /(^|\\/)(__MACOSX\\/|\\.DS_Store$)/;\n\n/**\n * Lay out the entries: drop directory entries and macOS noise, keep the first of a repeated name\n * (W_CYS_DUPLICATE_ENTRY), find the session marker and its root folder, classify what is under\n * it, and list what is not read.\n * @param zipEntries - the central directory\n * @param report - the report\n * @returns the layout\n */\nfunction layoutOf(zipEntries: readonly ZipEntry[], report: ImportReportBuilder): SessionLayout {\n const byName = new Map<string, ZipEntry>();\n const repeated: string[] = [];\n for (const entry of zipEntries) {\n if (entry.directory || NOISE.test(entry.name)) {\n continue;\n }\n if (byName.has(entry.name)) {\n repeated.push(entry.name);\n continue;\n }\n byName.set(entry.name, entry);\n }\n if (repeated.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.DUPLICATE_ENTRY,\n `${repeated.length} entry name(s) appear more than once; the first of each is read: ${listed(repeated)}`,\n );\n }\n const names = [...byName.keys()];\n const marker = names.find((n) => /^([^/]*\\/)?[^/]+\\.version$/.test(n));\n const cysession = names.find((n) => /^([^/]*\\/)?cysession\\.xml$/.test(n));\n if (marker === undefined && cysession === undefined) {\n report.fail(\n CYS_ISSUE.NOT_SESSION,\n \"the zip holds neither a session version marker (<x.y.z>.version) nor cysession.xml: it is not a Cytoscape session\",\n );\n }\n const anchor = marker ?? (cysession as string);\n const root = anchor.slice(0, anchor.lastIndexOf(\"/\") + 1);\n let era: \"2\" | \"3\" = \"2\";\n let version = \"2.0.0\";\n if (marker !== undefined) {\n version = marker.slice(root.length, -\".version\".length);\n const major = Number(version.split(\".\")[0]);\n if (!Number.isInteger(major) || major > 3) {\n report.fail(\n CYS_ISSUE.VERSION,\n `the session version ${version} is newer than the Cytoscape 3 sessions graph-io reads`,\n );\n }\n era = major === 3 ? \"3\" : \"2\";\n }\n const layout = {\n era,\n version,\n root,\n networks: [] as NetworkEntry[],\n views: [] as ViewEntry[],\n tables: [] as TableEntry[],\n cytables: null as SessionEntry | null,\n networkList: null as SessionEntry | null,\n cysession: null as SessionEntry | null,\n files: new Map<string, SessionEntry>(),\n styles: [] as SessionEntry[],\n skipped: [] as string[],\n };\n for (const [name, zip] of byName) {\n if (!name.startsWith(root) || name === marker) {\n if (name !== marker) {\n layout.skipped.push(name);\n }\n continue;\n }\n const path = name.slice(root.length);\n const entry: SessionEntry = { path, name, zip };\n if (era === \"3\") {\n classify3(entry, layout);\n } else {\n classify2(entry, layout);\n }\n }\n return layout;\n}\n\n/**\n * Classify one entry of a 3.x session.\n * @param entry - the entry\n * @param layout - the layout being built\n */\nfunction classify3(entry: SessionEntry, layout: Mutable): void {\n const { path } = entry;\n const network = NETWORK_FILE.exec(path);\n const view = VIEW_FILE.exec(path);\n const table = TABLE_FILE.exec(path);\n if (network !== null) {\n layout.networks.push({ ...entry, suid: network[1], title: urlDecode(network[2] ?? \"\") });\n } else if (view !== null) {\n layout.views.push({ ...entry, network: view[1], view: view[2] });\n } else if (path === \"tables/cytables.xml\") {\n layout.cytables = entry;\n } else if (table !== null) {\n const element = {\n \"org.cytoscape.model.CyNode\": \"node\",\n \"org.cytoscape.model.CyEdge\": \"edge\",\n \"org.cytoscape.model.CyNetwork\": \"network\",\n }[urlDecode(table[4])] as TableEntry[\"element\"] | undefined;\n layout.tables.push({\n ...entry,\n tablePath: table[1],\n network: table[2],\n namespace: urlDecode(table[3]),\n element: element ?? null,\n });\n } else if (path === \"apps/org.cytoscape.swing-application/network_list.xml\") {\n layout.networkList = entry;\n } else if (/(^|\\/)session_vizmap\\.(xml|props)$/.test(path)) {\n layout.styles.push(entry);\n } else {\n layout.skipped.push(entry.name);\n }\n}\n\n/**\n * Classify one entry of a 2.x session.\n * @param entry - the entry\n * @param layout - the layout being built\n */\nfunction classify2(entry: SessionEntry, layout: Mutable): void {\n const { path } = entry;\n if (path === \"cysession.xml\") {\n layout.cysession = entry;\n } else if (/^[^/]+\\.xgmml$/.test(path)) {\n layout.files.set(path, entry);\n } else if (/^session_vizmap\\.(props|xml)$/.test(path)) {\n layout.styles.push(entry);\n } else {\n layout.skipped.push(entry.name);\n }\n}\n\n/** The layout while it is built. */\ntype Mutable = {\n -readonly [K in keyof SessionLayout]: SessionLayout[K] extends readonly (infer T)[] ? T[] : SessionLayout[K];\n} & { files: Map<string, SessionEntry> };\n\n/**\n * A list of names for a message: the first ten, then a count.\n * @param names - the names\n * @returns the text\n */\nexport function listed(names: readonly string[]): string {\n const head = names.slice(0, 10).join(\", \");\n return names.length > 10 ? `${head} and ${names.length - 10} more` : head;\n}\n\n/** One element of a small XML document, as a tree. */\nexport interface XmlNode {\n /** The local name. */\n readonly name: string;\n /** The attributes by name as written (prefix included). */\n readonly attrs: ReadonlyMap<string, string>;\n /** The child elements. */\n readonly children: XmlNode[];\n}\n\n/**\n * Read a small XML entry (`cytables.xml`, `network_list.xml`, `cysession.xml`) as a tree. A\n * document that is not well-formed is E_CYS_CORRUPT naming the entry.\n * @param bytes - the entry's bytes\n * @param entry - the entry name\n * @param report - the report\n * @param common - cancellation\n * @returns the root element\n */\nexport async function readXmlTree(\n bytes: Uint8Array,\n entry: string,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): Promise<XmlNode> {\n const scratch = new ImportReportBuilder(FORMAT, 0);\n const stack: XmlNode[] = [{ name: \"\", attrs: new Map(), children: [] }];\n try {\n await tokenizeXml(\n textChunks(bytes, scratch, { signal: common.signal, declaredEncoding: xmlDeclaredEncoding }),\n {\n start(name, attrs): void {\n const node: XmlNode = { name: name.slice(name.lastIndexOf(\":\") + 1), attrs, children: [] };\n stack[stack.length - 1].children.push(node);\n stack.push(node);\n },\n end(): void {\n stack.pop();\n },\n text(): void {\n // the session documents keep everything in attributes\n },\n },\n );\n } catch (err) {\n if (err instanceof XmlSyntaxError || err instanceof ImportError) {\n report.fail(CYS_ISSUE.CORRUPT, `${entry}: ${err.message}`);\n }\n throw err;\n }\n const [root] = stack[0].children;\n if (root === undefined) {\n report.fail(CYS_ISSUE.CORRUPT, `${entry}: the document is empty`);\n }\n return root;\n}\n\n/**\n * Every element of a tree with a local name, depth first.\n * @param node - the tree\n * @param name - the local name\n * @returns the elements\n */\nexport function elementsNamed(node: XmlNode, name: string): XmlNode[] {\n const out: XmlNode[] = [];\n const stack = [node];\n while (stack.length > 0) {\n const n = stack.pop() as XmlNode;\n if (n.name === name) {\n out.push(n);\n }\n for (let i = n.children.length - 1; i >= 0; i--) {\n stack.push(n.children[i]);\n }\n }\n return out;\n}\n","/**\n * The tables of a Cytoscape 3 session: the CyCSV `.cytable` files (`research-session-and-style.md`\n * section 2.4; Cytoscape's `CSVCyReader`) and the virtual columns `tables/cytables.xml` joins into\n * them. Cells become XGMML att records, typed by the column's Java class, so the XGMML emitter\n * applies the same column rules (types, widening, equations, hidden columns, renames) to a\n * session's tables as to an XGMML file's atts.\n */\n\nimport { type ResolvedImportOptions } from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { ImportError } from \"../../types.js\";\nimport { CsvRecordReader } from \"../csv/records.js\";\nimport { type AttRec } from \"../xgmml/document.js\";\nimport { CYS_ISSUE, FORMAT } from \"./constants.js\";\n\n/** The Cytoscape type names of the Java classes a CyCSV column can hold. */\nconst JAVA_TYPES: Readonly<Record<string, string>> = {\n \"java.lang.String\": \"String\",\n \"java.lang.Long\": \"Long\",\n \"java.lang.Integer\": \"Integer\",\n \"java.lang.Double\": \"Double\",\n \"java.lang.Boolean\": \"Boolean\",\n};\n\n/** A list column's class: `java.util.List<java.lang.X>`. */\nconst LIST_CLASS = /^java\\.util\\.List<\\s*([\\w.]+)\\s*>$/;\n\n/** One column of a table. */\ninterface CyColumn {\n /** The name. */\n readonly name: string;\n /** The Cytoscape type of a scalar column, or of a list's items. */\n readonly type: string;\n /** A list column. */\n readonly list: boolean;\n}\n\n/** One table, read. */\nexport interface CyTable {\n /** The table's path under `tables/` as the archive spells it (what cytables.xml names). */\n readonly path: string;\n /** The entry name, for messages. */\n readonly entry: string;\n /** The columns; the first is the primary key. */\n readonly columns: readonly CyColumn[];\n /** The rows by key text, in file order (the first row of a repeated key). */\n readonly rows: ReadonlyMap<string, readonly string[]>;\n /** The line each row starts on, by key. */\n readonly lines: ReadonlyMap<string, number>;\n}\n\n/** What a table read reports besides its rows. */\ninterface RowProblems {\n short: number;\n long: number;\n repeated: number;\n}\n\n/**\n * Read one CyCSV table. A table that cannot be read at all (an unknown CyCSV version or column\n * class, a malformed header, broken CSV) is recorded as E_CYS_TABLE and skipped (null); rows with\n * the wrong number of cells or a repeated key are counted in one W_CYS_TABLE_ROW.\n * @param bytes - the entry's bytes\n * @param path - the table's path under `tables/`\n * @param entry - the entry name, for messages\n * @param report - the import's report\n * @param common - cancellation\n * @returns the table, or null\n */\nexport async function readCyTable(\n bytes: Uint8Array,\n path: string,\n entry: string,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): Promise<CyTable | null> {\n const scratch = new ImportReportBuilder(FORMAT, 0);\n const reader = new CsvRecordReader(bytes, scratch, { delimiter: \",\", encoding: \"utf-8\", signal: common.signal });\n const records: { readonly cells: string[]; readonly line: number }[] = [];\n try {\n for await (const cells of reader) {\n records.push({ cells, line: reader.line });\n }\n } catch (err) {\n if (err instanceof ImportError) {\n return tableError(report, entry, scratch.issues.at(-1)?.message ?? err.message);\n }\n throw err;\n }\n let at = 0;\n let version = 0;\n if (records[0]?.cells.length === 2 && records[0].cells[0] === \"CyCSV-Version\") {\n version = Number(records[0].cells[1]);\n at = 1;\n }\n if (version !== 0 && version !== 1) {\n return tableError(report, entry, `CyCSV version \"${records[0].cells[1]}\" is not 0 or 1`);\n }\n // version 1: names, types, column options, table title; version 0: names, types, table title\n const headerLines = version === 1 ? 4 : 3;\n if (records.length < at + headerLines) {\n return tableError(report, entry, \"the table header is incomplete\");\n }\n const names = records[at].cells;\n const classes = records[at + 1].cells;\n if (names.length === 0 || classes.length !== names.length) {\n return tableError(report, entry, `${names.length} column name(s) but ${classes.length} column class(es)`);\n }\n const columns: CyColumn[] = [];\n for (let i = 0; i < names.length; i++) {\n const column = columnOf(names[i], classes[i]);\n if (column === null) {\n return tableError(\n report,\n entry,\n `column \"${names[i]}\" has the class \"${classes[i]}\", which graph-io cannot read`,\n );\n }\n columns.push(column);\n }\n const rows = new Map<string, readonly string[]>();\n const lines = new Map<string, number>();\n const problems: RowProblems = { short: 0, long: 0, repeated: 0 };\n for (const record of records.slice(at + headerLines)) {\n const { cells } = record;\n if (cells.length < columns.length) {\n problems.short++;\n } else if (cells.length > columns.length) {\n problems.long++;\n }\n const key = cells[0];\n if (rows.has(key)) {\n problems.repeated++;\n continue;\n }\n rows.set(key, cells.slice(0, columns.length));\n lines.set(key, record.line);\n }\n if (problems.short + problems.long + problems.repeated > 0) {\n report.warning(\n \"parse-error\",\n CYS_ISSUE.TABLE_ROW,\n `${entry}: ${problems.short} row(s) with too few cells (the rest are unset), ${problems.long} with too many (the extra cells are ignored), ${problems.repeated} repeating a key (the first row is read)`,\n );\n }\n return { path, entry, columns, rows, lines };\n}\n\n/**\n * The column of a name and a Java class.\n * @param name - the name\n * @param javaClass - the class text\n * @returns the column, or null for a class graph-io cannot read\n */\nfunction columnOf(name: string, javaClass: string): CyColumn | null {\n const scalar = JAVA_TYPES[javaClass.trim()];\n if (scalar !== undefined) {\n return { name, type: scalar, list: false };\n }\n const list = LIST_CLASS.exec(javaClass.trim());\n const item = list === null ? undefined : JAVA_TYPES[list[1]];\n return item === undefined ? null : { name, type: item, list: true };\n}\n\n/**\n * Record E_CYS_TABLE for a table that is skipped.\n * @param report - the report\n * @param entry - the entry name\n * @param reason - why\n * @returns null\n */\nfunction tableError(report: ImportReportBuilder, entry: string, reason: string): null {\n report.error(\"parse-error\", CYS_ISSUE.TABLE, `${entry}: ${reason}; the table is not read`);\n return null;\n}\n\n/**\n * The att record of one cell, or null for an unset cell. CyCSV's rules: an empty cell is unset\n * except in a String column, where it is the empty string; a list cell holds its items separated\n * by newlines (Java's `split`, so trailing empty items vanish; an empty String-list cell is one\n * empty item, any other empty list cell unset); a cell starting with `=` is an equation.\n * @param column - the column\n * @param text - the cell text\n * @param line - the row's line\n * @param namespace - the table namespace the column belongs to (null for the network's own table)\n * @param hidden - whether the column is hidden (HIDDEN and app tables)\n * @returns the att, or null\n */\nexport function cellAtt(\n column: CyColumn,\n text: string,\n line: number,\n namespace: string | null,\n hidden: boolean,\n): AttRec | null {\n if (text.startsWith(\"=\")) {\n return att(column.name, column.list ? \"List\" : column.type, null, text, line, namespace, hidden, true);\n }\n if (!column.list) {\n if (text.length === 0 && column.type !== \"String\") {\n return null;\n }\n return att(column.name, column.type, null, text, line, namespace, hidden, false);\n }\n if (text.length === 0 && column.type !== \"String\") {\n return null;\n }\n const list = att(column.name, \"List\", column.type, null, line, namespace, hidden, false);\n for (const item of javaSplitLines(text)) {\n if (item.length === 0 && column.type !== \"String\") {\n continue;\n }\n list.children.push(att(column.name, column.type, null, item, line, namespace, hidden, false));\n }\n return list;\n}\n\n/**\n * Java's `String.split(\"\\n\")`: trailing empty strings are removed, and a text without a newline\n * is itself (so `\"\"` is one empty item).\n * @param text - the cell\n * @returns the items\n */\nfunction javaSplitLines(text: string): string[] {\n if (!text.includes(\"\\n\")) {\n return [text];\n }\n const items = text.split(\"\\n\");\n while (items.length > 0 && items[items.length - 1].length === 0) {\n items.pop();\n }\n return items;\n}\n\n/**\n * An att record.\n * @param name - the name\n * @param cyType - the Cytoscape type\n * @param elementType - a list's item type, or null\n * @param value - the value, or null\n * @param line - the line\n * @param namespace - the table namespace, or null\n * @param hidden - a hidden column\n * @param equation - the value is a formula\n * @returns the record\n */\nfunction att(\n name: string,\n cyType: string,\n elementType: string | null,\n value: string | null,\n line: number,\n namespace: string | null,\n hidden: boolean,\n equation: boolean,\n): AttRec {\n return {\n name,\n type: null,\n cyType,\n elementType,\n value,\n hidden,\n equation,\n children: [],\n extra: {},\n xml: null,\n hasGraph: false,\n text: \"\",\n line,\n namespace,\n };\n}\n\n/** One virtual column of `tables/cytables.xml`. */\nexport interface VirtualColumn {\n /** The column name in the target table. */\n readonly name: string;\n /** The target table's path under `tables/`. */\n readonly targetTable: string;\n /** The source table's path. */\n readonly sourceTable: string;\n /** The source column's name. */\n readonly sourceColumn: string;\n /** The join column of the source (normally SUID). */\n readonly sourceJoinKey: string;\n /** The join column of the target (normally SUID). */\n readonly targetJoinKey: string;\n}\n\n/** A resolved virtual column: its type and its value per target row key. */\ninterface VirtualValues {\n readonly column: CyColumn;\n readonly values: ReadonlyMap<string, string>;\n}\n\n/**\n * Resolve the virtual columns of one table: each one's values joined from its source table,\n * following a source that is itself a virtual column. A column whose source table or column is\n * missing, or whose sources form a cycle, is E_CYS_TABLE and skipped.\n * @param target - the table\n * @param virtuals - every virtual column of the session\n * @param tableOf - reads (and caches) a table by path, null when it cannot be read or is absent\n * @param report - the report\n * @returns the virtual columns of the table, in cytables.xml order\n */\nexport async function virtualColumnsOf(\n target: CyTable,\n virtuals: readonly VirtualColumn[],\n tableOf: (path: string) => Promise<CyTable | null>,\n report: ImportReportBuilder,\n): Promise<VirtualValues[]> {\n const out: VirtualValues[] = [];\n for (const virtual of virtuals) {\n if (virtual.targetTable !== target.path) {\n continue;\n }\n const resolved = await resolve(virtual, virtuals, tableOf, new Set());\n if (typeof resolved === \"string\") {\n report.error(\n \"parse-error\",\n CYS_ISSUE.TABLE,\n `${target.entry}: the virtual column \"${virtual.name}\" ${resolved}; the column is not read`,\n );\n continue;\n }\n const targetKey = target.columns.findIndex((c) => c.name === virtual.targetJoinKey);\n const values = new Map<string, string>();\n for (const [key, cells] of target.rows) {\n const join = targetKey <= 0 ? key : cells[targetKey];\n const value = join === undefined ? undefined : resolved.values.get(join);\n if (value !== undefined) {\n values.set(key, value);\n }\n }\n out.push({ column: { ...resolved.column, name: virtual.name }, values });\n }\n return out;\n}\n\n/**\n * The values of a virtual column's source, by the source's join key.\n * @param virtual - the virtual column\n * @param virtuals - every virtual column\n * @param tableOf - the table reader\n * @param seen - the virtual columns on the current chain (a cycle check)\n * @returns the values, or the reason they cannot be read\n */\nasync function resolve(\n virtual: VirtualColumn,\n virtuals: readonly VirtualColumn[],\n tableOf: (path: string) => Promise<CyTable | null>,\n seen: Set<VirtualColumn>,\n): Promise<VirtualValues | string> {\n if (seen.has(virtual)) {\n return \"is part of a cycle of virtual columns\";\n }\n seen.add(virtual);\n const source = await tableOf(virtual.sourceTable);\n if (source === null) {\n return `names the source table \"${virtual.sourceTable}\", which the session does not hold or cannot read`;\n }\n const joinIndex = source.columns.findIndex((c) => c.name === virtual.sourceJoinKey);\n if (joinIndex < 0) {\n return `joins on the column \"${virtual.sourceJoinKey}\", which its source table does not have`;\n }\n const joinOf = (key: string, cells: readonly string[]): string | undefined =>\n joinIndex === 0 ? key : cells[joinIndex];\n const own = source.columns.findIndex((c) => c.name === virtual.sourceColumn);\n if (own >= 0) {\n const values = new Map<string, string>();\n for (const [key, cells] of source.rows) {\n const join = joinOf(key, cells);\n if (join !== undefined && cells[own] !== undefined) {\n values.set(join, cells[own]);\n }\n }\n return { column: source.columns[own], values };\n }\n const chained = virtuals.find((v) => v.targetTable === source.path && v.name === virtual.sourceColumn);\n if (chained === undefined) {\n return `names the source column \"${virtual.sourceColumn}\", which its source table does not have`;\n }\n const inner = await resolve(chained, virtuals, tableOf, seen);\n if (typeof inner === \"string\") {\n return inner;\n }\n // re-key the chained values (by the chained source's join key) to this source's join key\n const values = new Map<string, string>();\n const chainedJoin = source.columns.findIndex((c) => c.name === chained.targetJoinKey);\n for (const [key, cells] of source.rows) {\n const lookup = chainedJoin <= 0 ? key : cells[chainedJoin];\n const value = lookup === undefined ? undefined : inner.values.get(lookup);\n const join = joinOf(key, cells);\n if (value !== undefined && join !== undefined) {\n values.set(join, value);\n }\n }\n return { column: inner.column, values };\n}\n","/**\n * The Cytoscape session importer (design `design/graph-io/cytoscape-and-obo/design.md` sections\n * 1.4 and 3; `research-session-and-style.md`). A session is a zip of every network of a Cytoscape\n * desktop; the unit of import is the registered subnetwork (3.x) or the network (2.x), one\n * snapshot each: `import()` reads the one `graphIndex` / `graphName` picks (the first by default),\n * `importAll()` every one, and `listGraphs()` lists them from the network files alone.\n *\n * 3.x: the network file gives the topology (shared nodes through `xlink:href`, per-edge direction,\n * groups, nested-network pointers); the subnetwork's CyCSV tables give its columns (LOCAL_ATTRS as\n * they are, the SHARED_ATTRS columns `cytables.xml` joins in, HIDDEN and app tables as hidden\n * columns under their namespace); its first view gives positions (y flipped) and the `graphics`\n * column, further views `position@<n>` columns. 2.x: one full XGMML file per network, with\n * selection and hidden state from `cysession.xml`. Everything is resolved by the XGMML emitter, so\n * both readers share every column rule. Styles are not read (issue #706): W_STYLES_NOT_IMPORTED.\n */\n\nimport { GraphFormatError, type GraphSink, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { declareResolved } from \"../../common/attributes.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { decodeEntryName, readBytes, 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 { startsLikeZip } from \"../../common/zip.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type GraphListing,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { XGMML_ISSUE, XGMML_ORIGIN_NAMESPACE } from \"../xgmml/constants.js\";\nimport {\n type AttRec,\n type EdgeRec,\n type GraphRec,\n isCyTrue,\n type NodeRec,\n type XgmmlDocument,\n} from \"../xgmml/document.js\";\nimport {\n type Dialect,\n dialectOf,\n type EmitExtras,\n membersOf,\n XgmmlEmitter,\n type XgmmlSettings,\n} from \"../xgmml/emit.js\";\nimport { parseXgmml, resolveSettings } from \"../xgmml/importer.js\";\nimport {\n CYS_ISSUE,\n CYTOSCAPE_NAMESPACE,\n DEFAULT_MAX_UNCOMPRESSED,\n EXTENSIONS,\n FORMAT,\n HIDDEN_COLUMN,\n META_KEY,\n MIME_TYPES,\n SELECTED_COLUMN,\n VIEW_POSITION_PREFIX,\n} from \"./constants.js\";\nimport {\n elementsNamed,\n listed,\n type NetworkEntry,\n openSession,\n readXmlTree,\n type Session,\n type SessionEntry,\n type TableEntry,\n urlDecode,\n type XmlNode,\n} from \"./session.js\";\nimport { cellAtt, type CyTable, readCyTable, type VirtualColumn, virtualColumnsOf } from \"./tables.js\";\n\n/** The format-specific options of the session importer. */\nexport interface CysImportOptions extends GraphChoiceOptions {\n /** Where Cytoscape's z (a stacking order) goes: the `z` column (default) or the position. */\n zAs?: \"column\" | \"position\" | undefined;\n /**\n * The most bytes one import may inflate, in total (default 2 GiB); an entry beyond it, or one\n * whose compression ratio is above 1000:1, is E_TOO_LARGE.\n */\n maxUncompressedBytes?: number | undefined;\n}\n\n/** The per-format defaults: SUIDs as written, edges directed unless they say otherwise, no weight. */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = {\n ids: \"keep\",\n defaultDirected: true,\n weightFrom: null,\n addMissingNodes: false,\n};\n\n/** The common options the session 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]);\n\n/** One network the session holds: a registered subnetwork of a 3.x network file, or a 2.x network. */\ntype Choice = Choice3 | Choice2;\n\n/** A registered subnetwork of a 3.x network file. */\ninterface Choice3 {\n readonly era: \"3\";\n readonly network: NetworkEntry;\n readonly graphId: string;\n readonly name: string | null;\n readonly nodes: number;\n readonly edges: number;\n}\n\n/** A 2.x network and its `cysession.xml` record. */\ninterface Choice2 {\n readonly era: \"2\";\n readonly file: SessionEntry;\n readonly name: string;\n readonly record: XmlNode;\n readonly parent: string | null;\n}\n\n/** What every import call sets up. */\ninterface Prepared {\n readonly report: ImportReportBuilder;\n readonly common: ResolvedImportOptions;\n /** The options the entries inside are read with: no progress, no encoding override. */\n readonly inner: ResolvedImportOptions;\n readonly zAs: \"column\" | \"position\";\n readonly session: Session;\n readonly choices: readonly Choice[];\n /** The network file documents parsed for the listing, by entry name (3.x). */\n readonly docs: Map<string, Parsed>;\n}\n\n/** A parsed XGMML entry. */\ninterface Parsed {\n readonly doc: XgmmlDocument;\n readonly dialect: Dialect;\n}\n\n/**\n * The maxUncompressedBytes option, checked.\n * @param value - the caller's value\n * @returns the byte budget; E_UNSUPPORTED for anything but a positive number\n */\nfunction budgetOption(value: unknown): number {\n if (value === undefined) {\n return DEFAULT_MAX_UNCOMPRESSED;\n }\n if (typeof value !== \"number\" || !(value > 0)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option maxUncompressedBytes: ${JSON.stringify(value)} is not a positive number`,\n {\n option: \"maxUncompressedBytes\",\n found: value,\n },\n );\n }\n return value;\n}\n\n/**\n * Resolve the options, open the archive and list its networks.\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: (CysImportOptions & 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 const { zAs } = resolveSettings({ zAs: options?.zAs }, false);\n const maxBytes = budgetOption(options?.maxUncompressedBytes);\n const session = await openSession(input, report, common, maxBytes);\n const inner: ResolvedImportOptions = Object.freeze({ ...common, onProgress: null, encoding: null });\n const docs = new Map<string, Parsed>();\n const choices =\n session.layout.era === \"3\"\n ? await networks3(session, report, inner, docs)\n : await networks2(session, report, inner);\n return { report, common, inner, zAs, session, choices, docs };\n}\n\n/**\n * Read an XGMML entry. Its issues are relayed into the import's report with the entry name in\n * the message; a fatal one fails the import.\n * @param session - the session\n * @param entry - the entry\n * @param report - the import's report\n * @param inner - the options entries are read with\n * @returns the document and its dialect\n */\nasync function parseEntry(\n session: Session,\n entry: SessionEntry,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<Parsed> {\n const bytes = await session.read(entry);\n const scratch = new ImportReportBuilder(FORMAT, Number.MAX_SAFE_INTEGER);\n try {\n const doc = await parseXgmml(bytes, scratch, inner, undefined);\n const dialect = dialectOf(doc, scratch);\n relay(scratch.issues, report, entry.name);\n return { doc, dialect };\n } catch (err) {\n if (!(err instanceof ImportError)) {\n throw err;\n }\n const { issues } = scratch;\n const fatal = issues.at(-1);\n relay(issues.slice(0, -1), report, entry.name);\n return report.fail(fatal?.code ?? CYS_ISSUE.CORRUPT, `${entry.name}: ${fatal?.message ?? err.message}`, {\n line: fatal?.line ?? null,\n });\n }\n}\n\n/**\n * Record issues of an entry in the import's report, the entry name before each message.\n * @param issues - the issues\n * @param report - the import's report\n * @param entry - the entry name\n */\nfunction relay(issues: ImportReport[\"issues\"], report: ImportReportBuilder, entry: string): void {\n for (const issue of issues) {\n const where = { line: issue.line, element: issue.element };\n if (issue.severity === \"error\") {\n report.error(issue.category, issue.code, `${entry}: ${issue.message}`, where);\n } else {\n report.warning(issue.category, issue.code, `${entry}: ${issue.message}`, where);\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------- 3.x\n\n/**\n * The registered subnetworks of a 3.x session, in `network_list.xml` order (else entry order).\n * @param session - the session\n * @param report - the report\n * @param inner - the options entries are read with\n * @param docs - where the parsed network files are kept\n * @returns the networks\n */\nasync function networks3(\n session: Session,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n docs: Map<string, Parsed>,\n): Promise<Choice3[]> {\n const { layout } = session;\n const choices: Choice3[] = [];\n for (const network of layout.networks) {\n const parsed = await parseEntry(session, network, report, inner);\n docs.set(network.name, parsed);\n for (const graph of registeredGraphs(parsed)) {\n const members = membersOf(parsed.doc, graph);\n choices.push({\n era: \"3\",\n network,\n graphId: graph.id ?? \"\",\n name: graph.label ?? graph.id,\n nodes: new Set(members.nodes).size,\n edges: members.edges.length,\n });\n }\n }\n const known = new Set(choices.map((c) => c.graphId));\n const strayViews = layout.views.filter((v) => !known.has(v.network)).map((v) => v.name);\n const strayTables = layout.tables.filter(\n (t) =>\n !known.has(t.network) &&\n !layout.networks.some((n) => n.suid === t.network) &&\n !isGroupTable(t, session, docs),\n );\n if (strayViews.length > 0 || strayTables.length > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `${strayViews.length + strayTables.length} view(s) or table(s) belong to a network the session does not hold and were not read: ${listed([...strayViews, ...strayTables.map((t) => t.name)])}`,\n );\n }\n if (layout.networkList === null) {\n return choices;\n }\n const tree = await readXmlTree(await session.read(layout.networkList), layout.networkList.name, report, inner);\n const order = new Map<string, number>();\n for (const node of elementsNamed(tree, \"network\")) {\n const id = node.attrs.get(\"id\");\n const position = Number(node.attrs.get(\"order\"));\n if (id !== undefined && Number.isFinite(position)) {\n order.set(id, position);\n }\n }\n return choices\n .map((choice, index) => ({ choice, index }))\n .sort(\n (a, b) =>\n (order.get(a.choice.graphId) ?? Infinity) - (order.get(b.choice.graphId) ?? Infinity) ||\n a.index - b.index,\n )\n .map((c) => c.choice);\n}\n\n/**\n * Whether a table belongs to a graph declared in some network file (a group's network): those are\n * read with their network, not reported.\n * @param table - the table\n * @param session - the session\n * @param docs - the parsed network files\n * @returns true for a table of a known graph\n */\nfunction isGroupTable(table: TableEntry, session: Session, docs: ReadonlyMap<string, Parsed>): boolean {\n for (const network of session.layout.networks) {\n if (docs.get(network.name)?.doc.graphs.some((g) => g.id === table.network) === true) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The registered subnetworks of a network file (`cy:registered` true under the root).\n * @param parsed - the network file\n * @returns the graphs\n */\nfunction registeredGraphs(parsed: Parsed): GraphRec[] {\n return parsed.doc.root.subgraphs.filter((g) => isCyTrue(g.registered));\n}\n\n/**\n * Import one registered subnetwork of a 3.x session.\n * @param prepared - the prepared import\n * @param choice - the subnetwork\n * @param sink - the sink\n * @param parsed - its network file, parsed for this import (its records are filled in)\n */\nasync function import3(prepared: Prepared, choice: Choice3, sink: GraphSink, parsed: Parsed): Promise<void> {\n const { report, inner, session } = prepared;\n const { layout } = session;\n const { doc, dialect } = parsed;\n const graph = doc.root.subgraphs.find((g) => g.id === choice.graphId) as GraphRec;\n const members = membersOf(doc, graph);\n const nodes = byId(members.nodes);\n const edges = byId(members.edges);\n const cache = new Map<string, Promise<CyTable | null>>();\n const tableOf = (path: string): Promise<CyTable | null> => {\n let pending = cache.get(path);\n if (pending === undefined) {\n const entry = layout.tables.find((t) => t.tablePath === path);\n pending =\n entry === undefined\n ? Promise.resolve(null)\n : session.read(entry).then((bytes) => readCyTable(bytes, path, entry.name, report, inner));\n cache.set(path, pending);\n }\n return pending;\n };\n const virtuals = layout.cytables === null ? [] : await readVirtuals(session, layout.cytables, report, inner);\n // a row of an element the file declares outside this network (a collapsed group's member, a\n // meta-edge) is Cytoscape's bookkeeping, not a stale row\n const declared = new Set<string>([\n ...doc.nodes.flatMap((n) => (n.id === null ? [] : [n.id])),\n ...doc.edges.flatMap((e) => (e.id === null ? [] : [e.id])),\n ]);\n let unmatched = 0;\n for (const entry of layout.tables.filter((t) => t.network === choice.graphId && t.element !== null)) {\n throwIfAborted(inner.signal);\n const table = await tableOf(entry.tablePath);\n if (table === null) {\n continue;\n }\n const local = entry.namespace === \"LOCAL_ATTRS\";\n const shared = entry.namespace === \"SHARED_ATTRS\";\n const namespace = local ? null : entry.namespace;\n const hidden = !local && !shared;\n const target = (key: string): AttRec[] | undefined => {\n if (entry.element === \"network\") {\n return key === choice.graphId ? graph.atts : undefined;\n }\n return (entry.element === \"node\" ? nodes : edges).get(key)?.atts;\n };\n for (const [key, cells] of table.rows) {\n const atts = target(key);\n if (atts === undefined) {\n if (!declared.has(key)) {\n unmatched++;\n }\n continue;\n }\n const line = table.lines.get(key) ?? 0;\n for (let i = 1; i < table.columns.length && i < cells.length; i++) {\n const att = cellAtt(table.columns[i], cells[i], line, namespace, hidden);\n if (att !== null) {\n atts.push(att);\n }\n }\n }\n for (const virtual of await virtualColumnsOf(table, virtuals, tableOf, report)) {\n // a shared column named like a local one is renamed; the local one keeps the name\n const owned = table.columns.some((c) => c.name === virtual.column.name);\n let ns = namespace;\n if (local) {\n ns = owned ? \"SHARED_ATTRS\" : null;\n }\n for (const [key, text] of virtual.values) {\n const att = cellAtt(virtual.column, text, table.lines.get(key) ?? 0, ns, hidden);\n if (att !== null) {\n target(key)?.push(att);\n }\n }\n }\n }\n if (unmatched > 0) {\n report.warning(\n \"parse-error\",\n CYS_ISSUE.TABLE_ROW,\n `${unmatched} table row(s) of network ${choice.graphId} name no node, edge or network of it (stale rows); they are not read`,\n );\n }\n const views = layout.views.filter((v) => v.network === choice.graphId);\n let visualStyle: string | null = null;\n const extraViews: Map<string, [number, number, number]>[] = [];\n for (const [i, view] of views.entries()) {\n const viewDoc = (await parseEntry(session, view, report, inner)).doc;\n if (i === 0) {\n visualStyle = viewDoc.root.attrs.get(\"cy:visualStyle\") ?? null;\n applyView(viewDoc, graph, nodes, edges, report, view.name);\n } else {\n extraViews.push(viewPositions(viewDoc, prepared.zAs));\n }\n }\n const cyMeta = sessionMeta(prepared, {\n collection: doc.root.label ?? choice.network.title,\n network: choice.graphId,\n parentNetwork: parentNetwork(graph, prepared.choices),\n visualStyle,\n });\n const groups: { group: string; members: string[] }[] = [];\n cyMeta.groups = groups;\n const extras: EmitExtras = {\n sourceFormat: FORMAT,\n entry: choice.network.name,\n graphName: localName(graph) ?? choice.name,\n metaExtra: { [META_KEY]: cyMeta },\n groupNodes: new Set(\n members.nodes\n .filter((n) => n.atts.some((a) => a.name === \"__isGroup\" && isCyTrue(a.value)))\n .flatMap((n) => (n.id === null ? [] : [n.id])),\n ),\n resolvePointer: pointerResolver(prepared, doc),\n onMissingMember: (group, member): void => {\n const record = groups.find((g) => g.group === group);\n if (record === undefined) {\n groups.push({ group, members: [member] });\n } else if (!record.members.includes(member)) {\n record.members.push(member);\n }\n },\n };\n const settings: XgmmlSettings = { labelAliases: false, cytoscapeEscapes: false, zAs: prepared.zAs };\n new XgmmlEmitter(doc, dialect, sink, report, prepared.inner, settings, extras).emit(graph);\n if (groups.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.COLLAPSED_GROUP,\n `${groups.length} collapsed group(s) hold ${groups.reduce((n, g) => n + g.members.length, 0)} member(s) that are not in the network; they are listed in meta.extra.cytoscape.groups`,\n );\n }\n reportRootOnly(parsed, report, choice.network.name);\n writeViewPositions(\n sink,\n extraViews,\n views.slice(1).map((v) => v.view),\n report,\n prepared.inner,\n );\n}\n\n/**\n * The virtual columns of `tables/cytables.xml`.\n * @param session - the session\n * @param entry - the cytables.xml entry\n * @param report - the report\n * @param inner - the options entries are read with\n * @returns the virtual columns in document order\n */\nasync function readVirtuals(\n session: Session,\n entry: SessionEntry,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<VirtualColumn[]> {\n const tree = await readXmlTree(await session.read(entry), entry.name, report, inner);\n const out: VirtualColumn[] = [];\n for (const node of elementsNamed(tree, \"virtualColumn\")) {\n const a = (key: string): string => node.attrs.get(key) ?? \"\";\n out.push({\n name: a(\"name\"),\n targetTable: a(\"targetTable\"),\n sourceTable: a(\"sourceTable\"),\n sourceColumn: a(\"sourceColumn\"),\n sourceJoinKey: node.attrs.get(\"sourceJoinKey\") ?? \"SUID\",\n targetJoinKey: node.attrs.get(\"targetJoinKey\") ?? \"SUID\",\n });\n }\n return out;\n}\n\n/**\n * Records by id.\n * @param records - node or edge records\n * @returns the first record of each id\n */\nfunction byId<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/**\n * Copy a view's coordinates and graphics onto the network's records (by `cy:nodeId` and\n * `cy:edgeId`), and its network graphics onto the graph. A view element naming nothing of the\n * network is counted in one W_DANGLING_REFERENCE.\n * @param view - the view document\n * @param graph - the subnetwork\n * @param nodes - its node records by id\n * @param edges - its edge records by id\n * @param report - the report\n * @param entry - the view entry name\n */\nfunction applyView(\n view: XgmmlDocument,\n graph: GraphRec,\n nodes: ReadonlyMap<string, NodeRec>,\n edges: ReadonlyMap<string, EdgeRec>,\n report: ImportReportBuilder,\n entry: string,\n): void {\n let dangling = 0;\n for (const node of view.nodes) {\n const target = node.viewId === null ? undefined : nodes.get(node.viewId);\n if (target === undefined) {\n dangling++;\n continue;\n }\n target.x = node.x;\n target.y = node.y;\n target.z = node.z;\n if (node.graphics !== null) {\n target.graphics = { ...(target.graphics ?? {}), ...node.graphics };\n }\n }\n for (const edge of view.edges) {\n const target = edge.viewId === null ? undefined : edges.get(edge.viewId);\n if (target === undefined) {\n dangling++;\n continue;\n }\n if (edge.graphics !== null) {\n target.graphics = { ...(target.graphics ?? {}), ...edge.graphics };\n }\n }\n if (view.root.graphics !== null) {\n graph.graphics = { ...(graph.graphics ?? {}), ...view.root.graphics };\n }\n if (dangling > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `${entry}: ${dangling} view element(s) name no node or edge of the network; they are not read`,\n );\n }\n}\n\n/**\n * The positions of a further view, by model node id: y flipped to y-up, z in the position only\n * under zAs \"position\".\n * @param view - the view document\n * @param zAs - where z goes\n * @returns the positions\n */\nfunction viewPositions(view: XgmmlDocument, zAs: \"column\" | \"position\"): Map<string, [number, number, number]> {\n const out = new Map<string, [number, number, number]>();\n for (const node of view.nodes) {\n const x = Number(node.x);\n const y = Number(node.y);\n const z = zAs === \"position\" ? Number(node.z ?? 0) : 0;\n if (node.viewId !== null && node.x !== null && node.y !== null && Number.isFinite(x) && Number.isFinite(y)) {\n out.set(node.viewId, [x, y === 0 ? 0 : -y, Number.isFinite(z) ? z : 0]);\n }\n }\n return out;\n}\n\n/**\n * Write each further view's positions as a `position@<n>` column (n from 2), no role.\n * @param sink - the sink\n * @param views - the positions of each further view\n * @param viewIds - each view's SUID\n * @param report - the report\n * @param common - the id rule\n */\nfunction writeViewPositions(\n sink: GraphSink,\n views: readonly Map<string, [number, number, number]>[],\n viewIds: readonly string[],\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n): void {\n const coercer = new IdCoercer(common.ids);\n views.forEach((positions, i) => {\n const name = `${VIEW_POSITION_PREFIX}${i + 2}`;\n const { handle } = declareResolved(\n sink,\n \"node\",\n {\n name,\n dtype: \"f32\",\n components: 3,\n nullable: true,\n origin: {\n format: FORMAT,\n id: viewIds[i],\n title: null,\n type: \"graphics\",\n namespace: XGMML_ORIGIN_NAMESPACE,\n },\n extra: { sourceDims: 2, units: \"file\" },\n },\n report,\n { element: name },\n );\n for (const [id, xyz] of positions) {\n let index: number;\n try {\n index = sink.indexOf(coercer.text(id));\n } catch {\n continue; // an id the id rule refuses was refused, and recorded, as a node already\n }\n if (index !== INVALID_INDEX) {\n sink.setNodeValue(handle, index, xyz);\n }\n }\n });\n}\n\n/**\n * The network's name from its own table (the LOCAL `name` att), else null.\n * @param graph - the subnetwork with its table atts\n * @returns the name\n */\nfunction localName(graph: GraphRec): string | null {\n const att = graph.atts.find((a) => a.name === \"name\" && (a.namespace ?? null) === null);\n return att?.value ?? null;\n}\n\n/**\n * The name of the network a subnetwork was made from: the hidden `__parentNetwork.SUID` (or the\n * pre-3.4 `Cy2 Parent Network.SUID`), named when the session holds it.\n * @param graph - the subnetwork with its table atts\n * @param choices - the session's networks\n * @returns the parent's name, its SUID when unnamed, or null\n */\nfunction parentNetwork(graph: GraphRec, choices: readonly Choice[]): string | null {\n const att = graph.atts.find((a) => a.name === \"__parentNetwork.SUID\" || a.name === \"Cy2 Parent Network.SUID\");\n if (att?.value === undefined || att.value === null || att.value.length === 0) {\n return null;\n }\n const suid = att.value;\n const named = choices.find((c) => c.era === \"3\" && c.graphId === suid);\n return named?.name ?? suid;\n}\n\n/**\n * The resolver of nested-network pointers into other network files of the session\n * (`207-Set+2.xgmml#223`): the target graph's label. Only the files a pointer names are read.\n * @param prepared - the prepared import\n * @param doc - the network file being read\n * @returns the resolver\n */\nfunction pointerResolver(prepared: Prepared, doc: XgmmlDocument): (href: string) => string | null {\n const names = new Map<string, string>();\n for (const graph of doc.graphs) {\n const { href } = graph;\n const hash = href?.indexOf(\"#\") ?? -1;\n if (href === null || hash <= 0 || names.has(href)) {\n continue;\n }\n const file = urlDecode(href.slice(0, hash));\n const id = href.slice(hash + 1);\n const network = prepared.session.layout.networks.find(\n (n) => urlDecode(n.path.slice(\"networks/\".length)) === file,\n );\n const parsed = network === undefined ? undefined : prepared.docs.get(network.name);\n const target = parsed?.doc.graphs.find((g) => g.id === id);\n if (target !== undefined) {\n names.set(href, target.label ?? id);\n }\n }\n return (href) => names.get(href) ?? null;\n}\n\n/**\n * W_XGMML_ROOT_ONLY_ELEMENTS for elements of a network file no registered subnetwork holds.\n * @param parsed - the network file\n * @param report - the report\n * @param entry - the entry name\n */\nfunction reportRootOnly(parsed: Parsed, report: ImportReportBuilder, entry: string): void {\n const held = new Set<unknown>();\n for (const graph of registeredGraphs(parsed)) {\n const members = membersOf(parsed.doc, graph);\n members.nodes.forEach((n) => held.add(n));\n members.edges.forEach((e) => held.add(e));\n }\n const nodes = parsed.doc.nodes.filter((n) => !held.has(n)).length;\n const edges = parsed.doc.edges.filter((e) => !held.has(e)).length;\n if (nodes + edges > 0) {\n report.warning(\n \"unsupported\",\n XGMML_ISSUE.ROOT_ONLY_ELEMENTS,\n `${entry}: ${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// ---------------------------------------------------------------------------------------- 2.x\n\n/**\n * The networks of a 2.x session: every network of `cysession.xml`'s tree except `Network Root`,\n * in the order of their files in the archive.\n * @param session - the session\n * @param report - the report\n * @param inner - the options entries are read with\n * @returns the networks\n */\nasync function networks2(\n session: Session,\n report: ImportReportBuilder,\n inner: ResolvedImportOptions,\n): Promise<Choice2[]> {\n const { layout } = session;\n if (layout.cysession === null) {\n return report.fail(CYS_ISSUE.NOT_SESSION, \"the session has no cysession.xml\");\n }\n const tree = await readXmlTree(await session.read(layout.cysession), layout.cysession.name, report, inner);\n const documentVersion = tree.attrs.get(\"documentVersion\") ?? \"\";\n if (documentVersion.startsWith(\"3\")) {\n report.fail(\n CYS_ISSUE.VERSION,\n `cysession.xml has documentVersion ${documentVersion} and no version marker: the 2011 Cytoscape 3.0 pre-release layout, which no released Cytoscape reads`,\n );\n }\n const byDecoded = new Map<string, SessionEntry>();\n for (const [path, entry] of layout.files) {\n byDecoded.set(path, entry);\n byDecoded.set(urlDecode(path), entry);\n }\n const order = [...layout.files.values()];\n const choices: Choice2[] = [];\n const missing: string[] = [];\n const named = new Set<SessionEntry>();\n for (const record of elementsNamed(tree, \"network\")) {\n const id = record.attrs.get(\"id\") ?? \"\";\n const filename = record.attrs.get(\"filename\") ?? `${id}.xgmml`;\n if (id === \"Network Root\") {\n continue;\n }\n const file = byDecoded.get(filename);\n if (file === undefined) {\n missing.push(filename);\n continue;\n }\n named.add(file);\n const parent = record.children.find((c) => c.name === \"parent\")?.attrs.get(\"id\") ?? null;\n choices.push({\n era: \"2\",\n file,\n name: id,\n record,\n parent: parent === \"Network Root\" || parent === \"NULL\" ? null : parent,\n });\n }\n if (missing.length > 0) {\n report.warning(\n \"validation-error\",\n CYS_ISSUE.DANGLING_REFERENCE,\n `cysession.xml names ${missing.length} network file(s) the session does not hold: ${listed(missing)}`,\n );\n }\n const unnamed = order.filter((e) => !named.has(e)).map((e) => e.name);\n if (unnamed.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `${unnamed.length} network file(s) are not in cysession.xml's network tree and were not read: ${listed(unnamed)}`,\n );\n }\n return choices.sort((a, b) => order.indexOf(a.file) - order.indexOf(b.file));\n}\n\n/**\n * Import one network of a 2.x session.\n * @param prepared - the prepared import\n * @param choice - the network\n * @param sink - the sink\n */\nasync function import2(prepared: Prepared, choice: Choice2, sink: GraphSink): Promise<void> {\n const { report, inner, session } = prepared;\n const { doc, dialect } = await parseEntry(session, choice.file, report, inner);\n for (const [list, column] of [\n [\"selectedNodes\", SELECTED_COLUMN],\n [\"hiddenNodes\", HIDDEN_COLUMN],\n ] as const) {\n mark(doc.nodes, idsIn(choice.record, list), column);\n }\n for (const [list, column] of [\n [\"selectedEdges\", SELECTED_COLUMN],\n [\"hiddenEdges\", HIDDEN_COLUMN],\n ] as const) {\n mark(doc.edges, idsIn(choice.record, list), column);\n }\n const cyMeta = sessionMeta(prepared, {\n collection: null,\n network: choice.name,\n parentNetwork: choice.parent,\n visualStyle: choice.record.attrs.get(\"visualStyle\") ?? null,\n });\n const extras: EmitExtras = {\n sourceFormat: FORMAT,\n entry: choice.file.name,\n graphName: choice.name,\n metaExtra: { [META_KEY]: cyMeta },\n };\n const settings: XgmmlSettings = { labelAliases: true, cytoscapeEscapes: true, zAs: prepared.zAs };\n new XgmmlEmitter(doc, dialect, sink, report, inner, settings, extras).emit(null);\n}\n\n/**\n * The element ids a `cysession.xml` network record lists under one key (`selectedNodes`, ...).\n * @param record - the network record\n * @param list - the list element's name\n * @returns the ids (2.x node names, edge identifiers)\n */\nfunction idsIn(record: XmlNode, list: string): Set<string> {\n const out = new Set<string>();\n for (const holder of record.children.filter((c) => c.name === list)) {\n for (const item of holder.children) {\n const id = item.attrs.get(\"id\");\n if (id !== undefined) {\n out.add(id);\n }\n }\n }\n return out;\n}\n\n/**\n * Give the records 2.x lists by name (a node's name is its label; an edge is named by its id or\n * label) a true cell in a bool column of the cytoscape namespace.\n * @param records - the node or edge records\n * @param ids - the listed names\n * @param column - the column\n */\nfunction mark(records: readonly (NodeRec | EdgeRec)[], ids: ReadonlySet<string>, column: string): void {\n if (ids.size === 0) {\n return;\n }\n for (const record of records) {\n if ((record.id !== null && ids.has(record.id)) || (record.label !== null && ids.has(record.label))) {\n record.atts.push({\n name: column,\n type: null,\n cyType: \"Boolean\",\n elementType: null,\n value: \"true\",\n hidden: false,\n equation: false,\n children: [],\n extra: {},\n xml: null,\n hasGraph: false,\n text: \"\",\n line: record.line,\n namespace: CYTOSCAPE_NAMESPACE,\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------- shared\n\n/** The session facts of `meta.extra.cytoscape`. */\ninterface SessionMeta {\n sessionVersion: string;\n collection: string | null;\n network: string;\n parentNetwork: string | null;\n visualStyle: string | null;\n skippedEntries: string[];\n groups?: { group: string; members: string[] }[];\n}\n\n/**\n * The session facts of one network, and the once-per-import warnings about what is not read\n * (styles, other entries).\n * @param prepared - the prepared import\n * @param facts - the network's facts\n * @param facts.collection - the root network's name (3.x)\n * @param facts.network - the network's id\n * @param facts.parentNetwork - the network it was made from\n * @param facts.visualStyle - the style its view uses\n * @returns the record\n */\nfunction sessionMeta(\n prepared: Prepared,\n facts: { collection: string | null; network: string; parentNetwork: string | null; visualStyle: string | null },\n): SessionMeta {\n const { layout } = prepared.session;\n const { report } = prepared;\n if (layout.styles.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.STYLES_NOT_IMPORTED,\n `the session's styles (${layout.styles.map((s) => s.path).join(\", \")}) are not applied: style import is issue #706`,\n );\n }\n if (layout.skipped.length > 0) {\n report.warning(\n \"unsupported\",\n CYS_ISSUE.ENTRY_SKIPPED,\n `${layout.skipped.length} entries hold no graph data and were not read (apps, global tables, properties, images): ${listed(layout.skipped)}`,\n );\n }\n return {\n sessionVersion: layout.version,\n ...facts,\n skippedEntries: [...layout.skipped],\n };\n}\n\n/**\n * Import one network of a prepared session into a sink.\n * @param prepared - the prepared import\n * @param index - the network\n * @param sink - the sink\n * @returns the report\n */\nasync function importChoice(prepared: Prepared, index: number, sink: GraphSink): Promise<ImportReport> {\n const choice = prepared.choices[index];\n if (choice.era === \"3\") {\n const parsed = prepared.docs.get(choice.network.name) as Parsed;\n await import3(prepared, choice, sink, parsed);\n } else {\n await import2(prepared, choice, sink);\n }\n throwIfAborted(prepared.common.signal);\n return prepared.report.finish();\n}\n\n/**\n * Import one network of a session.\n * @param input - the session bytes\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError when the session cannot be read or the error limit is exceeded\n */\nasync function importCys(\n input: ImportInput,\n sink: GraphSink,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<ImportReport> {\n const prepared = await prepare(input, sink, options);\n const index = chooseGraph(\n prepared.choices.map((c) => c.name),\n options,\n prepared.report,\n );\n if (prepared.choices.length > 1) {\n prepared.report.warning(\n \"unsupported\",\n CYS_ISSUE.MULTIPLE_GRAPHS,\n `the session holds ${prepared.choices.length} networks; ${prepared.choices.length - 1} were not read (use importAll, graphIndex or graphName)`,\n );\n }\n return importChoice(prepared, index, sink);\n}\n\n/**\n * Import every network of a session, each into its own sink with its own report.\n * @param input - the session bytes\n * @param sinkFor - a sink per network\n * @param options - format-specific and common options\n * @returns one report per network\n */\nasync function importAllCys(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<ImportReport[]> {\n const bytes = (await readBytes(input, { signal: options?.signal ?? null })) ?? input;\n const first = await prepare(bytes, null, options);\n const reports: ImportReport[] = [];\n for (let i = 0; i < first.choices.length; i++) {\n const sink = sinkFor(i);\n // every network gets fresh records and a fresh report\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(await importChoice(prepared, i, sink));\n }\n return reports;\n}\n\n/**\n * List the networks of a session from its network files, without reading tables or views.\n * @param input - the session bytes\n * @param options - the options\n * @returns one listing per network; node and edge counts for 3.x sessions only\n */\nasync function listCysGraphs(\n input: ImportInput,\n options?: CysImportOptions & CommonImportOptions,\n): Promise<readonly GraphListing[]> {\n const prepared = await prepare(input, null, options);\n return prepared.choices.map((choice, index) =>\n Object.freeze({\n index,\n name: choice.name,\n nodes: choice.era === \"3\" ? choice.nodes : null,\n edges: choice.era === \"3\" ? choice.edges : null,\n }),\n );\n}\n\n/** A session's marker or folder name in the head of the archive. */\nconst SESSION_NAME = /CytoscapeSession|cysession\\.xml|\\d+\\.\\d+\\.\\d+\\.version/;\n\n/**\n * Confidence that a head of bytes is a Cytoscape session: 0.95 for a zip whose head names the\n * session folder, its version marker or cysession.xml; 0 for any other zip, so an `.xlsx`, a\n * `.docx` or a zipped GraphML ranks as no format rather than as a broken session. The zip may\n * start after a short stub (a self-extracting archive) within the head.\n * @param head - the first bytes\n * @returns the confidence\n */\nexport function sniffCys(head: Uint8Array): number {\n for (let at = 0; at + 4 <= head.byteLength; at++) {\n if (startsLikeZip(head.subarray(at))) {\n return SESSION_NAME.test(decodeEntryName(head.subarray(at))) ? 0.95 : 0;\n }\n }\n return 0;\n}\n\n/** The Cytoscape session importer. */\nexport const cysImporter: GraphImporter<CysImportOptions> = Object.freeze({\n format: FORMAT,\n extensions: EXTENSIONS,\n mimeTypes: MIME_TYPES,\n sniff: sniffCys,\n import: importCys,\n importAll: importAllCys,\n listGraphs: listCysGraphs,\n});\n"],"names":["values","att"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { a3 as SINK_OPTION_CODE, V as OPTION_IGNORED_CODE, a2 as ROLE_TAKEN_CODE, $ as RENAMED_CODE, v as ID_MERGED_CODE, D as DANGLING_REFERENCE_CODE, af as UNKNOWN_ELEMENT_CODE, m as DUPLICATE_ATTRIBUTE_CODE, p as DUPLICATE_NODE_CODE, e as BAD_VALUE_CODE, N as MISSING_ID_CODE, ag as UNKNOWN_ENCODING_CODE, s as ENCODING_FALLBACK_CODE, z as INVALID_ENCODING_CODE, F as INVALID_UTF8_CODE, r as EMPTY_INPUT_CODE, aD as resolveImportOptions, I as ImportReportBuilder, aA as reportSinkOptions, aB as reportUnusedOptions, L as LineReader, a as throwIfAborted, as as declareResolved, J as IdCoercer, q as DirectionResolver } from "./report-BOk0p5y8.js";
2
+ import { S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, R as ROLE_TAKEN_CODE, at as RENAMED_CODE, I as ID_MERGED_CODE, j as DANGLING_REFERENCE_CODE, Y as UNKNOWN_ELEMENT_CODE, i as DUPLICATE_ATTRIBUTE_CODE, d as DUPLICATE_NODE_CODE, B as BAD_VALUE_CODE, f as MISSING_ID_CODE, q as UNKNOWN_ENCODING_CODE, E as ENCODING_FALLBACK_CODE, r as INVALID_ENCODING_CODE, s as INVALID_UTF8_CODE, u as EMPTY_INPUT_CODE, v as resolveImportOptions, w as ImportReportBuilder, F as reportSinkOptions, z as reportUnusedOptions, ap as LineReader, y as throwIfAborted, L as declareResolved, K as IdCoercer, J as DirectionResolver } from "./report-B1z4WT9e.js";
3
3
  import { S as SYNONYM_SCOPES, O as OBO_NODE_COLUMNS, o as oboColumnDecl, P as PLACEHOLDER_COLUMN } from "./ontology-BnrJ4I98.js";
4
4
  const ESCAPES = Object.freeze({
5
5
  n: "\n",
@@ -1611,4 +1611,4 @@ export {
1611
1611
  OBO_ISSUE as O,
1612
1612
  oboImporter as o
1613
1613
  };
1614
- //# sourceMappingURL=importer-aNJfe0qu.js.map
1614
+ //# sourceMappingURL=importer-DEcKhsmQ.js.map