@graphty/graph-io 0.3.25 → 0.3.27

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 (581) hide show
  1. package/README.md +49 -414
  2. package/dist/chunks/children-CL3Cy0ez.js.map +1 -1
  3. package/dist/chunks/choose-DrXtu_96.js +56 -0
  4. package/dist/chunks/choose-DrXtu_96.js.map +1 -0
  5. package/dist/chunks/constants-ikG85dT8.js +231 -0
  6. package/dist/chunks/constants-ikG85dT8.js.map +1 -0
  7. package/dist/chunks/{escape-B-tkk_Cl.js → escape-D1HPTUrP.js} +390 -99
  8. package/dist/chunks/escape-D1HPTUrP.js.map +1 -0
  9. package/dist/chunks/export-CHd4tQE2.js +4333 -0
  10. package/dist/chunks/export-CHd4tQE2.js.map +1 -0
  11. package/dist/chunks/{importer-eUREhBGj.js → exporter-D23CKNqF.js} +4969 -3201
  12. package/dist/chunks/exporter-D23CKNqF.js.map +1 -0
  13. package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-DfWTgrti.js} +23 -21
  14. package/dist/chunks/exporter-DfWTgrti.js.map +1 -0
  15. package/dist/chunks/exporter-DhtW6FxK.js +3465 -0
  16. package/dist/chunks/exporter-DhtW6FxK.js.map +1 -0
  17. package/dist/chunks/{exporter-BGrsWamJ.js → exporter-IHv4nkCm.js} +38 -229
  18. package/dist/chunks/exporter-IHv4nkCm.js.map +1 -0
  19. package/dist/chunks/{importer-BWY2FFc5.js → importer-B1wmPQjr.js} +255 -77
  20. package/dist/chunks/importer-B1wmPQjr.js.map +1 -0
  21. package/dist/chunks/{importer-D_e7e7LX.js → importer-B2W_58pz.js} +399 -146
  22. package/dist/chunks/importer-B2W_58pz.js.map +1 -0
  23. package/dist/chunks/importer-BSALvkui.js +2811 -0
  24. package/dist/chunks/importer-BSALvkui.js.map +1 -0
  25. package/dist/chunks/{importer-vi3bSdtw.js → importer-BVRE--Un.js} +510 -77
  26. package/dist/chunks/importer-BVRE--Un.js.map +1 -0
  27. package/dist/chunks/{importer-DET1tg6s.js → importer-CIAzt-wo.js} +1689 -312
  28. package/dist/chunks/importer-CIAzt-wo.js.map +1 -0
  29. package/dist/chunks/{importer-DIrbbnAf.js → importer-DpEW5zeG.js} +585 -226
  30. package/dist/chunks/importer-DpEW5zeG.js.map +1 -0
  31. package/dist/chunks/{importer-zGLo8Dg_.js → importer-z_FL4VMb.js} +488 -161
  32. package/dist/chunks/importer-z_FL4VMb.js.map +1 -0
  33. package/dist/chunks/json-elements-BAmNBZok.js +1225 -0
  34. package/dist/chunks/json-elements-BAmNBZok.js.map +1 -0
  35. package/dist/chunks/ontology-export-Bab4eUA8.js +357 -0
  36. package/dist/chunks/ontology-export-Bab4eUA8.js.map +1 -0
  37. package/dist/chunks/{records-dbRkxwaq.js → records-CdlvL4RO.js} +298 -114
  38. package/dist/chunks/records-CdlvL4RO.js.map +1 -0
  39. package/dist/chunks/{text-Dr0Ifpag.js → text-DzXjAiTl.js} +29 -11
  40. package/dist/chunks/text-DzXjAiTl.js.map +1 -0
  41. package/dist/chunks/{writer-C7flM-Ih.js → writer-DxjgHwSe.js} +19 -1
  42. package/dist/chunks/writer-DxjgHwSe.js.map +1 -0
  43. package/dist/csv.js +952 -262
  44. package/dist/csv.js.map +1 -1
  45. package/dist/cx.js +6 -3
  46. package/dist/cx2.js +2 -2
  47. package/dist/cys.js +6 -3
  48. package/dist/dot.js +1 -1
  49. package/dist/gexf.js +554 -122
  50. package/dist/gexf.js.map +1 -1
  51. package/dist/gml.js +344 -87
  52. package/dist/gml.js.map +1 -1
  53. package/dist/graph-io.js +1105 -213
  54. package/dist/graph-io.js.map +1 -1
  55. package/dist/graphml.js +3 -2
  56. package/dist/graphml.js.map +1 -1
  57. package/dist/json.js +3 -2
  58. package/dist/neo4j.js +565 -158
  59. package/dist/neo4j.js.map +1 -1
  60. package/dist/obo.js +6 -3
  61. package/dist/pajek.js +1 -1
  62. package/dist/src/children.d.ts +18 -6
  63. package/dist/src/children.d.ts.map +1 -1
  64. package/dist/src/children.js +6 -3
  65. package/dist/src/children.js.map +1 -1
  66. package/dist/src/common/attributes.d.ts +29 -11
  67. package/dist/src/common/attributes.d.ts.map +1 -1
  68. package/dist/src/common/attributes.js +25 -7
  69. package/dist/src/common/attributes.js.map +1 -1
  70. package/dist/src/common/cell-budget.d.ts +9 -2
  71. package/dist/src/common/cell-budget.d.ts.map +1 -1
  72. package/dist/src/common/cell-budget.js +11 -3
  73. package/dist/src/common/cell-budget.js.map +1 -1
  74. package/dist/src/common/choose.d.ts +19 -0
  75. package/dist/src/common/choose.d.ts.map +1 -0
  76. package/dist/src/common/choose.js +72 -0
  77. package/dist/src/common/choose.js.map +1 -0
  78. package/dist/src/common/codes.d.ts +456 -66
  79. package/dist/src/common/codes.d.ts.map +1 -1
  80. package/dist/src/common/codes.js +458 -66
  81. package/dist/src/common/codes.js.map +1 -1
  82. package/dist/src/common/compare.d.ts +81 -0
  83. package/dist/src/common/compare.d.ts.map +1 -0
  84. package/dist/src/common/compare.js +394 -0
  85. package/dist/src/common/compare.js.map +1 -0
  86. package/dist/src/common/cx-export.d.ts +123 -0
  87. package/dist/src/common/cx-export.d.ts.map +1 -0
  88. package/dist/src/common/cx-export.js +334 -0
  89. package/dist/src/common/cx-export.js.map +1 -0
  90. package/dist/src/common/declared-types.d.ts +22 -2
  91. package/dist/src/common/declared-types.d.ts.map +1 -1
  92. package/dist/src/common/declared-types.js +21 -3
  93. package/dist/src/common/declared-types.js.map +1 -1
  94. package/dist/src/common/direction.d.ts +74 -50
  95. package/dist/src/common/direction.d.ts.map +1 -1
  96. package/dist/src/common/direction.js +47 -27
  97. package/dist/src/common/direction.js.map +1 -1
  98. package/dist/src/common/escape.d.ts +21 -9
  99. package/dist/src/common/escape.d.ts.map +1 -1
  100. package/dist/src/common/escape.js +39 -22
  101. package/dist/src/common/escape.js.map +1 -1
  102. package/dist/src/common/export.d.ts +144 -32
  103. package/dist/src/common/export.d.ts.map +1 -1
  104. package/dist/src/common/export.js +216 -42
  105. package/dist/src/common/export.js.map +1 -1
  106. package/dist/src/common/format.d.ts +23 -1
  107. package/dist/src/common/format.d.ts.map +1 -1
  108. package/dist/src/common/format.js +26 -1
  109. package/dist/src/common/format.js.map +1 -1
  110. package/dist/src/common/ids.d.ts +9 -2
  111. package/dist/src/common/ids.d.ts.map +1 -1
  112. package/dist/src/common/ids.js +6 -2
  113. package/dist/src/common/ids.js.map +1 -1
  114. package/dist/src/common/input.d.ts +122 -28
  115. package/dist/src/common/input.d.ts.map +1 -1
  116. package/dist/src/common/input.js +890 -124
  117. package/dist/src/common/input.js.map +1 -1
  118. package/dist/src/common/json-elements.d.ts +144 -20
  119. package/dist/src/common/json-elements.d.ts.map +1 -1
  120. package/dist/src/common/json-elements.js +869 -189
  121. package/dist/src/common/json-elements.js.map +1 -1
  122. package/dist/src/common/line-format.d.ts +90 -0
  123. package/dist/src/common/line-format.d.ts.map +1 -0
  124. package/dist/src/common/line-format.js +185 -0
  125. package/dist/src/common/line-format.js.map +1 -0
  126. package/dist/src/common/lists.d.ts +6 -1
  127. package/dist/src/common/lists.d.ts.map +1 -1
  128. package/dist/src/common/lists.js +3 -1
  129. package/dist/src/common/lists.js.map +1 -1
  130. package/dist/src/common/ontology-export.d.ts +167 -0
  131. package/dist/src/common/ontology-export.d.ts.map +1 -0
  132. package/dist/src/common/ontology-export.js +359 -0
  133. package/dist/src/common/ontology-export.js.map +1 -0
  134. package/dist/src/common/ontology.d.ts +25 -3
  135. package/dist/src/common/ontology.d.ts.map +1 -1
  136. package/dist/src/common/ontology.js +30 -9
  137. package/dist/src/common/ontology.js.map +1 -1
  138. package/dist/src/common/options.d.ts +62 -12
  139. package/dist/src/common/options.d.ts.map +1 -1
  140. package/dist/src/common/options.js +89 -11
  141. package/dist/src/common/options.js.map +1 -1
  142. package/dist/src/common/plural.d.ts +31 -0
  143. package/dist/src/common/plural.d.ts.map +1 -0
  144. package/dist/src/common/plural.js +46 -0
  145. package/dist/src/common/plural.js.map +1 -0
  146. package/dist/src/common/report.d.ts +72 -14
  147. package/dist/src/common/report.d.ts.map +1 -1
  148. package/dist/src/common/report.js +146 -22
  149. package/dist/src/common/report.js.map +1 -1
  150. package/dist/src/common/temporal.d.ts +22 -5
  151. package/dist/src/common/temporal.d.ts.map +1 -1
  152. package/dist/src/common/temporal.js +13 -2
  153. package/dist/src/common/temporal.js.map +1 -1
  154. package/dist/src/common/text.d.ts +39 -23
  155. package/dist/src/common/text.d.ts.map +1 -1
  156. package/dist/src/common/text.js +51 -21
  157. package/dist/src/common/text.js.map +1 -1
  158. package/dist/src/common/weights.d.ts +37 -4
  159. package/dist/src/common/weights.d.ts.map +1 -1
  160. package/dist/src/common/weights.js +61 -2
  161. package/dist/src/common/weights.js.map +1 -1
  162. package/dist/src/common/writer.d.ts +19 -3
  163. package/dist/src/common/writer.d.ts.map +1 -1
  164. package/dist/src/common/writer.js +30 -2
  165. package/dist/src/common/writer.js.map +1 -1
  166. package/dist/src/common/xml.d.ts +125 -9
  167. package/dist/src/common/xml.d.ts.map +1 -1
  168. package/dist/src/common/xml.js +402 -85
  169. package/dist/src/common/xml.js.map +1 -1
  170. package/dist/src/common/zip.d.ts +44 -4
  171. package/dist/src/common/zip.d.ts.map +1 -1
  172. package/dist/src/common/zip.js +134 -5
  173. package/dist/src/common/zip.js.map +1 -1
  174. package/dist/src/formats/csv/exporter.d.ts +80 -24
  175. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  176. package/dist/src/formats/csv/exporter.js +146 -33
  177. package/dist/src/formats/csv/exporter.js.map +1 -1
  178. package/dist/src/formats/csv/header.d.ts +38 -9
  179. package/dist/src/formats/csv/header.d.ts.map +1 -1
  180. package/dist/src/formats/csv/header.js +46 -10
  181. package/dist/src/formats/csv/header.js.map +1 -1
  182. package/dist/src/formats/csv/importer.d.ts +187 -37
  183. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  184. package/dist/src/formats/csv/importer.js +835 -204
  185. package/dist/src/formats/csv/importer.js.map +1 -1
  186. package/dist/src/formats/csv/index.d.ts +100 -19
  187. package/dist/src/formats/csv/index.d.ts.map +1 -1
  188. package/dist/src/formats/csv/index.js +94 -21
  189. package/dist/src/formats/csv/index.js.map +1 -1
  190. package/dist/src/formats/csv/records.d.ts +95 -10
  191. package/dist/src/formats/csv/records.d.ts.map +1 -1
  192. package/dist/src/formats/csv/records.js +333 -122
  193. package/dist/src/formats/csv/records.js.map +1 -1
  194. package/dist/src/formats/csv/values.d.ts +1 -0
  195. package/dist/src/formats/csv/values.d.ts.map +1 -1
  196. package/dist/src/formats/csv/values.js +1 -0
  197. package/dist/src/formats/csv/values.js.map +1 -1
  198. package/dist/src/formats/cx/exporter.d.ts +102 -0
  199. package/dist/src/formats/cx/exporter.d.ts.map +1 -0
  200. package/dist/src/formats/cx/exporter.js +1217 -0
  201. package/dist/src/formats/cx/exporter.js.map +1 -0
  202. package/dist/src/formats/cx/importer.d.ts +79 -32
  203. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  204. package/dist/src/formats/cx/importer.js +682 -287
  205. package/dist/src/formats/cx/importer.js.map +1 -1
  206. package/dist/src/formats/cx/index.d.ts +4 -3
  207. package/dist/src/formats/cx/index.d.ts.map +1 -1
  208. package/dist/src/formats/cx/index.js +4 -3
  209. package/dist/src/formats/cx/index.js.map +1 -1
  210. package/dist/src/formats/cx2/exporter.d.ts +29 -11
  211. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  212. package/dist/src/formats/cx2/exporter.js +39 -268
  213. package/dist/src/formats/cx2/exporter.js.map +1 -1
  214. package/dist/src/formats/cx2/importer.d.ts +78 -28
  215. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  216. package/dist/src/formats/cx2/importer.js +227 -80
  217. package/dist/src/formats/cx2/importer.js.map +1 -1
  218. package/dist/src/formats/cx2/index.d.ts +2 -1
  219. package/dist/src/formats/cx2/index.d.ts.map +1 -1
  220. package/dist/src/formats/cx2/index.js +2 -1
  221. package/dist/src/formats/cx2/index.js.map +1 -1
  222. package/dist/src/formats/cys/constants.d.ts +66 -17
  223. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  224. package/dist/src/formats/cys/constants.js +59 -18
  225. package/dist/src/formats/cys/constants.js.map +1 -1
  226. package/dist/src/formats/cys/exporter.d.ts +118 -0
  227. package/dist/src/formats/cys/exporter.d.ts.map +1 -0
  228. package/dist/src/formats/cys/exporter.js +1072 -0
  229. package/dist/src/formats/cys/exporter.js.map +1 -0
  230. package/dist/src/formats/cys/importer.d.ts +22 -8
  231. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  232. package/dist/src/formats/cys/importer.js +510 -149
  233. package/dist/src/formats/cys/importer.js.map +1 -1
  234. package/dist/src/formats/cys/index.d.ts +4 -2
  235. package/dist/src/formats/cys/index.d.ts.map +1 -1
  236. package/dist/src/formats/cys/index.js +4 -2
  237. package/dist/src/formats/cys/index.js.map +1 -1
  238. package/dist/src/formats/cys/session.d.ts +46 -7
  239. package/dist/src/formats/cys/session.d.ts.map +1 -1
  240. package/dist/src/formats/cys/session.js +101 -27
  241. package/dist/src/formats/cys/session.js.map +1 -1
  242. package/dist/src/formats/cys/tables.d.ts +9 -2
  243. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  244. package/dist/src/formats/cys/tables.js +29 -7
  245. package/dist/src/formats/cys/tables.js.map +1 -1
  246. package/dist/src/formats/dot/exporter.d.ts +42 -14
  247. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  248. package/dist/src/formats/dot/exporter.js +56 -29
  249. package/dist/src/formats/dot/exporter.js.map +1 -1
  250. package/dist/src/formats/dot/importer.d.ts +91 -29
  251. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  252. package/dist/src/formats/dot/importer.js +190 -39
  253. package/dist/src/formats/dot/importer.js.map +1 -1
  254. package/dist/src/formats/dot/index.d.ts +2 -1
  255. package/dist/src/formats/dot/index.d.ts.map +1 -1
  256. package/dist/src/formats/dot/index.js +2 -1
  257. package/dist/src/formats/dot/index.js.map +1 -1
  258. package/dist/src/formats/dot/names.d.ts +44 -11
  259. package/dist/src/formats/dot/names.d.ts.map +1 -1
  260. package/dist/src/formats/dot/names.js +44 -11
  261. package/dist/src/formats/dot/names.js.map +1 -1
  262. package/dist/src/formats/dot/tokenizer.d.ts +9 -2
  263. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  264. package/dist/src/formats/dot/tokenizer.js +20 -5
  265. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  266. package/dist/src/formats/gexf/exporter.d.ts +46 -15
  267. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  268. package/dist/src/formats/gexf/exporter.js +45 -15
  269. package/dist/src/formats/gexf/exporter.js.map +1 -1
  270. package/dist/src/formats/gexf/importer.d.ts +87 -23
  271. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  272. package/dist/src/formats/gexf/importer.js +471 -90
  273. package/dist/src/formats/gexf/importer.js.map +1 -1
  274. package/dist/src/formats/gexf/index.d.ts +84 -21
  275. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  276. package/dist/src/formats/gexf/index.js +80 -23
  277. package/dist/src/formats/gexf/index.js.map +1 -1
  278. package/dist/src/formats/gexf/schema.d.ts +67 -15
  279. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  280. package/dist/src/formats/gexf/schema.js +59 -13
  281. package/dist/src/formats/gexf/schema.js.map +1 -1
  282. package/dist/src/formats/gml/exporter.d.ts +69 -21
  283. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/gml/exporter.js +74 -29
  285. package/dist/src/formats/gml/exporter.js.map +1 -1
  286. package/dist/src/formats/gml/importer.d.ts +116 -25
  287. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  288. package/dist/src/formats/gml/importer.js +290 -61
  289. package/dist/src/formats/gml/importer.js.map +1 -1
  290. package/dist/src/formats/gml/index.d.ts +87 -24
  291. package/dist/src/formats/gml/index.d.ts.map +1 -1
  292. package/dist/src/formats/gml/index.js +79 -26
  293. package/dist/src/formats/gml/index.js.map +1 -1
  294. package/dist/src/formats/gml/syntax.d.ts +67 -18
  295. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  296. package/dist/src/formats/gml/syntax.js +110 -28
  297. package/dist/src/formats/gml/syntax.js.map +1 -1
  298. package/dist/src/formats/graphml/constants.d.ts +174 -44
  299. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  300. package/dist/src/formats/graphml/constants.js +165 -44
  301. package/dist/src/formats/graphml/constants.js.map +1 -1
  302. package/dist/src/formats/graphml/exporter.d.ts +17 -9
  303. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  304. package/dist/src/formats/graphml/exporter.js +33 -12
  305. package/dist/src/formats/graphml/exporter.js.map +1 -1
  306. package/dist/src/formats/graphml/importer.d.ts +19 -7
  307. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  308. package/dist/src/formats/graphml/importer.js +466 -39
  309. package/dist/src/formats/graphml/importer.js.map +1 -1
  310. package/dist/src/formats/graphml/index.d.ts +2 -1
  311. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  312. package/dist/src/formats/graphml/index.js +2 -1
  313. package/dist/src/formats/graphml/index.js.map +1 -1
  314. package/dist/src/formats/graphml/tree.d.ts +6 -2
  315. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  316. package/dist/src/formats/graphml/tree.js +6 -2
  317. package/dist/src/formats/graphml/tree.js.map +1 -1
  318. package/dist/src/formats/graphml/yfiles.d.ts +8 -3
  319. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  320. package/dist/src/formats/graphml/yfiles.js +36 -15
  321. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  322. package/dist/src/formats/json/dialect.d.ts +88 -24
  323. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  324. package/dist/src/formats/json/dialect.js +109 -19
  325. package/dist/src/formats/json/dialect.js.map +1 -1
  326. package/dist/src/formats/json/exporter.d.ts +134 -22
  327. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  328. package/dist/src/formats/json/exporter.js +135 -54
  329. package/dist/src/formats/json/exporter.js.map +1 -1
  330. package/dist/src/formats/json/importer.d.ts +173 -52
  331. package/dist/src/formats/json/importer.d.ts.map +1 -1
  332. package/dist/src/formats/json/importer.js +899 -220
  333. package/dist/src/formats/json/importer.js.map +1 -1
  334. package/dist/src/formats/json/index.d.ts +3 -2
  335. package/dist/src/formats/json/index.d.ts.map +1 -1
  336. package/dist/src/formats/json/index.js +3 -2
  337. package/dist/src/formats/json/index.js.map +1 -1
  338. package/dist/src/formats/json/obographs-export.d.ts +68 -0
  339. package/dist/src/formats/json/obographs-export.d.ts.map +1 -0
  340. package/dist/src/formats/json/obographs-export.js +941 -0
  341. package/dist/src/formats/json/obographs-export.js.map +1 -0
  342. package/dist/src/formats/json/obographs.d.ts +26 -0
  343. package/dist/src/formats/json/obographs.d.ts.map +1 -1
  344. package/dist/src/formats/json/obographs.js +297 -80
  345. package/dist/src/formats/json/obographs.js.map +1 -1
  346. package/dist/src/formats/neo4j/exporter.d.ts +109 -21
  347. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  348. package/dist/src/formats/neo4j/exporter.js +239 -86
  349. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  350. package/dist/src/formats/neo4j/header.d.ts +17 -4
  351. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  352. package/dist/src/formats/neo4j/header.js +36 -4
  353. package/dist/src/formats/neo4j/header.js.map +1 -1
  354. package/dist/src/formats/neo4j/importer.d.ts +107 -27
  355. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  356. package/dist/src/formats/neo4j/importer.js +415 -63
  357. package/dist/src/formats/neo4j/importer.js.map +1 -1
  358. package/dist/src/formats/neo4j/index.d.ts +73 -23
  359. package/dist/src/formats/neo4j/index.d.ts.map +1 -1
  360. package/dist/src/formats/neo4j/index.js +65 -25
  361. package/dist/src/formats/neo4j/index.js.map +1 -1
  362. package/dist/src/formats/obo/exporter.d.ts +150 -0
  363. package/dist/src/formats/obo/exporter.d.ts.map +1 -0
  364. package/dist/src/formats/obo/exporter.js +1736 -0
  365. package/dist/src/formats/obo/exporter.js.map +1 -0
  366. package/dist/src/formats/obo/importer.d.ts +95 -19
  367. package/dist/src/formats/obo/importer.d.ts.map +1 -1
  368. package/dist/src/formats/obo/importer.js +475 -104
  369. package/dist/src/formats/obo/importer.js.map +1 -1
  370. package/dist/src/formats/obo/index.d.ts +6 -3
  371. package/dist/src/formats/obo/index.d.ts.map +1 -1
  372. package/dist/src/formats/obo/index.js +6 -3
  373. package/dist/src/formats/obo/index.js.map +1 -1
  374. package/dist/src/formats/obo/syntax.d.ts +108 -4
  375. package/dist/src/formats/obo/syntax.d.ts.map +1 -1
  376. package/dist/src/formats/obo/syntax.js +211 -34
  377. package/dist/src/formats/obo/syntax.js.map +1 -1
  378. package/dist/src/formats/pajek/exporter.d.ts +54 -16
  379. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  380. package/dist/src/formats/pajek/exporter.js +67 -35
  381. package/dist/src/formats/pajek/exporter.js.map +1 -1
  382. package/dist/src/formats/pajek/importer.d.ts +84 -22
  383. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  384. package/dist/src/formats/pajek/importer.js +303 -83
  385. package/dist/src/formats/pajek/importer.js.map +1 -1
  386. package/dist/src/formats/pajek/index.d.ts +2 -1
  387. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  388. package/dist/src/formats/pajek/index.js +2 -1
  389. package/dist/src/formats/pajek/index.js.map +1 -1
  390. package/dist/src/formats/pajek/syntax.d.ts +77 -14
  391. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  392. package/dist/src/formats/pajek/syntax.js +186 -54
  393. package/dist/src/formats/pajek/syntax.js.map +1 -1
  394. package/dist/src/formats/xgmml/columns.d.ts +1 -0
  395. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  396. package/dist/src/formats/xgmml/columns.js +4 -0
  397. package/dist/src/formats/xgmml/columns.js.map +1 -1
  398. package/dist/src/formats/xgmml/constants.d.ts +186 -56
  399. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  400. package/dist/src/formats/xgmml/constants.js +181 -57
  401. package/dist/src/formats/xgmml/constants.js.map +1 -1
  402. package/dist/src/formats/xgmml/document.d.ts +65 -11
  403. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  404. package/dist/src/formats/xgmml/document.js +157 -28
  405. package/dist/src/formats/xgmml/document.js.map +1 -1
  406. package/dist/src/formats/xgmml/emit.d.ts +61 -3
  407. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  408. package/dist/src/formats/xgmml/emit.js +129 -26
  409. package/dist/src/formats/xgmml/emit.js.map +1 -1
  410. package/dist/src/formats/xgmml/exporter.d.ts +13 -6
  411. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  412. package/dist/src/formats/xgmml/exporter.js +21 -22
  413. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  414. package/dist/src/formats/xgmml/importer.d.ts +33 -12
  415. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  416. package/dist/src/formats/xgmml/importer.js +35 -72
  417. package/dist/src/formats/xgmml/importer.js.map +1 -1
  418. package/dist/src/formats/xgmml/index.d.ts +1 -0
  419. package/dist/src/formats/xgmml/index.d.ts.map +1 -1
  420. package/dist/src/formats/xgmml/index.js +1 -0
  421. package/dist/src/formats/xgmml/index.js.map +1 -1
  422. package/dist/src/formats/xgmml/values.d.ts +8 -1
  423. package/dist/src/formats/xgmml/values.d.ts.map +1 -1
  424. package/dist/src/formats/xgmml/values.js +8 -3
  425. package/dist/src/formats/xgmml/values.js.map +1 -1
  426. package/dist/src/index.d.ts +23 -18
  427. package/dist/src/index.d.ts.map +1 -1
  428. package/dist/src/index.js +28 -16
  429. package/dist/src/index.js.map +1 -1
  430. package/dist/src/registry.d.ts +478 -92
  431. package/dist/src/registry.d.ts.map +1 -1
  432. package/dist/src/registry.js +807 -88
  433. package/dist/src/registry.js.map +1 -1
  434. package/dist/src/sniff.d.ts +61 -19
  435. package/dist/src/sniff.d.ts.map +1 -1
  436. package/dist/src/sniff.js +121 -29
  437. package/dist/src/sniff.js.map +1 -1
  438. package/dist/src/types.d.ts +362 -112
  439. package/dist/src/types.d.ts.map +1 -1
  440. package/dist/src/types.js +28 -7
  441. package/dist/src/types.js.map +1 -1
  442. package/dist/xgmml.js +2 -2
  443. package/docs/samples/README.md +25 -0
  444. package/docs/samples/got-edges.csv +353 -0
  445. package/docs/samples/got-network.graphml +1384 -0
  446. package/docs/samples/got-nodes.csv +108 -0
  447. package/docs/samples/got.cx +930 -0
  448. package/docs/samples/got.cx2 +465 -0
  449. package/docs/samples/got.gexf +471 -0
  450. package/docs/samples/got.gml +2650 -0
  451. package/docs/samples/got.json +2546 -0
  452. package/docs/samples/got.net +461 -0
  453. package/docs/samples/movies-nodes.csv +9 -0
  454. package/docs/samples/movies-rels.csv +8 -0
  455. package/docs/samples/networks.cys +0 -0
  456. package/docs/samples/proteins.xgmml +9 -0
  457. package/docs/samples/teams.gv +24 -0
  458. package/docs/samples/vehicles.obo +25 -0
  459. package/package.json +9 -4
  460. package/src/children.ts +18 -6
  461. package/src/common/attributes.ts +29 -11
  462. package/src/common/cell-budget.ts +11 -3
  463. package/src/common/choose.ts +89 -0
  464. package/src/common/codes.ts +490 -66
  465. package/src/common/compare.ts +472 -0
  466. package/src/common/cx-export.ts +432 -0
  467. package/src/common/declared-types.ts +40 -6
  468. package/src/common/direction.ts +78 -51
  469. package/src/common/escape.ts +39 -22
  470. package/src/common/export.ts +284 -47
  471. package/src/common/format.ts +30 -1
  472. package/src/common/ids.ts +14 -3
  473. package/src/common/input.ts +1057 -134
  474. package/src/common/json-elements.ts +1035 -199
  475. package/src/common/line-format.ts +249 -0
  476. package/src/common/lists.ts +7 -2
  477. package/src/common/ontology-export.ts +461 -0
  478. package/src/common/ontology.ts +31 -9
  479. package/src/common/options.ts +110 -15
  480. package/src/common/plural.ts +49 -0
  481. package/src/common/report.ts +168 -25
  482. package/src/common/temporal.ts +22 -5
  483. package/src/common/text.ts +62 -23
  484. package/src/common/weights.ts +74 -4
  485. package/src/common/writer.ts +37 -3
  486. package/src/common/xml.ts +479 -90
  487. package/src/common/zip.ts +169 -7
  488. package/src/formats/csv/exporter.ts +202 -47
  489. package/src/formats/csv/header.ts +50 -11
  490. package/src/formats/csv/importer.ts +1133 -245
  491. package/src/formats/csv/index.ts +106 -19
  492. package/src/formats/csv/records.ts +396 -122
  493. package/src/formats/csv/values.ts +1 -0
  494. package/src/formats/cx/exporter.ts +1483 -0
  495. package/src/formats/cx/importer.ts +890 -302
  496. package/src/formats/cx/index.ts +4 -3
  497. package/src/formats/cx2/exporter.ts +62 -339
  498. package/src/formats/cx2/importer.ts +318 -87
  499. package/src/formats/cx2/index.ts +2 -1
  500. package/src/formats/cys/constants.ts +62 -17
  501. package/src/formats/cys/exporter.ts +1368 -0
  502. package/src/formats/cys/importer.ts +659 -157
  503. package/src/formats/cys/index.ts +4 -2
  504. package/src/formats/cys/session.ts +142 -34
  505. package/src/formats/cys/tables.ts +47 -9
  506. package/src/formats/dot/exporter.ts +83 -37
  507. package/src/formats/dot/importer.ts +248 -54
  508. package/src/formats/dot/index.ts +2 -1
  509. package/src/formats/dot/names.ts +44 -11
  510. package/src/formats/dot/tokenizer.ts +25 -6
  511. package/src/formats/gexf/exporter.ts +57 -18
  512. package/src/formats/gexf/importer.ts +636 -105
  513. package/src/formats/gexf/index.ts +90 -21
  514. package/src/formats/gexf/schema.ts +67 -15
  515. package/src/formats/gml/exporter.ts +90 -36
  516. package/src/formats/gml/importer.ts +388 -67
  517. package/src/formats/gml/index.ts +85 -24
  518. package/src/formats/gml/syntax.ts +113 -28
  519. package/src/formats/graphml/constants.ts +178 -44
  520. package/src/formats/graphml/exporter.ts +52 -18
  521. package/src/formats/graphml/importer.ts +640 -60
  522. package/src/formats/graphml/index.ts +2 -1
  523. package/src/formats/graphml/tree.ts +6 -2
  524. package/src/formats/graphml/yfiles.ts +37 -15
  525. package/src/formats/json/dialect.ts +128 -29
  526. package/src/formats/json/exporter.ts +205 -68
  527. package/src/formats/json/importer.ts +1163 -253
  528. package/src/formats/json/index.ts +3 -1
  529. package/src/formats/json/obographs-export.ts +1197 -0
  530. package/src/formats/json/obographs.ts +353 -92
  531. package/src/formats/neo4j/exporter.ts +321 -102
  532. package/src/formats/neo4j/header.ts +44 -6
  533. package/src/formats/neo4j/importer.ts +512 -73
  534. package/src/formats/neo4j/index.ts +75 -23
  535. package/src/formats/obo/exporter.ts +2210 -0
  536. package/src/formats/obo/importer.ts +622 -109
  537. package/src/formats/obo/index.ts +6 -3
  538. package/src/formats/obo/syntax.ts +232 -37
  539. package/src/formats/pajek/exporter.ts +90 -42
  540. package/src/formats/pajek/importer.ts +407 -93
  541. package/src/formats/pajek/index.ts +2 -1
  542. package/src/formats/pajek/syntax.ts +216 -55
  543. package/src/formats/xgmml/columns.ts +10 -0
  544. package/src/formats/xgmml/constants.ts +183 -56
  545. package/src/formats/xgmml/document.ts +212 -34
  546. package/src/formats/xgmml/emit.ts +175 -34
  547. package/src/formats/xgmml/exporter.ts +36 -28
  548. package/src/formats/xgmml/importer.ts +64 -86
  549. package/src/formats/xgmml/index.ts +1 -0
  550. package/src/formats/xgmml/values.ts +12 -4
  551. package/src/index.ts +81 -11
  552. package/src/registry.ts +1121 -135
  553. package/src/sniff.ts +163 -32
  554. package/src/types.ts +385 -114
  555. package/dist/chunks/escape-B-tkk_Cl.js.map +0 -1
  556. package/dist/chunks/export-Bh60Dv-n.js +0 -582
  557. package/dist/chunks/export-Bh60Dv-n.js.map +0 -1
  558. package/dist/chunks/exporter-BGrsWamJ.js.map +0 -1
  559. package/dist/chunks/exporter-DIeGJXAZ.js.map +0 -1
  560. package/dist/chunks/importer-BWY2FFc5.js.map +0 -1
  561. package/dist/chunks/importer-DD-xv9_Y.js +0 -1471
  562. package/dist/chunks/importer-DD-xv9_Y.js.map +0 -1
  563. package/dist/chunks/importer-DET1tg6s.js.map +0 -1
  564. package/dist/chunks/importer-DEcKhsmQ.js +0 -1614
  565. package/dist/chunks/importer-DEcKhsmQ.js.map +0 -1
  566. package/dist/chunks/importer-DIrbbnAf.js.map +0 -1
  567. package/dist/chunks/importer-D_e7e7LX.js.map +0 -1
  568. package/dist/chunks/importer-eUREhBGj.js.map +0 -1
  569. package/dist/chunks/importer-vi3bSdtw.js.map +0 -1
  570. package/dist/chunks/importer-zGLo8Dg_.js.map +0 -1
  571. package/dist/chunks/json-elements-DDS8N2Dd.js +0 -779
  572. package/dist/chunks/json-elements-DDS8N2Dd.js.map +0 -1
  573. package/dist/chunks/ontology-BnrJ4I98.js +0 -113
  574. package/dist/chunks/ontology-BnrJ4I98.js.map +0 -1
  575. package/dist/chunks/records-dbRkxwaq.js.map +0 -1
  576. package/dist/chunks/report-B1z4WT9e.js +0 -2372
  577. package/dist/chunks/report-B1z4WT9e.js.map +0 -1
  578. package/dist/chunks/text-Dr0Ifpag.js.map +0 -1
  579. package/dist/chunks/weights-Dzba96G3.js +0 -176
  580. package/dist/chunks/weights-Dzba96G3.js.map +0 -1
  581. package/dist/chunks/writer-C7flM-Ih.js.map +0 -1
@@ -8,7 +8,7 @@
8
8
  * every node block first, then every edge block, so node indices follow the file's node order
9
9
  * and forward edge references resolve.
10
10
  *
11
- * Conventions honoured: NetworkX's `_networkx_list_start` marker and `"[]"` empty lists, `&#NN;`
11
+ * Conventions honored: NetworkX's `_networkx_list_start` marker and `"[]"` empty lists, `&#NN;`
12
12
  * character references in strings, `Creator` / `Version` top-level metadata, `directed 0|1` and
13
13
  * `multigraph 0|1` graph flags, comments, keys and values on one line or split across lines, and
14
14
  * a `graphics [ x y z ]` node record mapped to the `position` role (note 07 section 9) with the
@@ -35,6 +35,7 @@ import {
35
35
  } from "@graphty/graph-format";
36
36
 
37
37
  import { declareResolved, DictHeuristic, uniqueColumnName } from "../../common/attributes.js";
38
+ import { importChosenGraph } from "../../common/choose.js";
38
39
  import {
39
40
  COLUMN_RENAMED_CODE,
40
41
  DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,
@@ -44,20 +45,29 @@ import {
44
45
  NO_GRAPH_CODE as SHARED_NO_GRAPH_CODE,
45
46
  PRECISION_CODE as SHARED_PRECISION_CODE,
46
47
  ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,
48
+ WIDENED_CODE as SHARED_WIDENED_CODE,
47
49
  } from "../../common/codes.js";
48
50
  import { DirectionResolver } from "../../common/direction.js";
49
51
  import { IdCoercer } from "../../common/ids.js";
50
52
  import { readText, throwIfAborted } from "../../common/input.js";
51
53
  import {
54
+ graphChosen,
52
55
  type ImportFormatDefaults,
53
56
  reportSinkOptions,
54
57
  reportUnusedOptions,
55
58
  type ResolvedImportOptions,
56
59
  resolveImportOptions,
57
60
  } from "../../common/options.js";
61
+ import { plural } from "../../common/plural.js";
58
62
  import { ImportReportBuilder } from "../../common/report.js";
59
- import { parseWeightText, weightFromValue } from "../../common/weights.js";
60
- import { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from "../../types.js";
63
+ import { parseWeightText, reportWeightPrecision, weightFromValue } from "../../common/weights.js";
64
+ import {
65
+ type CommonImportOptions,
66
+ type GraphChoiceOptions,
67
+ type GraphImporter,
68
+ type ImportInput,
69
+ type ImportReport,
70
+ } from "../../types.js";
61
71
  import {
62
72
  EMPTY_LIST_TEXT,
63
73
  EMPTY_TUPLE_TEXT,
@@ -76,53 +86,141 @@ import {
76
86
  tokenizeGml,
77
87
  } from "./syntax.js";
78
88
 
79
- /** The format-specific options of the GML importer. */
80
- export interface GmlImportOptions {
89
+ /**
90
+ * The format-specific options of the GML importer.
91
+ * @category Built-in formats
92
+ */
93
+ export interface GmlImportOptions extends GraphChoiceOptions, CommonImportOptions {
81
94
  /**
82
- * Map a node's `graphics [ x y z ]` record to a `position` column with the position role
83
- * (default true); false keeps the whole record in the `graphics` json column.
95
+ * Read a node's `graphics [ x y z ]` record as its position; false keeps the whole record as a
96
+ * JSON attribute named `graphics`.
97
+ * @defaultValue true
84
98
  */
85
99
  positions?: boolean | undefined;
86
- /** Apply the dictionary heuristic of design section 5.4 to string columns (default true). */
100
+ /**
101
+ * Store a text attribute whose values repeat a lot (fewer distinct values than half the rows)
102
+ * as a dictionary column, which uses less memory and reads the same. Such a column reports
103
+ * `meta.dtype` "dict" instead of "string". A column with a role, such as the `label` column,
104
+ * always stays "string".
105
+ * @defaultValue true
106
+ */
87
107
  dictionaries?: boolean | undefined;
88
108
  }
89
109
 
90
- /** Issue code: the text holds no `graph [ ... ]` block. */
110
+ /**
111
+ * The text holds no `graph [ ... ]` block.
112
+ * @category Issue and loss codes
113
+ */
91
114
  export const NO_GRAPH_CODE = SHARED_NO_GRAPH_CODE;
92
- /** Issue code: the text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one. */
115
+ /**
116
+ * The text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one.
117
+ * @category Issue and loss codes
118
+ */
93
119
  export const SECOND_GRAPH_CODE = MULTIPLE_GRAPHS_CODE;
94
- /** Issue code: a node block has no `id` key. */
120
+ /**
121
+ * A node block has no `id` key.
122
+ * @category Issue and loss codes
123
+ */
95
124
  export const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;
96
- /** Issue code: a node block has no `label` key under `nodeIdFrom: "label"`. */
125
+ /**
126
+ * A node block has no `label` key under `nodeIdFrom: "label"`.
127
+ * @category Issue and loss codes
128
+ */
97
129
  export const MISSING_LABEL_CODE = "E_GML_MISSING_LABEL";
98
- /** Issue code: an edge block has no `source` or no `target` key. */
130
+ /**
131
+ * An edge block has no `source` or no `target` key.
132
+ * @category Issue and loss codes
133
+ */
99
134
  export const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;
100
- /** Issue code: an `id`, `source` or `target` value is neither an integer nor a string. */
135
+ /**
136
+ * An `id`, `source` or `target` value is neither an integer nor a string.
137
+ * @category Issue and loss codes
138
+ */
101
139
  export const ID_TYPE_CODE = "E_GML_ID_TYPE";
102
- /** Issue code: string `id`, `source` or `target` values, outside the GML spec's integer ids; warned once per file. */
140
+ /**
141
+ * Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option. Reported
142
+ * once per file.
143
+ * @category Issue and loss codes
144
+ */
103
145
  export const STRING_ID_CODE = "W_GML_STRING_ID";
104
- /** Issue code: a node id (or label under `nodeIdFrom: "label"`) is declared twice; later keys overwrite. */
146
+ /**
147
+ * A node id (or label under `nodeIdFrom: "label"`) is declared twice; later keys overwrite.
148
+ * @category Issue and loss codes
149
+ */
105
150
  export const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;
106
- /** Issue code: a structural key (`id`, `source`, `target`) appears twice in one block. */
151
+ /**
152
+ * A structural key (`id`, `source`, `target`) appears twice in one block.
153
+ * @category Issue and loss codes
154
+ */
107
155
  export const REPEATED_KEY_CODE = "E_GML_REPEATED_KEY";
108
- /** Issue code: a `node` or `edge` key whose value is not a `[ ... ]` block. */
156
+ /**
157
+ * A `node` or `edge` key whose value is not a `[ ... ]` block.
158
+ * @category Issue and loss codes
159
+ */
109
160
  export const ELEMENT_TYPE_CODE = "E_GML_ELEMENT_TYPE";
110
- /** Issue code: a `directed` or `multigraph` flag that is not an integer. */
161
+ /**
162
+ * A `directed` or `multigraph` flag that is not an integer.
163
+ * @category Issue and loss codes
164
+ */
111
165
  export const FLAG_TYPE_CODE = "E_GML_FLAG_TYPE";
112
- /** Issue code: a `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or one repeated. */
166
+ /**
167
+ * A `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or
168
+ * one repeated.
169
+ * @category Issue and loss codes
170
+ */
113
171
  export const FLAG_VALUE_CODE = "W_GML_FLAG_VALUE";
114
172
 
115
173
  /** A flag written as a quoted integer, surrounding spaces allowed. */
116
174
  const QUOTED_INT = /^\s*[+-]?[0-9]+\s*$/;
117
- /** Issue code: a named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity; it is kept as written. */
175
+ /**
176
+ * A named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity, or a numeric reference beyond
177
+ * U+10FFFF; it is kept as written.
178
+ * @category Issue and loss codes
179
+ */
118
180
  export const UNKNOWN_ENTITY_CODE = "W_GML_UNKNOWN_ENTITY";
119
- /** Issue code: an integer beyond 2^53 stored as the nearest f64 (design section 5.1). */
181
+ /**
182
+ * A node's `graphics` value cannot give a position as written (not a record, repeated in the node, or with an x / y /
183
+ * z that is not one number); the value is kept in the graphics json column. Warned once per kind of problem, naming
184
+ * the first node.
185
+ * @category Issue and loss codes
186
+ */
187
+ export const GRAPHICS_CODE = "W_GML_GRAPHICS";
188
+ /**
189
+ * A `graph`, `node` or `edge` record inside a node or edge; kept as a json column, not read as structure.
190
+ * @category Issue and loss codes
191
+ */
192
+ export const NESTED_ELEMENT_CODE = "W_GML_NESTED_ELEMENT";
193
+ /**
194
+ * YEd's group keys (`isGroup`, `gid`); kept as plain node columns, the hierarchy is not read as containment.
195
+ * @category Issue and loss codes
196
+ */
197
+ export const GROUPS_CODE = "W_GML_GROUPS";
198
+ /**
199
+ * A key whose values mix numbers and strings; the column is string, the numbers kept as written.
200
+ * @category Issue and loss codes
201
+ */
202
+ export const WIDENED_CODE = SHARED_WIDENED_CODE;
203
+ /**
204
+ * An integer above 2^53 was stored as the nearest JavaScript number, so its last digits may differ. Pass `long:
205
+ * "string"` to keep every digit as text.
206
+ * @category Issue and loss codes
207
+ */
120
208
  export const PRECISION_CODE = SHARED_PRECISION_CODE;
121
- /** Issue code: the sink already holds a column of the name with another declaration; renamed `<name>#<key>`. */
209
+ /**
210
+ * Two attributes would have had the same name, so this one was renamed `<name>#<key>`.
211
+ * @category Plugin helpers
212
+ */
122
213
  export const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;
123
- /** Issue code: the sink already holds a column with the role; the column is declared without it. */
214
+ /**
215
+ * You read into a graph builder that already has an attribute with this role, so this file's attribute is kept without
216
+ * the role.
217
+ * @category Issue and loss codes
218
+ */
124
219
  export const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;
125
- /** Loss code: under `nodeIdFrom` "label" / "index" the integer `id` keys are not kept. */
220
+ /**
221
+ * Under `nodeIdFrom` "label" / "index" the integer `id` keys are not kept.
222
+ * @category Issue and loss codes
223
+ */
126
224
  export const ID_DROPPED_CODE = "W_GML_ID_DROPPED";
127
225
 
128
226
  const FORMAT_DEFAULTS: ImportFormatDefaults = { ids: "canonical", defaultDirected: false, weightFrom: "value" };
@@ -150,6 +248,7 @@ const USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof Commo
150
248
  "weightFrom",
151
249
  "weightDtype",
152
250
  "restoreMangledIds",
251
+ "long",
153
252
  "errorLimit",
154
253
  "signal",
155
254
  "onProgress",
@@ -220,6 +319,34 @@ interface ColumnPlan {
220
319
  /** A table's plans by key. */
221
320
  type PlanMap = Map<string, ColumnPlan>;
222
321
 
322
+ /** Where a node issue is recorded. */
323
+ interface IssueWhere {
324
+ readonly line: number;
325
+ readonly element: string;
326
+ }
327
+
328
+ /** The table a GML key belongs to. */
329
+ type GmlDomain = "node" | "edge" | "graph";
330
+
331
+ /**
332
+ * Whether a key is the label of a node or edge (text, never a NetworkX list marker).
333
+ * @param domain - the table
334
+ * @param key - the key
335
+ * @returns true for a node or edge label
336
+ */
337
+ function isLabel(domain: GmlDomain, key: string): boolean {
338
+ return roleOf(domain, key) === "label";
339
+ }
340
+
341
+ /**
342
+ * Whether a parsed value is a GML record.
343
+ * @param value - the value
344
+ * @returns true for a record object
345
+ */
346
+ function isRecord(value: unknown): value is Record<string, unknown> {
347
+ return typeof value === "object" && value !== null && !Array.isArray(value);
348
+ }
349
+
223
350
  /**
224
351
  * Whether a key gets a role in its table (design section 5.6 applied to GML keys).
225
352
  * @param domain - the table
@@ -309,6 +436,9 @@ class GmlImport {
309
436
  /** The sink id every file id maps to when they differ (label / index / restored ids), else null. */
310
437
  private idMap: Map<NodeId, NodeId> | null = null;
311
438
 
439
+ /** The file ids of node blocks that were skipped: an edge naming one is skipped too, never given a new node. */
440
+ private readonly skippedIds = new Set<NodeId>();
441
+
312
442
  /** Node indices declared by a node block of this import, for duplicate detection. */
313
443
  private declared = new Uint32Array(64);
314
444
 
@@ -354,7 +484,7 @@ class GmlImport {
354
484
  this.report.warnOnce(
355
485
  "parse-error",
356
486
  UNKNOWN_ENTITY_CODE,
357
- `unknown character entity ${entity} is kept as written`,
487
+ `character entity ${entity} cannot be decoded; it is kept as written`,
358
488
  { line, element: entity },
359
489
  `${UNKNOWN_ENTITY_CODE}:${entity}`,
360
490
  );
@@ -371,10 +501,14 @@ class GmlImport {
371
501
  */
372
502
  private scan(): void {
373
503
  const t = this.requireTokens();
504
+ let scalarGraph = -1;
374
505
  for (let p = 0; p < t.count; p = t.nextPair(p)) {
375
506
  const key = t.textOf(p);
376
507
  const v = p + 1;
377
508
  const record = t.kind[v] === TOKEN_OPEN;
509
+ if (key === "graph" && !record && scalarGraph < 0) {
510
+ scalarGraph = v;
511
+ }
378
512
  if (key === "graph" && record) {
379
513
  if (this.graphCount++ === this.which) {
380
514
  this.graphOpen = v;
@@ -389,6 +523,13 @@ class GmlImport {
389
523
  }
390
524
  }
391
525
  if (this.graphOpen < 0) {
526
+ if (scalarGraph >= 0) {
527
+ this.report.fail(
528
+ NO_GRAPH_CODE,
529
+ `the graph key at line ${t.line[scalarGraph]} holds ${describeValue(t, scalarGraph)}, not a [ ... ] block; the input contains no graph block`,
530
+ { line: t.line[scalarGraph] },
531
+ );
532
+ }
392
533
  this.report.fail(NO_GRAPH_CODE, "the input contains no graph [ ... ] block", { line: null });
393
534
  }
394
535
  }
@@ -483,7 +624,9 @@ class GmlImport {
483
624
  seq: number,
484
625
  ): void {
485
626
  const t = this.requireTokens();
627
+ this.noteStructure(domain, key, v);
486
628
  let entry = schema.get(key);
629
+ const graphics = domain === "node" && key === "graphics" && this.positions;
487
630
  if (entry === undefined) {
488
631
  entry = {
489
632
  key,
@@ -499,13 +642,22 @@ class GmlImport {
499
642
  schema.set(key, entry);
500
643
  } else if (entry.lastSeq === seq) {
501
644
  entry.list = true;
645
+ // a repeated graphics record: the extra records go to the json column
646
+ entry.rest ||= graphics;
502
647
  } else {
503
648
  entry.lastSeq = seq;
504
649
  }
650
+ if (graphics && t.kind[v] !== TOKEN_OPEN) {
651
+ entry.rest = true;
652
+ }
505
653
  switch (t.kind[v]) {
506
654
  case TOKEN_STRING: {
507
655
  const raw = t.textOf(v);
508
- if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {
656
+ // a label is text: "[]" there is a label, never NetworkX's empty list
657
+ if (
658
+ raw === LIST_START_MARKER ||
659
+ (!isLabel(domain, key) && (raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT))
660
+ ) {
509
661
  entry.list = true;
510
662
  return;
511
663
  }
@@ -532,8 +684,49 @@ class GmlImport {
532
684
  this.inspectGraphics(entry, v);
533
685
  }
534
686
  return;
535
- default:
687
+ default: {
536
688
  entry.kinds |= KIND_REAL;
689
+ const text = t.textOf(v);
690
+ if (/\d/.test(text) && !Number.isFinite(Number(text))) {
691
+ this.report.warnOnce(
692
+ "precision",
693
+ PRECISION_CODE,
694
+ `${domain} key "${key}" holds the real ${text}, beyond the f64 range; it is stored as ${numberOfText(text) > 0 ? "" : "-"}Infinity`,
695
+ { line: t.line[v], element: key },
696
+ `${PRECISION_CODE}:overflow:${domain}:${key}`,
697
+ );
698
+ }
699
+ }
700
+ }
701
+ }
702
+
703
+ /**
704
+ * Warn about keys of a node or edge whose meaning GML readers give but this import does not:
705
+ * a nested graph / node / edge record, and yEd's group hierarchy.
706
+ * @param domain - the table
707
+ * @param key - the key
708
+ * @param v - the value token
709
+ */
710
+ private noteStructure(domain: "node" | "edge" | "graph", key: string, v: number): void {
711
+ const t = this.requireTokens();
712
+ if (domain === "graph") {
713
+ return;
714
+ }
715
+ if ((key === "graph" || key === "node" || key === "edge") && t.kind[v] === TOKEN_OPEN) {
716
+ this.report.warnOnce(
717
+ "unsupported",
718
+ NESTED_ELEMENT_CODE,
719
+ `a nested ${key} record inside a ${domain} is kept as the json column "${key}"; it is not read as structure`,
720
+ { line: t.line[v], element: key },
721
+ `${NESTED_ELEMENT_CODE}:${domain}:${key}`,
722
+ );
723
+ } else if (domain === "node" && (key === "isGroup" || key === "gid")) {
724
+ this.report.warnOnce(
725
+ "unsupported",
726
+ GROUPS_CODE,
727
+ "yEd group keys (isGroup, gid) are kept as plain node columns; the group hierarchy is not read as containment",
728
+ { line: t.line[v], element: key },
729
+ );
537
730
  }
538
731
  }
539
732
 
@@ -620,7 +813,9 @@ class GmlImport {
620
813
  * @returns the plan
621
814
  */
622
815
  private planOf(domain: "node" | "edge" | "graph", entry: KeySchema, top = false): ColumnPlan {
623
- const kind = kindOf(entry);
816
+ // long: "string" keeps every digit of an integer key that holds values beyond 2^53, as text
817
+ const asText = entry.unsafe && this.options.long === "string" && kindOf(entry) === "int";
818
+ const kind = asText ? "string" : kindOf(entry);
624
819
  let scalar: ScalarDtype = dtypeOfKind(kind, entry);
625
820
  if (
626
821
  scalar === "string" &&
@@ -631,11 +826,24 @@ class GmlImport {
631
826
  ) {
632
827
  scalar = "dict";
633
828
  }
634
- if (entry.unsafe) {
829
+ if (
830
+ (entry.kinds & KIND_STRING) !== 0 &&
831
+ (entry.kinds & (KIND_INT | KIND_REAL)) !== 0 &&
832
+ (entry.kinds & KIND_RECORD) === 0
833
+ ) {
834
+ this.report.warnOnce(
835
+ "coercion",
836
+ WIDENED_CODE,
837
+ `${domain} key "${entry.key}" mixes numbers and strings; the column is string and the numbers are kept as written`,
838
+ { element: entry.key },
839
+ `${WIDENED_CODE}:${domain}:${entry.key}`,
840
+ );
841
+ }
842
+ if (entry.unsafe && !asText) {
635
843
  this.report.warnOnce(
636
844
  "precision",
637
845
  PRECISION_CODE,
638
- `${domain} key "${entry.key}" holds integers beyond 2^53; they are stored as the nearest f64`,
846
+ `${domain} key "${entry.key}" holds integers beyond 2^53; they are stored as the nearest f64 (pass long: "string" to keep every digit as text)`,
639
847
  { element: entry.key },
640
848
  `${PRECISION_CODE}:${domain}:${entry.key}`,
641
849
  );
@@ -661,13 +869,7 @@ class GmlImport {
661
869
  items: null,
662
870
  seq: Number.NEGATIVE_INFINITY,
663
871
  };
664
- if (
665
- domain === "node" &&
666
- entry.key === "graphics" &&
667
- entry.position &&
668
- entry.kinds === KIND_RECORD &&
669
- !entry.list
670
- ) {
872
+ if (domain === "node" && entry.key === "graphics" && this.positions && (entry.kinds & KIND_RECORD) !== 0) {
671
873
  const taken = (candidate: string): boolean =>
672
874
  this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;
673
875
  const position: ColumnPlan = {
@@ -676,9 +878,12 @@ class GmlImport {
676
878
  dtype: "f64",
677
879
  itemDtype: null,
678
880
  kind: "real",
881
+ list: false,
679
882
  role: "position",
680
883
  };
681
- const rest: ColumnPlan | null = entry.rest ? { ...plan } : null;
884
+ const rest: ColumnPlan | null = entry.rest
885
+ ? { ...plan, dtype: "json", itemDtype: null, kind: "record", list: false }
886
+ : null;
682
887
  return { ...plan, position, rest };
683
888
  }
684
889
  return plan;
@@ -692,6 +897,14 @@ class GmlImport {
692
897
  private uniqueGraphName(key: string): string {
693
898
  const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));
694
899
  this.graphNames.add(name);
900
+ if (name !== key) {
901
+ this.report.warning(
902
+ "coercion",
903
+ COLUMN_RENAMED_CODE_GML,
904
+ `the top-level key "${key}" and a key of the graph block share the graph column name; the top-level value is stored as "${name}"`,
905
+ { element: key },
906
+ );
907
+ }
695
908
  return name;
696
909
  }
697
910
 
@@ -867,6 +1080,7 @@ class GmlImport {
867
1080
  this.checkAbort();
868
1081
  let index: number;
869
1082
  let sinkId: NodeId;
1083
+ let fileId: NodeId | undefined;
870
1084
  try {
871
1085
  let idTok = -1;
872
1086
  let labelTok = -1;
@@ -886,7 +1100,7 @@ class GmlImport {
886
1100
  }
887
1101
  // the file id under the ids rule, so `id 1` and `source "1"` meet in idMap (except under
888
1102
  // "keep", where the integer 1 and the string "1" are different ids by design)
889
- const fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, "id"));
1103
+ fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, "id"));
890
1104
  if (originalTok >= 0) {
891
1105
  sinkId = this.restoredId(originalTok);
892
1106
  } else {
@@ -906,13 +1120,25 @@ class GmlImport {
906
1120
  sinkId = fileId;
907
1121
  }
908
1122
  }
1123
+ index = sink.addNode(sinkId);
909
1124
  if (this.idMap !== null) {
1125
+ const before = this.idMap.get(fileId);
1126
+ if (before !== undefined && before !== sinkId) {
1127
+ report.warning(
1128
+ "merged",
1129
+ DUPLICATE_NODE_CODE,
1130
+ `file id ${JSON.stringify(fileId)} is declared twice (nodes ${JSON.stringify(before)} and ${JSON.stringify(sinkId)}); edges to it resolve to the later`,
1131
+ { line, element: String(fileId) },
1132
+ );
1133
+ }
910
1134
  this.idMap.set(fileId, sinkId);
911
1135
  }
912
- index = sink.addNode(sinkId);
913
1136
  } catch (err) {
914
1137
  this.recordNodeError(err, line);
915
1138
  report.counts.skippedNodes++;
1139
+ if (fileId !== undefined) {
1140
+ this.skippedIds.add(fileId);
1141
+ }
916
1142
  return;
917
1143
  }
918
1144
  if (this.isDeclared(index)) {
@@ -928,16 +1154,27 @@ class GmlImport {
928
1154
  }
929
1155
  this.beginElement(this.seq++);
930
1156
  try {
1157
+ const graphics: number[] = [];
1158
+ let graphicsPlan: ColumnPlan | null = null;
931
1159
  for (let p = open + 1; p < close; p = t.nextPair(p)) {
932
1160
  const key = t.textOf(p);
933
1161
  if (key === "id" || (key === ORIGINAL_ID_KEY && options.restoreMangledIds)) {
934
1162
  continue;
935
1163
  }
936
1164
  const plan = this.nodePlans.get(key);
937
- if (plan !== undefined) {
1165
+ if (plan !== undefined && plan.position !== null) {
1166
+ graphicsPlan = plan;
1167
+ graphics.push(p + 1);
1168
+ } else if (plan !== undefined) {
938
1169
  this.writeNode(plan, index, p + 1);
939
1170
  }
940
1171
  }
1172
+ if (graphicsPlan !== null) {
1173
+ this.writeGraphics(graphicsPlan, index, graphics, {
1174
+ line: t.line[graphics[0]],
1175
+ element: String(sinkId),
1176
+ });
1177
+ }
941
1178
  this.flushLists("node", index);
942
1179
  } catch (err) {
943
1180
  this.touched.length = 0;
@@ -1144,7 +1381,20 @@ class GmlImport {
1144
1381
  */
1145
1382
  private endpoint(v: number, key: string): NodeId {
1146
1383
  const id = this.coerceFileId(v, this.fileIdOf(v, key));
1147
- return this.idMap?.get(id) ?? id;
1384
+ const mapped = this.idMap?.get(id);
1385
+ if (mapped !== undefined) {
1386
+ return mapped;
1387
+ }
1388
+ if (this.skippedIds.has(id)) {
1389
+ // the node block was skipped: creating the endpoint would bring the node back under
1390
+ // its raw file id (beside label ids under nodeIdFrom "label")
1391
+ throw new GraphFormatError(
1392
+ "E_UNKNOWN_NODE",
1393
+ `${key} ${JSON.stringify(id)} names a node block that was skipped after an error`,
1394
+ { reason: "skipped node", id },
1395
+ );
1396
+ }
1397
+ return id;
1148
1398
  }
1149
1399
 
1150
1400
  /**
@@ -1156,11 +1406,17 @@ class GmlImport {
1156
1406
  const t = this.requireTokens();
1157
1407
  switch (t.kind[v]) {
1158
1408
  case TOKEN_STRING:
1159
- return parseWeightText(t.stringOf(v));
1409
+ return parseWeightText(t.stringOf(v), this.report);
1160
1410
  case TOKEN_OPEN:
1161
1411
  throw new GraphFormatError("E_INVALID_WEIGHT", "edge weight is a record", { value: "[...]" });
1162
- default:
1163
- return weightFromValue(numberOfText(t.textOf(v)));
1412
+ default: {
1413
+ const text = t.textOf(v);
1414
+ const weight = weightFromValue(numberOfText(text));
1415
+ if (weight !== undefined) {
1416
+ reportWeightPrecision(text, weight, this.report);
1417
+ }
1418
+ return weight;
1419
+ }
1164
1420
  }
1165
1421
  }
1166
1422
 
@@ -1228,10 +1484,6 @@ class GmlImport {
1228
1484
  * @param v - the value token
1229
1485
  */
1230
1486
  private writeNode(plan: ColumnPlan, index: number, v: number): void {
1231
- if (plan.position !== null) {
1232
- this.writeGraphics(plan, index, v);
1233
- return;
1234
- }
1235
1487
  if (plan.list) {
1236
1488
  this.collectItem(plan, v, this.seqNow, this.touched);
1237
1489
  return;
@@ -1264,37 +1516,98 @@ class GmlImport {
1264
1516
  this.collectItem(plan, v, seq, this.graphTouched);
1265
1517
  return;
1266
1518
  }
1267
- this.sink.setGraphValue(plan.name, this.scalarOf(plan, v), graphDecl(plan));
1519
+ const value = this.scalarOf(plan, v);
1520
+ this.sink.setGraphValue(plan.name, value, graphDecl(plan));
1521
+ if (seq === GRAPH_SEQ && plan.key === "name" && typeof value === "string") {
1522
+ // the graph block's `name` is the graph's name too (snapshot.meta.name, and what graphName matches)
1523
+ this.sink.setMeta({ name: value });
1524
+ }
1268
1525
  }
1269
1526
 
1270
1527
  /**
1271
- * Write a node's graphics record: the position column from x / y / z, the remaining keys to
1272
- * the json column.
1528
+ * Write a node's graphics values: the position column from the x / y / z of the first record,
1529
+ * everything else (the remaining keys, a value that is not a record, a repeated record) to the
1530
+ * json column, with a warning when the value cannot give a position as written.
1273
1531
  * @param plan - the graphics plan
1274
1532
  * @param index - the node index
1275
- * @param v - the value token (a record)
1533
+ * @param vs - the value tokens of the node's graphics keys, in order
1534
+ * @param where - the line and the node, for issues
1276
1535
  */
1277
- private writeGraphics(plan: ColumnPlan, index: number, v: number): void {
1536
+ private writeGraphics(plan: ColumnPlan, index: number, vs: readonly number[], where: IssueWhere): void {
1278
1537
  const t = this.requireTokens();
1279
1538
  const { sink } = this;
1280
- const record = parseRecord(t, v);
1281
- const { x, y, z } = record;
1539
+ const values = vs.map((v) => (t.kind[v] === TOKEN_OPEN ? parseRecord(t, v) : this.scalarOf(plan, v)));
1540
+ const first = values[0];
1282
1541
  const positionPlan = plan.position;
1283
- if (positionPlan !== null && typeof x === "number" && typeof y === "number") {
1284
- sink.setNodeValue(this.handleOf(positionPlan, "node"), index, [x, y, typeof z === "number" ? z : 0]);
1542
+ let rest: unknown = first;
1543
+ if (isRecord(first) && positionPlan !== null) {
1544
+ rest = this.writePosition(positionPlan, index, first, where);
1545
+ } else if (!isRecord(first)) {
1546
+ this.graphicsWarning("scalar", `node ${where.element}'s graphics is not a record`, where);
1547
+ }
1548
+ if (values.length > 1) {
1549
+ this.graphicsWarning(
1550
+ "repeated",
1551
+ `node ${where.element} has ${values.length} graphics records; the position comes from the first`,
1552
+ where,
1553
+ );
1554
+ rest = values;
1555
+ }
1556
+ if (rest !== undefined && plan.rest !== null) {
1557
+ sink.setNodeValue(this.handleOf(plan.rest, "node"), index, rest);
1558
+ }
1559
+ }
1560
+
1561
+ /**
1562
+ * Write a node's position from the x / y / z of its graphics record, taking them out of it.
1563
+ * @param positionPlan - the position column's plan
1564
+ * @param index - the node index
1565
+ * @param record - the graphics record
1566
+ * @param where - the line and the node, for issues
1567
+ * @returns what is left of the record for the json column, or undefined when nothing is
1568
+ */
1569
+ private writePosition(
1570
+ positionPlan: ColumnPlan,
1571
+ index: number,
1572
+ record: Record<string, unknown>,
1573
+ where: IssueWhere,
1574
+ ): unknown {
1575
+ const { x, y, z } = record;
1576
+ let rest: unknown = record;
1577
+ if (typeof x === "number" && typeof y === "number") {
1578
+ const depth = typeof z === "number" ? z : 0;
1579
+ this.sink.setNodeValue(this.handleOf(positionPlan, "node"), index, [x, y, depth]);
1285
1580
  delete record.x;
1286
1581
  delete record.y;
1287
1582
  if (typeof z === "number") {
1288
1583
  delete record.z;
1289
1584
  }
1290
- if (plan.rest !== null && Object.keys(record).length > 0) {
1291
- sink.setNodeValue(this.handleOf(plan.rest, "node"), index, record);
1292
- }
1293
- return;
1585
+ rest = Object.keys(record).length > 0 ? record : undefined;
1294
1586
  }
1295
- if (plan.rest !== null) {
1296
- sink.setNodeValue(this.handleOf(plan.rest, "node"), index, record);
1587
+ if ("x" in record || "y" in record || "z" in record) {
1588
+ this.graphicsWarning(
1589
+ "coordinate",
1590
+ `node ${where.element}'s graphics x / y / z is not one number each`,
1591
+ where,
1592
+ );
1297
1593
  }
1594
+ return rest;
1595
+ }
1596
+
1597
+ /**
1598
+ * Warn once per kind of graphics problem.
1599
+ * @param kind - the problem
1600
+ * @param what - the message start, naming the node
1601
+ * @param where - the line and the node
1602
+ */
1603
+ private graphicsWarning(kind: string, what: string, where: IssueWhere): void {
1604
+ this.report.warnOnce(
1605
+ "validation-error",
1606
+ GRAPHICS_CODE,
1607
+ `${what}; the value is kept in the graphics json column (warned once for every such node)`,
1608
+ where,
1609
+ `${GRAPHICS_CODE}:${kind}`,
1610
+ );
1298
1611
  }
1299
1612
 
1300
1613
  /**
@@ -1605,9 +1918,13 @@ function sniffGml(head: Uint8Array): number {
1605
1918
  return 0;
1606
1919
  }
1607
1920
 
1608
- /** The GML importer plugin. */
1921
+ /**
1922
+ * The GML importer plugin.
1923
+ * @category Built-in formats
1924
+ */
1609
1925
  export const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({
1610
1926
  format: "gml",
1927
+ options: Object.freeze(["dictionaries", "positions"]),
1611
1928
  extensions: Object.freeze([".gml"]),
1612
1929
  mimeTypes: Object.freeze(["text/x-gml", "text/plain"]),
1613
1930
  sniff: sniffGml,
@@ -1623,6 +1940,10 @@ export const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({
1623
1940
  sink: GraphSink,
1624
1941
  options?: GmlImportOptions & CommonImportOptions,
1625
1942
  ): Promise<ImportReport> {
1943
+ if (graphChosen(options)) {
1944
+ // the choice is honored here too, not only by the registry
1945
+ return importChosenGraph(gmlImporter, input, sink, options);
1946
+ }
1626
1947
  const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);
1627
1948
  const report = new ImportReportBuilder("gml", resolved.errorLimit);
1628
1949
  reportSinkOptions(sink, options, report);
@@ -1635,7 +1956,7 @@ export const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({
1635
1956
  report.warning(
1636
1957
  "unsupported",
1637
1958
  SECOND_GRAPH_CODE,
1638
- `the input holds ${gml.graphCount - 1} more graph block(s) after the first; import() reads the first, importAll() reads every one`,
1959
+ `the input holds ${gml.graphCount - 1} more graph block${plural(gml.graphCount - 1)} after the first; the first is read (graphIndex or graphName chooses another; importAllGraphs() reads every one)`,
1639
1960
  );
1640
1961
  }
1641
1962
  // an abort raised during the last few elements (after the last periodic check) still rejects