@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
@@ -1,32 +1,277 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { T as TOO_LARGE_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, D as DIRECTION_FORCED_CODE, a as DIRECTION_REFUSED_CODE, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, Y as UNKNOWN_ELEMENT_CODE, I as ID_MERGED_CODE, P as PRECISION_CODE, b as ID_TEXT_TYPE_CODE, c as DUPLICATE_EDGE_ID_CODE, d as DUPLICATE_NODE_CODE, e as MISSING_ENDPOINT_CODE, f as MISSING_ID_CODE, i as DUPLICATE_ATTRIBUTE_CODE, j as DANGLING_REFERENCE_CODE, k as UNKNOWN_ATTR_TYPE_CODE, Z as BAD_DEFAULT_CODE, B as BAD_VALUE_CODE, l as COUNT_MISMATCH_CODE, m as ASPECT_ORDER_CODE, n as BAD_ASPECT_BLOCK_CODE, g as STYLES_NOT_IMPORTED_CODE, o as STATUS_WARNING_CODE, p as STATUS_FAILED_CODE, q as UNKNOWN_ENCODING_CODE, E as ENCODING_FALLBACK_CODE, r as INVALID_ENCODING_CODE, s as INVALID_UTF8_CODE, t as SYNTAX_CODE, u as EMPTY_INPUT_CODE, v as resolveImportOptions, w as ImportReportBuilder, F as reportSinkOptions, z as reportUnusedOptions, y as throwIfAborted, x as textChunks, J as DirectionResolver, K as IdCoercer, L as declareResolved, Q as uniqueColumnName } from "./report-B1z4WT9e.js";
3
- import { s as scanAspects, r as reportTooDeep, C as CxStructure, i as isRecord, J as JsonScanError, p as plainJson, c as cxId, z as zDecl, a as positionDecl, f as flipY, d as declareFresh, E as ExactInteger, b as inexactLiteral } from "./json-elements-DDS8N2Dd.js";
4
- import { w as weightFromValue } from "./weights-Dzba96G3.js";
2
+ import { b as plural, $ as agree, L as LOSS, ad as TOO_LARGE_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, D as DIRECTION_FORCED_CODE, d as DIRECTION_REFUSED_CODE, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, g as UNKNOWN_ELEMENT_CODE, I as ID_MERGED_CODE, P as PRECISION_CODE, J as ID_TEXT_TYPE_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, o as DUPLICATE_ATTRIBUTE_CODE, i as DANGLING_REFERENCE_CODE, U as UNKNOWN_ATTR_TYPE_CODE, B as BAD_DEFAULT_CODE, a3 as BAD_VALUE_CODE, j as COUNT_MISMATCH_CODE, Y as ASPECT_ORDER_CODE, V as BAD_ASPECT_BLOCK_CODE, ah as STYLES_NOT_IMPORTED_CODE, a2 as JSON_NONSTANDARD_NUMBER_CODE, W as MULTI_ASPECT_FRAGMENT_CODE, ag as SINGLE_OBJECT_ASPECT_CODE, _ as STATUS_WARNING_CODE, Z as STATUS_FAILED_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, ak as SYNTAX_CODE, E as EMPTY_INPUT_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, ao as reportSinkOptions, an as reportUnusedOptions, am as throwIfAborted, a4 as textChunks, aq as DirectionResolver, ar as IdCoercer, a1 as declareResolved, a0 as uniqueColumnName, as as weightFromValue } from "./export-CHd4tQE2.js";
3
+ import { h as headText, s as scanAspects, r as reportTooDeep, C as CxStructure, a as reportSharedBlock, J as JsonScanError, i as isRecord, j as setOwn, p as plainJson, c as cxId, f as fitsF32, z as zDecl, d as positionDecl, b as flipY, e as declareFresh, E as ExactInteger, g as inexactLiteral, k as keptPrecision } from "./json-elements-BAmNBZok.js";
4
+ const RAW = `${String.fromCodePoint(0)}cx:`;
5
+ const RAW_JSON = /"\\u0000cx:(-?\d+)"/g;
6
+ const BIG_INTEGER_TEXT = /^-?[1-9]\d{15,}$/;
7
+ function writableId(id) {
8
+ return typeof id === "number" ? Number.isSafeInteger(id) : BIG_INTEGER_TEXT.test(id) && !Number.isSafeInteger(Number(id));
9
+ }
10
+ function writtenIds(snapshot, mode, format) {
11
+ const { ids } = snapshot;
12
+ const bad = [];
13
+ const used = /* @__PURE__ */ new Set();
14
+ for (let i = 0; i < ids.size; i++) {
15
+ const id = ids.idOf(i);
16
+ if (!writableId(id)) {
17
+ bad.push(i);
18
+ } else if (typeof id === "number") {
19
+ used.add(id);
20
+ }
21
+ }
22
+ if (bad.length > 0 && mode === "error") {
23
+ const first = ids.idOf(bad[0]);
24
+ throw new GraphFormatError(
25
+ "E_INVALID_ID",
26
+ `${bad.length} node id${plural(bad.length)} cannot be written as ${format} integers (first: ${JSON.stringify(first)} at index ${bad[0]}); pass sanitizeIds: "mangle" to rewrite them`,
27
+ { reason: "charset", charset: "integer", count: bad.length, index: bad[0] }
28
+ );
29
+ }
30
+ const renumbered = /* @__PURE__ */ new Map();
31
+ let next = 0;
32
+ for (const i of bad) {
33
+ while (used.has(next)) {
34
+ next++;
35
+ }
36
+ used.add(next);
37
+ renumbered.set(i, next);
38
+ }
39
+ return {
40
+ changed: bad.length,
41
+ idAt: (i) => {
42
+ const id = renumbered.get(i) ?? ids.idOf(i);
43
+ return typeof id === "string" ? `${RAW}${id}` : id;
44
+ },
45
+ isChanged: (i) => renumbered.has(i),
46
+ originalAt: (i) => ids.idOf(i)
47
+ };
48
+ }
49
+ function nextNodeId(ids, count) {
50
+ let max = -1n;
51
+ for (let i = 0; i < count; i++) {
52
+ const id = ids.idAt(i);
53
+ const value = typeof id === "number" ? BigInt(id) : BigInt(id.slice(RAW.length));
54
+ if (value > max) {
55
+ max = value;
56
+ }
57
+ }
58
+ const next = max + 1n;
59
+ return next <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(next) : `${RAW}${next.toString()}`;
60
+ }
61
+ function unwritableIds(snapshot) {
62
+ let count = 0;
63
+ for (let i = 0; i < snapshot.ids.size; i++) {
64
+ if (!writableId(snapshot.ids.idOf(i))) {
65
+ count++;
66
+ }
67
+ }
68
+ return count;
69
+ }
70
+ function planNodeIds(snapshot, common, format, attribute, note) {
71
+ const unwritable = unwritableIds(snapshot);
72
+ if (unwritable > 0) {
73
+ note(
74
+ common.sanitizeIds === "mangle" ? LOSS.ID_MANGLED : LOSS.ID_CHARSET,
75
+ common.sanitizeIds === "mangle" ? `${unwritable} node id${plural(unwritable)} ${agree(unwritable, "is", "are")} not integers, so they are renumbered; the original ids are written to the ${attribute} attribute, and an import with restoreMangledIds: true reads them back` : `${unwritable} node id${plural(unwritable)} ${agree(unwritable, "is", "are")} not integers, so the save fails unless sanitizeIds is "mangle"`,
76
+ null,
77
+ unwritable
78
+ );
79
+ }
80
+ try {
81
+ return writtenIds(snapshot, common.sanitizeIds, format);
82
+ } catch (err) {
83
+ if (err instanceof GraphFormatError) {
84
+ return err;
85
+ }
86
+ throw err;
87
+ }
88
+ }
89
+ function scalarType(dtype, longOrigin) {
90
+ switch (dtype) {
91
+ case "f64":
92
+ return longOrigin ? "long" : "double";
93
+ case "f32":
94
+ return "double";
95
+ case "i32":
96
+ case "u8":
97
+ return "integer";
98
+ case "u32":
99
+ return "long";
100
+ case "bool":
101
+ return "boolean";
102
+ default:
103
+ return "string";
104
+ }
105
+ }
106
+ function allIntegral(column) {
107
+ for (let i = 0; i < column.length; i++) {
108
+ if (column.isSet(i) && !Number.isSafeInteger(column.value(i))) {
109
+ return false;
110
+ }
111
+ }
112
+ return true;
113
+ }
114
+ function declaredType(column) {
115
+ const { meta } = column;
116
+ const origin = meta.origin?.type ?? null;
117
+ const longOrigin = origin !== null && origin.endsWith("long") && (meta.dtype !== "f64" || allIntegral(column));
118
+ if (meta.dtype === "list") {
119
+ return meta.itemDtype === null || meta.itemDtype === "json" ? "string" : `list_of_${scalarType(meta.itemDtype, longOrigin)}`;
120
+ }
121
+ return meta.components > 1 ? `list_of_${scalarType(meta.dtype, false)}` : scalarType(meta.dtype, longOrigin);
122
+ }
123
+ function nonFinitePositions(position) {
124
+ let count = 0;
125
+ for (let i = 0; i < position.length; i++) {
126
+ if (position.isSet(i)) {
127
+ const p = position.value(i);
128
+ if (!Number.isFinite(p[0]) || !Number.isFinite(p[1])) {
129
+ count++;
130
+ }
131
+ }
132
+ }
133
+ return count;
134
+ }
135
+ function planEdgeIds(snapshot, note) {
136
+ const column = snapshot.edges.byRole("id");
137
+ const used = /* @__PURE__ */ new Set();
138
+ let generated = 0;
139
+ const ids = keptEdgeIds(column, snapshot.edgeCount, used);
140
+ let next = 0;
141
+ const out = [];
142
+ for (let e = 0; e < snapshot.edgeCount; e++) {
143
+ let id = ids[e];
144
+ if (id === null) {
145
+ while (used.has(next)) {
146
+ next++;
147
+ }
148
+ id = next;
149
+ used.add(next);
150
+ generated++;
151
+ }
152
+ out.push(id);
153
+ }
154
+ if (column !== null && generated > 0) {
155
+ note(
156
+ LOSS.EDGE_IDS_GENERATED,
157
+ `${generated} edge${plural(generated)} ${agree(generated, "has", "have")} no distinct integer id in "${column.meta.name}"; they are written with generated ids`,
158
+ column.meta.name,
159
+ generated
160
+ );
161
+ }
162
+ if (column !== null && column.dtype !== "f64") {
163
+ note(
164
+ LOSS.DTYPE,
165
+ `edge id column "${column.meta.name}" is ${column.dtype}; CX edge ids are integers and read back as f64`,
166
+ column.meta.name,
167
+ snapshot.edgeCount - column.nullCount
168
+ );
169
+ }
170
+ return out;
171
+ }
172
+ function keptEdgeIds(column, edgeCount, used) {
173
+ const ids = new Array(edgeCount).fill(null);
174
+ if (column === null) {
175
+ return ids;
176
+ }
177
+ for (let e = 0; e < edgeCount; e++) {
178
+ const value = column.isSet(e) ? column.value(e) : void 0;
179
+ const n = typeof value === "number" || typeof value === "string" ? Number(value) : Number.NaN;
180
+ if (Number.isSafeInteger(n) && !used.has(n)) {
181
+ ids[e] = n === 0 ? 0 : n;
182
+ used.add(n);
183
+ }
184
+ }
185
+ return ids;
186
+ }
187
+ function directionNotes(snapshot, folding, common, undirectedCode, note) {
188
+ if (!snapshot.directed) {
189
+ note(
190
+ undirectedCode,
191
+ `the snapshot is undirected; every edge is written as a directed edge (${snapshot.edgeCount} edge${plural(snapshot.edgeCount)})`,
192
+ null,
193
+ snapshot.edgeCount
194
+ );
195
+ } else if (common.onMixedDirection !== "error") {
196
+ let undirected = 0;
197
+ for (let e = 0; e < snapshot.edgeCount; e++) {
198
+ if (!folding.folded(e) && !folding.sourceDirected(e)) {
199
+ undirected++;
200
+ }
201
+ }
202
+ if (undirected > 0) {
203
+ note(
204
+ undirectedCode,
205
+ `${undirected} undirected edge${plural(undirected)} ${agree(undirected, "is", "are")} written as one directed edge each (a pair folded to its primary); CX has no undirected edge`,
206
+ null,
207
+ undirected
208
+ );
209
+ }
210
+ }
211
+ if (folding.mutualCount > 0) {
212
+ note(
213
+ LOSS.MUTUAL_EXPANDED,
214
+ `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, "is", "are")} written as two directed edges; the mutual mark is lost`,
215
+ null,
216
+ folding.mutualCount
217
+ );
218
+ }
219
+ }
220
+ function noteList() {
221
+ const notes = [];
222
+ const note = (code, message, column = null, count = null) => {
223
+ notes.push(Object.freeze({ code, message, column, count }));
224
+ };
225
+ return { notes, note };
226
+ }
227
+ function stringify(value) {
228
+ const text = JSON.stringify(value, (_key, v) => Object.is(v, -0) ? `${RAW}-0` : v);
229
+ return text.includes(String.raw`\u0000cx:`) ? text.replaceAll(RAW_JSON, "$1") : text;
230
+ }
231
+ function* aspectBlock(aspect, elements) {
232
+ yield `{${JSON.stringify(aspect)}:[`;
233
+ let first = true;
234
+ for (const element of elements) {
235
+ yield first ? `
236
+ ${element}` : `,
237
+ ${element}`;
238
+ first = false;
239
+ }
240
+ yield "]},\n";
241
+ }
5
242
  const CX2_FORMAT = "cx2";
6
243
  const ORIGINAL_ID_ATTRIBUTE = "graphty:originalId";
7
244
  const BYPASS_NAMESPACE = "cx2.bypass";
8
245
  const CX2_ISSUE = Object.freeze({
9
- /** The input is empty (fatal). */
246
+ ...INPUT_ISSUE,
247
+ ...ELEMENT_ISSUE,
248
+ /** The input is empty. The import stops. */
10
249
  EMPTY_INPUT: EMPTY_INPUT_CODE,
11
- /** The text is not JSON (fatal). */
250
+ /** The text is not valid JSON. The import stops. */
12
251
  SYNTAX: SYNTAX_CODE,
13
- /** Invalid UTF-8 (fatal). */
252
+ /** The input is not valid UTF-8. The import stops. */
14
253
  INVALID_UTF8: INVALID_UTF8_CODE,
15
- /** Invalid bytes in the encoding a BOM or the encoding option chose (fatal). */
254
+ /**
255
+ * Some bytes are not valid in the encoding that was chosen (by a byte order mark or the `encoding` option). The
256
+ * import stops.
257
+ */
16
258
  INVALID_ENCODING: INVALID_ENCODING_CODE,
17
259
  /** Bytes that are not UTF-8 were read as windows-1252. */
18
260
  ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,
19
261
  /** An encoding the platform cannot decode was ignored. */
20
262
  UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,
21
- /** The document is not an array or does not start with a descriptor holding CXVersion (fatal). */
263
+ /**
264
+ * The document is not a JSON array, or its first element is not the CX2 descriptor with `CXVersion`. The import
265
+ * stops.
266
+ */
22
267
  NO_DESCRIPTOR: "E_CX2_NO_DESCRIPTOR",
23
- /** CXVersion names a major version other than 2 (fatal); "1.x" says the file is CX1. */
268
+ /** `CXVersion` names a version other than 2 ("1.x" means the file is CX1; read it as `cx`). The import stops. */
24
269
  VERSION: "E_CX2_VERSION",
25
270
  /** CXVersion is a 2.x other than "2.0" (or not a string); the document is read. */
26
271
  MINOR_VERSION: "W_CX2_MINOR_VERSION",
27
272
  /** The document has no status block, or a malformed one. */
28
273
  NO_STATUS: "E_CX2_NO_STATUS",
29
- /** The producer marked the document as failed (fatal). */
274
+ /** The program that wrote the file marked it as failed, so it is incomplete. The import stops. */
30
275
  STATUS_FAILED: STATUS_FAILED_CODE,
31
276
  /** The producer marked the document as successful with an error text. */
32
277
  STATUS_WARNING: STATUS_WARNING_CODE,
@@ -50,9 +295,18 @@ const CX2_ISSUE = Object.freeze({
50
295
  ALIAS_BYPASSED: "W_CX2_ALIAS_BYPASSED",
51
296
  /** A CX1 cartesianLayout aspect next to node coordinates; kept, not applied. */
52
297
  LEGACY_LAYOUT: "W_CX2_LEGACY_LAYOUT",
53
- /** The file's style rules are not applied (issue #706). */
298
+ /** An aspect CX2 defines as an array of elements written as one object; read as one element. */
299
+ SINGLE_OBJECT_ASPECT: SINGLE_OBJECT_ASPECT_CODE,
300
+ /** A member holding several aspects; each array-valued key is read as its own block. */
301
+ MULTI_ASPECT_FRAGMENT: MULTI_ASPECT_FRAGMENT_CODE,
302
+ /** The bare tokens NaN / Infinity / -Infinity (Python's json writes them), read as numbers. */
303
+ JSON_NONSTANDARD_NUMBER: JSON_NONSTANDARD_NUMBER_CODE,
304
+ /** The file's style rules are not applied; they are kept so a CX2 export writes them back. */
54
305
  STYLES_NOT_IMPORTED: STYLES_NOT_IMPORTED_CODE,
55
- /** A member of the top-level array that is not a one-key aspect block, or an element that is not an object. */
306
+ /**
307
+ * A member of the file's top-level array that is not a block with one key (`{"nodes": [...]}`), or an element of a
308
+ * block that is not an object. It is skipped; the rest of the file is read.
309
+ */
56
310
  BAD_ASPECT_BLOCK: BAD_ASPECT_BLOCK_CODE,
57
311
  /** An aspect out of its place (after the post-metadata or the status, a third metaData, late declarations). */
58
312
  ASPECT_ORDER: ASPECT_ORDER_CODE,
@@ -84,25 +338,37 @@ const CX2_ISSUE = Object.freeze({
84
338
  INVALID_WEIGHT: "E_INVALID_WEIGHT",
85
339
  /** An id spelled as a string or a non-integer literal; read as the integer. */
86
340
  ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,
87
- /** An integer beyond 2^53: an id kept as its digits, a value stored as the nearest f64. */
341
+ /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: "string"` to keep every digit. */
88
342
  PRECISION: PRECISION_CODE,
89
343
  /** Two id texts merged under `ids: "number"`. */
90
344
  ID_MERGED: ID_MERGED_CODE,
91
345
  /** An element key CX2 does not define. */
92
346
  UNKNOWN_ELEMENT: UNKNOWN_ELEMENT_CODE,
93
- /** A column renamed because its name was taken. */
347
+ /**
348
+ * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example
349
+ * two attributes declared with the same name.
350
+ */
94
351
  COLUMN_RENAMED: COLUMN_RENAMED_CODE,
95
- /** A column that lost its role because another column holds it. */
352
+ /**
353
+ * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as
354
+ * a plain attribute.
355
+ */
96
356
  ROLE_TAKEN: ROLE_TAKEN_CODE,
97
- /** The sink refused the direction. */
357
+ /**
358
+ * You read into a graph builder whose direction is already set, or which already holds edges, so the file is read
359
+ * with the builder's direction instead of its own.
360
+ */
98
361
  DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,
99
- /** Edges forced to the policy's direction. */
362
+ /** Edges of the other direction were read with the direction `onMixedDirection` chose. */
100
363
  DIRECTION_FORCED: DIRECTION_FORCED_CODE,
101
- /** A common option CX2 has no use for. */
364
+ /** You set an option this format does not use; it had no effect. The message names the option. */
102
365
  OPTION_IGNORED: OPTION_IGNORED_CODE,
103
- /** A builder option the caller's sink does not honour. */
366
+ /**
367
+ * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,
368
+ * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.
369
+ */
104
370
  SINK_OPTION: SINK_OPTION_CODE,
105
- /** The input is beyond a size limit (fatal). */
371
+ /** The input is larger than graph-io's size limit. The import stops. */
106
372
  TOO_LARGE: TOO_LARGE_CODE
107
373
  });
108
374
  const USED_OPTIONS = /* @__PURE__ */ new Set([
@@ -137,20 +403,30 @@ const STYLE_ASPECTS = [
137
403
  "cyTableVisualProperties"
138
404
  ];
139
405
  const STRUCTURE_ASPECTS = /* @__PURE__ */ new Set(["metaData", "status"]);
140
- const SCALARS = {
141
- string: "string",
142
- long: "long",
143
- integer: "integer",
144
- double: "double",
145
- boolean: "boolean",
146
- str: "string",
147
- int: "integer",
148
- bool: "boolean",
149
- float: "double"
150
- };
406
+ const ARRAY_ASPECTS = /* @__PURE__ */ new Set([
407
+ "nodes",
408
+ "edges",
409
+ "attributeDeclarations",
410
+ "networkAttributes",
411
+ "nodeBypasses",
412
+ "edgeBypasses",
413
+ "status",
414
+ "metaData"
415
+ ]);
416
+ const SCALARS = /* @__PURE__ */ new Map([
417
+ ["string", "string"],
418
+ ["long", "long"],
419
+ ["integer", "integer"],
420
+ ["double", "double"],
421
+ ["boolean", "boolean"],
422
+ ["str", "string"],
423
+ ["int", "integer"],
424
+ ["bool", "boolean"],
425
+ ["float", "double"]
426
+ ]);
151
427
  function cx2Type(d) {
152
428
  const list = d.startsWith("list_of_");
153
- const scalar = SCALARS[list ? d.slice("list_of_".length) : d];
429
+ const scalar = SCALARS.get(list ? d.slice("list_of_".length) : d);
154
430
  if (scalar === void 0) {
155
431
  return null;
156
432
  }
@@ -185,6 +461,7 @@ function convertScalar(value, scalar, long, onPrecision) {
185
461
  return typeof value === "boolean" ? value : BAD;
186
462
  case "double":
187
463
  if (value instanceof ExactInteger) {
464
+ onPrecision(value.digits);
188
465
  return Number(value.digits);
189
466
  }
190
467
  return typeof value === "number" ? value : BAD;
@@ -235,13 +512,13 @@ function shown(value) {
235
512
  }
236
513
  return text.length > 60 ? `${text.slice(0, 57)}...` : text;
237
514
  }
238
- function inexactBits(text, keys) {
515
+ function inexactBits(text, keys, depth = 1) {
239
516
  if (!/[0-9][.eE]/.test(text)) {
240
517
  return 0;
241
518
  }
242
519
  let bits = 0;
243
520
  keys.forEach((key, i) => {
244
- if (inexactLiteral(text, key)) {
521
+ if (inexactLiteral(text, key, depth)) {
245
522
  bits |= 1 << i;
246
523
  }
247
524
  });
@@ -265,16 +542,17 @@ async function readDocument(input, report, options) {
265
542
  let descriptor = false;
266
543
  let elementsSeen = false;
267
544
  let sinceCheck = 0;
268
- const collect = (aspect, value, text, line, exact) => {
545
+ const opaquePrecision = keptPrecision(report, "meta.extra.cx2.opaque");
546
+ const collect = (aspect, value, text, line, exact, depth = 1) => {
269
547
  structure.element(aspect, value, line);
270
548
  switch (aspect) {
271
549
  case "nodes":
272
550
  elementsSeen = true;
273
- doc.nodes.push({ value, line, inexact: inexactBits(text, ["id"]) });
551
+ doc.nodes.push({ value, line, inexact: inexactBits(text, ["id"], depth) });
274
552
  return;
275
553
  case "edges":
276
554
  elementsSeen = true;
277
- doc.edges.push({ value, line, inexact: inexactBits(text, ["id", "s", "t"]) });
555
+ doc.edges.push({ value, line, inexact: inexactBits(text, ["id", "s", "t"], depth) });
278
556
  return;
279
557
  case "attributeDeclarations":
280
558
  if (elementsSeen) {
@@ -286,7 +564,7 @@ async function readDocument(input, report, options) {
286
564
  `${ASPECT_ORDER_CODE}:declarations`
287
565
  );
288
566
  }
289
- doc.declarations.push({ value: plainJson(value), line, inexact: 0 });
567
+ doc.declarations.push({ value, line, inexact: 0 });
290
568
  return;
291
569
  case "networkAttributes":
292
570
  elementsSeen = true;
@@ -308,11 +586,11 @@ async function readDocument(input, report, options) {
308
586
  if (!doc.opaque.has(aspect)) {
309
587
  doc.opaque.set(aspect, []);
310
588
  }
311
- doc.opaque.get(aspect)?.push(exact ? plainJson(value, () => void 0) : value);
589
+ doc.opaque.get(aspect)?.push(exact ? plainJson(value, opaquePrecision) : value);
312
590
  }
313
591
  };
314
592
  try {
315
- for await (const event of scanAspects(textChunks(input, report, options))) {
593
+ for await (const event of scanAspects(textChunks(input, report, options), report)) {
316
594
  if (++sinceCheck >= ABORT_CHECK_INTERVAL) {
317
595
  sinceCheck = 0;
318
596
  throwIfAborted(options.signal);
@@ -321,7 +599,7 @@ async function readDocument(input, report, options) {
321
599
  case "root":
322
600
  report.fail(
323
601
  CX2_ISSUE.NO_DESCRIPTOR,
324
- `a CX2 document is a JSON array; found ${isRecord(event.value) ? "an object" : shown(event.value)}`,
602
+ `a CX2 document is a JSON array; found ${event.object ? "an object" : shown(event.value)}`,
325
603
  { line: event.line }
326
604
  );
327
605
  break;
@@ -332,10 +610,11 @@ async function readDocument(input, report, options) {
332
610
  break;
333
611
  }
334
612
  memberAspect(event.value, event.line, structure, report, (aspect, value) => {
335
- collect(aspect, value, JSON.stringify(value) ?? "", event.line, event.exact);
613
+ collect(aspect, value, event.text, event.line, event.exact, 2);
336
614
  });
337
615
  break;
338
616
  case "block":
617
+ reportSharedBlock(report, event);
339
618
  if (!descriptor) {
340
619
  report.fail(
341
620
  CX2_ISSUE.NO_DESCRIPTOR,
@@ -358,7 +637,7 @@ async function readDocument(input, report, options) {
358
637
  report.error(
359
638
  "parse-error",
360
639
  BAD_ASPECT_BLOCK_CODE,
361
- `the "${event.aspect}" block holds more keys (${event.keys.join(", ")}); an aspect block has one key, the others are skipped`,
640
+ `the "${event.aspect}" block holds more keys (${event.keys.join(", ")}) whose values are not arrays; an aspect block has one key, the others are skipped`,
362
641
  { line: event.line, element: event.aspect }
363
642
  );
364
643
  break;
@@ -388,8 +667,8 @@ function readDescriptor(value, line, doc, report) {
388
667
  }
389
668
  const raw = value.CXVersion;
390
669
  const text = typeof raw === "string" || typeof raw === "number" ? String(raw) : "";
391
- const match = /^([0-9]+)(?:\.([0-9]+))?$/.exec(text);
392
- const major = match === null ? NaN : Number(match[1]);
670
+ const match = /^\s*(\d+)(?=$|[.\s-])/.exec(text);
671
+ const major = match === null ? Number.NaN : Number(match[1]);
393
672
  if (major === 1) {
394
673
  report.fail(
395
674
  CX2_ISSUE.VERSION,
@@ -432,6 +711,14 @@ function readDescriptor(value, line, doc, report) {
432
711
  function memberAspect(value, line, structure, report, collect) {
433
712
  const keys = isRecord(value) ? Object.keys(value) : [];
434
713
  if (isRecord(value) && keys.length === 1 && isRecord(value[keys[0]])) {
714
+ if (ARRAY_ASPECTS.has(keys[0])) {
715
+ report.warning(
716
+ "validation-error",
717
+ CX2_ISSUE.SINGLE_OBJECT_ASPECT,
718
+ `the "${keys[0]}" aspect is one object, not an array of elements; read as one element`,
719
+ { line, element: keys[0] }
720
+ );
721
+ }
435
722
  structure.block(keys[0], line);
436
723
  collect(keys[0], value[keys[0]]);
437
724
  return;
@@ -505,7 +792,14 @@ class DeclarationTable {
505
792
  return decl === void 0 ? null : { decl, viaAlias: false };
506
793
  }
507
794
  }
508
- const DECLARATION_KEYS = { nodes: "node", edges: "edge", networkAttributes: "network" };
795
+ const DECLARATION_KEYS = /* @__PURE__ */ new Map([
796
+ ["nodes", "node"],
797
+ ["edges", "edge"],
798
+ ["networkAttributes", "network"]
799
+ ]);
800
+ function hasOwn(record, key) {
801
+ return Object.hasOwn(record, key);
802
+ }
509
803
  class Cx2Reader {
510
804
  /**
511
805
  * Create the reader.
@@ -524,6 +818,7 @@ class Cx2Reader {
524
818
  };
525
819
  this.nodeRows = /* @__PURE__ */ new Map();
526
820
  this.sinkIds = /* @__PURE__ */ new Map();
821
+ this.restored = /* @__PURE__ */ new Set();
527
822
  this.edgeRows = /* @__PURE__ */ new Map();
528
823
  this.positionHandle = INVALID_INDEX;
529
824
  this.zHandle = INVALID_INDEX;
@@ -557,7 +852,7 @@ class Cx2Reader {
557
852
  report.warnOnce(
558
853
  "missing-value",
559
854
  CX2_ISSUE.PARTIAL_LAYOUT,
560
- `${this.nodeRows.size - this.positioned.size} of ${this.nodeRows.size} node(s) have no coordinates; their positions are unset`,
855
+ `${this.nodeRows.size - this.positioned.size} of ${this.nodeRows.size} node${plural(this.nodeRows.size)} ${agree(this.nodeRows.size - this.positioned.size, "has", "have")} no coordinates; their positions are unset`,
561
856
  { element: "nodes" }
562
857
  );
563
858
  }
@@ -571,7 +866,7 @@ class Cx2Reader {
571
866
  report.warning(
572
867
  "validation-error",
573
868
  DANGLING_REFERENCE_CODE,
574
- `${count} ${kind} name(s) no element; ignored`,
869
+ `${count} ${kind}${plural(count)} ${agree(count, "names", "name")} no element; ignored`,
575
870
  { element: kind }
576
871
  );
577
872
  }
@@ -596,9 +891,21 @@ class Cx2Reader {
596
891
  continue;
597
892
  }
598
893
  for (const [key, table] of Object.entries(held.value)) {
599
- const domain = DECLARATION_KEYS[key];
894
+ const domain = DECLARATION_KEYS.get(key);
600
895
  if (domain === void 0) {
601
- this.decls.other[key] = table;
896
+ report.warning(
897
+ "unsupported",
898
+ UNKNOWN_ELEMENT_CODE,
899
+ `attributeDeclarations holds the table "${key}", which CX2 does not define; kept in meta.extra.cx2.declarations, not applied`,
900
+ { line: held.line, element: key }
901
+ );
902
+ setOwn(
903
+ this.decls.other,
904
+ key,
905
+ plainJson(table, (digits) => {
906
+ this.precision(key, digits);
907
+ })
908
+ );
602
909
  continue;
603
910
  }
604
911
  if (!isRecord(table)) {
@@ -636,7 +943,7 @@ class Cx2Reader {
636
943
  }
637
944
  for (const [key, raw] of Object.entries(value.v)) {
638
945
  const resolved = table.resolve(key);
639
- if (resolved !== null && resolved.decl.type !== null || raw === null || raw === void 0) {
946
+ if (key === "" || resolved !== null && resolved.decl.type !== null || raw === null || raw === void 0) {
640
947
  continue;
641
948
  }
642
949
  const name = resolved?.decl.name ?? key;
@@ -682,6 +989,15 @@ class Cx2Reader {
682
989
  const { report } = this;
683
990
  const table = this.decls[domain];
684
991
  const where = { line, element: name };
992
+ if (name === "") {
993
+ report.error(
994
+ "validation-error",
995
+ BAD_VALUE_CODE,
996
+ `a ${domain} attribute declaration has an empty name; ignored`,
997
+ where
998
+ );
999
+ return;
1000
+ }
685
1001
  if (!isRecord(raw)) {
686
1002
  report.error(
687
1003
  "validation-error",
@@ -723,6 +1039,14 @@ class Cx2Reader {
723
1039
  }
724
1040
  return;
725
1041
  }
1042
+ if (raw.a !== void 0 && raw.a !== null && typeof raw.a !== "string") {
1043
+ report.error(
1044
+ "validation-error",
1045
+ BAD_VALUE_CODE,
1046
+ `the alias ${shown(raw.a)} of "${name}" is not a string; ignored`,
1047
+ where
1048
+ );
1049
+ }
726
1050
  let alias = typeof raw.a === "string" ? raw.a : null;
727
1051
  let hasDefault = raw.v !== void 0 && raw.v !== null;
728
1052
  if (domain === "network" && (raw.a !== void 0 || raw.v !== void 0)) {
@@ -763,7 +1087,9 @@ class Cx2Reader {
763
1087
  * @returns the default, or BAD when dropped
764
1088
  */
765
1089
  convertDefault(name, value, type, where) {
766
- const converted = convertValue(value, type, this.options.long, () => void 0);
1090
+ const converted = convertValue(value, type, this.options.long, (digits) => {
1091
+ this.precision(name, digits);
1092
+ });
767
1093
  if (converted !== BAD) {
768
1094
  return converted;
769
1095
  }
@@ -879,10 +1205,11 @@ class Cx2Reader {
879
1205
  * @param raw - the parsed id
880
1206
  * @param inexact - whether the literal was not a plain integer
881
1207
  * @param element - the element name for issues
1208
+ * @param line - the element's line
882
1209
  * @param edgeId - whether this is an edge's own id (stored in the f64 id column, not kept as digits)
883
1210
  * @returns the id, or null when it was reported
884
1211
  */
885
- idOf(raw, inexact, element, edgeId = false) {
1212
+ idOf(raw, inexact, element, line, edgeId = false) {
886
1213
  let id;
887
1214
  try {
888
1215
  const parsed = cxId(raw, inexact);
@@ -891,14 +1218,14 @@ class Cx2Reader {
891
1218
  "coercion",
892
1219
  ID_TEXT_TYPE_CODE,
893
1220
  `${element}: the id ${shown(raw)} is not written as an integer; read as ${String(parsed.id)}`,
894
- { element }
1221
+ { line, element }
895
1222
  );
896
1223
  } else if (parsed.note === "precision" && edgeId) {
897
1224
  this.report.warnOnce(
898
1225
  "precision",
899
1226
  PRECISION_CODE,
900
1227
  `${element}: the edge id ${String(parsed.id)} is beyond 2^53; the id column holds the nearest double`,
901
- { element },
1228
+ { line, element },
902
1229
  `${PRECISION_CODE}:edge`
903
1230
  );
904
1231
  } else if (parsed.note === "precision") {
@@ -907,12 +1234,12 @@ class Cx2Reader {
907
1234
  "precision",
908
1235
  PRECISION_CODE,
909
1236
  `${element}: the id ${String(parsed.id)} is beyond 2^53; kept as its digits (a string id)`,
910
- { element }
1237
+ { line, element }
911
1238
  );
912
1239
  }
913
1240
  id = this.options.ids === "keep" ? parsed.id : this.coercer.value(parsed.id);
914
1241
  } catch (err) {
915
- this.report.recordError(err, { element });
1242
+ this.report.recordError(err, { line, element });
916
1243
  return null;
917
1244
  }
918
1245
  return id;
@@ -970,7 +1297,7 @@ class Cx2Reader {
970
1297
  return;
971
1298
  }
972
1299
  const element = `node ${shown(value.id)}`;
973
- const cx = this.idOf(value.id, (held.inexact & 1) !== 0, element);
1300
+ const cx = this.idOf(value.id, (held.inexact & 1) !== 0, element, line);
974
1301
  if (cx === null) {
975
1302
  report.counts.skippedNodes++;
976
1303
  return;
@@ -991,7 +1318,19 @@ class Cx2Reader {
991
1318
  { line, element }
992
1319
  );
993
1320
  } else {
994
- const original = this.originalIdOf(attrs);
1321
+ let original = this.originalIdOf(attrs, element, line);
1322
+ if (original !== null && this.restored.has(original)) {
1323
+ report.warning(
1324
+ "merged",
1325
+ DUPLICATE_NODE_CODE,
1326
+ `${element}: its original id ${shown(original)} is already another node's; it keeps its CX id`,
1327
+ { line, element }
1328
+ );
1329
+ original = null;
1330
+ }
1331
+ if (original !== null) {
1332
+ this.restored.add(original);
1333
+ }
995
1334
  this.idTypeOf(original ?? cx);
996
1335
  try {
997
1336
  row = sink.addNode(original ?? cx);
@@ -1012,14 +1351,24 @@ class Cx2Reader {
1012
1351
  /**
1013
1352
  * The original id the exporter's `sanitizeIds: "mangle"` kept, when it is to be restored.
1014
1353
  * @param attrs - the node's v
1354
+ * @param element - the element name for issues
1355
+ * @param line - its line
1015
1356
  * @returns the original id, or null
1016
1357
  */
1017
- originalIdOf(attrs) {
1358
+ originalIdOf(attrs, element, line) {
1018
1359
  if (attrs === null || !this.options.restoreMangledIds) {
1019
1360
  return null;
1020
1361
  }
1021
1362
  const alias = this.decls.node.byName.get(ORIGINAL_ID_ATTRIBUTE)?.alias ?? null;
1022
1363
  const raw = attrs[ORIGINAL_ID_ATTRIBUTE] ?? (alias === null ? void 0 : attrs[alias]);
1364
+ if (raw !== void 0 && raw !== null && typeof raw !== "string") {
1365
+ this.report.error(
1366
+ "validation-error",
1367
+ BAD_VALUE_CODE,
1368
+ `${element}: ${ORIGINAL_ID_ATTRIBUTE} is ${shown(raw)}, not a string; the node keeps its CX id`,
1369
+ { line, element }
1370
+ );
1371
+ }
1023
1372
  return typeof raw === "string" ? raw : null;
1024
1373
  }
1025
1374
  /**
@@ -1074,7 +1423,14 @@ class Cx2Reader {
1074
1423
  `${CX2_ISSUE.PARTIAL_LAYOUT}:z`
1075
1424
  );
1076
1425
  }
1077
- if (x !== null && y !== null) {
1426
+ if (x !== null && y !== null && (!fitsF32(x) || !fitsF32(y))) {
1427
+ this.report.error(
1428
+ "validation-error",
1429
+ BAD_VALUE_CODE,
1430
+ `${element}: the coordinates ${String(x)}, ${String(y)} are beyond what the f32 position column holds; the position is unset`,
1431
+ { line, element }
1432
+ );
1433
+ } else if (x !== null && y !== null) {
1078
1434
  this.setPosition(row, x, y, z);
1079
1435
  }
1080
1436
  if (z !== null && this.zAs === "column") {
@@ -1120,11 +1476,13 @@ class Cx2Reader {
1120
1476
  this.report.warning(
1121
1477
  "unsupported",
1122
1478
  CX2_ISSUE.LEGACY_LAYOUT,
1123
- `a CX1 cartesianLayout aspect (${cartesianLayout.length} element(s)) next to node coordinates; the node coordinates are used, the aspect is kept in meta.extra.cx2`,
1479
+ `a CX1 cartesianLayout aspect (${cartesianLayout.length} element${plural(cartesianLayout.length)}) next to node coordinates; the node coordinates are used, the aspect is kept in meta.extra.cx2`,
1124
1480
  { element: "cartesianLayout" }
1125
1481
  );
1126
1482
  return;
1127
1483
  }
1484
+ let view;
1485
+ const seen = /* @__PURE__ */ new Set();
1128
1486
  for (const held of cartesianLayout) {
1129
1487
  const entry = held.value;
1130
1488
  if (!isRecord(entry) || typeof entry.x !== "number" || typeof entry.y !== "number") {
@@ -1141,6 +1499,31 @@ class Cx2Reader {
1141
1499
  this.dangle("cartesianLayout entry");
1142
1500
  continue;
1143
1501
  }
1502
+ view ??= entry.view ?? null;
1503
+ if ((entry.view ?? null) !== view) {
1504
+ this.doc.opaque.set(
1505
+ "cartesianLayout",
1506
+ cartesianLayout.map((h) => plainJson(h.value))
1507
+ );
1508
+ this.report.warnOnce(
1509
+ "validation-error",
1510
+ DUPLICATE_ATTRIBUTE_CODE,
1511
+ `the cartesianLayout aspect names several views; view ${shown(view)} is read, the aspect is kept in meta.extra.cx2`,
1512
+ { line: held.line, element: "cartesianLayout" },
1513
+ `${DUPLICATE_ATTRIBUTE_CODE}:layout:view`
1514
+ );
1515
+ continue;
1516
+ }
1517
+ if (seen.has(row)) {
1518
+ this.report.warnOnce(
1519
+ "validation-error",
1520
+ DUPLICATE_ATTRIBUTE_CODE,
1521
+ `node ${shown(entry.node)} has two cartesianLayout entries; the later wins`,
1522
+ { line: held.line, element: "cartesianLayout" },
1523
+ `${DUPLICATE_ATTRIBUTE_CODE}:layout`
1524
+ );
1525
+ }
1526
+ seen.add(row);
1144
1527
  const z = typeof entry.z === "number" ? entry.z : null;
1145
1528
  this.setPosition(row, entry.x, entry.y, z);
1146
1529
  if (z !== null && this.zAs === "column") {
@@ -1186,6 +1569,15 @@ class Cx2Reader {
1186
1569
  const table = this.decls[domain];
1187
1570
  for (const key of Object.keys(attrs)) {
1188
1571
  const value = attrs[key];
1572
+ if (key === "") {
1573
+ report.error(
1574
+ "validation-error",
1575
+ BAD_VALUE_CODE,
1576
+ `${element}: v holds an attribute with an empty name; skipped`,
1577
+ { line, element }
1578
+ );
1579
+ continue;
1580
+ }
1189
1581
  const resolved = table.resolve(key);
1190
1582
  const name = resolved?.decl.name ?? key;
1191
1583
  if (domain === "node" && this.options.restoreMangledIds && name === ORIGINAL_ID_ATTRIBUTE) {
@@ -1204,7 +1596,7 @@ class Cx2Reader {
1204
1596
  );
1205
1597
  }
1206
1598
  if (resolved !== null && !resolved.viaAlias && resolved.decl.alias !== null && resolved.decl.alias !== key) {
1207
- if (resolved.decl.alias in attrs) {
1599
+ if (hasOwn(attrs, resolved.decl.alias)) {
1208
1600
  report.warning(
1209
1601
  "validation-error",
1210
1602
  DUPLICATE_ATTRIBUTE_CODE,
@@ -1307,9 +1699,9 @@ class Cx2Reader {
1307
1699
  return;
1308
1700
  }
1309
1701
  }
1310
- const id = this.idOf(value.id, (held.inexact & 1) !== 0, element, true);
1311
- const s = id === null ? null : this.idOf(value.s, (held.inexact & 2) !== 0, element);
1312
- const t = s === null ? null : this.idOf(value.t, (held.inexact & 4) !== 0, element);
1702
+ const id = this.idOf(value.id, (held.inexact & 1) !== 0, element, line, true);
1703
+ const s = id === null ? null : this.idOf(value.s, (held.inexact & 2) !== 0, element, line);
1704
+ const t = s === null ? null : this.idOf(value.t, (held.inexact & 4) !== 0, element, line);
1313
1705
  if (id === null || s === null || t === null) {
1314
1706
  report.counts.skippedEdges++;
1315
1707
  return;
@@ -1331,6 +1723,12 @@ class Cx2Reader {
1331
1723
  return;
1332
1724
  }
1333
1725
  const attrs = isRecord(value.v) ? value.v : null;
1726
+ if (value.v !== void 0 && value.v !== null && attrs === null) {
1727
+ report.error("validation-error", BAD_VALUE_CODE, `${element}: v is ${shown(value.v)}, not an object`, {
1728
+ line,
1729
+ element
1730
+ });
1731
+ }
1334
1732
  let weight;
1335
1733
  const weightKey = this.weightKey(attrs);
1336
1734
  try {
@@ -1370,10 +1768,10 @@ class Cx2Reader {
1370
1768
  return null;
1371
1769
  }
1372
1770
  const alias = this.decls.edge.byName.get(weightFrom)?.alias ?? null;
1373
- if (alias !== null && alias in attrs) {
1771
+ if (alias !== null && hasOwn(attrs, alias)) {
1374
1772
  return alias;
1375
1773
  }
1376
- return weightFrom in attrs ? weightFrom : null;
1774
+ return hasOwn(attrs, weightFrom) ? weightFrom : null;
1377
1775
  }
1378
1776
  /**
1379
1777
  * The sink id of an edge endpoint: a known node, or a node created under addMissingNodes.
@@ -1516,13 +1914,38 @@ class Cx2Reader {
1516
1914
  if (raw === null || raw === void 0) {
1517
1915
  continue;
1518
1916
  }
1917
+ if (property === "") {
1918
+ this.report.error(
1919
+ "validation-error",
1920
+ BAD_VALUE_CODE,
1921
+ `a ${domain}Bypasses element holds a visual property with an empty name; skipped`,
1922
+ { line, element: `${domain}Bypasses` }
1923
+ );
1924
+ continue;
1925
+ }
1519
1926
  let column = columns.get(property);
1520
1927
  if (column === void 0) {
1521
- column = { rows: [], values: [] };
1928
+ column = { rows: [], values: [], at: /* @__PURE__ */ new Map() };
1522
1929
  columns.set(property, column);
1523
1930
  }
1524
- column.rows.push(row);
1525
- column.values.push(plainJson(raw));
1931
+ const plain = plainJson(raw);
1932
+ const index = column.at.get(row);
1933
+ if (index === void 0) {
1934
+ column.at.set(row, column.rows.length);
1935
+ column.rows.push(row);
1936
+ column.values.push(plain);
1937
+ continue;
1938
+ }
1939
+ if (JSON.stringify(column.values[index]) !== JSON.stringify(plain)) {
1940
+ this.report.warnOnce(
1941
+ "validation-error",
1942
+ DUPLICATE_ATTRIBUTE_CODE,
1943
+ `a ${domain} has the visual property "${property}" in two ${domain}Bypasses elements; the later wins`,
1944
+ { line, element: property },
1945
+ `${DUPLICATE_ATTRIBUTE_CODE}:bypass:${domain}:${property}`
1946
+ );
1947
+ }
1948
+ column.values[index] = plain;
1526
1949
  }
1527
1950
  }
1528
1951
  for (const [property, { rows: targets, values }] of columns) {
@@ -1559,7 +1982,7 @@ class Cx2Reader {
1559
1982
  report.warning(
1560
1983
  "unsupported",
1561
1984
  STYLES_NOT_IMPORTED_CODE,
1562
- `the file's style rules are not applied (${styles.join("; ")}); they are kept in meta.extra.cx2.opaque (style import is issue #706)`,
1985
+ `the file's style rules are not applied (${styles.join("; ")}); they are kept in meta.extra.cx2.opaque`,
1563
1986
  { element: STYLE_ASPECTS.filter((a) => doc.opaque.has(a)).join(",") }
1564
1987
  );
1565
1988
  }
@@ -1652,9 +2075,9 @@ function describeStyle(aspect, elements) {
1652
2075
  if (aspect === "visualProperties" && isRecord(first)) {
1653
2076
  const count = (key) => isRecord(first[key]) ? Object.keys(first[key]).length : 0;
1654
2077
  const defaults = isRecord(first.default) ? Object.values(first.default).reduce((n, v) => n + (isRecord(v) ? Object.keys(v).length : 0), 0) : 0;
1655
- return `visualProperties: ${defaults} default(s), ${count("nodeMapping")} node mapping(s), ${count("edgeMapping")} edge mapping(s)`;
2078
+ return `visualProperties: ${defaults} default${plural(defaults)}, ${count("nodeMapping")} node mapping${plural(count("nodeMapping"))}, ${count("edgeMapping")} edge mapping${plural(count("edgeMapping"))}`;
1656
2079
  }
1657
- return `${aspect}: ${elements.length} element(s)`;
2080
+ return `${aspect}: ${elements.length} element${plural(elements.length)}`;
1658
2081
  }
1659
2082
  function zAsOption(value) {
1660
2083
  if (value === void 0) {
@@ -1670,6 +2093,7 @@ function zAsOption(value) {
1670
2093
  }
1671
2094
  const cx2Importer = Object.freeze({
1672
2095
  format: CX2_FORMAT,
2096
+ options: Object.freeze(["zAs"]),
1673
2097
  extensions: Object.freeze([".cx2"]),
1674
2098
  mimeTypes: Object.freeze(["application/json"]),
1675
2099
  /**
@@ -1679,7 +2103,7 @@ const cx2Importer = Object.freeze({
1679
2103
  * @returns the confidence
1680
2104
  */
1681
2105
  sniff(head) {
1682
- const text = new TextDecoder("utf-8").decode(head.subarray(0, 1024)).replace(/^\uFEFF/, "");
2106
+ const text = headText(head);
1683
2107
  return /^\s*\[\s*\{(?:\s*"[^"]*"\s*:\s*(?:true|false|"[^"]*"|[0-9.]+)\s*,)*\s*"CXVersion"\s*:/.test(text) ? 0.97 : 0;
1684
2108
  },
1685
2109
  /**
@@ -1706,8 +2130,17 @@ export {
1706
2130
  CX2_ISSUE as C,
1707
2131
  ORIGINAL_ID_ATTRIBUTE as O,
1708
2132
  CX2_FORMAT as a,
1709
- cx2Type as b,
2133
+ planEdgeIds as b,
1710
2134
  cx2Importer as c,
2135
+ directionNotes as d,
2136
+ cx2Type as e,
2137
+ aspectBlock as f,
2138
+ declaredType as g,
2139
+ nextNodeId as h,
2140
+ noteList as i,
2141
+ nonFinitePositions as n,
2142
+ planNodeIds as p,
2143
+ stringify as s,
1711
2144
  zAsOption as z
1712
2145
  };
1713
- //# sourceMappingURL=importer-vi3bSdtw.js.map
2146
+ //# sourceMappingURL=importer-BVRE--Un.js.map