@graphty/graph-io 0.3.47 → 0.3.49

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 (770) hide show
  1. package/dist/chunks/{approximations-wWjCRzKj.js → approximations-Bzn3L-je.js} +2 -2
  2. package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-Bzn3L-je.js.map} +1 -1
  3. package/dist/chunks/bends-BGXjv_U4.js +129 -0
  4. package/dist/chunks/bends-BGXjv_U4.js.map +1 -0
  5. package/dist/chunks/{block-DiGq58c3.js → block-iptrlMBb.js} +947 -134
  6. package/dist/chunks/block-iptrlMBb.js.map +1 -0
  7. package/dist/chunks/choose-CczZJaX_.js +717 -0
  8. package/dist/chunks/choose-CczZJaX_.js.map +1 -0
  9. package/dist/chunks/codes-BE2xir2k.js +157 -0
  10. package/dist/chunks/codes-BE2xir2k.js.map +1 -0
  11. package/dist/chunks/{constants-BKwqelYD.js → constants-CKkYLPtt.js} +2 -2
  12. package/dist/chunks/{constants-BKwqelYD.js.map → constants-CKkYLPtt.js.map} +1 -1
  13. package/dist/chunks/context-C3p0RQxR.js +664 -0
  14. package/dist/chunks/context-C3p0RQxR.js.map +1 -0
  15. package/dist/chunks/{convert-BcQ8_jMo.js → convert-Ct2zelbQ.js} +7 -2
  16. package/dist/chunks/convert-Ct2zelbQ.js.map +1 -0
  17. package/dist/chunks/credentials-DXHx7nwR.js +349 -0
  18. package/dist/chunks/credentials-DXHx7nwR.js.map +1 -0
  19. package/dist/chunks/cx-export-Bt6NoqTQ.js +259 -0
  20. package/dist/chunks/cx-export-Bt6NoqTQ.js.map +1 -0
  21. package/dist/chunks/descriptor-B28U25x4.js +60 -0
  22. package/dist/chunks/descriptor-B28U25x4.js.map +1 -0
  23. package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
  24. package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
  25. package/dist/chunks/descriptor-DLA5kINx.js +142 -0
  26. package/dist/chunks/descriptor-DLA5kINx.js.map +1 -0
  27. package/dist/chunks/{emit-CwU8cUmG.js → emit-BwHQkZle.js} +1690 -103
  28. package/dist/chunks/emit-BwHQkZle.js.map +1 -0
  29. package/dist/chunks/{escape-CgzxiYPg.js → escape-CuCIzNMB.js} +12 -12
  30. package/dist/chunks/{escape-CgzxiYPg.js.map → escape-CuCIzNMB.js.map} +1 -1
  31. package/dist/chunks/{export-BvqAXCKh.js → export-Cha4dRFz.js} +48 -1780
  32. package/dist/chunks/export-Cha4dRFz.js.map +1 -0
  33. package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-BP6otMO6.js} +6 -4
  34. package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-BP6otMO6.js.map} +1 -1
  35. package/dist/chunks/{exporter-CrDWIyiq.js → exporter-D2CETOMK.js} +1222 -154
  36. package/dist/chunks/exporter-D2CETOMK.js.map +1 -0
  37. package/dist/chunks/{exporter-DndFlGSa.js → exporter-D9yMtocA.js} +7 -6
  38. package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-D9yMtocA.js.map} +1 -1
  39. package/dist/chunks/exporter-_jrBTnos.js +1009 -0
  40. package/dist/chunks/exporter-_jrBTnos.js.map +1 -0
  41. package/dist/chunks/{exporter-CJgfhF-l.js → exporter-nDfxIK5D.js} +9 -7
  42. package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-nDfxIK5D.js.map} +1 -1
  43. package/dist/chunks/format-BXiAb-1h.js +408 -0
  44. package/dist/chunks/format-BXiAb-1h.js.map +1 -0
  45. package/dist/chunks/{generic-Dq1ntt9q.js → generic-ymWCETAJ.js} +387 -31
  46. package/dist/chunks/generic-ymWCETAJ.js.map +1 -0
  47. package/dist/chunks/{importer-CMmeMWlC.js → importer-B92x1xY5.js} +15 -263
  48. package/dist/chunks/importer-B92x1xY5.js.map +1 -0
  49. package/dist/chunks/{importer-DiZRmOQG.js → importer-CT9mJ1nn.js} +328 -90
  50. package/dist/chunks/importer-CT9mJ1nn.js.map +1 -0
  51. package/dist/chunks/{importer-COTK9Tsl.js → importer-DaLTjbds.js} +116 -1099
  52. package/dist/chunks/importer-DaLTjbds.js.map +1 -0
  53. package/dist/chunks/{importer-iFYPEKaJ.js → importer-GREKMdIf.js} +28 -16
  54. package/dist/chunks/importer-GREKMdIf.js.map +1 -0
  55. package/dist/chunks/{importer-BSvfrX_h.js → importer-PqaaKKnY.js} +23 -1016
  56. package/dist/chunks/importer-PqaaKKnY.js.map +1 -0
  57. package/dist/chunks/{importer-yh_aBCU6.js → importer-Vn5QvmmJ.js} +66 -12
  58. package/dist/chunks/importer-Vn5QvmmJ.js.map +1 -0
  59. package/dist/chunks/{importer-e6LGpqHB.js → importer-vRq4h3j5.js} +1470 -354
  60. package/dist/chunks/importer-vRq4h3j5.js.map +1 -0
  61. package/dist/chunks/input-CAxt_aV-.js +1397 -0
  62. package/dist/chunks/input-CAxt_aV-.js.map +1 -0
  63. package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-Cq76WjnZ.js} +4 -4
  64. package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
  65. package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-Clf4QIyl.js} +299 -77
  66. package/dist/chunks/lexicon-Clf4QIyl.js.map +1 -0
  67. package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-OMo91mb0.js} +4 -3
  68. package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-OMo91mb0.js.map} +1 -1
  69. package/dist/chunks/{records-CiaWZrFH.js → records-NJiYvekn.js} +2 -2
  70. package/dist/chunks/{records-CiaWZrFH.js.map → records-NJiYvekn.js.map} +1 -1
  71. package/dist/chunks/{format-BpQBx8MZ.js → report-CwMfYa9J.js} +70 -127
  72. package/dist/chunks/report-CwMfYa9J.js.map +1 -0
  73. package/dist/chunks/round-trip-Zm3_ivgq.js +79 -0
  74. package/dist/chunks/round-trip-Zm3_ivgq.js.map +1 -0
  75. package/dist/chunks/sigv4-EokFic1V.js +247 -0
  76. package/dist/chunks/sigv4-EokFic1V.js.map +1 -0
  77. package/dist/chunks/{styles-BQnsga7p.js → styles-CCs214_3.js} +1300 -168
  78. package/dist/chunks/styles-CCs214_3.js.map +1 -0
  79. package/dist/chunks/styles-Cm62yyQX.js +2812 -0
  80. package/dist/chunks/styles-Cm62yyQX.js.map +1 -0
  81. package/dist/chunks/styles-DPQQIig4.js +1928 -0
  82. package/dist/chunks/styles-DPQQIig4.js.map +1 -0
  83. package/dist/chunks/styles-yed-UMFdNqze.js +1213 -0
  84. package/dist/chunks/styles-yed-UMFdNqze.js.map +1 -0
  85. package/dist/chunks/{text-CzJNFOS9.js → text-ystE2bYi.js} +2 -2
  86. package/dist/chunks/{text-CzJNFOS9.js.map → text-ystE2bYi.js.map} +1 -1
  87. package/dist/csv.js +7 -5
  88. package/dist/csv.js.map +1 -1
  89. package/dist/cx.js +5 -4
  90. package/dist/cx.js.map +1 -1
  91. package/dist/cx2.js +2 -2
  92. package/dist/cys.js +1 -1
  93. package/dist/dot.js +5 -4
  94. package/dist/dot.js.map +1 -1
  95. package/dist/gexf.js +42 -10
  96. package/dist/gexf.js.map +1 -1
  97. package/dist/gml.js +850 -193
  98. package/dist/gml.js.map +1 -1
  99. package/dist/graph-io.js +1189 -220
  100. package/dist/graph-io.js.map +1 -1
  101. package/dist/graphml.js +3 -3
  102. package/dist/json.js +3 -2
  103. package/dist/neo4j.js +6 -4
  104. package/dist/neo4j.js.map +1 -1
  105. package/dist/obo.js +1 -1
  106. package/dist/pajek.js +1 -1
  107. package/dist/positions.js +45 -3
  108. package/dist/positions.js.map +1 -1
  109. package/dist/sources-cypher.d.ts +1 -0
  110. package/dist/sources-cypher.js +1351 -0
  111. package/dist/sources-cypher.js.map +1 -0
  112. package/dist/sources-ndex.d.ts +1 -0
  113. package/dist/sources-ndex.js +278 -0
  114. package/dist/sources-ndex.js.map +1 -0
  115. package/dist/sources-rest.d.ts +1 -0
  116. package/dist/sources-rest.js +1377 -0
  117. package/dist/sources-rest.js.map +1 -0
  118. package/dist/sources-sparql.d.ts +1 -0
  119. package/dist/sources-sparql.js +405 -0
  120. package/dist/sources-sparql.js.map +1 -0
  121. package/dist/src/common/report.d.ts +6 -3
  122. package/dist/src/common/report.d.ts.map +1 -1
  123. package/dist/src/common/report.js +15 -9
  124. package/dist/src/common/report.js.map +1 -1
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +5 -1
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +24 -1
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  130. package/dist/src/formats/cx/styles.js +118 -11
  131. package/dist/src/formats/cx/styles.js.map +1 -1
  132. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  133. package/dist/src/formats/cx2/importer.js +1 -0
  134. package/dist/src/formats/cx2/importer.js.map +1 -1
  135. package/dist/src/formats/cx2/styles.d.ts.map +1 -1
  136. package/dist/src/formats/cx2/styles.js +3 -1
  137. package/dist/src/formats/cx2/styles.js.map +1 -1
  138. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  139. package/dist/src/formats/cys/importer.js +1 -0
  140. package/dist/src/formats/cys/importer.js.map +1 -1
  141. package/dist/src/formats/cys/styles.d.ts +2 -0
  142. package/dist/src/formats/cys/styles.d.ts.map +1 -1
  143. package/dist/src/formats/cys/styles.js +15 -7
  144. package/dist/src/formats/cys/styles.js.map +1 -1
  145. package/dist/src/formats/dot/drawing.d.ts +98 -0
  146. package/dist/src/formats/dot/drawing.d.ts.map +1 -0
  147. package/dist/src/formats/dot/drawing.js +734 -0
  148. package/dist/src/formats/dot/drawing.js.map +1 -0
  149. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  150. package/dist/src/formats/dot/importer.js +108 -31
  151. package/dist/src/formats/dot/importer.js.map +1 -1
  152. package/dist/src/formats/dot/label-places.d.ts +34 -0
  153. package/dist/src/formats/dot/label-places.d.ts.map +1 -0
  154. package/dist/src/formats/dot/label-places.js +179 -0
  155. package/dist/src/formats/dot/label-places.js.map +1 -0
  156. package/dist/src/formats/dot/record.d.ts +50 -0
  157. package/dist/src/formats/dot/record.d.ts.map +1 -0
  158. package/dist/src/formats/dot/record.js +275 -0
  159. package/dist/src/formats/dot/record.js.map +1 -0
  160. package/dist/src/formats/dot/styles.d.ts +62 -2
  161. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  162. package/dist/src/formats/dot/styles.js +1457 -120
  163. package/dist/src/formats/dot/styles.js.map +1 -1
  164. package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
  165. package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
  166. package/dist/src/formats/gexf/dialog-metrics.js +59 -0
  167. package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
  168. package/dist/src/formats/gexf/importer.d.ts +7 -0
  169. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  170. package/dist/src/formats/gexf/importer.js +41 -5
  171. package/dist/src/formats/gexf/importer.js.map +1 -1
  172. package/dist/src/formats/gexf/preview.d.ts +77 -0
  173. package/dist/src/formats/gexf/preview.d.ts.map +1 -0
  174. package/dist/src/formats/gexf/preview.js +191 -0
  175. package/dist/src/formats/gexf/preview.js.map +1 -0
  176. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  177. package/dist/src/formats/gexf/schema.js +2 -1
  178. package/dist/src/formats/gexf/schema.js.map +1 -1
  179. package/dist/src/formats/gexf/styles.d.ts +60 -16
  180. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  181. package/dist/src/formats/gexf/styles.js +883 -131
  182. package/dist/src/formats/gexf/styles.js.map +1 -1
  183. package/dist/src/formats/gml/importer.d.ts +5 -2
  184. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  185. package/dist/src/formats/gml/importer.js +258 -71
  186. package/dist/src/formats/gml/importer.js.map +1 -1
  187. package/dist/src/formats/gml/index.d.ts +1 -1
  188. package/dist/src/formats/gml/index.d.ts.map +1 -1
  189. package/dist/src/formats/gml/index.js +1 -1
  190. package/dist/src/formats/gml/index.js.map +1 -1
  191. package/dist/src/formats/gml/positions.d.ts +7 -0
  192. package/dist/src/formats/gml/positions.d.ts.map +1 -1
  193. package/dist/src/formats/gml/positions.js +29 -7
  194. package/dist/src/formats/gml/positions.js.map +1 -1
  195. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  196. package/dist/src/formats/gml/styles.js +756 -103
  197. package/dist/src/formats/gml/styles.js.map +1 -1
  198. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  199. package/dist/src/formats/graphml/styles-plain.js +8 -12
  200. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  201. package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
  202. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  203. package/dist/src/formats/graphml/styles-yed.js +749 -148
  204. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  205. package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
  206. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
  207. package/dist/src/formats/graphml/styles-yfiles3.js +429 -64
  208. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
  209. package/dist/src/formats/graphml/yfiles.d.ts +3 -3
  210. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  211. package/dist/src/formats/graphml/yfiles.js +16 -6
  212. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  213. package/dist/src/formats/json/dialect.d.ts +3 -2
  214. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  215. package/dist/src/formats/json/dialect.js +39 -5
  216. package/dist/src/formats/json/dialect.js.map +1 -1
  217. package/dist/src/formats/json/importer.d.ts +13 -2
  218. package/dist/src/formats/json/importer.d.ts.map +1 -1
  219. package/dist/src/formats/json/importer.js +42 -6
  220. package/dist/src/formats/json/importer.js.map +1 -1
  221. package/dist/src/formats/json/index.d.ts +1 -1
  222. package/dist/src/formats/json/index.d.ts.map +1 -1
  223. package/dist/src/formats/json/index.js +1 -1
  224. package/dist/src/formats/json/index.js.map +1 -1
  225. package/dist/src/formats/json/positions.d.ts +5 -2
  226. package/dist/src/formats/json/positions.d.ts.map +1 -1
  227. package/dist/src/formats/json/positions.js +20 -4
  228. package/dist/src/formats/json/positions.js.map +1 -1
  229. package/dist/src/formats/json/styles.d.ts +12 -1
  230. package/dist/src/formats/json/styles.d.ts.map +1 -1
  231. package/dist/src/formats/json/styles.js +1755 -136
  232. package/dist/src/formats/json/styles.js.map +1 -1
  233. package/dist/src/formats/pajek/draw.d.ts +96 -0
  234. package/dist/src/formats/pajek/draw.d.ts.map +1 -0
  235. package/dist/src/formats/pajek/draw.js +372 -0
  236. package/dist/src/formats/pajek/draw.js.map +1 -0
  237. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  238. package/dist/src/formats/pajek/exporter.js +70 -51
  239. package/dist/src/formats/pajek/exporter.js.map +1 -1
  240. package/dist/src/formats/pajek/importer.d.ts +9 -0
  241. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  242. package/dist/src/formats/pajek/importer.js +233 -102
  243. package/dist/src/formats/pajek/importer.js.map +1 -1
  244. package/dist/src/formats/pajek/index.d.ts +1 -0
  245. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  246. package/dist/src/formats/pajek/index.js.map +1 -1
  247. package/dist/src/formats/pajek/styles.d.ts +15 -7
  248. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  249. package/dist/src/formats/pajek/styles.js +1279 -114
  250. package/dist/src/formats/pajek/styles.js.map +1 -1
  251. package/dist/src/formats/pajek/syntax.d.ts +10 -1
  252. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  253. package/dist/src/formats/pajek/syntax.js +26 -2
  254. package/dist/src/formats/pajek/syntax.js.map +1 -1
  255. package/dist/src/formats/xgmml/emit.d.ts +1 -0
  256. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  257. package/dist/src/formats/xgmml/emit.js +65 -5
  258. package/dist/src/formats/xgmml/emit.js.map +1 -1
  259. package/dist/src/formats/xgmml/styles.d.ts +23 -3
  260. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  261. package/dist/src/formats/xgmml/styles.js +278 -60
  262. package/dist/src/formats/xgmml/styles.js.map +1 -1
  263. package/dist/src/index.d.ts +10 -2
  264. package/dist/src/index.d.ts.map +1 -1
  265. package/dist/src/index.js +11 -2
  266. package/dist/src/index.js.map +1 -1
  267. package/dist/src/positions/convert.d.ts.map +1 -1
  268. package/dist/src/positions/convert.js +11 -1
  269. package/dist/src/positions/convert.js.map +1 -1
  270. package/dist/src/positions/extract.d.ts.map +1 -1
  271. package/dist/src/positions/extract.js +53 -1
  272. package/dist/src/positions/extract.js.map +1 -1
  273. package/dist/src/positions/index.d.ts +1 -1
  274. package/dist/src/positions/index.d.ts.map +1 -1
  275. package/dist/src/positions/types.d.ts +59 -0
  276. package/dist/src/positions/types.d.ts.map +1 -1
  277. package/dist/src/registry.d.ts +173 -1
  278. package/dist/src/registry.d.ts.map +1 -1
  279. package/dist/src/registry.js +196 -1
  280. package/dist/src/registry.js.map +1 -1
  281. package/dist/src/sources/builtins.d.ts +11 -0
  282. package/dist/src/sources/builtins.d.ts.map +1 -0
  283. package/dist/src/sources/builtins.js +53 -0
  284. package/dist/src/sources/builtins.js.map +1 -0
  285. package/dist/src/sources/codes.d.ts +230 -0
  286. package/dist/src/sources/codes.d.ts.map +1 -0
  287. package/dist/src/sources/codes.js +58 -0
  288. package/dist/src/sources/codes.js.map +1 -0
  289. package/dist/src/sources/context.d.ts +112 -0
  290. package/dist/src/sources/context.d.ts.map +1 -0
  291. package/dist/src/sources/context.js +740 -0
  292. package/dist/src/sources/context.js.map +1 -0
  293. package/dist/src/sources/credentials.d.ts +179 -0
  294. package/dist/src/sources/credentials.d.ts.map +1 -0
  295. package/dist/src/sources/credentials.js +301 -0
  296. package/dist/src/sources/credentials.js.map +1 -0
  297. package/dist/src/sources/cypher/descriptor.d.ts +21 -0
  298. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
  299. package/dist/src/sources/cypher/descriptor.js +124 -0
  300. package/dist/src/sources/cypher/descriptor.js.map +1 -0
  301. package/dist/src/sources/cypher/flatten.d.ts +72 -0
  302. package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
  303. package/dist/src/sources/cypher/flatten.js +279 -0
  304. package/dist/src/sources/cypher/flatten.js.map +1 -0
  305. package/dist/src/sources/cypher/index.d.ts +33 -0
  306. package/dist/src/sources/cypher/index.d.ts.map +1 -0
  307. package/dist/src/sources/cypher/index.js +511 -0
  308. package/dist/src/sources/cypher/index.js.map +1 -0
  309. package/dist/src/sources/cypher/params.d.ts +40 -0
  310. package/dist/src/sources/cypher/params.d.ts.map +1 -0
  311. package/dist/src/sources/cypher/params.js +6 -0
  312. package/dist/src/sources/cypher/params.js.map +1 -0
  313. package/dist/src/sources/cypher/profiles.d.ts +44 -0
  314. package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
  315. package/dist/src/sources/cypher/profiles.js +61 -0
  316. package/dist/src/sources/cypher/profiles.js.map +1 -0
  317. package/dist/src/sources/cypher/query-builder.d.ts +123 -0
  318. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
  319. package/dist/src/sources/cypher/query-builder.js +267 -0
  320. package/dist/src/sources/cypher/query-builder.js.map +1 -0
  321. package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
  322. package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
  323. package/dist/src/sources/cypher/transports/bolt.js +185 -0
  324. package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
  325. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
  326. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
  327. package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
  328. package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
  329. package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
  330. package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
  331. package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
  332. package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
  333. package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
  334. package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
  335. package/dist/src/sources/cypher/transports/query-api.js +80 -0
  336. package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
  337. package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
  338. package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
  339. package/dist/src/sources/cypher/transports/transport.js +77 -0
  340. package/dist/src/sources/cypher/transports/transport.js.map +1 -0
  341. package/dist/src/sources/cypher/types-map.d.ts +91 -0
  342. package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
  343. package/dist/src/sources/cypher/types-map.js +306 -0
  344. package/dist/src/sources/cypher/types-map.js.map +1 -0
  345. package/dist/src/sources/define.d.ts +47 -0
  346. package/dist/src/sources/define.d.ts.map +1 -0
  347. package/dist/src/sources/define.js +173 -0
  348. package/dist/src/sources/define.js.map +1 -0
  349. package/dist/src/sources/fail.d.ts +33 -0
  350. package/dist/src/sources/fail.d.ts.map +1 -0
  351. package/dist/src/sources/fail.js +49 -0
  352. package/dist/src/sources/fail.js.map +1 -0
  353. package/dist/src/sources/ids.d.ts +69 -0
  354. package/dist/src/sources/ids.d.ts.map +1 -0
  355. package/dist/src/sources/ids.js +69 -0
  356. package/dist/src/sources/ids.js.map +1 -0
  357. package/dist/src/sources/ndex/client.d.ts +31 -0
  358. package/dist/src/sources/ndex/client.d.ts.map +1 -0
  359. package/dist/src/sources/ndex/client.js +90 -0
  360. package/dist/src/sources/ndex/client.js.map +1 -0
  361. package/dist/src/sources/ndex/descriptor.d.ts +10 -0
  362. package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
  363. package/dist/src/sources/ndex/descriptor.js +55 -0
  364. package/dist/src/sources/ndex/descriptor.js.map +1 -0
  365. package/dist/src/sources/ndex/expand.d.ts +20 -0
  366. package/dist/src/sources/ndex/expand.d.ts.map +1 -0
  367. package/dist/src/sources/ndex/expand.js +87 -0
  368. package/dist/src/sources/ndex/expand.js.map +1 -0
  369. package/dist/src/sources/ndex/index.d.ts +25 -0
  370. package/dist/src/sources/ndex/index.d.ts.map +1 -0
  371. package/dist/src/sources/ndex/index.js +191 -0
  372. package/dist/src/sources/ndex/index.js.map +1 -0
  373. package/dist/src/sources/ndex/params.d.ts +17 -0
  374. package/dist/src/sources/ndex/params.d.ts.map +1 -0
  375. package/dist/src/sources/ndex/params.js +6 -0
  376. package/dist/src/sources/ndex/params.js.map +1 -0
  377. package/dist/src/sources/ndex/share-url.d.ts +40 -0
  378. package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
  379. package/dist/src/sources/ndex/share-url.js +64 -0
  380. package/dist/src/sources/ndex/share-url.js.map +1 -0
  381. package/dist/src/sources/params.d.ts +31 -0
  382. package/dist/src/sources/params.d.ts.map +1 -0
  383. package/dist/src/sources/params.js +6 -0
  384. package/dist/src/sources/params.js.map +1 -0
  385. package/dist/src/sources/registry.d.ts +118 -0
  386. package/dist/src/sources/registry.d.ts.map +1 -0
  387. package/dist/src/sources/registry.js +193 -0
  388. package/dist/src/sources/registry.js.map +1 -0
  389. package/dist/src/sources/rest/descriptor.d.ts +16 -0
  390. package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
  391. package/dist/src/sources/rest/descriptor.js +76 -0
  392. package/dist/src/sources/rest/descriptor.js.map +1 -0
  393. package/dist/src/sources/rest/index.d.ts +14 -0
  394. package/dist/src/sources/rest/index.d.ts.map +1 -0
  395. package/dist/src/sources/rest/index.js +13 -0
  396. package/dist/src/sources/rest/index.js.map +1 -0
  397. package/dist/src/sources/rest/mapping.d.ts +30 -0
  398. package/dist/src/sources/rest/mapping.d.ts.map +1 -0
  399. package/dist/src/sources/rest/mapping.js +362 -0
  400. package/dist/src/sources/rest/mapping.js.map +1 -0
  401. package/dist/src/sources/rest/openalex.d.ts +27 -0
  402. package/dist/src/sources/rest/openalex.d.ts.map +1 -0
  403. package/dist/src/sources/rest/openalex.js +269 -0
  404. package/dist/src/sources/rest/openalex.js.map +1 -0
  405. package/dist/src/sources/rest/paging.d.ts +53 -0
  406. package/dist/src/sources/rest/paging.d.ts.map +1 -0
  407. package/dist/src/sources/rest/paging.js +138 -0
  408. package/dist/src/sources/rest/paging.js.map +1 -0
  409. package/dist/src/sources/rest/params.d.ts +216 -0
  410. package/dist/src/sources/rest/params.d.ts.map +1 -0
  411. package/dist/src/sources/rest/params.js +7 -0
  412. package/dist/src/sources/rest/params.js.map +1 -0
  413. package/dist/src/sources/rest/records.d.ts +41 -0
  414. package/dist/src/sources/rest/records.d.ts.map +1 -0
  415. package/dist/src/sources/rest/records.js +240 -0
  416. package/dist/src/sources/rest/records.js.map +1 -0
  417. package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
  418. package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
  419. package/dist/src/sources/rest/samples/deps-dev.js +47 -0
  420. package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
  421. package/dist/src/sources/rest/samples/string.d.ts +9 -0
  422. package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
  423. package/dist/src/sources/rest/samples/string.js +42 -0
  424. package/dist/src/sources/rest/samples/string.js.map +1 -0
  425. package/dist/src/sources/rest/selectors.d.ts +41 -0
  426. package/dist/src/sources/rest/selectors.d.ts.map +1 -0
  427. package/dist/src/sources/rest/selectors.js +81 -0
  428. package/dist/src/sources/rest/selectors.js.map +1 -0
  429. package/dist/src/sources/rest/source.d.ts +67 -0
  430. package/dist/src/sources/rest/source.d.ts.map +1 -0
  431. package/dist/src/sources/rest/source.js +650 -0
  432. package/dist/src/sources/rest/source.js.map +1 -0
  433. package/dist/src/sources/rest/templates.d.ts +38 -0
  434. package/dist/src/sources/rest/templates.d.ts.map +1 -0
  435. package/dist/src/sources/rest/templates.js +125 -0
  436. package/dist/src/sources/rest/templates.js.map +1 -0
  437. package/dist/src/sources/run.d.ts +93 -0
  438. package/dist/src/sources/run.d.ts.map +1 -0
  439. package/dist/src/sources/run.js +673 -0
  440. package/dist/src/sources/run.js.map +1 -0
  441. package/dist/src/sources/sha256.d.ts +12 -0
  442. package/dist/src/sources/sha256.d.ts.map +1 -0
  443. package/dist/src/sources/sha256.js +95 -0
  444. package/dist/src/sources/sha256.js.map +1 -0
  445. package/dist/src/sources/sigv4.d.ts +26 -0
  446. package/dist/src/sources/sigv4.d.ts.map +1 -0
  447. package/dist/src/sources/sigv4.js +184 -0
  448. package/dist/src/sources/sigv4.js.map +1 -0
  449. package/dist/src/sources/sparql/descriptor.d.ts +10 -0
  450. package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
  451. package/dist/src/sources/sparql/descriptor.js +64 -0
  452. package/dist/src/sources/sparql/descriptor.js.map +1 -0
  453. package/dist/src/sources/sparql/index.d.ts +28 -0
  454. package/dist/src/sources/sparql/index.d.ts.map +1 -0
  455. package/dist/src/sources/sparql/index.js +314 -0
  456. package/dist/src/sources/sparql/index.js.map +1 -0
  457. package/dist/src/sources/sparql/ntriples.d.ts +69 -0
  458. package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
  459. package/dist/src/sources/sparql/ntriples.js +180 -0
  460. package/dist/src/sources/sparql/ntriples.js.map +1 -0
  461. package/dist/src/sources/sparql/params.d.ts +27 -0
  462. package/dist/src/sources/sparql/params.d.ts.map +1 -0
  463. package/dist/src/sources/sparql/params.js +5 -0
  464. package/dist/src/sources/sparql/params.js.map +1 -0
  465. package/dist/src/sources/sparql/query.d.ts +72 -0
  466. package/dist/src/sources/sparql/query.d.ts.map +1 -0
  467. package/dist/src/sources/sparql/query.js +113 -0
  468. package/dist/src/sources/sparql/query.js.map +1 -0
  469. package/dist/src/sources/testing.d.ts +96 -0
  470. package/dist/src/sources/testing.d.ts.map +1 -0
  471. package/dist/src/sources/testing.js +138 -0
  472. package/dist/src/sources/testing.js.map +1 -0
  473. package/dist/src/sources/types.d.ts +696 -0
  474. package/dist/src/sources/types.d.ts.map +1 -0
  475. package/dist/src/sources/types.js +10 -0
  476. package/dist/src/sources/types.js.map +1 -0
  477. package/dist/src/styles/annotations.d.ts +61 -5
  478. package/dist/src/styles/annotations.d.ts.map +1 -1
  479. package/dist/src/styles/annotations.js +130 -22
  480. package/dist/src/styles/annotations.js.map +1 -1
  481. package/dist/src/styles/canon/bends.d.ts +46 -0
  482. package/dist/src/styles/canon/bends.d.ts.map +1 -1
  483. package/dist/src/styles/canon/bends.js +123 -0
  484. package/dist/src/styles/canon/bends.js.map +1 -1
  485. package/dist/src/styles/canon/color-tables.d.ts +6 -1
  486. package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
  487. package/dist/src/styles/canon/color-tables.js +10 -4
  488. package/dist/src/styles/canon/color-tables.js.map +1 -1
  489. package/dist/src/styles/canon/color.d.ts +3 -1
  490. package/dist/src/styles/canon/color.d.ts.map +1 -1
  491. package/dist/src/styles/canon/color.js +103 -3
  492. package/dist/src/styles/canon/color.js.map +1 -1
  493. package/dist/src/styles/canon/enums.d.ts +2 -2
  494. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  495. package/dist/src/styles/canon/enums.js +82 -7
  496. package/dist/src/styles/canon/enums.js.map +1 -1
  497. package/dist/src/styles/canon/graphviz.d.ts +12 -3
  498. package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
  499. package/dist/src/styles/canon/graphviz.js +57 -9
  500. package/dist/src/styles/canon/graphviz.js.map +1 -1
  501. package/dist/src/styles/canon/number.d.ts +8 -0
  502. package/dist/src/styles/canon/number.d.ts.map +1 -1
  503. package/dist/src/styles/canon/number.js +18 -0
  504. package/dist/src/styles/canon/number.js.map +1 -1
  505. package/dist/src/styles/canon/text.d.ts +29 -2
  506. package/dist/src/styles/canon/text.d.ts.map +1 -1
  507. package/dist/src/styles/canon/text.js +156 -16
  508. package/dist/src/styles/canon/text.js.map +1 -1
  509. package/dist/src/styles/codes.d.ts +2 -0
  510. package/dist/src/styles/codes.d.ts.map +1 -1
  511. package/dist/src/styles/codes.js +2 -0
  512. package/dist/src/styles/codes.js.map +1 -1
  513. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  514. package/dist/src/styles/cyjs/cascade.js +1037 -35
  515. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  516. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  517. package/dist/src/styles/cyjs/defaults-table.js +5 -0
  518. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  519. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  520. package/dist/src/styles/cyjs/emit.js +216 -12
  521. package/dist/src/styles/cyjs/emit.js.map +1 -1
  522. package/dist/src/styles/cyjs/face.d.ts +20 -0
  523. package/dist/src/styles/cyjs/face.d.ts.map +1 -0
  524. package/dist/src/styles/cyjs/face.js +332 -0
  525. package/dist/src/styles/cyjs/face.js.map +1 -0
  526. package/dist/src/styles/cyjs/mappers.d.ts +48 -2
  527. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  528. package/dist/src/styles/cyjs/mappers.js +463 -26
  529. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  530. package/dist/src/styles/cyjs/routes.d.ts +53 -0
  531. package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
  532. package/dist/src/styles/cyjs/routes.js +360 -0
  533. package/dist/src/styles/cyjs/routes.js.map +1 -0
  534. package/dist/src/styles/cytoscape/charts.d.ts +23 -0
  535. package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
  536. package/dist/src/styles/cytoscape/charts.js +560 -0
  537. package/dist/src/styles/cytoscape/charts.js.map +1 -0
  538. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  539. package/dist/src/styles/cytoscape/emit.js +204 -44
  540. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  541. package/dist/src/styles/cytoscape/lexicon.d.ts +97 -3
  542. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  543. package/dist/src/styles/cytoscape/lexicon.js +413 -79
  544. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  545. package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
  546. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
  547. package/dist/src/styles/cytoscape/mappings.js +92 -0
  548. package/dist/src/styles/cytoscape/mappings.js.map +1 -1
  549. package/dist/src/styles/cytoscape/resolve.d.ts +46 -3
  550. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  551. package/dist/src/styles/cytoscape/resolve.js +632 -22
  552. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  553. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
  554. package/dist/src/styles/cytoscape/translate.js +10 -10
  555. package/dist/src/styles/cytoscape/translate.js.map +1 -1
  556. package/dist/src/styles/defaults.d.ts +50 -0
  557. package/dist/src/styles/defaults.d.ts.map +1 -1
  558. package/dist/src/styles/defaults.js +315 -37
  559. package/dist/src/styles/defaults.js.map +1 -1
  560. package/dist/src/styles/index.d.ts +4 -3
  561. package/dist/src/styles/index.d.ts.map +1 -1
  562. package/dist/src/styles/index.js +3 -2
  563. package/dist/src/styles/index.js.map +1 -1
  564. package/dist/src/styles/internal.d.ts +1 -0
  565. package/dist/src/styles/internal.d.ts.map +1 -1
  566. package/dist/src/styles/internal.js +1 -0
  567. package/dist/src/styles/internal.js.map +1 -1
  568. package/dist/src/styles/io/block.d.ts.map +1 -1
  569. package/dist/src/styles/io/block.js +9 -0
  570. package/dist/src/styles/io/block.js.map +1 -1
  571. package/dist/src/styles/io/generic.d.ts.map +1 -1
  572. package/dist/src/styles/io/generic.js +56 -16
  573. package/dist/src/styles/io/generic.js.map +1 -1
  574. package/dist/src/styles/io/round-trip.d.ts +56 -0
  575. package/dist/src/styles/io/round-trip.d.ts.map +1 -0
  576. package/dist/src/styles/io/round-trip.js +138 -0
  577. package/dist/src/styles/io/round-trip.js.map +1 -0
  578. package/dist/src/styles/io/writer.d.ts.map +1 -1
  579. package/dist/src/styles/io/writer.js +13 -4
  580. package/dist/src/styles/io/writer.js.map +1 -1
  581. package/dist/src/styles/notes.d.ts.map +1 -1
  582. package/dist/src/styles/notes.js +1 -0
  583. package/dist/src/styles/notes.js.map +1 -1
  584. package/dist/src/styles/plan/features.d.ts +1 -1
  585. package/dist/src/styles/plan/features.d.ts.map +1 -1
  586. package/dist/src/styles/plan/features.js +22 -2
  587. package/dist/src/styles/plan/features.js.map +1 -1
  588. package/dist/src/styles/plan/index.d.ts +1 -1
  589. package/dist/src/styles/plan/index.d.ts.map +1 -1
  590. package/dist/src/styles/plan/index.js +1 -1
  591. package/dist/src/styles/plan/index.js.map +1 -1
  592. package/dist/src/styles/plan/plan.d.ts.map +1 -1
  593. package/dist/src/styles/plan/plan.js +61 -4
  594. package/dist/src/styles/plan/plan.js.map +1 -1
  595. package/dist/src/styles/plan/resolve.d.ts +13 -1
  596. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  597. package/dist/src/styles/plan/resolve.js +53 -6
  598. package/dist/src/styles/plan/resolve.js.map +1 -1
  599. package/dist/src/styles/slots.d.ts +14 -0
  600. package/dist/src/styles/slots.d.ts.map +1 -0
  601. package/dist/src/styles/slots.js +20 -0
  602. package/dist/src/styles/slots.js.map +1 -0
  603. package/dist/src/styles/types.d.ts +638 -5
  604. package/dist/src/styles/types.d.ts.map +1 -1
  605. package/dist/src/styles/vocabulary.d.ts +3 -2
  606. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  607. package/dist/src/styles/vocabulary.js +218 -1
  608. package/dist/src/styles/vocabulary.js.map +1 -1
  609. package/dist/src/types.d.ts +19 -5
  610. package/dist/src/types.d.ts.map +1 -1
  611. package/dist/src/types.js.map +1 -1
  612. package/dist/styles.js +29 -238
  613. package/dist/styles.js.map +1 -1
  614. package/dist/xgmml.js +3 -3
  615. package/docs/samples/people.json +6 -0
  616. package/package.json +53 -8
  617. package/src/common/report.ts +27 -7
  618. package/src/formats/cx/importer.ts +6 -1
  619. package/src/formats/cx/styles.ts +144 -9
  620. package/src/formats/cx2/importer.ts +1 -0
  621. package/src/formats/cx2/styles.ts +3 -1
  622. package/src/formats/cys/importer.ts +1 -0
  623. package/src/formats/cys/styles.ts +27 -5
  624. package/src/formats/dot/drawing.ts +799 -0
  625. package/src/formats/dot/importer.ts +120 -35
  626. package/src/formats/dot/label-places.ts +228 -0
  627. package/src/formats/dot/record.ts +336 -0
  628. package/src/formats/dot/styles.ts +1657 -154
  629. package/src/formats/gexf/dialog-metrics.ts +61 -0
  630. package/src/formats/gexf/importer.ts +50 -5
  631. package/src/formats/gexf/preview.ts +217 -0
  632. package/src/formats/gexf/schema.ts +2 -1
  633. package/src/formats/gexf/styles.ts +1144 -142
  634. package/src/formats/gml/importer.ts +291 -76
  635. package/src/formats/gml/index.ts +1 -1
  636. package/src/formats/gml/positions.ts +29 -7
  637. package/src/formats/gml/styles.ts +854 -111
  638. package/src/formats/graphml/styles-plain.ts +8 -23
  639. package/src/formats/graphml/styles-yed.ts +821 -159
  640. package/src/formats/graphml/styles-yfiles3.ts +485 -63
  641. package/src/formats/graphml/yfiles.ts +19 -6
  642. package/src/formats/json/dialect.ts +41 -5
  643. package/src/formats/json/importer.ts +59 -7
  644. package/src/formats/json/index.ts +1 -0
  645. package/src/formats/json/positions.ts +22 -5
  646. package/src/formats/json/styles.ts +2041 -185
  647. package/src/formats/pajek/draw.ts +458 -0
  648. package/src/formats/pajek/exporter.ts +81 -49
  649. package/src/formats/pajek/importer.ts +278 -103
  650. package/src/formats/pajek/index.ts +1 -0
  651. package/src/formats/pajek/styles.ts +1382 -133
  652. package/src/formats/pajek/syntax.ts +27 -2
  653. package/src/formats/xgmml/emit.ts +73 -5
  654. package/src/formats/xgmml/styles.ts +331 -71
  655. package/src/index.ts +94 -0
  656. package/src/positions/convert.ts +12 -1
  657. package/src/positions/extract.ts +55 -1
  658. package/src/positions/index.ts +1 -0
  659. package/src/positions/types.ts +60 -0
  660. package/src/registry.ts +326 -1
  661. package/src/sources/builtins.ts +63 -0
  662. package/src/sources/codes.ts +235 -0
  663. package/src/sources/context.ts +894 -0
  664. package/src/sources/credentials.ts +409 -0
  665. package/src/sources/cypher/descriptor.ts +131 -0
  666. package/src/sources/cypher/flatten.ts +323 -0
  667. package/src/sources/cypher/index.ts +628 -0
  668. package/src/sources/cypher/params.ts +41 -0
  669. package/src/sources/cypher/profiles.ts +78 -0
  670. package/src/sources/cypher/query-builder.ts +327 -0
  671. package/src/sources/cypher/transports/bolt.ts +228 -0
  672. package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
  673. package/src/sources/cypher/transports/neptune-https.ts +122 -0
  674. package/src/sources/cypher/transports/query-api.ts +100 -0
  675. package/src/sources/cypher/transports/transport.ts +139 -0
  676. package/src/sources/cypher/types-map.ts +418 -0
  677. package/src/sources/define.ts +195 -0
  678. package/src/sources/fail.ts +70 -0
  679. package/src/sources/ids.ts +80 -0
  680. package/src/sources/ndex/client.ts +102 -0
  681. package/src/sources/ndex/descriptor.ts +64 -0
  682. package/src/sources/ndex/expand.ts +100 -0
  683. package/src/sources/ndex/index.ts +235 -0
  684. package/src/sources/ndex/params.ts +17 -0
  685. package/src/sources/ndex/share-url.ts +84 -0
  686. package/src/sources/params.ts +32 -0
  687. package/src/sources/registry.ts +325 -0
  688. package/src/sources/rest/descriptor.ts +79 -0
  689. package/src/sources/rest/index.ts +22 -0
  690. package/src/sources/rest/mapping.ts +401 -0
  691. package/src/sources/rest/openalex.ts +288 -0
  692. package/src/sources/rest/paging.ts +180 -0
  693. package/src/sources/rest/params.ts +243 -0
  694. package/src/sources/rest/records.ts +289 -0
  695. package/src/sources/rest/samples/deps-dev.ts +49 -0
  696. package/src/sources/rest/samples/string.ts +44 -0
  697. package/src/sources/rest/selectors.ts +91 -0
  698. package/src/sources/rest/source.ts +776 -0
  699. package/src/sources/rest/templates.ts +151 -0
  700. package/src/sources/run.ts +793 -0
  701. package/src/sources/sha256.ts +99 -0
  702. package/src/sources/sigv4.ts +209 -0
  703. package/src/sources/sparql/descriptor.ts +67 -0
  704. package/src/sources/sparql/index.ts +356 -0
  705. package/src/sources/sparql/ntriples.ts +219 -0
  706. package/src/sources/sparql/params.ts +28 -0
  707. package/src/sources/sparql/query.ts +162 -0
  708. package/src/sources/testing.ts +210 -0
  709. package/src/sources/types.ts +776 -0
  710. package/src/styles/annotations.ts +201 -27
  711. package/src/styles/canon/bends.ts +137 -0
  712. package/src/styles/canon/color-tables.ts +10 -4
  713. package/src/styles/canon/color.ts +105 -3
  714. package/src/styles/canon/enums.ts +99 -8
  715. package/src/styles/canon/graphviz.ts +71 -10
  716. package/src/styles/canon/number.ts +19 -0
  717. package/src/styles/canon/text.ts +187 -16
  718. package/src/styles/codes.ts +2 -0
  719. package/src/styles/cyjs/cascade.ts +1193 -38
  720. package/src/styles/cyjs/defaults-table.ts +5 -0
  721. package/src/styles/cyjs/emit.ts +247 -16
  722. package/src/styles/cyjs/face.ts +372 -0
  723. package/src/styles/cyjs/mappers.ts +498 -28
  724. package/src/styles/cyjs/routes.ts +432 -0
  725. package/src/styles/cytoscape/charts.ts +684 -0
  726. package/src/styles/cytoscape/emit.ts +220 -44
  727. package/src/styles/cytoscape/lexicon.ts +459 -80
  728. package/src/styles/cytoscape/mappings.ts +108 -0
  729. package/src/styles/cytoscape/resolve.ts +763 -23
  730. package/src/styles/cytoscape/translate.ts +11 -11
  731. package/src/styles/defaults.ts +436 -38
  732. package/src/styles/index.ts +5 -0
  733. package/src/styles/internal.ts +1 -0
  734. package/src/styles/io/block.ts +10 -0
  735. package/src/styles/io/generic.ts +79 -23
  736. package/src/styles/io/round-trip.ts +202 -0
  737. package/src/styles/io/writer.ts +14 -4
  738. package/src/styles/notes.ts +1 -0
  739. package/src/styles/plan/features.ts +23 -2
  740. package/src/styles/plan/index.ts +1 -1
  741. package/src/styles/plan/plan.ts +69 -5
  742. package/src/styles/plan/resolve.ts +61 -6
  743. package/src/styles/slots.ts +25 -0
  744. package/src/styles/types.ts +658 -4
  745. package/src/styles/vocabulary.ts +226 -3
  746. package/src/types.ts +19 -5
  747. package/dist/chunks/block-DiGq58c3.js.map +0 -1
  748. package/dist/chunks/choose--jM0yYCo.js +0 -57
  749. package/dist/chunks/choose--jM0yYCo.js.map +0 -1
  750. package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
  751. package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
  752. package/dist/chunks/export-BvqAXCKh.js.map +0 -1
  753. package/dist/chunks/exporter-CrDWIyiq.js.map +0 -1
  754. package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
  755. package/dist/chunks/generic-Dq1ntt9q.js.map +0 -1
  756. package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
  757. package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
  758. package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
  759. package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
  760. package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
  761. package/dist/chunks/importer-iFYPEKaJ.js.map +0 -1
  762. package/dist/chunks/importer-yh_aBCU6.js.map +0 -1
  763. package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
  764. package/dist/chunks/styles-BQnsga7p.js.map +0 -1
  765. package/dist/chunks/styles-D3fRphrO.js +0 -690
  766. package/dist/chunks/styles-D3fRphrO.js.map +0 -1
  767. package/dist/chunks/styles-yed-BF5x3_Y5.js +0 -842
  768. package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
  769. package/dist/chunks/writer-DMKvthQE.js +0 -448
  770. package/dist/chunks/writer-DMKvthQE.js.map +0 -1
package/dist/gml.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"gml.js","sources":["../src/formats/gml/syntax.ts","../src/formats/gml/styles.ts","../src/formats/gml/exporter.ts","../src/formats/gml/positions.ts","../src/formats/gml/importer.ts","../src/formats/gml/index.ts"],"sourcesContent":["/**\n * The GML lexical layer shared by the importer and the exporter (research note 07 section 2.2,\n * NetworkX readwrite/gml.py as the reference reader): the token list a whole GML text lexes into,\n * the structural validation that guarantees every later walk sees balanced `key value` pairs, the\n * value grammar (int, real, quoted string with `&#NN;` character references, `[ ... ]` record),\n * the NetworkX list conventions (`_networkx_list_start`, `\"[]\"`) and the key charset.\n *\n * Tokens are kept in typed arrays (kind, start, end, line, matching bracket) rather than objects:\n * the token list is the one intermediate structure of the GML importer, and it costs 17 bytes per\n * token instead of an object per node.\n */\n\nimport { SYNTAX_CODE } from \"../../common/codes.js\";\nimport { decodeGmlString } from \"../../common/escape.js\";\nimport { plural } from \"../../common/plural.js\";\n\n/**\n * A bare word: a key, or `INF` / `NAN` at a value position.\n * @category Plugin helpers\n */\nexport const TOKEN_WORD = 0;\n/**\n * An integer literal.\n * @category Plugin helpers\n */\nexport const TOKEN_INT = 1;\n/**\n * A real literal, including the non-finite spellings.\n * @category Plugin helpers\n */\nexport const TOKEN_REAL = 2;\n/**\n * A double-quoted string; start / end delimit the body between the quotes.\n * @category Plugin helpers\n */\nexport const TOKEN_STRING = 3;\n/**\n * `[`.\n * @category Plugin helpers\n */\nexport const TOKEN_OPEN = 4;\n/**\n * `]`.\n * @category Plugin helpers\n */\nexport const TOKEN_CLOSE = 5;\n\n/** The kind of one token. */\ntype TokenKind = 0 | 1 | 2 | 3 | 4 | 5;\n\n/**\n * The NetworkX marker that starts a one-element list written as repeated keys.\n * @category Plugin helpers\n */\nexport const LIST_START_MARKER = \"_networkx_list_start\";\n\n/**\n * The string NetworkX writes for an empty list.\n * @category Plugin helpers\n */\nexport const EMPTY_LIST_TEXT = \"[]\";\n\n/**\n * The string NetworkX writes for an empty tuple, read as an empty list too.\n * @category Plugin helpers\n */\nexport const EMPTY_TUPLE_TEXT = \"()\";\n\n/**\n * The node key the exporter writes a mangled node's original id into (design section 8.5).\n * @category Plugin helpers\n */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/**\n * The text breaks the format's syntax: a word that is not a key or a number, an unclosed string or `[`, a `]` with no\n * open `[`, or a key without a value. The message says where. The import stops.\n * @category Issue and loss codes\n */\nexport const SYNTAX_STRUCTURE_CODE = SYNTAX_CODE;\n/**\n * The code of an untokenizable bare token (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_TOKEN_CODE = SYNTAX_CODE;\n/**\n * The code of an unclosed string (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_STRING_CODE = SYNTAX_CODE;\n/**\n * The code of an unclosed `[` (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_BRACKET_CODE = SYNTAX_CODE;\n\nconst KEY_TEXT = /^[A-Za-z_]\\w*$/;\nconst STRICT_KEY_TEXT = /^[A-Za-z]\\w*$/;\nconst INT_TEXT = /^[+-]?\\d+$/;\nconst REAL_TEXT = /^[+-]?(?:(?:\\d+\\.\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?|\\d+[eE][+-]?\\d+)$/;\nconst NON_FINITE_TEXT = /^[+-]?(?:inf|infinity|nan)$/i;\nconst NON_FINITE_WORD = /^(?:inf|infinity|nan)$/i;\n\n/**\n * A lexical or structural error of a GML text, with the 1-based line it was found on. The importer\n * turns it into a fatal parse-error issue.\n * @category Plugin helpers\n */\nexport class GmlSyntaxError extends Error {\n /** The issue code. */\n readonly code: string;\n\n /** The 1-based line. */\n readonly line: number;\n\n /**\n * Create a syntax error.\n * @param code - the issue code\n * @param message - a plain-ASCII message\n * @param line - the 1-based line\n */\n constructor(code: string, message: string, line: number) {\n super(message);\n this.name = \"GmlSyntaxError\";\n this.code = code;\n this.line = line;\n }\n}\n\n/**\n * The tokens of one GML text, structurally validated: every `[` has its matching `]` recorded and\n * every key is followed by a value, so walkers need no error paths.\n * @category Plugin helpers\n */\nexport class GmlTokens {\n /** The source text the offsets index into. */\n readonly text: string;\n\n /** The kind of every token. */\n kind: Uint8Array;\n\n /** The start offset of every token (a string's body start). */\n start: Uint32Array;\n\n /** The end offset (exclusive) of every token (a string's body end). */\n end: Uint32Array;\n\n /** The 1-based line of every token. */\n line: Uint32Array;\n\n /** For an open bracket, the index of its matching close bracket; 0 elsewhere. */\n match: Uint32Array;\n\n /** The number of tokens. */\n count = 0;\n\n /**\n * Whether a backslash escapes the next character inside a string (`\\\"`, `\\\\`): set for files OGDF wrote, whose\n * writer escapes quotes that way. Plain GML has no escape mechanism.\n */\n backslashEscapes = false;\n\n /** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */\n onUnknownEntity: ((entity: string, line: number) => void) | null = null;\n\n /**\n * Create an empty token list over a text.\n * @param text - the source text\n * @param capacity - the initial capacity\n */\n constructor(text: string, capacity = 1024) {\n this.text = text;\n this.kind = new Uint8Array(capacity);\n this.start = new Uint32Array(capacity);\n this.end = new Uint32Array(capacity);\n this.line = new Uint32Array(capacity);\n this.match = new Uint32Array(0);\n }\n\n /**\n * Append a token.\n * @param kind - the kind\n * @param start - the start offset\n * @param end - the end offset\n * @param line - the 1-based line\n */\n push(kind: TokenKind, start: number, end: number, line: number): void {\n if (this.count === this.kind.length) {\n this.grow();\n }\n const i = this.count++;\n this.kind[i] = kind;\n this.start[i] = start;\n this.end[i] = end;\n this.line[i] = line;\n }\n\n /**\n * The raw text of a token (a string's body without the quotes, entities undecoded).\n * @param i - the token index\n * @returns the text\n */\n textOf(i: number): string {\n return this.text.slice(this.start[i], this.end[i]);\n }\n\n /**\n * The decoded value of a string token.\n * @param i - the token index\n * @returns the body with character references decoded\n */\n stringOf(i: number): string {\n let text = this.textOf(i);\n if (text.includes(\"\\r\")) {\n // a line break inside a string is part of it, as LF whatever the file's line ends\n text = text.replaceAll(/\\r\\n?/g, \"\\n\");\n }\n if (this.backslashEscapes && text.includes(\"\\\\\")) {\n text = text.replaceAll(/\\\\([\\s\\S])/g, \"$1\");\n }\n if (!text.includes(\"&\")) {\n return text;\n }\n const report = this.onUnknownEntity;\n return decodeGmlString(\n text,\n report === null\n ? undefined\n : (entity) => {\n report(entity, this.line[i]);\n },\n );\n }\n\n /**\n * Whether a token is a `[` or `]`.\n * @param i - the token index\n * @returns true for a bracket\n */\n isBracket(i: number): boolean {\n return this.kind[i] >= TOKEN_OPEN;\n }\n\n /**\n * The index of the pair following the pair whose key is at `key`.\n * @param key - the index of a key token\n * @returns the index after the pair's value (after the matching `]` for a record)\n */\n nextPair(key: number): number {\n const value = key + 1;\n return this.kind[value] === TOKEN_OPEN ? this.match[value] + 1 : value + 1;\n }\n\n /** Double every array. */\n private grow(): void {\n const capacity = this.kind.length * 2;\n const kind = new Uint8Array(capacity);\n kind.set(this.kind);\n this.kind = kind;\n const start = new Uint32Array(capacity);\n start.set(this.start);\n this.start = start;\n const end = new Uint32Array(capacity);\n end.set(this.end);\n this.end = end;\n const line = new Uint32Array(capacity);\n line.set(this.line);\n this.line = line;\n }\n}\n\n/**\n * Lex and structurally validate a whole GML text.\n *\n * Lexical rules (NetworkX): whitespace separates tokens; `#` outside a string starts a comment\n * that runs to the end of the line; a string is delimited by double quotes and may span lines (a\n * line break inside is part of it, GML draft 3.2.5; there is no escape mechanism; `&#NN;`\n * references are decoded later); a U+FEFF between tokens is whitespace; `[` and `]` are\n * single-character tokens; every other run of characters is a key (`[A-Za-z_][0-9A-Za-z_]*`),\n * an integer (`[+-]?[0-9]+`), a real (with a decimal point or an exponent, or `INF` / `NAN` in\n * any case with an optional sign) or an error.\n *\n * Structural rules: the text is a sequence of `key value` pairs where a value is a number, a\n * string, `INF` / `NAN`, or a bracketed sequence of pairs; every `[` has a `]`.\n * @param text - the GML text\n * @returns the validated tokens; GmlSyntaxError with the line of the first problem\n * @category Plugin helpers\n */\nexport function tokenizeGml(text: string): GmlTokens {\n const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));\n tokens.backslashEscapes = writtenByOgdf(text);\n const lex: GmlLex = { text, tokens, i: 0, line: 1, spanningLine: 0 };\n while (lex.i < text.length) {\n const c = text.codePointAt(lex.i) ?? 0;\n if (c === 34) {\n lexString(lex);\n } else if (c === 91 || c === 93) {\n tokens.push(c === 91 ? TOKEN_OPEN : TOKEN_CLOSE, lex.i, lex.i + 1, lex.line);\n lex.i++;\n } else if (!skipSpace(lex, c)) {\n lexBare(lex);\n }\n }\n validateStructure(tokens);\n return tokens;\n}\n\n/** Where tokenizeGml() is. */\ninterface GmlLex {\n readonly text: string;\n readonly tokens: GmlTokens;\n /** The offset of the next character. */\n i: number;\n /** The line of the next character. */\n line: number;\n /** The opening line of the first string that spans lines: where a missing quote most likely is; 0 for none. */\n spanningLine: number;\n}\n\n/**\n * Skips one line break, space or comment.\n * @param lex - the lexer\n * @param c - the char code at the offset\n * @returns false when the character starts a token\n */\nfunction skipSpace(lex: GmlLex, c: number): boolean {\n const { text } = lex;\n if (c === 10 || c === 13) {\n lex.line++;\n lex.i++;\n if (c === 13 && lex.i < text.length && text.codePointAt(lex.i) === 10) {\n lex.i++;\n }\n } else if (c === 32 || c === 9 || c === 11 || c === 12 || c === 0xfeff) {\n // a BOM left inside by concatenated files is whitespace; the shared text check reports it\n lex.i++;\n } else if (c === 35) {\n lex.i = endOfLine(text, lex.i);\n } else {\n return false;\n }\n return true;\n}\n\n/**\n * Lexes a string starting at the offset (its opening quote).\n * @param lex - the lexer\n */\nfunction lexString(lex: GmlLex): void {\n const { text, tokens, i } = lex;\n const close = tokens.backslashEscapes ? escapedClose(text, i + 1) : text.indexOf('\"', i + 1);\n if (close < 0) {\n const hint =\n lex.spanningLine === 0\n ? \"\"\n : `; the string opened at line ${lex.spanningLine} spans lines, so a quote may be missing there`;\n throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${lex.line}${hint}`, lex.line);\n }\n tokens.push(TOKEN_STRING, i + 1, close, lex.line);\n const opened = lex.line;\n for (let k = i + 1; k < close; k++) {\n const d = text.codePointAt(k);\n if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {\n lex.line++;\n }\n }\n if (lex.line !== opened && lex.spanningLine === 0) {\n lex.spanningLine = opened;\n }\n lex.i = close + 1;\n}\n\n/**\n * Lexes a bare token (a key, a number) starting at the offset.\n * @param lex - the lexer\n */\nfunction lexBare(lex: GmlLex): void {\n const { text, i } = lex;\n let j = i + 1;\n while (j < text.length && !isDelimiter(text.codePointAt(j) ?? 0)) {\n j++;\n }\n lex.tokens.push(classifyBare(text, i, j, lex.line), i, j, lex.line);\n lex.i = j;\n}\n\n/**\n * Whether OGDF wrote the file: its first key is `Creator \"ogdf::...\"`, after any whitespace and\n * comment lines. A plain scan, so a banner of `#` characters costs time linear in its length.\n * @param text - the GML text\n * @returns true when the file opens with an OGDF creator line\n */\nfunction writtenByOgdf(text: string): boolean {\n const end = Math.min(text.length, 512);\n let i = 0;\n while (i < end) {\n const c = text.codePointAt(i);\n if (c === 35) {\n // '#': a comment runs to the next line break\n while (i < end && text.codePointAt(i) !== 10 && text.codePointAt(i) !== 13) {\n i++;\n }\n } else if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12 || c === 11) {\n i++;\n } else {\n break;\n }\n }\n return /^Creator\\s+\"ogdf::/.test(text.slice(i, i + 64));\n}\n\n/**\n * The offset of the quote closing a string whose backslashes escape the next character, or -1.\n * @param text - the text\n * @param from - the offset after the opening quote\n * @returns the offset of the closing quote\n */\nfunction escapedClose(text: string, from: number): number {\n let k = from;\n while (k < text.length) {\n const c = text.codePointAt(k);\n if (c === 34) {\n return k;\n }\n // a backslash escapes the next character\n k += c === 92 ? 2 : 1;\n }\n return -1;\n}\n\n/**\n * The offset of the line terminator at or after `from`, or the text length.\n * @param text - the text\n * @param from - the offset to search from\n * @returns the offset of the next `\\n` or `\\r`\n */\nfunction endOfLine(text: string, from: number): number {\n const n = text.length;\n for (let i = from; i < n; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || c === 13) {\n return i;\n }\n }\n return n;\n}\n\n/**\n * Whether a character ends a bare token.\n * @param c - the char code\n * @returns true for whitespace, brackets, a quote or `#`\n */\nfunction isDelimiter(c: number): boolean {\n return (\n c === 32 ||\n c === 9 ||\n c === 10 ||\n c === 13 ||\n c === 11 ||\n c === 12 ||\n c === 91 ||\n c === 93 ||\n c === 34 ||\n c === 35\n );\n}\n\n/**\n * Classify a bare token.\n * @param text - the text\n * @param start - the token start\n * @param end - the token end\n * @param line - the token line, for the error\n * @returns WORD, INT or REAL; GmlSyntaxError for anything else\n */\nfunction classifyBare(text: string, start: number, end: number, line: number): TokenKind {\n const token = text.slice(start, end);\n if (KEY_TEXT.test(token)) {\n return TOKEN_WORD;\n }\n if (INT_TEXT.test(token)) {\n return TOKEN_INT;\n }\n if (REAL_TEXT.test(token) || NON_FINITE_TEXT.test(token)) {\n return TOKEN_REAL;\n }\n // the message is ASCII: a character outside it is shown as \\uXXXX and named, since it may look\n // like something else (a no-break space pasted from a web page looks like a space)\n const hex = (c: string): string => (c.codePointAt(0) ?? 0).toString(16).toUpperCase().padStart(4, \"0\");\n const head = token.length > 20 ? `${token.slice(0, 20)}...` : token;\n const shown = head.replaceAll(/[^\\x20-\\x7e]/gu, (c) => String.raw`\\u` + hex(c));\n const odd = /[^\\x21-\\x7e]/u.exec(token);\n const note = odd === null ? \"\" : ` (it holds U+${hex(odd[0])}, which GML allows only inside a string)`;\n throw new GmlSyntaxError(SYNTAX_TOKEN_CODE, `cannot tokenize \"${shown}\" at line ${line}${note}`, line);\n}\n\n/**\n * Check the `key value` structure and record the matching bracket of every `[`.\n * @param tokens - the lexed tokens\n */\nfunction validateStructure(tokens: GmlTokens): void {\n const { count, kind } = tokens;\n const match = new Uint32Array(count);\n const stack: number[] = [];\n let i = 0;\n while (i < count) {\n const k = kind[i];\n if (k === TOKEN_CLOSE) {\n const open = stack.pop();\n if (open === undefined) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `unexpected \"]\" at line ${tokens.line[i]}: no open \"[\"`,\n tokens.line[i],\n );\n }\n match[open] = i;\n i++;\n continue;\n }\n if (k !== TOKEN_WORD) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a key at line ${tokens.line[i]}, found ${describeToken(tokens, i)}`,\n tokens.line[i],\n );\n }\n const value = i + 1;\n if (value >= count) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `key \"${tokens.textOf(i)}\" at line ${tokens.line[i]} has no value`,\n tokens.line[i],\n );\n }\n if (checkValue(tokens, i) === TOKEN_OPEN) {\n stack.push(value);\n }\n i = value + 1;\n }\n if (stack.length > 0) {\n const open = stack[stack.length - 1];\n throw new GmlSyntaxError(\n SYNTAX_BRACKET_CODE,\n `unexpected end of input: ${stack.length} bracket${plural(stack.length)} still open, the last opened at line ${tokens.line[open]}`,\n tokens.line[open],\n );\n }\n tokens.match = match;\n}\n\n/**\n * Checks the value of a key: a number, a string, `INF` / `NAN` or an opening bracket. Gephi writes its name\n * unquoted (`Creator Gephi`): the word is read as the string it means.\n * @param tokens - the lexed tokens\n * @param key - the key's token index (its value follows it)\n * @returns the value's kind\n */\nfunction checkValue(tokens: GmlTokens, key: number): TokenKind {\n const { kind } = tokens;\n const value = key + 1;\n const word = kind[value] === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value));\n if (word && tokens.textOf(key) === \"Creator\") {\n kind[value] = TOKEN_STRING;\n return TOKEN_STRING;\n }\n if (kind[value] === TOKEN_CLOSE || word) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a value for key \"${tokens.textOf(key)}\" at line ${tokens.line[key]}, found ${describeToken(tokens, value)}`,\n tokens.line[value],\n );\n }\n return kind[value] as TokenKind;\n}\n\n/**\n * A short description of a token for messages.\n * @param tokens - the tokens\n * @param i - the token index\n * @returns the quoted text or the bracket\n */\nfunction describeToken(tokens: GmlTokens, i: number): string {\n switch (tokens.kind[i]) {\n case TOKEN_OPEN:\n return '\"[\"';\n case TOKEN_CLOSE:\n return '\"]\"';\n case TOKEN_STRING:\n return `the string \"${tokens.textOf(i)}\"`;\n default:\n return `\"${tokens.textOf(i)}\"`;\n }\n}\n\n/**\n * The numeric value of an INT or REAL token (or a WORD that is `INF` / `NAN` at a value position).\n * @param text - the token text\n * @returns the number; Infinity / -Infinity / NaN for the non-finite spellings\n * @category Plugin helpers\n */\nexport function numberOfText(text: string): number {\n if (NON_FINITE_TEXT.test(text)) {\n const lower = text.toLowerCase();\n if (lower.endsWith(\"nan\")) {\n return Number.NaN;\n }\n return lower.startsWith(\"-\") ? -Infinity : Infinity;\n }\n return Number(text);\n}\n\n/**\n * Whether a value token is one of the non-finite bare words (`INF`, `NAN`), which lex as words.\n * @param tokens - the tokens\n * @param i - the value token index\n * @returns true when the word is a real\n * @category Plugin helpers\n */\nexport function isNonFiniteWord(tokens: GmlTokens, i: number): boolean {\n return tokens.kind[i] === TOKEN_WORD && NON_FINITE_WORD.test(tokens.textOf(i));\n}\n\n/**\n * Whether a text is a GML key the strict grammar accepts (`[A-Za-z][0-9A-Za-z_]*`, what NetworkX\n * writes and reads).\n * @param text - the candidate key\n * @returns true when it can be written as a key\n * @category Plugin helpers\n */\nexport function isGmlKey(text: string): boolean {\n return STRICT_KEY_TEXT.test(text);\n}\n\n/**\n * Keys rewritten under sanitizeKeys \"mangle\", or a data column renamed because its key would read back as one of\n * graphty's style values.\n * @category Issue and loss codes\n */\nexport const KEY_MANGLED_CODE = \"W_GML_KEY_MANGLED\";\n\n/**\n * Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading\n * non-letter is prefixed with `x` (the exporter's `sanitizeKeys: \"mangle\"`).\n * @param text - the text\n * @returns a valid key\n * @category Plugin helpers\n */\nexport function mangleGmlKey(text: string): string {\n const body = text.replaceAll(/\\W/g, \"_\");\n return /^[A-Za-z]/.test(body) ? body : `x${body}`;\n}\n\n/** One open record while parseRecord() walks the tokens without recursion. */\ninterface RecordFrame {\n readonly record: Record<string, unknown>;\n listKeys: Set<string> | null;\n /** The index of the record's `]`. */\n readonly close: number;\n /** The next key token to read. */\n next: number;\n /** The key the record is stored under in its parent, or null for the root. */\n readonly key: string | null;\n}\n\n/**\n * Parse a bracketed record into a JSON object (design section 8.5: nested GML records map to\n * `json`). Values follow the value grammar; repeated keys become arrays with the NetworkX\n * conventions: the `_networkx_list_start` marker starts a list so a one-element list survives,\n * `\"[]\"` and `\"()\"` are empty lists, and a key seen twice without the marker becomes a\n * two-element array. Nested records are walked with an explicit stack, so the nesting depth is\n * bounded by memory, not by the call stack.\n * @param tokens - the validated tokens\n * @param open - the index of the record's `[`\n * @returns a null-prototype object\n * @category Plugin helpers\n */\nexport function parseRecord(tokens: GmlTokens, open: number): Record<string, unknown> {\n const root = Object.create(null) as Record<string, unknown>;\n const stack: RecordFrame[] = [\n { record: root, listKeys: null, close: tokens.match[open], next: open + 1, key: null },\n ];\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame.next >= frame.close) {\n stack.pop();\n if (frame.key !== null) {\n storeValue(stack[stack.length - 1], frame.key, frame.record);\n }\n continue;\n }\n const p = frame.next;\n frame.next = tokens.nextPair(p);\n const key = tokens.textOf(p);\n const v = p + 1;\n if (tokens.kind[v] === TOKEN_STRING) {\n storeString(frame, key, tokens.stringOf(v));\n } else if (tokens.kind[v] === TOKEN_OPEN) {\n stack.push({\n record: Object.create(null) as Record<string, unknown>,\n listKeys: null,\n close: tokens.match[v],\n next: v + 1,\n key,\n });\n } else {\n storeValue(frame, key, numberOfText(tokens.textOf(v)));\n }\n }\n return root;\n}\n\n/**\n * Store a string value: the list-start marker opens an empty list for the key, the empty list and\n * tuple texts store an empty list, anything else stores the text.\n * @param frame - the open record\n * @param key - the key\n * @param text - the string\n */\nfunction storeString(frame: RecordFrame, key: string, text: string): void {\n if (text === LIST_START_MARKER) {\n frame.record[key] = [];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n return;\n }\n storeValue(frame, key, text === EMPTY_LIST_TEXT || text === EMPTY_TUPLE_TEXT ? [] : text);\n}\n\n/**\n * Store one value under a key: appended to the key's list when the key is a list, paired with the\n * earlier value when the key repeats, set otherwise.\n * @param frame - the open record\n * @param key - the key\n * @param value - the value\n */\nfunction storeValue(frame: RecordFrame, key: string, value: unknown): void {\n const { record } = frame;\n if (frame.listKeys?.has(key)) {\n (record[key] as unknown[]).push(value);\n } else if (key in record) {\n record[key] = [record[key], value];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n } else {\n record[key] = value;\n }\n}\n\n/**\n * The JSON value of a non-string value token: a number, or a record.\n * @param tokens - the tokens\n * @param v - the value token index (INT, REAL, non-finite WORD or OPEN)\n * @returns the value\n * @category Plugin helpers\n */\nexport function scalarOrRecord(tokens: GmlTokens, v: number): unknown {\n return tokens.kind[v] === TOKEN_OPEN ? parseRecord(tokens, v) : numberOfText(tokens.textOf(v));\n}\n","/**\n * GML styles: each node's and edge's `graphics [ ... ]` and `LabelGraphics [ ... ]` records read the way the program\n * that wrote the file draws them, and a graph's styles written back as yEd GML graphics.\n *\n * GML has one syntax and many vocabularies. The `Creator` line (top level, or inside the graph as Gephi writes it,\n * quoted or not) names the writer: yEd and yFiles, Cytoscape, Gephi, OGDF and igraph are recognized; every other file\n * (NetworkX writes no `Creator`) is read with the keys of the GML draft (Graphlet). A recognized drawing program's\n * defaults go beneath the file's own values; igraph and unknown writers get none.\n *\n * Writing: the yEd keys (`fill`, `outline`, `outlineWidth`, `outlineStyle`, `w`, `h`, `type`; edge `fill`, `width`,\n * `style`, `sourceArrow`, `targetArrow`, `smoothBends`; `LabelGraphics` `text`, `color`, `fontSize`, `fontName`,\n * `fontStyle`) replace every style key any reader here reads, inside the records the graph already has, so positions,\n * bends and other keys stay. The `graphty.styles` block and the per-element values its rules read are keys too,\n * named by the GML writer's rule for names that are not GML keys (`graphty_styles`, `graphty_style_node_<key>`).\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { type BendPoint, bendsToPoints, canonBends } from \"../../styles/canon/bends.js\";\nimport { canonColor, colorOpacity } from \"../../styles/canon/color.js\";\nimport { canonEnum } from \"../../styles/canon/enums.js\";\nimport { canonNumber } from \"../../styles/canon/number.js\";\nimport { type CanonSite, MAX_STYLE_VALUE_LENGTH, noteAt, scalarText } from \"../../styles/canon/site.js\";\nimport { canonText } from \"../../styles/canon/text.js\";\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport { CYTOSCAPE_LEXICON } from \"../../styles/cytoscape/lexicon.js\";\nimport { StyleApproximations } from \"../../styles/io/approximations.js\";\nimport {\n blockStyles,\n parseStyleBlock,\n STYLE_BLOCK_NAME,\n styleBlockLosses,\n styleTag,\n writeStyleBlock,\n} from \"../../styles/io/block.js\";\nimport { dataRead, type ExporterStyleInput } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { styleFingerprint } from \"../../styles/plan/features.js\";\nimport { plainCell, resolveStyles } from \"../../styles/plan/resolve.js\";\nimport type {\n ImporterStyles,\n StyleColumn,\n StyleDialect,\n StyleReadContext,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWriteCapabilities,\n} from \"../../styles/types.js\";\nimport type { LossNote } from \"../../types.js\";\nimport { gephiRules } from \"../gexf/styles.js\";\nimport {\n flowchartShape,\n FONT_STYLES,\n type ValueColumns,\n valueColumns,\n YED_ARROWS,\n YED_LINES,\n YED_SHAPES,\n yedColor,\n yedSpelled,\n yedValue,\n} from \"../graphml/styles-yed.js\";\nimport { KEY_MANGLED_CODE, mangleGmlKey } from \"./syntax.js\";\n\n/** A GML record as the importer keeps it (a json cell). */\ntype Rec = Record<string, unknown>;\n\n/** The key vocabulary a file's graphics are read with. */\ntype Vocabulary = \"yed\" | \"cytoscape\" | \"ogdf\" | \"graphlet\";\n\n/** Who wrote a GML file, as far as its styles go. */\ninterface GmlWriter {\n /** The dialect recorded in the styles. */\n readonly dialect: StyleDialect;\n /** The program whose defaults apply, or null. */\n readonly tool: StyleTool | null;\n /** The keys its graphics are read with. */\n readonly vocabulary: Vocabulary;\n /** How its colors and names are spelled. */\n readonly spelling: StyleDialect;\n /** The unit of its lengths. */\n readonly units: \"px\" | \"relative\";\n /** Whether it draws the `label` key of an element that has graphics (the GML draft does; yEd and Gephi do not). */\n readonly labelKey: boolean;\n}\n\n/** The writers recognized by their `Creator` text, first match wins. */\nconst WRITERS: readonly (readonly [RegExp, GmlWriter])[] = [\n [\n /^\\s*(yfiles|yed)\\b/i,\n { dialect: \"yed\", tool: \"yed\", vocabulary: \"yed\", spelling: \"yed\", units: \"px\", labelKey: false },\n ],\n [\n /^\\s*cytoscape\\b/i,\n {\n dialect: \"cytoscape\",\n tool: \"cytoscape\",\n vocabulary: \"cytoscape\",\n spelling: \"cytoscape\",\n units: \"px\",\n labelKey: true,\n },\n ],\n [\n /^\\s*gephi\\b/i,\n {\n dialect: \"gephi\",\n tool: \"gephi\",\n vocabulary: \"graphlet\",\n spelling: \"css\",\n units: \"relative\",\n labelKey: false,\n },\n ],\n [\n /^\\s*ogdf::/i,\n { dialect: \"ogdf\", tool: \"ogdf\", vocabulary: \"ogdf\", spelling: \"css\", units: \"px\", labelKey: true },\n ],\n // igraph writes a Creator line, but no drawing defaults of igraph's are stated by a primary source\n [\n /^\\s*igraph\\b/i,\n { dialect: \"igraph\", tool: null, vocabulary: \"graphlet\", spelling: \"css\", units: \"px\", labelKey: true },\n ],\n];\n\n/** Any other writer (NetworkX, SNDlib, hand-written files): the GML draft's keys, no defaults. */\nconst UNKNOWN_WRITER: GmlWriter = {\n dialect: \"gml\",\n tool: null,\n vocabulary: \"graphlet\",\n spelling: \"css\",\n units: \"px\",\n labelKey: true,\n};\n\n/** A file graphty wrote: yEd keys, and the `graphty.styles` block gives the rules. */\nconst GRAPHTY_WRITER: GmlWriter = { ...WRITERS[0][1], tool: null };\n\n/**\n * The graph key holding the `graphty.styles` block: the block's name under the GML writer's rule for names that are\n * not GML keys.\n * @category Built-in formats\n */\nexport const GML_STYLE_BLOCK_KEY = mangleGmlKey(STYLE_BLOCK_NAME);\n\n/** The key prefix of the per-element style values (`graphty.style.` under the same rule). */\nconst TAG_PREFIX = mangleGmlKey(\"graphty.style.\");\n\n/**\n * The GML key of one style column's per-element values.\n * @param target - nodes or edges\n * @param key - the style column's key\n * @returns the key\n */\nfunction tagKey(target: StyleTarget, key: string): string {\n return mangleGmlKey(styleTag(target, key));\n}\n\n/**\n * A graph value as text, or null.\n * @param snapshot - the graph\n * @param name - the graph column\n * @returns the text\n */\nfunction graphText(snapshot: GraphSnapshot, name: string): string | null {\n if (!snapshot.graph.has(name)) {\n return null;\n }\n const v = plainCell(snapshot.graph.value(name, 0));\n if (typeof v === \"string\") {\n return v;\n }\n return typeof v === \"number\" ? String(v) : null;\n}\n\n/**\n * Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), or graphty when\n * the file holds a `graphty.styles` block.\n * @param snapshot - the graph\n * @returns the writer\n */\nfunction writerOf(snapshot: GraphSnapshot): GmlWriter {\n if (snapshot.graph.has(GML_STYLE_BLOCK_KEY)) {\n return GRAPHTY_WRITER;\n }\n const creator = snapshot.meta.creator ?? graphText(snapshot, \"Creator\") ?? \"\";\n for (const [pattern, writer] of WRITERS) {\n if (pattern.test(creator)) {\n return writer;\n }\n }\n return UNKNOWN_WRITER;\n}\n\n// ============================================================ reading\n\n/** One element's canonical value of a property; null leaves it unset. */\ntype Put = (property: string, value: StyleValue | null) => void;\n\n/** Where a value of an element was read, by property. */\ntype At = (property: string) => CanonSite;\n\n/** The edge's `arrow` key of the GML draft: which ends have an arrow. */\nconst ARROW_ENDS: ReadonlyMap<string, readonly [string, string]> = new Map([\n [\"none\", [\"none\", \"none\"]],\n [\"last\", [\"none\", \"triangle\"]],\n [\"first\", [\"triangle\", \"none\"]],\n [\"both\", [\"triangle\", \"triangle\"]],\n]);\n\n/** OGDF's stroke types (`stipple`), by number. */\nconst OGDF_STROKES: readonly string[] = [\"none\", \"solid\", \"dashed\", \"dotted\", \"dash-dot\", \"dash-dot\"];\n\n/** OGDF's shape names the common table does not know. */\nconst OGDF_SHAPES: ReadonlyMap<string, string> = new Map([\n [\"rect\", \"rectangle\"],\n [\"rhomb\", \"diamond\"],\n [\"trapeze\", \"trapezoid\"],\n [\"invtrapeze\", \"trapezoid\"],\n [\"invtriangle\", \"triangle\"],\n [\"invparallelogram\", \"parallelogram\"],\n]);\n\n/** Keys only yEd writes in a label record: its `fill` is the label's background, not the text color. */\nconst YED_LABEL_KEYS: readonly string[] = [\n \"outline\",\n \"autoSizePolicy\",\n \"model\",\n \"configuration\",\n \"borderDistance\",\n \"modelName\",\n \"modelPosition\",\n];\n\n/** Cytoscape's legacy numbered arrows (`source_arrow 3`), read as Cytoscape reads them. */\nconst cytoscapeArrow = CYTOSCAPE_LEXICON.edge.get(\"targetArrow\")?.[0]?.[1];\n\n/**\n * A short sample of a value for a note.\n * @param raw - the value\n * @returns its text, or \"a record\" for a record\n */\nfunction sampleOf(raw: unknown): string {\n return typeof raw === \"string\" || typeof raw === \"number\"\n ? String(raw).slice(0, MAX_STYLE_VALUE_LENGTH)\n : \"a record\";\n}\n\n/**\n * Whether a value is a GML record.\n * @param v - the value\n * @returns true for a non-array object\n */\nfunction isRec(v: unknown): v is Rec {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * The first defined value of some keys of a record.\n * @param r - the record\n * @param keys - the keys, in order of preference\n * @returns the value, or undefined\n */\nfunction first(r: Rec, ...keys: string[]): unknown {\n for (const k of keys) {\n if (Object.hasOwn(r, k) && r[k] !== undefined) {\n return r[k];\n }\n }\n return undefined;\n}\n\n/**\n * Reads a color and its alpha.\n * @param raw - the value\n * @param property - the color property\n * @param opacity - its opacity property, or null\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readColor(raw: unknown, property: string, opacity: string | null, writer: GmlWriter, put: Put, at: At): void {\n if (raw === undefined) {\n return;\n }\n const c = canonColor(raw, writer.spelling, at(property));\n if (c === null) {\n return;\n }\n put(property, c.color);\n const alpha = colorOpacity(c, null, at(property), opacity !== null);\n if (opacity !== null) {\n put(opacity, alpha);\n }\n}\n\n/**\n * A stroke style: OGDF's numbered `stipple`, or a line type name.\n * @param raw - the value\n * @param kind - border or line style\n * @param writer - the writer\n * @param at - the site\n * @returns the style, or null\n */\nfunction strokeStyle(raw: unknown, kind: \"borderStyle\" | \"lineStyle\", writer: GmlWriter, at: CanonSite): string | null {\n if (raw === undefined) {\n return null;\n }\n if (writer.vocabulary === \"ogdf\") {\n const stroke = OGDF_STROKES[Number(raw)] as string | undefined;\n if (stroke === undefined || stroke === \"none\") {\n noteAt(at, STYLE_ISSUE.UNKNOWN_VALUE, sampleOf(raw));\n return null;\n }\n return stroke;\n }\n return canonEnum(kind, raw, writer.spelling, at);\n}\n\n/**\n * Reads one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeGraphics(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n readNodeFill(g, writer, put, at);\n readNodeOutline(g, writer, put, at);\n put(\n \"borderStyle\",\n strokeStyle(v === \"ogdf\" ? g.stipple : g.outlineStyle, \"borderStyle\", writer, at(\"borderStyle\")),\n );\n put(\"width\", g.w === undefined ? null : canonNumber(g.w, at(\"width\")));\n put(\"height\", g.h === undefined ? null : canonNumber(g.h, at(\"height\")));\n if (g.type !== undefined) {\n const raw =\n v === \"ogdf\" && typeof g.type === \"string\" ? (OGDF_SHAPES.get(g.type.toLowerCase()) ?? g.type) : g.type;\n put(\"shape\", canonEnum(\"shape\", raw, writer.spelling, at(\"shape\")));\n } else if (v === \"yed\" && typeof g.customconfiguration === \"string\") {\n // yEd's flowchart palette keeps a node's shape as a configuration, not a `type`.\n put(\"shape\", flowchartShape(g.customconfiguration));\n }\n}\n\n/**\n * Reads the fill of one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeFill(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n if (writer.vocabulary === \"yed\" && Number(g.hasFill) === 0) {\n noteAt(at(\"fill\"), STYLE_ISSUE.NO_FILL, \"hasFill 0\");\n put(\"fillOpacity\", 0);\n return;\n }\n readColor(g.fill, \"fill\", \"fillOpacity\", writer, put, at);\n if (g.fill2 !== undefined) {\n noteAt(at(\"fill\"), STYLE_ISSUE.GRADIENT, sampleOf(g.fill2));\n }\n}\n\n/**\n * Reads the outline color and width of one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeOutline(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n if (v === \"yed\" && Number(g.hasOutline) === 0) {\n put(\"borderWidth\", 0);\n return;\n }\n readColor(v === \"ogdf\" ? g.line : g.outline, \"borderColor\", null, writer, put, at);\n const width = outlineWidthOf(g, v);\n put(\"borderWidth\", width === undefined ? null : canonNumber(width, at(\"borderWidth\")));\n}\n\n/**\n * The outline width of a node's `graphics` record, under the key its writer uses.\n * @param g - the record\n * @param v - the writer's vocabulary\n * @returns the raw width, or undefined\n */\nfunction outlineWidthOf(g: Rec, v: GmlWriter[\"vocabulary\"]): unknown {\n switch (v) {\n case \"yed\":\n return g.outlineWidth;\n case \"cytoscape\":\n return first(g, \"outline_width\", \"width\");\n case \"ogdf\":\n return g.lineWidth;\n default:\n return first(g, \"width\", \"outlineWidth\");\n }\n}\n\n/**\n * Reads one edge's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdgeGraphics(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n readColor(g.fill, \"color\", \"opacity\", writer, put, at);\n const width = v === \"ogdf\" ? first(g, \"lineWidth\", \"width\") : g.width;\n put(\"width\", width === undefined ? null : canonNumber(width, at(\"width\")));\n put(\"lineStyle\", strokeStyle(v === \"ogdf\" ? g.stipple : g.style, \"lineStyle\", writer, at(\"lineStyle\")));\n if (typeof g.arrow === \"string\") {\n const ends = ARROW_ENDS.get(g.arrow.trim().toLowerCase());\n if (ends === undefined) {\n noteAt(at(\"targetArrow\"), STYLE_ISSUE.UNKNOWN_VALUE, g.arrow.slice(0, MAX_STYLE_VALUE_LENGTH));\n } else {\n put(\"sourceArrow\", ends[0]);\n put(\"targetArrow\", ends[1]);\n }\n }\n for (const [keys, property] of [\n [[\"sourceArrow\", \"source_arrow\"], \"sourceArrow\"],\n [[\"targetArrow\", \"target_arrow\"], \"targetArrow\"],\n ] as const) {\n const raw = first(g, ...keys);\n if (raw === undefined) {\n continue;\n }\n put(\n property,\n v === \"cytoscape\" && cytoscapeArrow !== undefined\n ? cytoscapeArrow(raw, at(property))\n : canonEnum(\"arrow\", raw, writer.spelling, at(property)),\n );\n }\n if (v === \"yed\") {\n readYedCurve(g, put);\n }\n}\n\n/**\n * Reads whether yEd draws an edge curved: `smoothBends` rounds the bends of its `Line`, whose points run from the\n * source through the bends to the target, so a line of two points (or none) stays straight.\n * @param g - the edge's `graphics` record\n * @param put - receives the value\n */\nfunction readYedCurve(g: Rec, put: Put): void {\n if (g.smoothBends !== undefined) {\n const points = isRec(g.Line) ? g.Line.point : undefined;\n put(\"curved\", Number(g.smoothBends) === 1 && Array.isArray(points) && points.length > 2);\n }\n}\n\n/**\n * Reads an element's label records: the first visible one with text; further visible ones are noted.\n * @param raw - the `LabelGraphics` value (one record or several)\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readLabelGraphics(raw: unknown, writer: GmlWriter, put: Put, at: At): void {\n const visible = (Array.isArray(raw) ? raw : [raw]).filter((l): l is Rec => isRec(l) && Number(l.visible) !== 0);\n const lg = visible.at(0);\n if (lg === undefined) {\n return;\n }\n const extra = visible.slice(1).filter((l) => l.text !== undefined).length;\n if (extra > 0) {\n noteAt(at(\"label\"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);\n }\n if (lg.text !== undefined) {\n put(\"label\", canonText(lg.text, at(\"label\")));\n }\n // the GML draft's `fill` is the text color; yEd's is the label's background box, its `color` the text color\n const yedLabel = writer.vocabulary === \"yed\" || YED_LABEL_KEYS.some((k) => Object.hasOwn(lg, k));\n if (lg.color !== undefined) {\n readColor(lg.color, \"labelColor\", null, writer, put, at);\n } else if (lg.fill !== undefined && !yedLabel) {\n readColor(lg.fill, \"labelColor\", null, writer, put, at);\n }\n if (lg.fill !== undefined && yedLabel) {\n noteAt(at(\"label\"), STYLE_ISSUE.NOT_CARRIED, \"label background\");\n }\n readLabelFont(lg, put, at);\n}\n\n/**\n * Reads a label record's font: its size, name, weight and slant.\n * @param lg - the record\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readLabelFont(lg: Rec, put: Put, at: At): void {\n put(\"labelSize\", lg.fontSize === undefined ? null : canonNumber(lg.fontSize, at(\"labelSize\")));\n put(\"labelFont\", lg.fontName === undefined ? null : canonText(lg.fontName, at(\"labelFont\")));\n const style = scalarText(lg.fontStyle, at(\"labelWeight\"))?.trim().toLowerCase();\n if (style !== undefined) {\n const known = FONT_STYLES.get(style);\n if (known === undefined) {\n noteAt(at(\"labelWeight\"), STYLE_ISSUE.UNKNOWN_VALUE, style.slice(0, MAX_STYLE_VALUE_LENGTH));\n } else {\n put(\"labelWeight\", known[0]);\n put(\"labelItalic\", known[1]);\n }\n }\n}\n\n/**\n * Reads one element: its `graphics` and `LabelGraphics`, and the `label` key where the writer draws it.\n * @param target - nodes or edges\n * @param g - the graphics value\n * @param lg - the LabelGraphics value\n * @param label - the `label` key's value\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readElement(\n target: StyleTarget,\n g: unknown,\n lg: unknown,\n label: unknown,\n writer: GmlWriter,\n put: Put,\n at: At,\n): void {\n let text = false;\n const putLabel: Put = (property, value) => {\n text ||= property === \"label\" && value !== null;\n put(property, value);\n };\n if (isRec(g)) {\n (target === \"node\" ? readNodeGraphics : readEdgeGraphics)(g, writer, put, at);\n }\n if (lg !== null && lg !== undefined) {\n readLabelGraphics(lg, writer, putLabel, at);\n }\n // the GML draft draws the label key; Cytoscape reads it as the node's name, which its default style shows\n const drawn =\n writer.vocabulary === \"cytoscape\" ? target === \"node\" : writer.labelKey && (isRec(g) || lg !== undefined);\n if (!text && drawn && label !== null && label !== undefined) {\n put(\"label\", canonText(label, at(\"label\")));\n }\n}\n\n/**\n * The value of a column, or undefined when the table has no such column.\n * @param table - the node or edge table\n * @param name - the column\n * @param i - the row\n * @returns the value\n */\nfunction cellOf(table: GraphSnapshot[\"nodes\"], name: string, i: number): unknown {\n if (!table.has(name)) {\n return undefined;\n }\n const v = plainCell(table.value(name, i));\n return v ?? undefined;\n}\n\n/**\n * A node's center: the `graphics` `x` and `y` the importer moved into the position column.\n * @param snapshot - the graph\n * @param i - the node's index\n * @returns the center; NaN where the node has none\n */\nfunction centerOf(snapshot: GraphSnapshot, i: number): BendPoint {\n const column = snapshot.nodes.byRole(\"position\");\n const v = column?.isSet(i) === true ? (column.value(i) as ArrayLike<number>) : null;\n return v === null ? [Number.NaN, Number.NaN] : [v[0], v[1]];\n}\n\n/**\n * An edge's bends: the points of its `graphics` `Line` between the first and the last, which are where it leaves\n * the source and meets the target.\n * @param snapshot - the graph\n * @param g - the edge's `graphics` value\n * @param e - the edge's row\n * @returns the `bends` value, or null without bends\n */\nfunction lineBends(snapshot: GraphSnapshot, g: unknown, e: number): string | null {\n const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;\n if (!Array.isArray(raw) || raw.length < 3) {\n return null;\n }\n const points = raw.slice(1, -1).map((p): BendPoint => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));\n return canonBends(\n centerOf(snapshot, snapshot.edgeSource(e)),\n centerOf(snapshot, snapshot.edgeTarget(e)),\n points,\n true,\n );\n}\n\n/**\n * Every element's values, read with a writer's vocabulary.\n * @param snapshot - the graph\n * @param writer - the writer\n * @param notes - where problems are noted\n * @param context - the work budget\n * @returns the values per target, and whether anything was read\n */\nfunction readValues(\n snapshot: GraphSnapshot,\n writer: GmlWriter,\n notes: StyleNotes,\n context: Pick<StyleReadContext, \"budget\">,\n): { readonly node: ValueColumns; readonly edge: ValueColumns; readonly found: boolean } {\n let found = false;\n const read = (target: StyleTarget): ValueColumns => {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const out = valueColumns(n);\n if (!table.has(\"graphics\") && !table.has(\"LabelGraphics\") && writer.vocabulary !== \"cytoscape\") {\n return out.values;\n }\n for (let i = 0; i < n; i++) {\n context.budget.spend(target, 1);\n const at: At = (property) => ({ notes, target, property, element: i, budget: context.budget });\n readElement(\n target,\n cellOf(table, \"graphics\", i),\n cellOf(table, \"LabelGraphics\", i),\n cellOf(table, \"label\", i),\n writer,\n (property, value) => {\n if (value !== null) {\n found = true;\n out.put(i, property, value);\n }\n },\n at,\n );\n if (target === \"edge\") {\n const bends = lineBends(snapshot, cellOf(table, \"graphics\", i), i);\n if (bends !== null) {\n found = true;\n out.put(i, \"bends\", bends);\n }\n }\n }\n return out.values;\n };\n const node = read(\"node\");\n const edge = read(\"edge\");\n return { node, edge, found };\n}\n\n/**\n * The `graphty.styles` block of a file graphty wrote, with the per-element values its rules read moved inside it from\n * their `graphty_style_*` keys; the block as written when it is ignored anyway (graph-io then says why).\n * @param snapshot - the graph\n * @param text - the block's text\n * @returns the block's text for graph-io to read\n */\nfunction blockWithValues(snapshot: GraphSnapshot, text: string): string {\n const parsed = parseStyleBlock(text, styleFingerprint(snapshot));\n if (!parsed.ok || parsed.block.values !== undefined) {\n return text;\n }\n const node = tagValues(snapshot, \"node\", parsed.block.columns.node);\n const edge = tagValues(snapshot, \"edge\", parsed.block.columns.edge);\n if (node === null || edge === null) {\n // a style column is missing: graph-io ignores the block with a note\n return text;\n }\n const raw = JSON.parse(text) as Record<string, unknown>;\n return JSON.stringify({ ...raw, values: { node, edge } });\n}\n\n/**\n * The per-element values of a target's style columns, read from their `graphty_style_*` keys.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param keys - the style columns the block names\n * @returns the values by key, or null when a key is missing\n */\nfunction tagValues(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n keys: readonly string[],\n): Record<string, StyleColumn> | null {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const values: Record<string, StyleColumn> = {};\n for (const key of keys) {\n const name = tagKey(target, key);\n if (!table.has(name)) {\n return null;\n }\n values[key] = Array.from({ length: n }, (_, i) => {\n const v = plainCell(table.value(name, i));\n return typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\" ? v : null;\n });\n }\n return values;\n}\n\n/**\n * The columns of a table that hold styles: the graphics records and graphty's per-element style values.\n * @param table - the node or edge table\n * @returns the column names\n */\nfunction styleColumns(table: GraphSnapshot[\"nodes\"]): string[] {\n return [...table.names()].filter((c) => c === \"graphics\" || c === \"LabelGraphics\" || c.startsWith(TAG_PREFIX));\n}\n\n/**\n * The styles of a GML file, read the way the program that wrote it draws them, with that program's defaults beneath:\n * yEd, Cytoscape, Gephi and OGDF are recognized by the `Creator` line; igraph and every other writer get the GML\n * draft's keys and no defaults. A file graphty wrote gives back its `graphty.styles` block.\n * @param snapshot - the graph the import built\n * @param context - the work budget\n * @returns the styles, or null when the file has none\n */\nexport function gmlStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles | null {\n const notes = new StyleNotes();\n const writer = writerOf(snapshot);\n const values = readValues(snapshot, writer, notes, context);\n const blockText = graphText(snapshot, GML_STYLE_BLOCK_KEY);\n const block = blockText === null ? null : blockWithValues(snapshot, blockText);\n if (block !== null) {\n exactFromBlock(snapshot, block, values);\n }\n if (writer.tool === null && !values.found && block === null) {\n return null;\n }\n const gephi =\n writer.tool === \"gephi\"\n ? gephiRules(snapshot, values.node.fill, values.edge.color, context.budget, values.edge.width)\n : { rules: [], columns: new Map<string, StyleColumn>() };\n return {\n canonical: true,\n dialect: writer.dialect,\n tool: writer.tool,\n units: writer.units,\n node: { values: values.node },\n edge: { values: values.edge, rules: gephi.rules, columns: gephi.columns },\n notes: notes.list(),\n opacityInColor: true,\n block,\n // the graphics records and the per-element style values of a file graphty wrote hold styles, not data\n readFrom: { node: styleColumns(snapshot.nodes), edge: styleColumns(snapshot.edges) },\n };\n}\n\n// ============================================================ writing\n\n/**\n * What the GML writer holds natively: yEd GML `graphics` and `LabelGraphics`. The `graphty.styles` block and the\n * per-element values its rules read are keys of the graph and of each element.\n * @category Built-in formats\n */\nexport const GML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({\n node: Object.freeze([\n \"fill\",\n \"fillOpacity\",\n \"borderColor\",\n \"borderWidth\",\n \"borderStyle\",\n \"shape\",\n \"width\",\n \"height\",\n \"label\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"labelWeight\",\n \"labelItalic\",\n ] as const),\n edge: Object.freeze([\n \"color\",\n \"opacity\",\n \"width\",\n \"lineStyle\",\n \"sourceArrow\",\n \"targetArrow\",\n \"curved\",\n \"bends\",\n \"label\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"labelWeight\",\n \"labelItalic\",\n ] as const),\n block: \"native\",\n});\n\n/** Every style key a reader here reads, per record: the writer replaces them all. */\nconst OWNED: Readonly<Record<\"node\" | \"edge\" | \"label\", ReadonlySet<string>>> = {\n node: new Set([\n \"fill\",\n \"fill2\",\n \"hasFill\",\n \"outline\",\n \"hasOutline\",\n \"outlineWidth\",\n \"outline_width\",\n \"outlineStyle\",\n \"width\",\n \"line\",\n \"lineWidth\",\n \"stipple\",\n \"w\",\n \"h\",\n \"type\",\n ]),\n edge: new Set([\n \"fill\",\n \"width\",\n \"lineWidth\",\n \"style\",\n \"stipple\",\n \"arrow\",\n \"sourceArrow\",\n \"targetArrow\",\n \"source_arrow\",\n \"target_arrow\",\n \"smoothBends\",\n ]),\n label: new Set([\"text\", \"color\", \"fill\", \"fontSize\", \"fontName\", \"fontStyle\", \"visible\"]),\n};\n\n/** One element's value of a property. */\ntype Get = (property: string) => StyleValue | null;\n\n/** Records a value written as the nearest one yEd has. */\ntype Approximate = (property: string, value: StyleValue) => void;\n\n/**\n * A node's yEd `graphics` keys from its values.\n * @param get - the node's values\n * @param approximate - records approximations\n * @returns the keys\n */\nfunction nodeGraphics(get: Get, approximate: Approximate): Rec {\n const g: Rec = {};\n const width = get(\"width\");\n const height = get(\"height\");\n if (typeof width === \"number\") {\n g.w = width;\n }\n if (typeof height === \"number\") {\n g.h = height;\n }\n const shape = get(\"shape\");\n if (typeof shape === \"string\") {\n const w = yedValue(YED_SHAPES, shape, shape === \"vee\" ? \"triangle\" : \"rectangle\");\n if (!w.exact) {\n approximate(\"shape\", shape);\n }\n g.type = w.value;\n }\n const fill = get(\"fill\");\n const fillOpacity = get(\"fillOpacity\");\n if (typeof fill === \"string\") {\n g.fill = yedColor(fill, fillOpacity);\n } else if (fillOpacity === 0) {\n g.hasFill = 0;\n }\n const borderColor = get(\"borderColor\");\n const borderWidth = get(\"borderWidth\");\n const borderStyle = get(\"borderStyle\");\n if (typeof borderColor === \"string\") {\n g.outline = borderColor.toUpperCase();\n }\n if (typeof borderStyle === \"string\") {\n const w = yedValue(YED_LINES, borderStyle, \"line\");\n if (!w.exact) {\n approximate(\"borderStyle\", borderStyle);\n }\n g.outlineStyle = w.value;\n }\n if (borderWidth === 0) {\n g.hasOutline = 0;\n } else if (typeof borderWidth === \"number\") {\n g.outlineWidth = borderWidth;\n }\n return g;\n}\n\n/**\n * An edge's yEd `graphics` keys from its values.\n * @param get - the edge's values\n * @param approximate - records approximations\n * @returns the keys\n */\nfunction edgeGraphics(get: Get, approximate: Approximate): Rec {\n const g: Rec = {};\n const color = get(\"color\");\n if (typeof color === \"string\") {\n g.fill = yedColor(color, get(\"opacity\"));\n }\n const width = get(\"width\");\n if (typeof width === \"number\") {\n g.width = width;\n }\n const lineStyle = get(\"lineStyle\");\n if (typeof lineStyle === \"string\") {\n g.style = yedSpelled(\n YED_LINES,\n lineStyle,\n lineStyle === \"long-dash\" ? \"dashed\" : \"line\",\n \"lineStyle\",\n approximate,\n );\n }\n for (const property of [\"sourceArrow\", \"targetArrow\"]) {\n const arrow = get(property);\n if (typeof arrow === \"string\") {\n g[property] = yedSpelled(YED_ARROWS, arrow, \"standard\", property, approximate);\n }\n }\n const curved = get(\"curved\");\n if (typeof curved === \"boolean\") {\n g.smoothBends = curved ? 1 : 0;\n }\n return g;\n}\n\n/**\n * An element's yEd `LabelGraphics` keys from its values, or null when it has no label text.\n * @param get - the element's values\n * @returns the keys\n */\nfunction labelGraphics(get: Get): Rec | null {\n const text = get(\"label\");\n if (typeof text !== \"string\" || text.trim().length === 0) {\n return null;\n }\n const lg: Rec = { text };\n const color = get(\"labelColor\");\n if (typeof color === \"string\") {\n lg.color = color.toUpperCase();\n }\n const size = get(\"labelSize\");\n if (typeof size === \"number\") {\n lg.fontSize = size;\n }\n const font = get(\"labelFont\");\n if (typeof font === \"string\") {\n lg.fontName = font;\n }\n const weight = get(\"labelWeight\");\n const italic = get(\"labelItalic\");\n if (weight !== null || italic !== null) {\n const style = (weight === \"bold\" ? \"bold\" : \"\") + (italic === true ? \"italic\" : \"\");\n lg.fontStyle = style.length === 0 ? \"plain\" : style;\n }\n return lg;\n}\n\n/**\n * A record with the style keys replaced: the kept keys of the old record, then the written ones.\n * @param old - the record the element had, or anything else\n * @param owned - the style keys\n * @param written - the new style keys\n * @returns the record, or undefined (an unset cell) when it is empty\n */\nfunction merged(old: unknown, owned: ReadonlySet<string>, written: Rec): Rec | undefined {\n const out: Rec = {};\n if (isRec(old)) {\n for (const [k, v] of Object.entries(old)) {\n if (!owned.has(k)) {\n out[k] = v;\n }\n }\n }\n Object.assign(out, written);\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\n/**\n * An element's `LabelGraphics` value with its first label's style keys replaced; further labels are kept.\n * @param old - the value the element had\n * @param written - the new label keys, or null for no label\n * @returns the value, or undefined (an unset cell)\n */\nfunction mergedLabels(old: unknown, written: Rec | null): unknown {\n const labels = Array.isArray(old) ? old : [old];\n const head = merged(labels[0], OWNED.label, written ?? {});\n const rest = labels.slice(1).filter((l) => l !== null && l !== undefined);\n if (rest.length === 0) {\n return head;\n }\n return head === undefined ? rest : [head, ...rest];\n}\n\n/**\n * Each element's values of the properties the writer writes, as a getter per element.\n * @param picture - each element's value of a property\n * @param target - nodes or edges\n * @returns the getter\n */\nfunction getter(\n picture: (target: StyleTarget, property: string) => readonly (StyleValue | null)[],\n target: StyleTarget,\n): (i: number) => Get {\n const columns = new Map<string, readonly (StyleValue | null)[]>();\n for (const p of GML_STYLE_CAPABILITIES[target]) {\n columns.set(p, picture(target, p));\n }\n return (i) => (property) => columns.get(property)?.[i] ?? null;\n}\n\n/**\n * For a file graphty wrote: where a value read from the graphics is what the writer writes for the block's own value\n * (a pentagon written as a rectangle, an opacity rounded to 255 steps), the block's exact value is the truth, so a\n * re-import gives back the same rules; a value another program changed since stays the truth.\n * @param snapshot - the graph\n * @param text - the block's text\n * @param read - the values read, changed in place\n * @param read.node - the node values\n * @param read.edge - the edge values\n */\nfunction exactFromBlock(\n snapshot: GraphSnapshot,\n text: string,\n read: { readonly node: ValueColumns; readonly edge: ValueColumns },\n): void {\n const parsed = parseStyleBlock(text, styleFingerprint(snapshot));\n const ex = parsed.ok ? blockStyles(parsed.block, snapshot, \"gml\") : null;\n if (ex === null) {\n return;\n }\n const notes = new StyleNotes();\n for (const target of [\"node\", \"edge\"] as const) {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const get = getter((t, p) => resolveStyles(ex, t, p as never, snapshot), target);\n const values = read[target];\n for (let i = 0; i < n; i++) {\n const want = get(i);\n const back = writtenAndReadBack(target, want, notes);\n for (const property of GML_STYLE_CAPABILITIES[target]) {\n const native = values[property]?.[i] ?? null;\n const w = want(property);\n if (native !== w && native === (back.get(property) ?? null)) {\n values[property] ??= new Array<StyleValue | null>(n).fill(null);\n values[property][i] = w;\n }\n }\n }\n }\n}\n\n/**\n * An element's values written as the writer writes them and read back as the reader reads them.\n * @param target - nodes or edges\n * @param want - its values\n * @param notes - a scratch for the notes the round trip makes\n * @returns the values read back, by property\n */\nfunction writtenAndReadBack(target: StyleTarget, want: Get, notes: StyleNotes): Map<string, StyleValue> {\n const ignore: Approximate = () => undefined;\n const g = target === \"node\" ? nodeGraphics(want, ignore) : edgeGraphics(want, ignore);\n const back = new Map<string, StyleValue>();\n readElement(\n target,\n g,\n labelGraphics(want) ?? undefined,\n undefined,\n GRAPHTY_WRITER,\n (property, value) => {\n if (value !== null) {\n back.set(property, value);\n }\n },\n (property) => ({ notes, target, property }),\n );\n return back;\n}\n\n/** A GML export with styles worked out. */\ninterface GmlStyledExport {\n /** The graph to write: yEd graphics written from the styles, the block and the per-element style values added. */\n readonly snapshot: GraphSnapshot;\n /** W_STYLE_APPROXIMATED for every value written as the nearest one yEd has. */\n readonly notes: readonly LossNote[];\n}\n\n/**\n * Works out a GML export with styles: every node's and edge's `graphics` and `LabelGraphics` records get yEd's keys\n * for what graphty draws in place of every style key they had (positions, bends and other keys stay), the\n * `graphty.styles` block becomes the graph key `graphty_styles` and the per-element values its rules read become\n * element keys. Should two style columns map to one key, the values go inside the block instead.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles, or undefined when none are written\n * @returns the styled export, or null without styles\n */\nexport function gmlStyledExport(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput | undefined,\n): GmlStyledExport | null {\n if (input === undefined) {\n return null;\n }\n const approximated = new StyleApproximations();\n const out = snapshot.withColumns();\n const renames: LossNote[] = [];\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n writeGraphicsColumns(snapshot, input, target, table, approximated);\n // the per-element style values of an earlier write go; a data column the rules read, or any other whose key\n // would read back as a style value, is renamed out of the keys the style values take\n const read = dataRead(input.rules.styles.rules, target);\n for (const name of table.names().filter((c) => mangleGmlKey(c).startsWith(TAG_PREFIX))) {\n const col = table.get(name);\n table.remove(name);\n if (col !== null && !(name.startsWith(TAG_PREFIX) && !read.has(name))) {\n renames.push(renameDataColumn(table, target, name, col));\n }\n }\n }\n let { block } = input;\n const keys = [...input.rules.columns.node.keys()].map((k) => tagKey(\"node\", k));\n const edgeKeys = [...input.rules.columns.edge.keys()].map((k) => tagKey(\"edge\", k));\n if (new Set(keys).size !== keys.length || new Set(edgeKeys).size !== edgeKeys.length) {\n block = writeStyleBlock(input.rules, { inlineColumns: true, snapshot });\n } else {\n setTagColumns(out, input);\n }\n out.graph.set(GML_STYLE_BLOCK_KEY, [block], { dtype: \"string\" });\n const notes: LossNote[] = [\n ...renames,\n ...(block === input.block ? [] : styleBlockLosses(block, input.rules.styles.rules.length, \"size\")),\n ...approximated.notes(\"yEd's GML\"),\n ];\n return { snapshot: out, notes };\n}\n\n/**\n * Writes every element's `graphics` and `LabelGraphics` records of a target with yEd's keys for what graphty draws,\n * keeping the keys that are not style keys.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles\n * @param target - nodes or edges\n * @param table - the target's table being written, changed in place\n * @param approximated - where approximations are counted\n */\nfunction writeGraphicsColumns(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput,\n target: StyleTarget,\n table: GraphSnapshot[\"nodes\"],\n approximated: StyleApproximations,\n): void {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const approximate: Approximate = (property, value) => {\n approximated.add(target, property, value);\n };\n const get = getter((t, p) => input.picture(t, p as never), target);\n const graphics: unknown[] = [];\n const labels: unknown[] = [];\n for (let i = 0; i < n; i++) {\n const g = target === \"node\" ? nodeGraphics(get(i), approximate) : edgeGraphics(get(i), approximate);\n if (target === \"edge\") {\n const line = bendsLine(snapshot, get(i)(\"bends\"), i);\n if (line !== null) {\n g.Line = line;\n }\n }\n graphics.push(merged(cellOf(table, \"graphics\", i), OWNED[target], g));\n labels.push(mergedLabels(cellOf(table, \"LabelGraphics\", i), labelGraphics(get(i))));\n }\n for (const [name, cells] of [\n [\"graphics\", graphics],\n [\"LabelGraphics\", labels],\n ] as const) {\n if (cells.some((c) => c !== undefined)) {\n table.set(name, cells, { dtype: \"json\", nullable: true });\n } else if (table.has(name)) {\n table.remove(name);\n }\n }\n}\n\n/**\n * An edge's `Line` from its `bends` value: the node centers it is written between, with the bends placed between them,\n * so the bends read back as written.\n * @param snapshot - the graph handed to the exporter\n * @param bends - the edge's `bends` value\n * @param e - the edge's row\n * @returns the `Line` record, or null without a value or without both centers\n */\nfunction bendsLine(snapshot: GraphSnapshot, bends: StyleValue | null, e: number): Rec | null {\n const source = centerOf(snapshot, snapshot.edgeSource(e));\n const target = centerOf(snapshot, snapshot.edgeTarget(e));\n const points = typeof bends === \"string\" ? bendsToPoints(source, target, bends, true) : null;\n if (points === null || ![...source, ...target].every(Number.isFinite)) {\n return null;\n }\n return { point: [source, ...points, target].map(([x, y]) => ({ x, y })) };\n}\n\n/**\n * Writes a data column under a name out of the keys the style values take.\n * @param table - the table, changed in place\n * @param target - nodes or edges\n * @param name - the column's name\n * @param col - the column\n * @returns the note saying so\n */\nfunction renameDataColumn(\n table: GraphSnapshot[\"nodes\"],\n target: StyleTarget,\n name: string,\n col: NonNullable<ReturnType<GraphSnapshot[\"nodes\"][\"get\"]>>,\n): LossNote {\n let renamed = `data_${name}`;\n let k = 2;\n while (table.has(renamed)) {\n renamed = `data_${name}_${String(k)}`;\n k++;\n }\n table.set(renamed, col);\n return Object.freeze({\n code: KEY_MANGLED_CODE,\n message: `${target} column \"${name}\" is written as \"${renamed}\": keys starting with ${TAG_PREFIX} hold graphty's style values`,\n column: name,\n count: null,\n });\n}\n\n/**\n * Sets the per-element values the rules read as element keys.\n * @param out - the graph, changed in place\n * @param input - the styles\n */\nfunction setTagColumns(out: GraphSnapshot, input: ExporterStyleInput): void {\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n for (const [key, col] of input.rules.columns[target]) {\n const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));\n const text = kinds.size > 1 || kinds.has(\"string\");\n let dtype: \"string\" | \"bool\" | \"f64\" = kinds.has(\"boolean\") ? \"bool\" : \"f64\";\n if (text) {\n dtype = \"string\";\n }\n table.set(tagKey(target, key), text ? col.map((v) => (v === null ? null : String(v))) : col, { dtype });\n }\n }\n}\n","/**\n * The GML exporter (design section 8.5, research note 07 sections 2.2 and 9): writes a snapshot in\n * the NetworkX dialect of GML. Node ids must be integers (`idCharset: \"integer\"`; `sanitizeIds:\n * \"mangle\"` renumbers the others and keeps the original in a `graphty_originalId` key the importer\n * restores); columns are written per dtype (`int` for the integer dtypes, `real` with a decimal\n * point guaranteed for f32 / f64 so the dtype survives a re-import, quoted strings with `&#NN;`\n * references, repeated keys for lists with the `_networkx_list_start` marker for one-element\n * lists and `\"[]\"` for empty ones, nested records for json objects); the position role becomes\n * `graphics [ x y z ]` merged with the node's `graphics` json record; graph columns are written\n * inside `graph [ ]` (or at the top level when the importer found them there); `Creator` and\n * `Version` come from the metadata.\n *\n * check() reports, before anything is written, the capability gaps of the common check plus the\n * GML-specific ones: json columns holding numbers (JSON cannot keep the int / real distinction:\n * `W_GML_RECORD_NUMBER_TYPE`), booleans (written 1 / 0) or nulls (omitted), arrays nested in\n * arrays (no GML spelling; export() throws), column names and record keys that are not GML keys\n * or collide with the structural keys (`E_GML_INVALID_KEY` / `E_GML_RESERVED_KEY`, or\n * `W_GML_KEY_MANGLED` under `sanitizeKeys: \"mangle\"`), and graphics / position overlaps.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n GraphFormatError,\n type GraphSnapshot,\n type JsonColumn,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { DICT_SAMPLE_ROWS, DictHeuristic } from \"../../common/attributes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteGmlString } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n countMixedEdges,\n LOSS,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatGmlReal, formatInteger } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport type { ExporterStyleOptions } from \"../../styles/io/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { GML_STYLE_CAPABILITIES, gmlStyledExport } from \"./styles.js\";\nimport {\n EMPTY_LIST_TEXT,\n isGmlKey,\n KEY_MANGLED_CODE,\n LIST_START_MARKER,\n mangleGmlKey,\n ORIGINAL_ID_KEY,\n} from \"./syntax.js\";\n\n/** What the writer takes: the format's options, the common ones and the styles. */\ntype GmlWriteOptions = GmlExportOptions & CommonExportOptions & ExporterStyleOptions;\n\n/**\n * The format-specific options of the GML exporter.\n * @category Built-in formats\n */\nexport interface GmlExportOptions extends CommonExportOptions {\n /**\n * The edge key the weights are written under. The default is the key a GML import read them\n * from, else `value`.\n * @defaultValue as read, else \"value\"\n */\n weightKey?: string | undefined;\n /**\n * What to do with an attribute name or record key that GML cannot write: one that is not a GML\n * key (letters, digits and `_`, starting with a letter, so `Edge Label` is not one), or one that\n * GML uses itself in that record: `id` for a node attribute; `source`, `target` and `directed`\n * for an edge attribute; `node`, `edge`, `directed` and `multigraph` for a graph attribute. A node\n * attribute named `source` is fine. \"error\" makes the save fail, \"mangle\" rewrites the name (`.`\n * and other characters become `_`, a clash gets a `_2` suffix) and checkExport() lists each\n * rename. An options object shared by saves to several formats that include GML should set it.\n * @defaultValue \"error\"\n */\n sanitizeKeys?: \"error\" | \"mangle\" | undefined;\n}\n\n/**\n * A nested (json) attribute holds numbers; GML records do not keep the difference between integers and decimals.\n * @category Issue and loss codes\n */\nexport const RECORD_NUMBER_TYPE_CODE = \"W_GML_RECORD_NUMBER_TYPE\";\n/**\n * A json column holds booleans, written as 1 / 0.\n * @category Issue and loss codes\n */\nexport const RECORD_BOOLEAN_CODE = \"W_GML_RECORD_BOOLEAN\";\n/**\n * A json column holds nulls, which GML cannot write; the key (or the row) is omitted.\n * @category Issue and loss codes\n */\nexport const RECORD_NULL_CODE = \"W_GML_RECORD_NULL\";\n/**\n * An attribute holds an array inside an array, which GML cannot write; the save fails.\n * @category Issue and loss codes\n */\nexport const NESTED_ARRAY_CODE = \"E_GML_NESTED_ARRAY\";\n/**\n * A nested (json) attribute holds arrays; they are written as repeated keys and read back as a list attribute.\n * @category Issue and loss codes\n */\nexport const JSON_ARRAY_CODE = \"W_GML_JSON_ARRAY\";\n/**\n * A column name or record key is not a GML key; export() throws unless sanitizeKeys is \"mangle\".\n * @category Issue and loss codes\n */\nexport const INVALID_KEY_CODE = \"E_GML_INVALID_KEY\";\n/**\n * A column name collides with a structural GML key; export() throws unless sanitizeKeys is \"mangle\".\n * @category Issue and loss codes\n */\nexport const RESERVED_KEY_CODE = \"E_GML_RESERVED_KEY\";\nexport { KEY_MANGLED_CODE } from \"./syntax.js\";\n/**\n * A position column with more than three components; x, y and z are written.\n * @category Issue and loss codes\n */\nexport const POSITION_COMPONENTS_CODE = \"W_GML_POSITION_COMPONENTS\";\n/**\n * A node's graphics record has x / y / z keys the position column replaces.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_OVERRIDDEN_CODE = \"W_GML_GRAPHICS_OVERRIDDEN\";\n/**\n * A node's graphics value is not a record and cannot hold the position; export() throws.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_CONFLICT_CODE = \"E_GML_GRAPHICS_CONFLICT\";\n\n/**\n * The default weight key (design section 8.4: GML weights are read from `value` by default).\n * @category Plugin helpers\n */\nexport const DEFAULT_WEIGHT_KEY = \"value\";\n\n/** The roles GML has a key for (`label`, the edge `id` and `key`); every other role is reported. */\nconst KEPT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"key\"]);\n\n/** The key the importer maps each kept role back from (the column name after re-import). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"label\",\n id: \"id\",\n key: \"key\",\n});\n\nconst GML_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"integer\",\n dtypes: [\"i32\", \"f64\", \"string\", \"dict\", \"json\"],\n components: false,\n lists: true,\n json: true,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** Roles whose columns are never written as attributes (structural, or dropped per the capabilities). */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\nconst NODE_RESERVED: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_RESERVED: ReadonlySet<string> = new Set([\"source\", \"target\", \"directed\"]);\nconst GRAPH_RESERVED: ReadonlySet<string> = new Set([\"node\", \"edge\", \"directed\", \"multigraph\"]);\nconst TOP_RESERVED: ReadonlySet<string> = new Set([\"graph\"]);\nconst NUMBER_TEXT = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n/** The resolved options of one export. */\ninterface GmlExportPlan {\n readonly common: ResolvedExportOptions;\n readonly weightKey: string;\n readonly mangle: boolean;\n}\n\n/** What one json column holds that GML cannot write exactly. */\ninterface JsonStats {\n numbers: number;\n booleans: number;\n nulls: number;\n nestedArrays: number;\n arrays: number;\n invalidKeys: number;\n}\n\n/** The kinds of value already counted for one row while inspecting a json value. */\ninterface SeenFlags {\n numbers: boolean;\n booleans: boolean;\n nulls: boolean;\n nested: boolean;\n}\n\n/** The columns of one table selected for writing, with their keys. */\ninterface WrittenColumn {\n readonly column: Column;\n readonly key: string;\n}\n\n/**\n * Resolve the options of one export call.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planOf(snapshot: GraphSnapshot, options: (GmlExportOptions & CommonExportOptions) | undefined): GmlExportPlan {\n const common = resolveExportOptions(options);\n const mode = options?.sanitizeKeys ?? \"error\";\n if (mode !== \"error\" && mode !== \"mangle\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option sanitizeKeys: ${JSON.stringify(mode)} is not \"error\" or \"mangle\"`,\n {\n option: \"sanitizeKeys\",\n found: mode,\n },\n );\n }\n let weightKey = options?.weightKey;\n if (weightKey === undefined) {\n const origin = snapshot.meta.weightOrigin;\n weightKey = origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : DEFAULT_WEIGHT_KEY;\n } else if (typeof weightKey !== \"string\" || !isGmlKey(weightKey)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option weightKey: ${JSON.stringify(weightKey)} is not a GML key`, {\n option: \"weightKey\",\n found: weightKey,\n });\n }\n return { common, weightKey, mangle: mode === \"mangle\" };\n}\n\n/**\n * Whether a column is written as an attribute (its role is neither structural nor dropped).\n * @param column - the column\n * @returns true when written\n */\nfunction isWritten(column: Column): boolean {\n const { role } = column.meta;\n return role === null || !SKIPPED_ROLES.has(role);\n}\n\n/**\n * The key a column is written under.\n * @param meta - the column metadata\n * @returns origin.id when the column came from GML under that key (its name is the key, or the importer's\n * `<key>#...` rename of it), else the name: a column renamed since it was read is written under its new name\n */\nfunction preferredKey(meta: ColumnMeta): string {\n const { origin, name } = meta;\n if (origin?.format !== \"gml\" || origin.id === null) {\n return name;\n }\n return name === origin.id || name.startsWith(`${origin.id}#`) ? origin.id : name;\n}\n\n/**\n * Whether a snapshot has explicit weights to write.\n * @param snapshot - the snapshot\n * @returns true when weighted\n */\nfunction hasWeights(snapshot: GraphSnapshot): boolean {\n return snapshot.flags.weighted;\n}\n\n/**\n * Whether the graph column is a top-level key (the importer's `extra.gmlTopLevel`).\n * @param column - the column\n * @returns true for a top-level key\n */\nfunction isTopLevel(column: Column): boolean {\n return column.meta.extra.gmlTopLevel === true;\n}\n\n/**\n * The text of a `Version` value: bare when it is a number text, quoted otherwise.\n * @param text - the version text\n * @returns the GML value\n */\nfunction versionText(text: string): string {\n return NUMBER_TEXT.test(text) ? text : quoteGmlString(text);\n}\n\n/**\n * A node or edge table's label role column, which is written under \"label\" (the key the importer\n * gives the role back to): the key is marked used so a plain column of that name cannot have it.\n * @param columns - the written columns\n * @param label - the table name\n * @param used - the keys already taken, gaining \"label\" when there is a label role column\n * @returns the label role column, or undefined\n */\nfunction labelRoleColumn(columns: readonly Column[], label: string, used: Set<string>): Column | undefined {\n if (label !== \"node\" && label !== \"edge\") {\n return undefined;\n }\n const column = columns.find((c) => c.meta.role === \"label\");\n if (column !== undefined) {\n used.add(\"label\");\n }\n return column;\n}\n\n/**\n * Select the written columns of a table and assign their keys, recording invalid and reserved\n * keys as notes (or rewriting them under mangle).\n * @param table - the columns\n * @param reserved - the structural keys of the table\n * @param label - the table name for messages\n * @param plan - the export plan\n * @param notes - where to record\n * @param filter - an extra selection predicate\n * @returns the written columns with their keys\n */\nfunction selectColumns(\n table: Iterable<Column>,\n reserved: ReadonlySet<string>,\n label: string,\n plan: GmlExportPlan,\n notes: LossNote[] | null,\n filter: (column: Column) => boolean = (): boolean => true,\n): WrittenColumn[] {\n const used = new Set<string>(reserved);\n const out: WrittenColumn[] = [];\n const columns = [...table].filter((c) => isWritten(c) && filter(c));\n const labelRole = labelRoleColumn(columns, label, used);\n for (const column of columns) {\n const preferred = column === labelRole ? \"label\" : preferredKey(column.meta);\n let key = preferred;\n const valid = isGmlKey(preferred);\n const taken = column !== labelRole && used.has(preferred);\n if (!valid || taken) {\n const code = valid ? RESERVED_KEY_CODE : INVALID_KEY_CODE;\n let why = \"is not a GML key\";\n if (valid) {\n why = reserved.has(preferred) ? \"collides with a structural GML key\" : \"repeats another column's key\";\n }\n if (!plan.mangle) {\n if (notes === null) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `${label} column \"${column.meta.name}\" ${why}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column: column.meta.name,\n key: preferred,\n },\n );\n }\n notes.push(\n note(\n code,\n `${label} column \"${column.meta.name}\" ${why}; the save fails unless sanitizeKeys is \"mangle\"`,\n column.meta.name,\n ),\n );\n continue;\n }\n key = uniqueKey(valid ? preferred : mangleGmlKey(preferred), used);\n notes?.push(\n note(\n KEY_MANGLED_CODE,\n `${label} column \"${column.meta.name}\" is written as \"${key}\"`,\n column.meta.name,\n ),\n );\n }\n used.add(key);\n out.push({ column, key });\n }\n return out;\n}\n\n/**\n * A key not yet used: the base, else base_2, base_3...\n * @param base - a valid key\n * @param used - the keys taken\n * @returns a free key\n */\nfunction uniqueKey(base: string, used: ReadonlySet<string>): string {\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n return candidate;\n}\n\n/**\n * Build a frozen note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n * @returns the note\n */\nfunction note(code: string, message: string, column: string | null = null, count: number | null = null): LossNote {\n return Object.freeze({ code, message, column, count });\n}\n\n/**\n * Count a kind of json value once per row.\n * @param seen - the flags already counted for this row\n * @param flag - the flag of the kind\n * @param stats - the counters\n * @param counter - the counter of the kind\n */\nfunction countOnce(seen: SeenFlags, flag: keyof SeenFlags, stats: JsonStats, counter: keyof JsonStats): void {\n if (!seen[flag]) {\n seen[flag] = true;\n stats[counter]++;\n }\n}\n\n/**\n * Inspect a JSON value for what GML cannot write exactly.\n * @param value - the value\n * @param stats - the counters to update (each counted at most once per call for numbers / booleans / nulls)\n * @param inArray - whether the value is an array item\n * @param seen - the flags already counted for this row\n */\nfunction inspectJson(value: unknown, stats: JsonStats, inArray: boolean, seen: SeenFlags): void {\n if (value === null) {\n countOnce(seen, \"nulls\", stats, \"nulls\");\n return;\n }\n switch (typeof value) {\n case \"number\":\n countOnce(seen, \"numbers\", stats, \"numbers\");\n return;\n case \"boolean\":\n countOnce(seen, \"booleans\", stats, \"booleans\");\n return;\n case \"string\":\n return;\n default:\n break;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n countOnce(seen, \"nested\", stats, \"nestedArrays\");\n }\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n return;\n }\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!isGmlKey(key)) {\n stats.invalidKeys++;\n }\n inspectJson(record[key], stats, false, seen);\n }\n}\n\n/**\n * A row count in words.\n * @param count - the count\n * @returns the count and the word row, pluralised\n */\nfunction rowCount(count: number): string {\n return `${count} row${plural(count)}`;\n}\n\n/**\n * Record a note for a counter that is not zero.\n * @param notes - where to record\n * @param count - the counter\n * @param code - the note code\n * @param text - the note message\n * @param column - the column name\n */\nfunction pushCounted(notes: LossNote[], count: number, code: string, text: string, column: string): void {\n if (count > 0) {\n notes.push(note(code, text, column, count));\n }\n}\n\n/**\n * The GML-specific notes of one table's json columns.\n * @param columns - the written columns\n * @param label - the table name\n * @param plan - the export plan\n * @param notes - where to record\n */\nfunction jsonNotes(columns: readonly WrittenColumn[], label: string, plan: GmlExportPlan, notes: LossNote[]): void {\n for (const { column } of columns) {\n const stats = jsonStatsOf(column);\n if (stats === null) {\n continue;\n }\n const { name } = column.meta;\n const where = `${label} column \"${name}\"`;\n const counted = (count: number, code: string, text: string): void => {\n pushCounted(notes, count, code, text, name);\n };\n counted(\n stats.numbers,\n RECORD_NUMBER_TYPE_CODE,\n `${where} holds numbers in ${rowCount(stats.numbers)}; GML records cannot keep the int / real distinction`,\n );\n counted(\n stats.booleans,\n RECORD_BOOLEAN_CODE,\n `${where} holds booleans in ${rowCount(stats.booleans)}; written as 1 / 0`,\n );\n counted(\n stats.nulls,\n RECORD_NULL_CODE,\n `${where} holds nulls in ${rowCount(stats.nulls)}; GML has no null, the key is omitted`,\n );\n counted(\n stats.arrays,\n JSON_ARRAY_CODE,\n `${where} holds arrays as values in ${rowCount(stats.arrays)}; written as repeated keys, they re-import as a list`,\n );\n counted(\n stats.nestedArrays,\n NESTED_ARRAY_CODE,\n `${where} holds arrays nested in arrays in ${rowCount(stats.nestedArrays)}; GML cannot write them and the save fails`,\n );\n const keys = `${stats.invalidKeys} record key${plural(stats.invalidKeys)} ${agree(stats.invalidKeys, \"is\", \"are\")} not GML keys`;\n counted(\n stats.invalidKeys,\n plan.mangle ? KEY_MANGLED_CODE : INVALID_KEY_CODE,\n plan.mangle\n ? `${where}: ${keys} and are rewritten`\n : `${where}: ${keys}; the save fails unless sanitizeKeys is \"mangle\"`,\n );\n }\n}\n\n/**\n * The json statistics of a json column, or of a list column with json items; null for other dtypes.\n * @param column - the column\n * @returns the stats, or null\n */\nfunction jsonStatsOf(column: Column): JsonStats | null {\n const stats: JsonStats = { numbers: 0, booleans: 0, nulls: 0, nestedArrays: 0, arrays: 0, invalidKeys: 0 };\n if (column.dtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const value = column.values[r];\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n if (Array.isArray(value)) {\n stats.arrays++;\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n } else {\n inspectJson(value, stats, false, seen);\n }\n }\n return stats;\n }\n if (column.dtype === \"list\" && column.meta.itemDtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n for (const item of column.sliceOf(r)) {\n inspectJson(item, stats, true, seen);\n }\n }\n return stats;\n }\n return null;\n}\n\n/**\n * The node position column when it can be mapped to graphics x / y / z: a numeric scalar column\n * with the position role.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction positionColumn(snapshot: GraphSnapshot): Column | null {\n const column = snapshot.nodes.byRole(\"position\");\n if (column === null) {\n return null;\n }\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return column;\n default:\n return null;\n }\n}\n\n/**\n * The node `graphics` json column, when present.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction graphicsColumn(snapshot: GraphSnapshot): JsonColumn | null {\n return snapshot.nodes.typed(\"graphics\", \"json\");\n}\n\n/**\n * The GML-specific notes about the position / graphics mapping.\n * @param snapshot - the snapshot\n * @param notes - where to record\n */\nfunction graphicsNotes(snapshot: GraphSnapshot, notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n if (position.meta.components > 3) {\n notes.push(\n note(\n POSITION_COMPONENTS_CODE,\n `node column \"${position.meta.name}\" has ${position.meta.components} components; only x, y and z are written`,\n position.meta.name,\n position.length - position.nullCount,\n ),\n );\n }\n const graphics = graphicsColumn(snapshot);\n if (graphics === null) {\n return;\n }\n let overridden = 0;\n let conflicts = 0;\n for (let r = 0; r < snapshot.nodeCount; r++) {\n if (!position.isSet(r) || !graphics.isSet(r)) {\n continue;\n }\n const value = graphics.values[r];\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n conflicts++;\n } else if (\"x\" in value || \"y\" in value || \"z\" in value) {\n overridden++;\n }\n }\n if (overridden > 0) {\n notes.push(\n note(\n GRAPHICS_OVERRIDDEN_CODE,\n `${overridden} node graphics record${plural(overridden)} ${agree(overridden, \"has\", \"have\")} x / y / z keys the position column replaces`,\n \"graphics\",\n overridden,\n ),\n );\n }\n if (conflicts > 0) {\n notes.push(\n note(\n GRAPHICS_CONFLICT_CODE,\n `${conflicts} node graphics value${plural(conflicts)} ${agree(conflicts, \"is\", \"are\")} not records and cannot hold the position; the save fails`,\n \"graphics\",\n conflicts,\n ),\n );\n }\n}\n\n/**\n * What the importer's own rules change on re-import of the written columns: an all-unset column\n * vanishes (GML writes cells, never declarations), a role-less column named like a role key\n * gains the role, and the dictionary heuristic of design section 5.4 turns a low-cardinality\n * string column into a dict (or a wide dict into a string).\n * @param columns - the written columns\n * @param domain - node or edge\n * @param notes - where to record\n */\nfunction reimportNotes(columns: readonly WrittenColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, key } of columns) {\n const { meta } = column;\n const set = column.length - column.nullCount;\n if (set === 0) {\n notes.push(\n note(\n LOSS.EMPTY_COLUMN,\n `${domain} column \"${meta.name}\" has no set cell and is not written: GML writes cells, never declarations`,\n meta.name,\n 0,\n ),\n );\n continue;\n }\n if (meta.role === null && (key === \"label\" || (domain === \"edge\" && (key === \"id\" || key === \"key\")))) {\n notes.push(\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${meta.name}\" is written under \"${key}\" and reads back with the ${key === \"label\" ? \"label\" : key} role`,\n meta.name,\n set,\n ),\n );\n continue;\n }\n if (column.dtype === \"list\" || !(column.dtype === \"string\" || column.dtype === \"dict\")) {\n continue;\n }\n const heuristic = new DictHeuristic(DICT_SAMPLE_ROWS);\n for (let r = 0; r < column.length && !heuristic.decided; r++) {\n if (column.isSet(r)) {\n heuristic.observe(column.value(r) as string);\n }\n }\n const readsAsDict = heuristic.decide() === \"dict\";\n if (column.dtype === \"string\" && readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as dict (low cardinality)`,\n meta.name,\n null,\n ),\n );\n } else if (column.dtype === \"dict\" && !readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as string (cardinality too high for a dict)`,\n meta.name,\n null,\n ),\n );\n }\n }\n}\n\n/**\n * The importer names the graphics-derived position column `position`, or `position#graphics`\n * when a plain `position` key is written next to it (design section 5.6); a position column\n * named otherwise reads back under that name.\n * @param snapshot - the snapshot\n * @param nodeColumns - the written node columns\n * @param notes - where to record\n */\nfunction positionNameNote(snapshot: GraphSnapshot, nodeColumns: readonly WrittenColumn[], notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n const { name } = position.meta;\n const plainPosition = nodeColumns.some((c) => c.key === \"position\");\n const reimportName = plainPosition ? \"position#graphics\" : \"position\";\n if (name !== reimportName) {\n notes.push(\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `node column \"${name}\" (position) is written as the graphics x / y / z keys and reads back as \"${reimportName}\"`,\n name,\n position.length - position.nullCount,\n ),\n );\n }\n}\n\n/**\n * Pre-flight: the common capability notes plus the GML-specific ones.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\nfunction check(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planOf(snapshot, options);\n const notes = checkCapabilities(snapshot, GML_CAPABILITIES, plan.common, {\n positionDtype: \"f64\",\n roles: KEPT_ROLES,\n roleNames: ROLE_NAMES,\n });\n const nodeReserved = new Set(NODE_RESERVED);\n if (\n (plan.common.sanitizeIds === \"mangle\" && countMangled(snapshot) > 0) ||\n snapshot.nodes.byRole(\"originalId\") !== null\n ) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n const nodeColumns = selectColumns(snapshot.nodes, nodeReserved, \"node\", plan, notes);\n const edgeColumns = selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, notes, (c) => c !== edgeIds);\n const graphColumns = selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, notes, (c) => !isTopLevel(c));\n const topColumns = selectColumns(snapshot.graph, topReserved, \"top-level\", plan, notes, isTopLevel);\n jsonNotes(nodeColumns, \"node\", plan, notes);\n jsonNotes(edgeColumns, \"edge\", plan, notes);\n jsonNotes(graphColumns, \"graph\", plan, notes);\n jsonNotes(topColumns, \"top-level\", plan, notes);\n graphicsNotes(snapshot, notes);\n positionNameNote(snapshot, nodeColumns, notes);\n reimportNotes(nodeColumns, \"node\", notes);\n reimportNotes(edgeColumns, \"edge\", notes);\n if (!hasWeights(snapshot)) {\n const clash = edgeColumns.find((c) => c.key === plan.weightKey);\n if (clash !== undefined) {\n notes.push(\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${clash.column.meta.name}\" is written under \"${plan.weightKey}\", the key the importer reads edge weights from; it reads back as the weight, not as a column`,\n clash.column.meta.name,\n clash.column.length - clash.column.nullCount,\n ),\n );\n }\n }\n const folding = pairFolding(snapshot);\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two directed edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n ),\n );\n }\n return Object.freeze(notes);\n}\n\n/**\n * The structural keys of the edge table: source, target, the weight key when weights are written,\n * and `id` when a role-id column is written as the edge id.\n * @param snapshot - the snapshot\n * @param plan - the export plan\n * @param edgeIds - the role-id edge column, or null\n * @returns the reserved keys\n */\nfunction edgeReservedKeys(snapshot: GraphSnapshot, plan: GmlExportPlan, edgeIds: Column | null): Set<string> {\n const reserved = new Set(EDGE_RESERVED);\n if (hasWeights(snapshot)) {\n reserved.add(plan.weightKey);\n }\n if (edgeIds !== null) {\n reserved.add(\"id\");\n }\n return reserved;\n}\n\n/**\n * The structural keys of the top level: graph, plus Creator and Version when the metadata writes them.\n * @param snapshot - the snapshot\n * @returns the reserved keys\n */\nfunction topReservedKeys(snapshot: GraphSnapshot): Set<string> {\n const reserved = new Set(TOP_RESERVED);\n if (snapshot.meta.creator !== null) {\n reserved.add(\"Creator\");\n }\n if (snapshot.meta.sourceFormat === \"gml\" && snapshot.meta.sourceVersion !== null) {\n reserved.add(\"Version\");\n }\n return reserved;\n}\n\n/**\n * How many node ids are not safe integers (what sanitizeIds \"mangle\" rewrites).\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countMangled(snapshot: GraphSnapshot): number {\n let count = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id !== \"number\" || !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n// ============================================================ writing\n\n/**\n * The GML text of a number by the dtype and origin of its column: an integer text for the integer\n * dtypes and for an f64 column that came from GML `int` values, a real text otherwise.\n * @param value - the value\n * @param meta - the column metadata\n * @returns the text\n */\nfunction numberText(value: number, meta: ColumnMeta): string {\n switch (meta.dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return formatGmlReal(value, \"f32\");\n default:\n if (meta.origin?.type === \"int\" && Number.isInteger(value)) {\n return formatInteger(value);\n }\n return formatGmlReal(value, \"f64\");\n }\n}\n\n/**\n * The GML text of a JSON scalar inside a record: integers as int, other numbers as real, strings\n * quoted, booleans as 1 / 0.\n * @param value - the scalar\n * @returns the text\n */\nfunction jsonScalarText(value: number | string | boolean): string {\n switch (typeof value) {\n case \"number\":\n return Number.isInteger(value) ? formatInteger(value) : formatGmlReal(value, \"f64\");\n case \"boolean\":\n return value ? \"1\" : \"0\";\n default:\n return quoteGmlString(value);\n }\n}\n\n/**\n * The GML text of a list item or components lane by the item dtype.\n * @param item - the item\n * @param itemDtype - the list's item dtype\n * @param meta - the list column metadata\n * @returns the text\n */\nfunction itemText(item: unknown, itemDtype: string, meta: ColumnMeta): string {\n switch (typeof item) {\n case \"number\":\n switch (itemDtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(item);\n case \"f32\":\n return formatGmlReal(item, \"f32\");\n case \"json\":\n return jsonScalarText(item);\n default:\n return meta.origin?.type === \"int\" && Number.isInteger(item)\n ? formatInteger(item)\n : formatGmlReal(item, \"f64\");\n }\n case \"boolean\":\n return item ? \"1\" : \"0\";\n case \"string\":\n return quoteGmlString(item);\n default:\n throw new GraphFormatError(\n \"E_COLUMN_TYPE\",\n `column \"${meta.name}\": a ${typeof item} list item cannot be written as GML`,\n {\n column: meta.name,\n found: typeof item,\n },\n );\n }\n}\n\n/** Writes lines with indentation into an array of parts. */\nclass GmlWriter {\n private readonly lines: string[] = [];\n\n private readonly mangle: boolean;\n\n /**\n * Create a writer.\n * @param mangle - whether record keys are rewritten rather than refused\n */\n constructor(mangle: boolean) {\n this.mangle = mangle;\n }\n\n /**\n * Take the lines written so far as one string.\n * @returns the text; the writer is empty afterwards\n */\n take(): string {\n const text = this.lines.join(\"\");\n this.lines.length = 0;\n return text;\n }\n\n /**\n * Write one `key value` line.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value text\n */\n line(indent: string, key: string, value: string): void {\n this.lines.push(`${indent}${key} ${value}\\n`);\n }\n\n /**\n * Write a raw line.\n * @param text - the line without its terminator\n */\n raw(text: string): void {\n this.lines.push(`${text}\\n`);\n }\n\n /**\n * Write one column cell of a row.\n * @param indent - the indentation\n * @param key - the key\n * @param column - the column\n * @param row - the row\n */\n cell(indent: string, key: string, column: Column, row: number): void {\n const { meta, dtype } = column;\n switch (dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const { components } = meta;\n if (components === 1) {\n this.line(indent, key, numberText(column.data[row], meta));\n } else {\n for (let k = 0; k < components; k++) {\n this.line(indent, key, numberText(column.data[row * components + k], meta));\n }\n }\n return;\n }\n case \"bool\":\n this.line(indent, key, column.value(row) === true ? \"1\" : \"0\");\n return;\n case \"dict\":\n case \"string\":\n this.line(indent, key, quoteGmlString(column.value(row) ?? \"\"));\n return;\n case \"list\":\n this.list(indent, key, column.sliceOf(row), meta.itemDtype ?? \"string\", meta);\n return;\n case \"json\":\n this.json(indent, key, column.values[row], meta.name);\n return;\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n }\n\n /**\n * Write a list as repeated keys with the NetworkX conventions.\n * @param indent - the indentation\n * @param key - the key\n * @param items - the items\n * @param itemDtype - the item dtype\n * @param meta - the column metadata\n */\n private list(indent: string, key: string, items: readonly unknown[], itemDtype: string, meta: ColumnMeta): void {\n if (items.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (items.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of items) {\n if (itemDtype === \"json\" && typeof item === \"object\") {\n this.json(indent, key, item, meta.name, true);\n } else {\n this.line(indent, key, itemText(item, itemDtype, meta));\n }\n }\n }\n\n /**\n * Write a JSON value: a record for an object, repeated keys for an array, a scalar otherwise;\n * null writes nothing.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value\n * @param column - the column name, for errors\n * @param inArray - whether the value is an array item (an array here has no GML spelling)\n */\n private json(indent: string, key: string, value: unknown, column: string, inArray = false): void {\n if (value === null || value === undefined) {\n return;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": an array nested in an array cannot be written as GML`,\n {\n reason: \"nested array\",\n column,\n },\n );\n }\n if (value.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (value.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of value) {\n this.json(indent, key, item, column, true);\n }\n return;\n }\n if (typeof value === \"object\") {\n this.record(indent, key, value as Record<string, unknown>, column);\n return;\n }\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") {\n this.line(indent, key, jsonScalarText(value));\n return;\n }\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `column \"${column}\": a ${typeof value} cannot be written as GML`, {\n column,\n found: typeof value,\n });\n }\n\n /**\n * Write a record `key [ ... ]`.\n * @param indent - the indentation\n * @param key - the key\n * @param record - the object\n * @param column - the column name, for errors\n * @param extra - lines to write first (the position of a graphics record), or null\n */\n record(\n indent: string,\n key: string,\n record: Record<string, unknown>,\n column: string,\n extra: readonly [string, string][] | null = null,\n ): void {\n this.raw(`${indent}${key} [`);\n const inner = `${indent} `;\n const used = new Set<string>();\n if (extra !== null) {\n for (const [k, v] of extra) {\n this.line(inner, k, v);\n used.add(k);\n }\n }\n for (const name of Object.keys(record)) {\n if (used.has(name) && extra !== null && (name === \"x\" || name === \"y\" || name === \"z\")) {\n continue;\n }\n const written = this.recordKey(name, used, column);\n used.add(written);\n this.json(inner, written, record[name], column);\n }\n this.raw(`${indent}]`);\n }\n\n /**\n * The key a record field is written under.\n * @param name - the field name\n * @param used - the keys already written in the record\n * @param column - the column name, for errors\n * @returns a valid, unused key; E_UNSUPPORTED for an invalid key unless mangling\n */\n private recordKey(name: string, used: ReadonlySet<string>, column: string): string {\n if (isGmlKey(name) && !used.has(name)) {\n return name;\n }\n if (!this.mangle) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": record key \"${name}\" ${isGmlKey(name) ? \"repeats a key\" : \"is not a GML key\"}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column,\n key: name,\n },\n );\n }\n return uniqueKey(isGmlKey(name) ? name : mangleGmlKey(name), used);\n }\n}\n\n/** Everything the writer needs, resolved once before the first line. */\ninterface WriteContext {\n readonly snapshot: GraphSnapshot;\n readonly plan: GmlExportPlan;\n readonly ids: SanitizedIds;\n readonly writeDirected: boolean;\n readonly foldPairs: boolean;\n readonly nodeColumns: readonly WrittenColumn[];\n readonly edgeColumns: readonly WrittenColumn[];\n readonly graphColumns: readonly WrittenColumn[];\n readonly topColumns: readonly WrittenColumn[];\n readonly position: Column | null;\n readonly graphics: JsonColumn | null;\n readonly originalIds: Column | null;\n readonly edgeIds: Column | null;\n readonly weights: ExplicitWeights;\n readonly folding: PairFolding;\n}\n\n/**\n * Resolve everything export() needs, throwing for what check() reported as an error.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the context\n */\nfunction contextOf(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): WriteContext {\n const plan = planOf(snapshot, options);\n const ids = sanitizeIds(snapshot, \"integer\", plan.common.sanitizeIds);\n const mixed = countMixedEdges(snapshot);\n if (mixed > 0 && plan.common.onMixedDirection === \"error\") {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${mixed} undirected edge${plural(mixed)} in a directed graph, and GML holds one direction per file, so the save fails unless onMixedDirection is \"directed\" or \"undirected\"`,\n {\n reason: \"mixed direction\",\n count: mixed,\n },\n );\n }\n // design 8.5: exporters fold expanded pairs back; under \"directed\" the folded edge is written\n // once, as one directed edge, under \"undirected\" the whole graph is written undirected\n const foldPairs = mixed > 0;\n const writeDirected = snapshot.directed && plan.common.onMixedDirection !== \"undirected\";\n const originalIds = snapshot.nodes.byRole(\"originalId\");\n const nodeReserved = new Set(NODE_RESERVED);\n if (ids.changed > 0 || originalIds !== null) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n return {\n snapshot,\n plan,\n ids,\n writeDirected,\n foldPairs,\n nodeColumns: selectColumns(\n snapshot.nodes,\n nodeReserved,\n \"node\",\n plan,\n null,\n (c) => !(c.meta.name === \"graphics\" && c.dtype === \"json\"),\n ),\n edgeColumns: selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, null, (c) => c !== edgeIds),\n graphColumns: selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, null, (c) => !isTopLevel(c)),\n topColumns: selectColumns(snapshot.graph, topReserved, \"top-level\", plan, null, isTopLevel),\n position: positionColumn(snapshot),\n graphics: graphicsColumn(snapshot),\n originalIds,\n edgeIds,\n weights: explicitWeights(snapshot),\n folding: pairFolding(snapshot),\n };\n}\n\n/**\n * The GML text of an id written into `graphty_originalId`: quoted for a string, a number text\n * otherwise (an integer as int, else real, so the importer restores the same typed value).\n * @param id - the original id\n * @returns the text\n */\nfunction originalIdText(id: NodeId): string {\n if (typeof id === \"string\") {\n return quoteGmlString(id);\n }\n return Number.isSafeInteger(id) ? formatInteger(id) : formatGmlReal(id, \"f64\");\n}\n\n/**\n * The parts of the document.\n * @param context - the resolved context\n * @yields one string per header line, node or edge\n * @returns nothing\n */\nfunction* gmlParts(context: WriteContext): Generator<string, void, undefined> {\n const { snapshot, plan, ids } = context;\n const w = new GmlWriter(plan.mangle);\n const { meta } = snapshot;\n if (meta.creator !== null) {\n w.line(\"\", \"Creator\", quoteGmlString(meta.creator));\n }\n if (meta.sourceFormat === \"gml\" && meta.sourceVersion !== null) {\n w.line(\"\", \"Version\", versionText(meta.sourceVersion));\n }\n for (const { column, key } of context.topColumns) {\n if (column.isSet(0)) {\n w.cell(\"\", key, column, 0);\n }\n }\n w.raw(\"graph [\");\n w.line(\" \", \"directed\", context.writeDirected ? \"1\" : \"0\");\n const multigraph = meta.declaredMultigraph ?? (snapshot.flags.multigraph ? true : null);\n if (multigraph !== null) {\n w.line(\" \", \"multigraph\", multigraph ? \"1\" : \"0\");\n }\n for (const { column, key } of context.graphColumns) {\n if (column.isSet(0)) {\n w.cell(\" \", key, column, 0);\n }\n }\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.raw(\" node [\");\n w.line(\" \", \"id\", formatInteger(ids.idAt(i) as number));\n if (ids.isChanged(i)) {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(ids.originalAt(i)));\n } else if (context.originalIds?.isSet(i)) {\n const original = context.originalIds.value(i);\n if (typeof original === \"string\" || typeof original === \"number\") {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(original));\n }\n }\n for (const { column, key } of context.nodeColumns) {\n if (column.isSet(i)) {\n w.cell(\" \", key, column, i);\n }\n }\n writeGraphics(w, context, i);\n w.raw(\" ]\");\n yield w.take();\n }\n const el = snapshot.edgeList();\n const origin = meta.weightOrigin;\n const integerWeights = origin !== null && origin.type === \"int\";\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (context.foldPairs && context.folding.folded(e)) {\n continue;\n }\n w.raw(\" edge [\");\n w.line(\" \", \"source\", formatInteger(ids.idAt(el.src[e]) as number));\n w.line(\" \", \"target\", formatInteger(ids.idAt(el.dst[e]) as number));\n if (context.edgeIds?.isSet(e)) {\n w.cell(\" \", \"id\", context.edgeIds, e);\n }\n if (context.weights.isExplicit(e)) {\n const weight = context.weights.value(e);\n const text =\n integerWeights && Number.isInteger(weight)\n ? formatInteger(weight)\n : formatGmlReal(weight, context.weights.dtype);\n w.line(\" \", plan.weightKey, text);\n }\n for (const { column, key } of context.edgeColumns) {\n if (column.isSet(e)) {\n w.cell(\" \", key, column, e);\n }\n }\n w.raw(\" ]\");\n yield w.take();\n }\n w.raw(\"]\");\n yield w.take();\n}\n\n/**\n * Write a node's `graphics [ ... ]` record from the position column and the graphics json column.\n * @param w - the writer\n * @param context - the context\n * @param i - the node\n */\nfunction writeGraphics(w: GmlWriter, context: WriteContext, i: number): void {\n const { position, graphics } = context;\n const hasPosition = position?.isSet(i) === true;\n const graphicsValue = graphics?.isSet(i) ? graphics.values[i] : undefined;\n if (!hasPosition) {\n if (graphics !== null && graphicsValue !== undefined) {\n w.cell(\" \", \"graphics\", graphics, i);\n }\n return;\n }\n const numeric = position as Column & { readonly data: ArrayLike<number> };\n const { components } = numeric.meta;\n const lanes = Math.min(components, 3);\n const extra: [string, string][] = [];\n const names = [\"x\", \"y\", \"z\"];\n for (let k = 0; k < lanes; k++) {\n extra.push([names[k], numberText(numeric.data[i * components + k], numeric.meta)]);\n }\n let record: Record<string, unknown> = {};\n if (graphicsValue !== undefined) {\n if (typeof graphicsValue !== \"object\" || graphicsValue === null || Array.isArray(graphicsValue)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `node ${i}: the graphics value is not a record and cannot hold the position`,\n {\n reason: \"graphics conflict\",\n node: i,\n },\n );\n }\n record = graphicsValue as Record<string, unknown>;\n }\n w.record(\" \", \"graphics\", record, \"graphics\", extra);\n}\n\n/**\n * The GML exporter plugin.\n * @category Built-in formats\n */\nexport const gmlExporter: GraphExporter<GmlExportOptions> = Object.freeze({\n format: \"gml\",\n options: Object.freeze([\"sanitizeKeys\", \"weightKey\"]),\n capabilities: GML_CAPABILITIES,\n styles: Object.freeze({ capabilities: GML_STYLE_CAPABILITIES }),\n /**\n * Pre-flight: the common capability notes, the GML-specific ones and, with styles, the values written as the\n * nearest ones yEd's GML has.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: GmlWriteOptions): readonly LossNote[] {\n const styled = gmlStyledExport(snapshot, options?.styles);\n if (styled === null) {\n return check(snapshot, options);\n }\n return Object.freeze([...check(styled.snapshot, options), ...styled.notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks; the context is resolved on the first pull, so the\n * errors check() announced surface from the iteration.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GmlWriteOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(lazyParts(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GmlWriteOptions): Promise<string> {\n return joinText(lazyParts(snapshot, options));\n },\n});\n\n/**\n * The document parts, with the context resolved when iteration starts.\n * @param snapshot - the snapshot\n * @param options - the options\n * @yields the parts\n * @returns nothing\n */\nfunction* lazyParts(snapshot: GraphSnapshot, options: GmlWriteOptions | undefined): Generator<string, void, undefined> {\n yield* gmlParts(contextOf(gmlStyledExport(snapshot, options?.styles)?.snapshot ?? snapshot, options));\n}\n","/**\n * How a GML file's `graphics [ x y z ]` positions are spelled, for `extractPositions()`: the node's\n * center in pixels, y growing downward (the GML specification, yFiles and Cytoscape) unless the\n * `Creator` names a y-up tool (Gephi, Tulip).\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { toolOf } from \"../../common/units.js\";\nimport { median } from \"../../positions/convert.js\";\nimport type { ImporterPositions } from \"../../positions/types.js\";\n\n/** The json column the importer keeps the rest of each node's graphics record in. */\nconst GRAPHICS_COLUMN = \"graphics\";\n\n/**\n * The spelling of a GML file's positions.\n * @param snapshot - the graph the GML importer read\n * @returns the spelling, or null when no node has a position\n */\nexport function gmlPositions(snapshot: GraphSnapshot): ImporterPositions | null {\n if (snapshot.nodes.byRole(\"position\") === null) {\n return null;\n }\n const tool = toolOf(snapshot.meta.creator);\n return {\n units: \"px\",\n // a z that is the same on every node collapses to 2D\n sourceDims: 3,\n yAxis: tool === \"gephi\" || tool === \"tulip\" ? \"up\" : \"down\",\n tool,\n medianNodeSize: graphicsMedian(snapshot),\n };\n}\n\n/**\n * The median node diameter from the graphics records' `w` and `h`.\n * @param snapshot - the graph\n * @returns the median of each node's mean of w and h, or null when no node has both\n */\nfunction graphicsMedian(snapshot: GraphSnapshot): number | null {\n const graphics = snapshot.nodes.get(GRAPHICS_COLUMN);\n const sizes: number[] = [];\n for (let row = 0; graphics !== null && row < graphics.length; row++) {\n const g = graphics.isSet(row) ? graphics.value(row) : undefined;\n const { w, h } = typeof g === \"object\" && g !== null ? (g as Record<string, unknown>) : {};\n if (typeof w === \"number\" && typeof h === \"number\") {\n sizes.push((w + h) / 2);\n }\n }\n return median(sizes);\n}\n","/**\n * The GML importer (design sections 8.4 and 8.5, research note 07 section 2.2): reads a whole GML\n * text (GML awaits the whole text, 8.4), lexes it once into a typed token list, derives the column\n * schema of every node, edge and graph key in a first walk (GML types are lexical per value, so\n * the column dtype is the union of the value classes seen: `int` -> i32, `real` -> f64, `string`\n * -> string, a nested `[ ]` record -> json, a repeated key -> list; the class is recorded in\n * `origin.type` per column as 8.5 requires), then pushes scalars into the sink in a second walk:\n * every node block first, then every edge block, so node indices follow the file's node order\n * and forward edge references resolve.\n *\n * Conventions honored: NetworkX's `_networkx_list_start` marker and `\"[]\"` empty lists, `&#NN;`\n * character references in strings, `Creator` / `Version` top-level metadata, `directed 0|1` and\n * `multigraph 0|1` graph flags, comments, keys and values on one line or split across lines, and\n * a `graphics [ x y z ]` node record mapped to the `position` role (note 07 section 9) with the\n * remaining graphics keys kept as a json column.\n *\n * Node ids are the `id` keys under `nodeIdFrom: \"id\"`, the `label` under `\"label\"`, and the node's\n * ordinal under `\"index\"`; `source` / `target` always resolve through the `id` keys. The GML spec\n * types ids as integers; a string id (written by NetworkX and Gephi) is accepted under the `ids`\n * rule with one warning per file, and a real or record id is a validation error. A node's\n * `graphty_originalId` key written by the exporter's `sanitizeIds: \"mangle\"` restores the\n * original id under `restoreMangledIds` (the default).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ColumnRole,\n type Dtype,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, DictHeuristic, uniqueColumnName } from \"../../common/attributes.js\";\nimport { importChosenGraph } from \"../../common/choose.js\";\nimport {\n COLUMN_RENAMED_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE as SHARED_NO_GRAPH_CODE,\n PRECISION_CODE as SHARED_PRECISION_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n WIDENED_CODE as SHARED_WIDENED_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n graphChosen,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText, reportWeightPrecision, weightFromValue } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { gmlPositions } from \"./positions.js\";\nimport { gmlStyles } from \"./styles.js\";\nimport {\n EMPTY_LIST_TEXT,\n EMPTY_TUPLE_TEXT,\n GmlSyntaxError,\n type GmlTokens,\n LIST_START_MARKER,\n numberOfText,\n ORIGINAL_ID_KEY,\n parseRecord,\n scalarOrRecord,\n TOKEN_INT,\n TOKEN_OPEN,\n TOKEN_REAL,\n TOKEN_STRING,\n TOKEN_WORD,\n tokenizeGml,\n} from \"./syntax.js\";\n\n/**\n * The format-specific options of the GML importer.\n * @category Built-in formats\n */\nexport interface GmlImportOptions extends GraphChoiceOptions, CommonImportOptions {\n /**\n * Read a node's `graphics [ x y z ]` record as its position; false keeps the whole record as a\n * JSON attribute named `graphics`.\n * @defaultValue true\n */\n positions?: boolean | undefined;\n /**\n * With `positions`, also keep the whole `graphics` record, x / y / z included, as the JSON\n * attribute named `graphics`, so a reader gets both the position and the record as written.\n * @defaultValue false\n */\n keepPositionSource?: boolean | undefined;\n /**\n * Store a text attribute whose values repeat a lot (fewer distinct values than half the rows)\n * as a dictionary column, which uses less memory and reads the same. Such a column reports\n * `meta.dtype` \"dict\" instead of \"string\". A column with a role, such as the `label` column,\n * always stays \"string\".\n * @defaultValue true\n */\n dictionaries?: boolean | undefined;\n}\n\n/**\n * The text holds no `graph [ ... ]` block.\n * @category Issue and loss codes\n */\nexport const NO_GRAPH_CODE = SHARED_NO_GRAPH_CODE;\n/**\n * The text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one.\n * @category Issue and loss codes\n */\nexport const SECOND_GRAPH_CODE = MULTIPLE_GRAPHS_CODE;\n/**\n * A node block has no `id` key.\n * @category Issue and loss codes\n */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n/**\n * A node block has no `label` key under `nodeIdFrom: \"label\"`.\n * @category Issue and loss codes\n */\nexport const MISSING_LABEL_CODE = \"E_GML_MISSING_LABEL\";\n/**\n * An edge block has no `source` or no `target` key.\n * @category Issue and loss codes\n */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n/**\n * An `id`, `source` or `target` value is neither an integer nor a string.\n * @category Issue and loss codes\n */\nexport const ID_TYPE_CODE = \"E_GML_ID_TYPE\";\n/**\n * Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option. Reported\n * once per file.\n * @category Issue and loss codes\n */\nexport const STRING_ID_CODE = \"W_GML_STRING_ID\";\n/**\n * A node id (or label under `nodeIdFrom: \"label\"`) is declared twice; later keys overwrite.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n/**\n * A structural key (`id`, `source`, `target`) appears twice in one block.\n * @category Issue and loss codes\n */\nexport const REPEATED_KEY_CODE = \"E_GML_REPEATED_KEY\";\n/**\n * A `node` or `edge` key whose value is not a `[ ... ]` block.\n * @category Issue and loss codes\n */\nexport const ELEMENT_TYPE_CODE = \"E_GML_ELEMENT_TYPE\";\n/**\n * A `directed` or `multigraph` flag that is not an integer.\n * @category Issue and loss codes\n */\nexport const FLAG_TYPE_CODE = \"E_GML_FLAG_TYPE\";\n/**\n * A `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or\n * one repeated.\n * @category Issue and loss codes\n */\nexport const FLAG_VALUE_CODE = \"W_GML_FLAG_VALUE\";\n\n/** A flag written as a quoted integer, surrounding spaces allowed. */\nconst QUOTED_INT = /^\\s*[+-]?\\d+\\s*$/;\n/**\n * A named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity, or a numeric reference beyond\n * U+10FFFF; it is kept as written.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_ENTITY_CODE = \"W_GML_UNKNOWN_ENTITY\";\n/**\n * A node's `graphics` value cannot give a position as written (not a record, repeated in the node, or with an x / y /\n * z that is not one number); the value is kept in the graphics json column. Warned once per kind of problem, naming\n * the first node.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_CODE = \"W_GML_GRAPHICS\";\n/**\n * A `graph`, `node` or `edge` record inside a node or edge; kept as a json column, not read as structure.\n * @category Issue and loss codes\n */\nexport const NESTED_ELEMENT_CODE = \"W_GML_NESTED_ELEMENT\";\n/**\n * YEd's group keys (`isGroup`, `gid`); kept as plain node columns, the hierarchy is not read as containment.\n * @category Issue and loss codes\n */\nexport const GROUPS_CODE = \"W_GML_GROUPS\";\n/**\n * A key whose values mix numbers and strings; the column is string, the numbers kept as written.\n * @category Issue and loss codes\n */\nexport const WIDENED_CODE = SHARED_WIDENED_CODE;\n/**\n * An integer above 2^53 was stored as the nearest JavaScript number, so its last digits may differ. Pass `long:\n * \"string\"` to keep every digit as text.\n * @category Issue and loss codes\n */\nexport const PRECISION_CODE = SHARED_PRECISION_CODE;\n/**\n * Two attributes would have had the same name, so this one was renamed `<name>#<key>`.\n * @category Plugin helpers\n */\nexport const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;\n/**\n * You read into a graph builder that already has an attribute with this role, so this file's attribute is kept without\n * the role.\n * @category Issue and loss codes\n */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n/**\n * Under `nodeIdFrom` \"label\" / \"index\" the integer `id` keys are not kept.\n * @category Issue and loss codes\n */\nexport const ID_DROPPED_CODE = \"W_GML_ID_DROPPED\";\n\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"value\" };\n\nconst KIND_INT = 1;\nconst KIND_REAL = 2;\nconst KIND_STRING = 4;\nconst KIND_RECORD = 8;\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/** How many elements are pushed between abort-signal checks. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"restoreMangledIds\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** The element sequence number of the graph block's own keys. */\nconst GRAPH_SEQ = -1;\n/** The element sequence number of the top-level keys. */\nconst TOP_SEQ = -2;\n\n/** The GML value class a column stores. */\ntype GmlKind = \"int\" | \"real\" | \"string\" | \"record\";\n\n/** What the first walk learns about one key of one table. */\ninterface KeySchema {\n /** The key as written. */\n readonly key: string;\n /** The union of value classes seen (KIND_* bits). */\n kinds: number;\n /** Whether the key repeats within one element, or uses a list marker. */\n list: boolean;\n /** The element sequence the key was last seen in. */\n lastSeq: number;\n /** Whether an integer outside the i32 range was seen. */\n wide: boolean;\n /** Whether an integer beyond 2^53 was seen. */\n unsafe: boolean;\n /** The dictionary heuristic while every value is a string, else null. */\n dict: DictHeuristic | null;\n /** Node `graphics` only: some row has numeric x and y. */\n position: boolean;\n /** Node `graphics` only: some row keeps keys besides the position. */\n rest: boolean;\n}\n\n/** The column a key maps to in the second walk. */\ninterface ColumnPlan {\n /** The key as written. */\n readonly key: string;\n /** The column name (renamed `<name>#<key>` when the sink held the name with another shape). */\n name: string;\n /** The column dtype. */\n readonly dtype: Dtype;\n /** The list item dtype, or null. */\n readonly itemDtype: ScalarDtype | null;\n /** How scalar values (or list items) are converted. */\n readonly kind: GmlKind;\n /** Whether the column is a list. */\n readonly list: boolean;\n /** The role, or null. */\n readonly role: ColumnRole | null;\n /** Whether the values come from the top level of the file (graph table only). */\n readonly top: boolean;\n /** Node `graphics` with the position mapping: the position column plan, or null. */\n readonly position: ColumnPlan | null;\n /** Node `graphics` with the position mapping: the json column of the remaining keys, or null. */\n readonly rest: ColumnPlan | null;\n /** The handle once declared. */\n handle: ColumnHandle;\n /** Whether the declaration was attempted (a failed one reuses the sink's column or is null). */\n declared: boolean;\n /** The list items of the current element. */\n items: unknown[] | null;\n /** The element sequence the items belong to. */\n seq: number;\n}\n\n/** A table's plans by key. */\ntype PlanMap = Map<string, ColumnPlan>;\n\n/** Where a node issue is recorded. */\ninterface IssueWhere {\n readonly line: number;\n readonly element: string;\n}\n\n/** The table a GML key belongs to. */\ntype GmlDomain = \"node\" | \"edge\" | \"graph\";\n\n/**\n * Whether a key is the label of a node or edge (text, never a NetworkX list marker).\n * @param domain - the table\n * @param key - the key\n * @returns true for a node or edge label\n */\nfunction isLabel(domain: GmlDomain, key: string): boolean {\n return roleOf(domain, key) === \"label\";\n}\n\n/**\n * Whether a parsed value is a GML record.\n * @param value - the value\n * @returns true for a record object\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Whether a key gets a role in its table (design section 5.6 applied to GML keys).\n * @param domain - the table\n * @param key - the key\n * @returns the role, or null\n */\nfunction roleOf(domain: GmlDomain, key: string): ColumnRole | null {\n if (key === \"label\" && domain !== \"graph\") {\n return \"label\";\n }\n if (domain === \"edge\") {\n if (key === \"id\") {\n return \"id\";\n }\n if (key === \"key\") {\n return \"key\";\n }\n }\n return null;\n}\n\n/** One import call. */\nclass GmlImport {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly positions: boolean;\n\n private readonly keepPositionSource: boolean;\n\n private readonly dictionaries: boolean;\n\n private readonly coercer: IdCoercer;\n\n private tokens: GmlTokens | null = null;\n\n /** How many `graph [ ... ]` blocks the text holds (known after the scan). */\n graphCount = 0;\n\n private resolver: DirectionResolver | null = null;\n\n private readonly nodeSchema = new Map<string, KeySchema>();\n\n private readonly edgeSchema = new Map<string, KeySchema>();\n\n private readonly graphSchema = new Map<string, KeySchema>();\n\n private readonly topSchema = new Map<string, KeySchema>();\n\n private readonly nodePlans: PlanMap = new Map();\n\n private readonly edgePlans: PlanMap = new Map();\n\n private readonly graphPlans: PlanMap = new Map();\n\n private readonly topPlans: PlanMap = new Map();\n\n private readonly graphNames = new Set<string>();\n\n private graphOpen = -1;\n\n private directedToken = -1;\n\n private multigraphToken = -1;\n\n private creatorToken = -1;\n\n private versionToken = -1;\n\n private nodeCount = 0;\n\n private edgeCount = 0;\n\n private weightKinds = 0;\n\n private hasOriginalId = false;\n\n private headerDirected = false;\n\n private seq = 0;\n\n private nodeOrdinal = 0;\n\n private elementsSinceCheck = 0;\n\n /** The sink id every file id maps to when they differ (label / index / restored ids), else null. */\n private idMap: Map<NodeId, NodeId> | null = null;\n\n /** The file ids of node blocks that were skipped: an edge naming one is skipped too, never given a new node. */\n private readonly skippedIds = new Set<NodeId>();\n\n /** Node indices declared by a node block of this import, for duplicate detection. */\n private declared = new Uint32Array(64);\n\n /** The list plans touched by the current node or edge. */\n private readonly touched: ColumnPlan[] = [];\n\n /** The list plans touched by the graph table's keys. */\n private readonly graphTouched: ColumnPlan[] = [];\n\n /** The sequence number of the current node or edge, which its list items belong to. */\n private seqNow = 0;\n\n /**\n * Create one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param format - the format-specific options\n * @param which - which `graph [ ... ]` block to read (0: the first)\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n format: GmlImportOptions | undefined,\n private readonly which = 0,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.positions = format?.positions ?? true;\n this.keepPositionSource = format?.keepPositionSource ?? false;\n this.dictionaries = format?.dictionaries ?? true;\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Run the import over the tokens of a text.\n * @param tokens - the whole text, tokenized (tokenize())\n */\n run(tokens: GmlTokens): void {\n this.tokens = tokens;\n tokens.onUnknownEntity = (entity, line) => {\n this.report.warnOnce(\n \"parse-error\",\n UNKNOWN_ENTITY_CODE,\n `character entity ${entity} cannot be decoded; it is kept as written`,\n { line, element: entity },\n `${UNKNOWN_ENTITY_CODE}:${entity}`,\n );\n };\n this.scan();\n this.push();\n }\n\n // ============================================================ pass 1: the schema\n\n /**\n * Walk the top level: find the graph block, the metadata keys and the top-level attributes,\n * and derive every table's schema.\n */\n private scan(): void {\n const t = this.requireTokens();\n let scalarGraph = -1;\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n const record = t.kind[v] === TOKEN_OPEN;\n if (key === \"graph\" && !record && scalarGraph < 0) {\n scalarGraph = v;\n }\n this.scanTopPair(key, record, v);\n }\n if (this.graphOpen < 0) {\n this.failNoGraph(t, scalarGraph);\n }\n }\n\n /**\n * Handle one top-level pair other than a scalar `graph`.\n * @param key - the key\n * @param record - whether the value is a `[ ... ]` block\n * @param v - the value token\n */\n private scanTopPair(key: string, record: boolean, v: number): void {\n if (key === \"graph\" && record) {\n if (this.graphCount++ === this.which) {\n this.graphOpen = v;\n this.scanGraph(v);\n }\n } else if (key === \"Creator\" && !record && this.creatorToken < 0) {\n this.creatorToken = v;\n } else if (key === \"Version\" && !record && this.versionToken < 0) {\n this.versionToken = v;\n } else {\n this.observe(this.topSchema, \"graph\", key, v, TOP_SEQ);\n }\n }\n\n /**\n * Fail because the input holds no graph block.\n * @param t - the tokens\n * @param scalarGraph - the token of a scalar `graph` key, or -1\n */\n private failNoGraph(t: ReturnType<GmlImport[\"requireTokens\"]>, scalarGraph: number): void {\n if (scalarGraph >= 0) {\n this.report.fail(\n NO_GRAPH_CODE,\n `the graph key at line ${t.line[scalarGraph]} holds ${describeValue(t, scalarGraph)}, not a [ ... ] block; the input contains no graph block`,\n { line: t.line[scalarGraph] },\n );\n }\n this.report.fail(NO_GRAPH_CODE, \"the input contains no graph [ ... ] block\", { line: null });\n }\n\n /**\n * Walk the graph block for the schema.\n * @param open - the index of the block's `[`\n */\n private scanGraph(open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.nodeCount++;\n this.scanElement(\"node\", v);\n }\n break;\n case \"edge\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.edgeCount++;\n this.scanElement(\"edge\", v);\n }\n break;\n case \"directed\":\n if (this.directedToken < 0) {\n this.directedToken = v;\n }\n break;\n case \"multigraph\":\n if (this.multigraphToken < 0) {\n this.multigraphToken = v;\n }\n break;\n default:\n this.observe(this.graphSchema, \"graph\", key, v, GRAPH_SEQ);\n }\n }\n }\n\n /**\n * Walk one node or edge block for the schema.\n * @param domain - node or edge\n * @param open - the block's `[`\n */\n private scanElement(domain: \"node\" | \"edge\", open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n const seq = this.seq++;\n const schema = domain === \"node\" ? this.nodeSchema : this.edgeSchema;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n if (this.skipsKey(domain, key, v)) {\n continue;\n }\n this.observe(schema, domain, key, v, seq);\n }\n }\n\n /**\n * Whether a key of a node or edge block is structural (id, endpoints, weight, original id), not\n * a column; notes the original id and the weight's kinds on the way.\n * @param domain - node or edge\n * @param key - the key\n * @param v - the value token\n * @returns true when the key is not a column\n */\n private skipsKey(domain: \"node\" | \"edge\", key: string, v: number): boolean {\n const { weightFrom, restoreMangledIds } = this.options;\n if (domain === \"node\") {\n if (key === ORIGINAL_ID_KEY && restoreMangledIds) {\n this.hasOriginalId = true;\n return true;\n }\n return key === \"id\";\n }\n if (key === \"source\" || key === \"target\" || key === \"directed\") {\n return true;\n }\n if (key === weightFrom) {\n this.weightKinds |= kindBit(this.requireTokens(), v);\n return true;\n }\n return false;\n }\n\n /**\n * Record one value of one key in a table's schema.\n * @param schema - the table's schema\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n * @param seq - the element sequence number\n */\n private observe(\n schema: Map<string, KeySchema>,\n domain: \"node\" | \"edge\" | \"graph\",\n key: string,\n v: number,\n seq: number,\n ): void {\n const t = this.requireTokens();\n this.noteStructure(domain, key, v);\n let entry = schema.get(key);\n const graphics = domain === \"node\" && key === \"graphics\" && this.positions;\n if (entry === undefined) {\n entry = {\n key,\n kinds: 0,\n list: false,\n lastSeq: seq,\n wide: false,\n unsafe: false,\n dict: this.dictionaries && roleOf(domain, key) === null ? new DictHeuristic() : null,\n position: false,\n rest: false,\n };\n schema.set(key, entry);\n } else if (entry.lastSeq === seq) {\n entry.list = true;\n // a repeated graphics record: the extra records go to the json column\n entry.rest ||= graphics;\n } else {\n entry.lastSeq = seq;\n }\n if (graphics && t.kind[v] !== TOKEN_OPEN) {\n entry.rest = true;\n }\n switch (t.kind[v]) {\n case TOKEN_STRING: {\n const raw = t.textOf(v);\n // a label is text: \"[]\" there is a label, never NetworkX's empty list\n if (\n raw === LIST_START_MARKER ||\n (!isLabel(domain, key) && (raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT))\n ) {\n entry.list = true;\n return;\n }\n entry.kinds |= KIND_STRING;\n if (entry.dict !== null && !entry.dict.decided) {\n entry.dict.observe(raw);\n }\n return;\n }\n case TOKEN_INT: {\n entry.kinds |= KIND_INT;\n const n = Number(t.textOf(v));\n if (n < I32_MIN || n > I32_MAX) {\n entry.wide = true;\n if (!Number.isSafeInteger(n)) {\n entry.unsafe = true;\n }\n }\n return;\n }\n case TOKEN_OPEN:\n entry.kinds |= KIND_RECORD;\n if (domain === \"node\" && key === \"graphics\" && this.positions) {\n this.inspectGraphics(entry, v);\n }\n return;\n default: {\n entry.kinds |= KIND_REAL;\n const text = t.textOf(v);\n if (/\\d/.test(text) && !Number.isFinite(Number(text))) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${domain} key \"${key}\" holds the real ${text}, beyond the f64 range; it is stored as ${numberOfText(text) > 0 ? \"\" : \"-\"}Infinity`,\n { line: t.line[v], element: key },\n `${PRECISION_CODE}:overflow:${domain}:${key}`,\n );\n }\n }\n }\n }\n\n /**\n * Warn about keys of a node or edge whose meaning GML readers give but this import does not:\n * a nested graph / node / edge record, and yEd's group hierarchy.\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n */\n private noteStructure(domain: \"node\" | \"edge\" | \"graph\", key: string, v: number): void {\n const t = this.requireTokens();\n if (domain === \"graph\") {\n return;\n }\n if ((key === \"graph\" || key === \"node\" || key === \"edge\") && t.kind[v] === TOKEN_OPEN) {\n this.report.warnOnce(\n \"unsupported\",\n NESTED_ELEMENT_CODE,\n `a nested ${key} record inside a ${domain} is kept as the json column \"${key}\"; it is not read as structure`,\n { line: t.line[v], element: key },\n `${NESTED_ELEMENT_CODE}:${domain}:${key}`,\n );\n } else if (domain === \"node\" && (key === \"isGroup\" || key === \"gid\")) {\n this.report.warnOnce(\n \"unsupported\",\n GROUPS_CODE,\n \"yEd group keys (isGroup, gid) are kept as plain node columns; the group hierarchy is not read as containment\",\n { line: t.line[v], element: key },\n );\n }\n }\n\n /**\n * Note whether a node's graphics record carries a position (numeric x and y) and whether\n * anything besides the position remains.\n * @param entry - the graphics schema entry\n * @param open - the record's `[`\n */\n private inspectGraphics(entry: KeySchema, open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n let x = false;\n let y = false;\n let other = false;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const numeric = t.kind[p + 1] === TOKEN_INT || t.kind[p + 1] === TOKEN_REAL;\n if (key === \"x\" && numeric && !x) {\n x = true;\n } else if (key === \"y\" && numeric && !y) {\n y = true;\n } else if (!(key === \"z\" && numeric)) {\n other = true;\n }\n }\n const positioned = x && y;\n entry.position ||= positioned;\n // with keepPositionSource the whole record, x / y / z included, goes to the json column too\n entry.rest ||= positioned ? other || this.keepPositionSource : true;\n }\n\n // ============================================================ pass 2: the push\n\n /** Declare what the schema needs, set the header and push every element. */\n private push(): void {\n const { sink, report, options } = this;\n const t = this.requireTokens();\n sink.reserve(this.nodeCount, this.edgeCount);\n this.buildPlans();\n this.setMetadata();\n this.headerDirected = this.readFlag(this.directedToken, \"directed\") ?? options.defaultDirected;\n const resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n resolver.setHeader(this.headerDirected, {\n line: this.directedToken >= 0 ? t.line[this.directedToken] : t.line[this.graphOpen],\n });\n this.resolver = resolver;\n if (options.nodeIdFrom !== \"id\" || this.hasOriginalId) {\n this.idMap = new Map();\n }\n if (options.nodeIdFrom !== \"id\") {\n report.loss(\n ID_DROPPED_CODE,\n `node ids taken from the ${options.nodeIdFrom}; the integer id keys are not kept as a column`,\n null,\n this.nodeCount,\n );\n }\n this.pushTopLevel();\n this.pushNodes();\n this.pushEdges();\n }\n\n /** Turn every schema entry into a column plan. */\n private buildPlans(): void {\n for (const [key, entry] of this.nodeSchema) {\n this.nodePlans.set(key, this.planOf(\"node\", entry));\n }\n for (const [key, entry] of this.edgeSchema) {\n this.edgePlans.set(key, this.planOf(\"edge\", entry));\n }\n for (const [key, entry] of this.graphSchema) {\n this.graphPlans.set(key, this.planOf(\"graph\", entry));\n }\n for (const [key, entry] of this.topSchema) {\n this.topPlans.set(key, this.planOf(\"graph\", entry, true));\n }\n }\n\n /**\n * Warn about a key that mixes numbers and strings, or holds integers beyond 2^53.\n * @param domain - the table\n * @param entry - the schema entry\n * @param asText - whether the integers are kept as text\n */\n private warnKinds(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, asText: boolean): void {\n if (\n (entry.kinds & KIND_STRING) !== 0 &&\n (entry.kinds & (KIND_INT | KIND_REAL)) !== 0 &&\n (entry.kinds & KIND_RECORD) === 0\n ) {\n this.report.warnOnce(\n \"coercion\",\n WIDENED_CODE,\n `${domain} key \"${entry.key}\" mixes numbers and strings; the column is string and the numbers are kept as written`,\n { element: entry.key },\n `${WIDENED_CODE}:${domain}:${entry.key}`,\n );\n }\n if (entry.unsafe && !asText) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${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)`,\n { element: entry.key },\n `${PRECISION_CODE}:${domain}:${entry.key}`,\n );\n }\n }\n\n /**\n * The plan of a node `graphics` record: the plan plus its position and rest columns.\n * @param plan - the record's plan\n * @param entry - the schema entry\n * @returns the plan with its position (and rest) plans\n */\n private graphicsPlan(plan: ColumnPlan, entry: KeySchema): ColumnPlan {\n const taken = (candidate: string): boolean =>\n this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;\n const position: ColumnPlan = {\n ...plan,\n name: uniqueColumnName(\"position\", \"graphics\", taken),\n dtype: \"f64\",\n itemDtype: null,\n kind: \"real\",\n list: false,\n role: \"position\",\n };\n const rest: ColumnPlan | null = entry.rest\n ? { ...plan, dtype: \"json\", itemDtype: null, kind: \"record\", list: false }\n : null;\n return { ...plan, position, rest };\n }\n\n /**\n * The plan of one schema entry.\n * @param domain - the table\n * @param entry - the schema entry\n * @param top - whether the key is a top-level one (graph table)\n * @returns the plan\n */\n private planOf(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, top = false): ColumnPlan {\n // long: \"string\" keeps every digit of an integer key that holds values beyond 2^53, as text\n const asText = entry.unsafe && this.options.long === \"string\" && kindOf(entry) === \"int\";\n const kind = asText ? \"string\" : kindOf(entry);\n let scalar: ScalarDtype = dtypeOfKind(kind, entry);\n if (\n scalar === \"string\" &&\n !entry.list &&\n entry.dict !== null &&\n entry.kinds === KIND_STRING &&\n entry.dict.decide() === \"dict\"\n ) {\n scalar = \"dict\";\n }\n this.warnKinds(domain, entry, asText);\n const name = domain === \"graph\" ? this.uniqueGraphName(entry.key) : entry.key;\n let itemDtype: ScalarDtype | null = null;\n if (entry.list) {\n itemDtype = scalar === \"dict\" ? \"string\" : scalar;\n }\n const plan: ColumnPlan = {\n key: entry.key,\n name,\n dtype: entry.list ? \"list\" : scalar,\n itemDtype,\n kind,\n list: entry.list,\n role: roleOf(domain, entry.key),\n top,\n position: null,\n rest: null,\n handle: INVALID_INDEX as ColumnHandle,\n declared: false,\n items: null,\n seq: Number.NEGATIVE_INFINITY,\n };\n if (domain === \"node\" && entry.key === \"graphics\" && this.positions && (entry.kinds & KIND_RECORD) !== 0) {\n return this.graphicsPlan(plan, entry);\n }\n return plan;\n }\n\n /**\n * A graph column name not yet used by this import (top-level and in-graph keys share the table).\n * @param key - the key\n * @returns the name\n */\n private uniqueGraphName(key: string): string {\n const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));\n this.graphNames.add(name);\n if (name !== key) {\n this.report.warning(\n \"coercion\",\n COLUMN_RENAMED_CODE_GML,\n `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}\"`,\n { element: key },\n );\n }\n return name;\n }\n\n /** Set the graph metadata: source format, creator, version, multigraph flag, weight origin. */\n private setMetadata(): void {\n const t = this.requireTokens();\n const { sink, options } = this;\n const textOf = (v: number): string => (t.kind[v] === TOKEN_STRING ? t.stringOf(v) : t.textOf(v));\n const multigraph = this.readFlag(this.multigraphToken, \"multigraph\");\n sink.setMeta({\n sourceFormat: \"gml\",\n creator: this.creatorToken >= 0 ? textOf(this.creatorToken) : undefined,\n sourceVersion: this.versionToken >= 0 ? textOf(this.versionToken) : undefined,\n declaredMultigraph: multigraph ?? undefined,\n weightOrigin:\n this.weightKinds !== 0 && options.weightFrom !== null\n ? {\n format: \"gml\",\n id: options.weightFrom,\n title: null,\n type: this.weightKinds === KIND_INT ? \"int\" : \"real\",\n namespace: null,\n }\n : undefined,\n // The header as written, so a reader can say which words set the direction and tell\n // `directed 0` from a file that relies on the specification's default.\n extra: this.directedToken >= 0 ? { gml: { directed: textOf(this.directedToken) } } : undefined,\n });\n }\n\n /**\n * Read a `directed` / `multigraph` flag token.\n * @param v - the value token, or -1 when absent\n * @param name - the flag name, for issues\n * @returns the flag, or null when absent or not an integer\n */\n private readFlag(v: number, name: string): boolean | null {\n if (v < 0) {\n return null;\n }\n const t = this.requireTokens();\n // Files in the wild write the flag as a quoted integer (`directed \"1\"`); read it, with a warning.\n const quoted = t.kind[v] === TOKEN_STRING && QUOTED_INT.test(t.stringOf(v));\n if (quoted) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is written as the string ${describeValue(t, v)}; read as an integer`,\n { line: t.line[v], element: name },\n );\n } else if (t.kind[v] !== TOKEN_INT) {\n this.report.error(\n \"validation-error\",\n FLAG_TYPE_CODE,\n `flag \"${name}\" must be the integer 0 or 1, found ${describeValue(t, v)}`,\n { line: t.line[v], element: name },\n );\n return null;\n }\n const n = Number(quoted ? t.stringOf(v) : t.textOf(v));\n if (n !== 0 && n !== 1) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is ${n}; read as ${n !== 0 ? \"1\" : \"0\"}`,\n { line: t.line[v], element: name },\n );\n }\n return n !== 0;\n }\n\n /** Push the top-level attributes (every top-level key but graph, Creator and Version). */\n private pushTopLevel(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const v = p + 1;\n if (v === this.graphOpen || v === this.creatorToken || v === this.versionToken) {\n continue;\n }\n const plan = this.topPlans.get(t.textOf(p));\n if (plan !== undefined) {\n this.writeGraph(plan, v, TOP_SEQ);\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every node block and the graph block's own attributes, in file order. */\n private pushNodes(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.importNode(v);\n } else {\n this.badElement(\"node\", p);\n this.report.counts.skippedNodes++;\n }\n break;\n case \"edge\":\n break;\n case \"directed\":\n case \"multigraph\":\n if (v !== this.directedToken && v !== this.multigraphToken) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `graph flag \"${key}\" repeated; the first value stands`,\n { line: t.line[p], element: key },\n );\n }\n break;\n default: {\n const plan = this.graphPlans.get(key);\n if (plan !== undefined) {\n this.writeGraph(plan, v, GRAPH_SEQ);\n }\n }\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every edge block, in file order. */\n private pushEdges(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n let ordinal = 0;\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n if (t.textOf(p) !== \"edge\") {\n continue;\n }\n const v = p + 1;\n if (t.kind[v] === TOKEN_OPEN) {\n this.importEdge(v, ordinal);\n } else {\n this.badElement(\"edge\", p);\n this.report.counts.skippedEdges++;\n }\n ordinal++;\n }\n }\n\n /**\n * Record a `node` / `edge` key whose value is not a block.\n * @param what - node or edge\n * @param p - the key token\n */\n private badElement(what: string, p: number): void {\n const t = this.requireTokens();\n this.report.error(\n \"validation-error\",\n ELEMENT_TYPE_CODE,\n `${what} must be a [ ... ] block, found ${describeValue(t, p + 1)}`,\n { line: t.line[p], element: what },\n );\n }\n\n /**\n * Push one node block.\n * @param open - the block's `[`\n */\n private importNode(open: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const ordinal = this.nodeOrdinal++;\n this.checkAbort();\n let index: number;\n let sinkId: NodeId;\n let fileId: NodeId | undefined;\n try {\n let idTok = -1;\n let labelTok = -1;\n let originalTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\") {\n idTok = this.structuralToken(idTok, p, \"id\");\n } else if (key === \"label\") {\n labelTok = labelTok < 0 ? p + 1 : labelTok;\n } else if (key === ORIGINAL_ID_KEY && options.restoreMangledIds) {\n originalTok = originalTok < 0 ? p + 1 : originalTok;\n }\n }\n if (idTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no id\", { reason: \"missing id\" });\n }\n // the file id under the ids rule, so `id 1` and `source \"1\"` meet in idMap (except under\n // \"keep\", where the integer 1 and the string \"1\" are different ids by design)\n fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, \"id\"));\n if (originalTok >= 0) {\n sinkId = this.restoredId(originalTok);\n } else {\n switch (options.nodeIdFrom) {\n case \"label\":\n if (labelTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no label\", {\n reason: \"missing label\",\n });\n }\n sinkId = this.coerceValueToken(labelTok);\n break;\n case \"index\":\n sinkId = ordinal;\n break;\n default:\n sinkId = fileId;\n }\n }\n index = sink.addNode(sinkId);\n if (this.idMap !== null) {\n const before = this.idMap.get(fileId);\n if (before !== undefined && before !== sinkId) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `file id ${JSON.stringify(fileId)} is declared twice (nodes ${JSON.stringify(before)} and ${JSON.stringify(sinkId)}); edges to it resolve to the later`,\n { line, element: String(fileId) },\n );\n }\n this.idMap.set(fileId, sinkId);\n }\n } catch (err) {\n this.recordNodeError(err, line);\n report.counts.skippedNodes++;\n if (fileId !== undefined) {\n this.skippedIds.add(fileId);\n }\n return;\n }\n if (this.isDeclared(index)) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${JSON.stringify(sinkId)} is declared twice; later keys overwrite`,\n { line, element: String(sinkId) },\n );\n } else {\n this.markDeclared(index);\n report.counts.nodes++;\n }\n this.beginElement(this.seq++);\n try {\n const graphics: number[] = [];\n let graphicsPlan: ColumnPlan | null = null;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\" || (key === ORIGINAL_ID_KEY && options.restoreMangledIds)) {\n continue;\n }\n const plan = this.nodePlans.get(key);\n if (plan !== undefined && plan.position !== null) {\n graphicsPlan = plan;\n graphics.push(p + 1);\n } else if (plan !== undefined) {\n this.writeNode(plan, index, p + 1);\n }\n }\n if (graphicsPlan !== null) {\n this.writeGraphics(graphicsPlan, index, graphics, {\n line: t.line[graphics[0]],\n element: String(sinkId),\n });\n }\n this.flushLists(\"node\", index);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element: String(sinkId) });\n }\n }\n\n /**\n * Push one edge block.\n * @param open - the block's `[`\n * @param ordinal - the edge's ordinal among edge blocks, for messages\n */\n private importEdge(open: number, ordinal: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const element = `edge #${ordinal}`;\n this.checkAbort();\n let edge: number;\n try {\n let sourceTok = -1;\n let targetTok = -1;\n let weightTok = -1;\n let directedTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\") {\n sourceTok = this.structuralToken(sourceTok, p, \"source\");\n } else if (key === \"target\") {\n targetTok = this.structuralToken(targetTok, p, \"target\");\n } else if (key === \"directed\") {\n directedTok = this.structuralToken(directedTok, p, \"directed\");\n } else if (key === options.weightFrom) {\n weightTok = p + 1;\n }\n }\n if (sourceTok < 0 || targetTok < 0) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge has no ${sourceTok < 0 ? \"source\" : \"target\"}`, {\n reason: \"missing endpoint\",\n });\n }\n const source = this.endpoint(sourceTok, \"source\");\n const target = this.endpoint(targetTok, \"target\");\n const weight = weightTok >= 0 ? this.weightOf(weightTok) : undefined;\n const before = sink.edgeCount;\n const sourceNew = sink.indexOf(source) === INVALID_INDEX;\n const targetNew = source !== target && sink.indexOf(target) === INVALID_INDEX;\n // an edge-level `directed` key overrides the graph's flag for that edge (mixed graphs)\n const directed = this.readFlag(directedTok, \"directed\") ?? this.headerDirected;\n edge = this.requireResolver().addEdge(source, target, directed ? \"directed\" : \"undirected\", weight, {\n line,\n element,\n });\n report.counts.edges += sink.edgeCount - before;\n // endpoints the file never declares (addMissingNodes) are nodes of the sink too\n report.counts.nodes += (sourceNew ? 1 : 0) + (targetNew ? 1 : 0);\n } catch (err) {\n this.recordEdgeError(err, line, element);\n report.counts.skippedEdges++;\n return;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\" || key === \"target\" || key === \"directed\" || key === options.weightFrom) {\n continue;\n }\n const plan = this.edgePlans.get(key);\n if (plan !== undefined) {\n this.writeEdge(plan, edge, p + 1);\n }\n }\n this.flushLists(\"edge\", edge);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element });\n }\n }\n\n // ============================================================ ids and weights\n\n /**\n * Note a structural key token, refusing a repeat.\n * @param previous - the token seen before, or -1\n * @param p - the key token\n * @param key - the key name\n * @returns the value token\n */\n private structuralToken(previous: number, p: number, key: string): number {\n if (previous >= 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", `key \"${key}\" appears twice in one block`, {\n reason: \"duplicate key\",\n key,\n });\n }\n return p + 1;\n }\n\n /**\n * The value of an id / source / target token: an integer (the GML spec's type) as a number, a\n * string (NetworkX and Gephi write them) as its text with one warning per file.\n * @param v - the value token\n * @param key - the key name, for the error\n * @returns the number or the string\n */\n private fileIdOf(v: number, key: string): number | string {\n const t = this.requireTokens();\n if (t.kind[v] === TOKEN_STRING) {\n this.report.warnOnce(\n \"validation-error\",\n STRING_ID_CODE,\n `${key} is the string \"${t.textOf(v)}\"; GML ids are integers, string ids are kept under the ids rule`,\n { line: t.line[v], element: t.stringOf(v) },\n );\n return t.stringOf(v);\n }\n if (t.kind[v] !== TOKEN_INT) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${key} must be an integer or a string, found ${describeValue(t, v)}`,\n {\n reason: \"not an integer\",\n key,\n value: t.kind[v] === TOKEN_OPEN ? \"[...]\" : t.textOf(v),\n },\n );\n }\n return Number(t.textOf(v));\n }\n\n /**\n * Coerce an id / source / target value under the `ids` rule: a string by its text, an integer\n * through coerceInteger().\n * @param v - the value token\n * @param id - its value (fileIdOf())\n * @returns the id\n */\n private coerceFileId(v: number, id: number | string): NodeId {\n return typeof id === \"string\" ? this.coercer.text(id) : this.coerceInteger(v, id);\n }\n\n /**\n * Coerce an integer id token under the `ids` rule: a safe integer passes as a typed number\n * (so `01` is 1 and `-0` is 0), a larger one goes through the text rule (a string under\n * \"canonical\"), and \"string\" keeps the text as written.\n * @param v - the value token\n * @param n - its numeric value\n * @returns the id\n */\n private coerceInteger(v: number, n: number): NodeId {\n if (Number.isSafeInteger(n) && this.coercer.mode !== \"string\") {\n return this.coercer.value(n);\n }\n return this.coercer.text(this.requireTokens().textOf(v));\n }\n\n /**\n * Coerce a label token under the `ids` rule: a string by its text, a number as a typed value.\n * @param v - the value token\n * @returns the id\n */\n private coerceValueToken(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return this.coercer.text(t.stringOf(v));\n case TOKEN_INT:\n return this.coerceInteger(v, Number(t.textOf(v)));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", \"label must be a string or a number, found a record\", {\n reason: \"record label\",\n });\n default:\n return this.coercer.value(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * The id a `graphty_originalId` key restores: typed, never coerced (the exporter wrote it exactly).\n * @param v - the value token\n * @returns the original id\n */\n private restoredId(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return t.stringOf(v);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", `${ORIGINAL_ID_KEY} must be a string or a number`, {\n reason: \"record original id\",\n });\n default:\n return numberOfText(t.textOf(v));\n }\n }\n\n /**\n * Resolve a source / target token to a sink id.\n * @param v - the value token\n * @param key - source or target\n * @returns the id\n */\n private endpoint(v: number, key: string): NodeId {\n const id = this.coerceFileId(v, this.fileIdOf(v, key));\n const mapped = this.idMap?.get(id);\n if (mapped !== undefined) {\n return mapped;\n }\n if (this.skippedIds.has(id)) {\n // the node block was skipped: creating the endpoint would bring the node back under\n // its raw file id (beside label ids under nodeIdFrom \"label\")\n throw new GraphFormatError(\n \"E_UNKNOWN_NODE\",\n `${key} ${JSON.stringify(id)} names a node block that was skipped after an error`,\n { reason: \"skipped node\", id },\n );\n }\n return id;\n }\n\n /**\n * The weight of an edge from its weight token.\n * @param v - the value token\n * @returns the weight; E_INVALID_WEIGHT for a record or non-numeric text\n */\n private weightOf(v: number): number | undefined {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return parseWeightText(t.stringOf(v), this.report);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"edge weight is a record\", { value: \"[...]\" });\n default: {\n const text = t.textOf(v);\n const weight = weightFromValue(numberOfText(text));\n if (weight !== undefined) {\n reportWeightPrecision(text, weight, this.report);\n }\n return weight;\n }\n }\n }\n\n /**\n * Record a node-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n */\n private recordNodeError(err: unknown, line: number): void {\n const { report } = this;\n if (err instanceof GraphFormatError && err.code === \"E_INVALID_ID\") {\n const { reason } = err.details;\n switch (reason) {\n case \"missing id\":\n report.error(\"missing-value\", MISSING_ID_CODE, err.message, { line, element: \"node\" });\n return;\n case \"missing label\":\n report.error(\"missing-value\", MISSING_LABEL_CODE, err.message, { line, element: \"node\" });\n return;\n case \"duplicate key\":\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element: \"node\" });\n return;\n case \"not an integer\":\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element: \"node\" });\n return;\n default:\n break;\n }\n }\n report.recordError(err, { line, element: \"node\" });\n }\n\n /**\n * Record an edge-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n * @param element - the edge description\n */\n private recordEdgeError(err: unknown, line: number, element: string): void {\n const { report } = this;\n if (err instanceof GraphFormatError) {\n const { reason } = err.details;\n if (err.code === \"E_UNKNOWN_NODE\" && reason === \"missing endpoint\") {\n report.error(\"missing-value\", MISSING_ENDPOINT_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"duplicate key\") {\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"not an integer\") {\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element });\n return;\n }\n }\n report.recordError(err, { line, element });\n }\n\n // ============================================================ values\n\n /**\n * Write one node value.\n * @param plan - the key's plan\n * @param index - the node index\n * @param v - the value token\n */\n private writeNode(plan: ColumnPlan, index: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setNodeValue(this.handleOf(plan, \"node\"), index, this.scalarOf(plan, v));\n }\n\n /**\n * Write one edge value.\n * @param plan - the key's plan\n * @param edge - the edge index\n * @param v - the value token\n */\n private writeEdge(plan: ColumnPlan, edge: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setEdgeValue(this.handleOf(plan, \"edge\"), edge, this.scalarOf(plan, v));\n }\n\n /**\n * Write one graph value.\n * @param plan - the key's plan\n * @param v - the value token\n * @param seq - TOP_SEQ or GRAPH_SEQ\n */\n private writeGraph(plan: ColumnPlan, v: number, seq: number): void {\n if (plan.list) {\n this.collectItem(plan, v, seq, this.graphTouched);\n return;\n }\n const value = this.scalarOf(plan, v);\n this.sink.setGraphValue(plan.name, value, graphDecl(plan));\n if (seq === GRAPH_SEQ && plan.key === \"name\" && typeof value === \"string\") {\n // the graph block's `name` is the graph's name too (snapshot.meta.name, and what graphName matches)\n this.sink.setMeta({ name: value });\n }\n }\n\n /**\n * Write a node's graphics values: the position column from the x / y / z of the first record,\n * everything else (the remaining keys, a value that is not a record, a repeated record) to the\n * json column, with a warning when the value cannot give a position as written.\n * @param plan - the graphics plan\n * @param index - the node index\n * @param vs - the value tokens of the node's graphics keys, in order\n * @param where - the line and the node, for issues\n */\n private writeGraphics(plan: ColumnPlan, index: number, vs: readonly number[], where: IssueWhere): void {\n const t = this.requireTokens();\n const { sink } = this;\n const values = vs.map((v) => (t.kind[v] === TOKEN_OPEN ? parseRecord(t, v) : this.scalarOf(plan, v)));\n const first = values[0];\n const positionPlan = plan.position;\n let rest: unknown = first;\n if (isRecord(first) && positionPlan !== null) {\n const left = this.writePosition(positionPlan, index, this.keepPositionSource ? { ...first } : first, where);\n rest = this.keepPositionSource ? first : left;\n } else if (!isRecord(first)) {\n this.graphicsWarning(\"scalar\", `node ${where.element}'s graphics is not a record`, where);\n }\n if (values.length > 1) {\n this.graphicsWarning(\n \"repeated\",\n `node ${where.element} has ${values.length} graphics records; the position comes from the first`,\n where,\n );\n rest = values;\n }\n if (rest !== undefined && plan.rest !== null) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, rest);\n }\n }\n\n /**\n * Write a node's position from the x / y / z of its graphics record, taking them out of it.\n * @param positionPlan - the position column's plan\n * @param index - the node index\n * @param record - the graphics record\n * @param where - the line and the node, for issues\n * @returns what is left of the record for the json column, or undefined when nothing is\n */\n private writePosition(\n positionPlan: ColumnPlan,\n index: number,\n record: Record<string, unknown>,\n where: IssueWhere,\n ): unknown {\n const { x, y, z } = record;\n let rest: unknown = record;\n if (typeof x === \"number\" && typeof y === \"number\") {\n const depth = typeof z === \"number\" ? z : 0;\n this.sink.setNodeValue(this.handleOf(positionPlan, \"node\"), index, [x, y, depth]);\n delete record.x;\n delete record.y;\n if (typeof z === \"number\") {\n delete record.z;\n }\n rest = Object.keys(record).length > 0 ? record : undefined;\n }\n if (\"x\" in record || \"y\" in record || \"z\" in record) {\n this.graphicsWarning(\n \"coordinate\",\n `node ${where.element}'s graphics x / y / z is not one number each`,\n where,\n );\n }\n return rest;\n }\n\n /**\n * Warn once per kind of graphics problem.\n * @param kind - the problem\n * @param what - the message start, naming the node\n * @param where - the line and the node\n */\n private graphicsWarning(kind: string, what: string, where: IssueWhere): void {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHICS_CODE,\n `${what}; the value is kept in the graphics json column (warned once for every such node)`,\n where,\n `${GRAPHICS_CODE}:${kind}`,\n );\n }\n\n /**\n * Collect one list item.\n * @param plan - the list plan\n * @param v - the value token\n * @param seq - the sequence number of the element the item belongs to\n * @param touched - the plans touched by that element\n */\n private collectItem(plan: ColumnPlan, v: number, seq: number, touched: ColumnPlan[]): void {\n const t = this.requireTokens();\n if (plan.seq !== seq) {\n plan.seq = seq;\n plan.items = [];\n touched.push(plan);\n }\n if (t.kind[v] === TOKEN_STRING) {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n return;\n }\n }\n (plan.items as unknown[]).push(this.scalarOf(plan, v));\n }\n\n /**\n * Start a node or edge: later list items belong to it.\n * @param seq - the element's sequence number\n */\n private beginElement(seq: number): void {\n this.seqNow = seq;\n this.touched.length = 0;\n }\n\n /**\n * Write the lists collected for the current node or edge.\n * @param domain - node or edge\n * @param row - the row\n */\n private flushLists(domain: \"node\" | \"edge\", row: number): void {\n const { sink, touched } = this;\n for (const plan of touched) {\n const handle = this.handleOf(plan, domain);\n if (domain === \"node\") {\n sink.setNodeValue(handle, row, plan.items);\n } else {\n sink.setEdgeValue(handle, row, plan.items);\n }\n plan.items = null;\n }\n touched.length = 0;\n }\n\n /** Write the lists collected for the graph table. */\n private flushGraphLists(): void {\n const { sink, graphTouched } = this;\n for (const plan of graphTouched) {\n sink.setGraphValue(plan.name, plan.items, graphDecl(plan));\n plan.items = null;\n }\n graphTouched.length = 0;\n }\n\n /**\n * The JS value of a scalar value token (or list item) under a plan's storage class.\n * @param plan - the plan\n * @param v - the value token\n * @returns the value to push\n */\n private scalarOf(plan: ColumnPlan, v: number): unknown {\n const t = this.requireTokens();\n const kind = t.kind[v];\n switch (plan.kind) {\n case \"int\":\n return Number(t.textOf(v));\n case \"real\":\n return numberOfText(t.textOf(v));\n case \"string\":\n return kind === TOKEN_STRING ? t.stringOf(v) : t.textOf(v);\n default:\n return kind === TOKEN_STRING ? t.stringOf(v) : scalarOrRecord(t, v);\n }\n }\n\n /**\n * The handle of a plan's column, declaring it on first use. A declaration the sink refuses\n * because a column of the name exists with another declaration falls back to that column\n * (reported once); a taken role is dropped (reported once).\n * @param plan - the plan\n * @param domain - node or edge\n * @returns the handle\n */\n private handleOf(plan: ColumnPlan, domain: \"node\" | \"edge\"): ColumnHandle {\n if (plan.declared) {\n return plan.handle;\n }\n plan.declared = true;\n const { sink, report } = this;\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.role === \"position\") {\n decl.components = 3;\n }\n if (plan.role !== null) {\n decl.role = plan.role;\n }\n const resolved = declareResolved(sink, domain, decl, report, { element: plan.name });\n plan.handle = resolved.handle;\n if (resolved.renamed) {\n plan.name = resolved.decl.name;\n }\n return plan.handle;\n }\n\n // ============================================================ bookkeeping\n\n /**\n * Whether a node index was declared by a node block of this import.\n * @param index - the node index\n * @returns true when declared\n */\n private isDeclared(index: number): boolean {\n const word = index >>> 5;\n return word < this.declared.length && ((this.declared[word] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark a node index as declared.\n * @param index - the node index\n */\n private markDeclared(index: number): void {\n const word = index >>> 5;\n if (word >= this.declared.length) {\n const grown = new Uint32Array(Math.max(word + 1, this.declared.length * 2));\n grown.set(this.declared);\n this.declared = grown;\n }\n this.declared[word] |= 1 << (index & 31);\n }\n\n /** Check the abort signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The tokens, which exist after run() lexed the text.\n * @returns the tokens\n */\n private requireTokens(): GmlTokens {\n if (this.tokens === null) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"the GML text was not lexed\", { reason: \"no tokens\" });\n }\n return this.tokens;\n }\n\n /**\n * The direction resolver, which exists once the header was set.\n * @returns the resolver\n */\n private requireResolver(): DirectionResolver {\n if (this.resolver === null) {\n throw new GraphFormatError(\"E_DIRECTED\", \"the header was not set\", { reason: \"no resolver\" });\n }\n return this.resolver;\n }\n}\n\n/**\n * The KIND_* bit of a value token.\n * @param t - the tokens\n * @param v - the value token\n * @returns the bit\n */\nfunction kindBit(t: GmlTokens, v: number): number {\n switch (t.kind[v]) {\n case TOKEN_INT:\n return KIND_INT;\n case TOKEN_STRING:\n return KIND_STRING;\n case TOKEN_OPEN:\n return KIND_RECORD;\n default:\n return KIND_REAL;\n }\n}\n\n/**\n * The storage class of a schema entry: the widest value class seen.\n * @param entry - the entry\n * @returns the class\n */\nfunction kindOf(entry: KeySchema): GmlKind {\n if ((entry.kinds & KIND_RECORD) !== 0) {\n return \"record\";\n }\n if ((entry.kinds & KIND_STRING) !== 0) {\n return \"string\";\n }\n if ((entry.kinds & KIND_REAL) !== 0) {\n return \"real\";\n }\n return \"int\";\n}\n\n/**\n * The scalar dtype of a storage class.\n * @param kind - the class\n * @param entry - the entry (a wide int keeps origin int but stores f64)\n * @returns the dtype\n */\nfunction dtypeOfKind(kind: GmlKind, entry: KeySchema): ScalarDtype {\n switch (kind) {\n case \"int\":\n return entry.wide ? \"f64\" : \"i32\";\n case \"real\":\n return \"f64\";\n case \"string\":\n return \"string\";\n default:\n return \"json\";\n }\n}\n\n/**\n * The origin.type text of a plan: the GML value class of its values (`int` for wide integers\n * stored as f64 too, so the exporter writes them without a decimal point).\n * @param plan - the plan\n * @returns the type text\n */\nfunction originTypeOf(plan: ColumnPlan): string {\n return plan.kind;\n}\n\n/**\n * The declaration patch of a graph column.\n * @param plan - the plan\n * @returns the decl for setGraphValue\n */\nfunction graphDecl(plan: ColumnPlan): ColumnDecl {\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.top) {\n decl.extra = { gmlTopLevel: true };\n }\n return decl;\n}\n\n/**\n * A short description of a value token for messages.\n * @param t - the tokens\n * @param v - the value token\n * @returns the description\n */\nfunction describeValue(t: GmlTokens, v: number): string {\n switch (t.kind[v]) {\n case TOKEN_OPEN:\n return \"a record\";\n case TOKEN_STRING:\n return `the string \"${t.textOf(v)}\"`;\n case TOKEN_REAL:\n return `the real ${t.textOf(v)}`;\n case TOKEN_WORD:\n return `the word ${t.textOf(v)}`;\n default:\n return t.textOf(v);\n }\n}\n\nconst SNIFF_GRAPH_START = /^(?:\\s|#[^\\n]*\\n)*graph\\s*\\[/;\nconst SNIFF_GRAPH_ANYWHERE = /(?:^|\\s)graph\\s*\\[/;\nconst SNIFF_KEY_START = /^(?:\\s|#[^\\n]*\\n)*[A-Za-z_]\\w*\\s+(?:\"|[+-]?[0-9.]|\\[)/;\n\n/**\n * Confidence that a head of bytes is GML: a `graph [` opener, or key-value text with a `graph [`\n * somewhere in the head.\n * @param head - the first bytes of the input\n * @returns 0.95 for a leading `graph [`, 0.85 for key-value text containing one, 0.4 for key-value text, 0 otherwise\n */\nfunction sniffGml(head: Uint8Array): number {\n let text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n if (text.charCodeAt(0) === 0xfeff) {\n text = text.slice(1);\n }\n if (SNIFF_GRAPH_START.test(text)) {\n return 0.95;\n }\n if (SNIFF_KEY_START.test(text)) {\n return SNIFF_GRAPH_ANYWHERE.test(text) ? 0.85 : 0.4;\n }\n return 0;\n}\n\n/**\n * The GML importer plugin.\n * @category Built-in formats\n */\nexport const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({\n format: \"gml\",\n options: Object.freeze([\"dictionaries\", \"keepPositionSource\", \"positions\"]),\n extensions: Object.freeze([\".gml\"]),\n mimeTypes: Object.freeze([\"text/x-gml\", \"text/plain\"]),\n sniff: sniffGml,\n styles: gmlStyles,\n positions: gmlPositions,\n /**\n * Read a GML text into a sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n if (graphChosen(options)) {\n // the choice is honored here too, not only by the registry\n return importChosenGraph(gmlImporter, input, sink, options);\n }\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const tokens = tokenize(await readText(input, report, resolved), report);\n throwIfAborted(resolved.signal);\n const gml = new GmlImport(sink, report, resolved, options);\n gml.run(tokens);\n if (gml.graphCount > 1) {\n report.warning(\n \"unsupported\",\n SECOND_GRAPH_CODE,\n `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)`,\n );\n }\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every `graph [ ... ]` block of a GML text, each into its own sink; the top-level keys\n * (Creator, Version, ...) apply to each.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph block\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const first = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const tokens = tokenize(await readText(input, first, resolved), first);\n const reports: ImportReport[] = [];\n let count = 1;\n for (let i = 0; i < count; i++) {\n throwIfAborted(resolved.signal);\n const report = i === 0 ? first : new ImportReportBuilder(\"gml\", resolved.errorLimit);\n const sink = sinkFor(i);\n reportSinkOptions(sink, options, report);\n const gml = new GmlImport(sink, report, resolved, options, i);\n gml.run(tokens);\n count = gml.graphCount;\n reports.push(report.finish());\n }\n throwIfAborted(resolved.signal);\n return reports;\n },\n});\n\n/**\n * Tokenize a GML text; a syntax error is fatal.\n * @param text - the whole text\n * @param report - where the syntax error is recorded\n * @returns the tokens\n */\nfunction tokenize(text: string, report: ImportReportBuilder): GmlTokens {\n try {\n return tokenizeGml(text);\n } catch (err) {\n if (err instanceof GmlSyntaxError) {\n report.fail(err.code, err.message, { line: err.line });\n }\n throw err;\n }\n}\n","/**\n * The `@graphty/graph-io/gml` subpath: the GML importer and exporter, their\n * option types, and their issue and loss-note codes grouped in two tables.\n * @module @graphty/graph-io/gml\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n COLUMN_RENAMED_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n ELEMENT_ISSUE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MIXED_DIRECTION_CODE,\n OPTION_IGNORED_CODE,\n SINK_OPTION_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport {\n GRAPHICS_CONFLICT_CODE,\n GRAPHICS_OVERRIDDEN_CODE,\n INVALID_KEY_CODE,\n JSON_ARRAY_CODE,\n KEY_MANGLED_CODE,\n NESTED_ARRAY_CODE,\n POSITION_COMPONENTS_CODE,\n RECORD_BOOLEAN_CODE,\n RECORD_NULL_CODE,\n RECORD_NUMBER_TYPE_CODE,\n RESERVED_KEY_CODE,\n} from \"./exporter.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ELEMENT_TYPE_CODE,\n FLAG_TYPE_CODE,\n FLAG_VALUE_CODE,\n GRAPHICS_CODE,\n GROUPS_CODE,\n ID_DROPPED_CODE,\n ID_TYPE_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_LABEL_CODE,\n NESTED_ELEMENT_CODE,\n NO_GRAPH_CODE,\n PRECISION_CODE,\n REPEATED_KEY_CODE,\n ROLE_TAKEN_CODE,\n SECOND_GRAPH_CODE,\n STRING_ID_CODE,\n UNKNOWN_ENTITY_CODE,\n WIDENED_CODE,\n} from \"./importer.js\";\n\nexport { gmlExporter, type GmlExportOptions } from \"./exporter.js\";\nexport { gmlImporter, type GmlImportOptions } from \"./importer.js\";\nexport { GML_STYLE_BLOCK_KEY, GML_STYLE_CAPABILITIES } from \"./styles.js\";\n\n/**\n * The issue codes the GML importer records, by name: the codes shared with\n * the other importers and the GML-specific ones. A key is the code without\n * its severity and format prefixes.\n * @category Built-in formats\n */\nexport const GML_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /**\n * The text breaks GML's syntax: a word that is not a key or a value, an unclosed string or `[`, a stray `]`, or a\n * key without a value. The import stops.\n */\n SYNTAX: SYNTAX_CODE,\n /** The input is not valid UTF-8. The import stops. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the\n * `encoding` option). The import stops.\n */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** There is no `graph [` block. The import stops. */\n NO_GRAPH: NO_GRAPH_CODE,\n /** The file holds more than one `graph` block and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph. */\n MULTIPLE_GRAPHS: SECOND_GRAPH_CODE,\n /** `graphIndex` or `graphName` names no graph of the file; the message lists the graphs it holds. The import stops. */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches more than one graph; pass `graphIndex`. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** A node without an `id`. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without a `label` under nodeIdFrom \"label\". */\n MISSING_LABEL: MISSING_LABEL_CODE,\n /** An edge without `source` or `target`. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id, source or target that is neither an integer nor a string. */\n ID_TYPE: ID_TYPE_CODE,\n /**\n * Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option.\n * Reported once per file.\n */\n STRING_ID: STRING_ID_CODE,\n /** A node id declared twice (later keys overwrite). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A structural key repeated in one element. */\n REPEATED_KEY: REPEATED_KEY_CODE,\n /** A `node` / `edge` key whose value is not a record. */\n ELEMENT_TYPE: ELEMENT_TYPE_CODE,\n /** A `directed` / `multigraph` flag that is not an integer. */\n FLAG_TYPE: FLAG_TYPE_CODE,\n /** A `directed` / `multigraph` flag outside 0 / 1, or repeated. */\n FLAG_VALUE: FLAG_VALUE_CODE,\n /** A named entity no table decodes, or a numeric reference beyond U+10FFFF; kept as written. */\n UNKNOWN_ENTITY: UNKNOWN_ENTITY_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /** A node's graphics value that cannot give a position as written; kept in the graphics json column. */\n GRAPHICS: GRAPHICS_CODE,\n /** A graph, node or edge record nested in a node or edge; kept as json, not read as structure. */\n NESTED_ELEMENT: NESTED_ELEMENT_CODE,\n /** YEd's isGroup / gid keys, kept as plain columns; the hierarchy is not read as containment. */\n GROUPS: GROUPS_CODE,\n /**\n * An attribute's type was widened because a later value did not fit: an integer above 2^31 in an integer column,\n * or two declared types for one attribute.\n */\n WIDENED: WIDENED_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example\n * two attributes declared with the same name.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two different id texts became the same number because `ids` is \"number\", so their nodes were merged. */\n ID_MERGED: ID_MERGED_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /**\n * You read into a graph builder whose direction is already set, or which already holds edges, so the file is read\n * with the builder's direction instead of its own.\n */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges of the other direction were read with the direction `onMixedDirection` chose. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /**\n * The graph has both directed and undirected edges and `onMixedDirection` is \"error\". An import stops; a save to a\n * format that holds one direction per file fails with E_DIRECTED. Pass \"directed\" or \"undirected\" to read or write\n * it anyway.\n */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n /**\n * Under `nodeIdFrom: \"label\"` or `\"index\"` the file's integer ids are not kept. It is listed in `report.lossy`, not\n * in `report.issues`.\n */\n ID_DROPPED: ID_DROPPED_CODE,\n});\n\n/**\n * The loss-note codes the GML exporter's check() reports beyond the shared LOSS table, by name.\n * @category Built-in formats\n */\nexport const GML_LOSS = Object.freeze({\n /** A json column holds numbers; GML records cannot keep int versus real. */\n RECORD_NUMBER_TYPE: RECORD_NUMBER_TYPE_CODE,\n /** A json column holds booleans, written 1 / 0. */\n RECORD_BOOLEAN: RECORD_BOOLEAN_CODE,\n /** A json column holds nulls, omitted. */\n RECORD_NULL: RECORD_NULL_CODE,\n /** An attribute holds an array inside an array, which GML cannot write; the save fails. */\n NESTED_ARRAY: NESTED_ARRAY_CODE,\n /** A json row that is an array, written as repeated keys. */\n JSON_ARRAY: JSON_ARRAY_CODE,\n /**\n * An attribute name GML cannot use as a key (keys are letters and digits, starting with a letter). The save fails\n * unless `sanitizeKeys` is \"mangle\".\n */\n INVALID_KEY: INVALID_KEY_CODE,\n /** A column named like a structural key. */\n RESERVED_KEY: RESERVED_KEY_CODE,\n /** A key rewritten under sanitizeKeys \"mangle\", or a column renamed because its key would read back as a style value. */\n KEY_MANGLED: KEY_MANGLED_CODE,\n /** A position column with more than three components. */\n POSITION_COMPONENTS: POSITION_COMPONENTS_CODE,\n /** A graphics record whose x / y / z the position column overrides. */\n GRAPHICS_OVERRIDDEN: GRAPHICS_OVERRIDDEN_CODE,\n /** A graphics record that cannot hold the position. */\n GRAPHICS_CONFLICT: GRAPHICS_CONFLICT_CODE,\n});\n"],"names":["note","SHARED_NO_GRAPH_CODE","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_WIDENED_CODE","SHARED_PRECISION_CODE","SHARED_ROLE_TAKEN_CODE","first"],"mappings":"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"}
1
+ {"version":3,"file":"gml.js","sources":["../src/formats/gml/positions.ts","../src/formats/gml/syntax.ts","../src/formats/gml/styles.ts","../src/formats/gml/exporter.ts","../src/formats/gml/importer.ts","../src/formats/gml/index.ts"],"sourcesContent":["/**\n * How a GML file's `graphics [ x y z ]` positions are spelled, for `extractPositions()`: the node's\n * center in pixels, y growing downward (the GML specification, yFiles and Cytoscape) unless the\n * `Creator` names a y-up tool (Gephi, Tulip).\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { toolOf } from \"../../common/units.js\";\nimport { median } from \"../../positions/convert.js\";\nimport type { ImporterPositions } from \"../../positions/types.js\";\n\n/** The json column the importer keeps the rest of each node's graphics record in. */\nconst GRAPHICS_COLUMN = \"graphics\";\n\n/**\n * The spelling of a GML file's positions.\n * @param snapshot - the graph the GML importer read\n * @returns the spelling, or null when no node has a position\n */\nexport function gmlPositions(snapshot: GraphSnapshot): ImporterPositions | null {\n if (snapshot.nodes.byRole(\"position\") === null) {\n return null;\n }\n // Gephi writes its Creator line inside the graph\n const inGraph = snapshot.graph.has(\"Creator\") ? snapshot.graph.value(\"Creator\", 0) : null;\n const gv2gml = writtenByGv2gml(snapshot);\n const graphCreator = typeof inGraph === \"string\" ? inGraph : null;\n const tool = gv2gml ? \"graphviz\" : toolOf(snapshot.meta.creator ?? graphCreator);\n return {\n units: \"px\",\n // a z that is the same on every node collapses to 2D\n sourceDims: 3,\n // gv2gml writes Graphviz's own coordinates, y up\n yAxis: tool === \"gephi\" || tool === \"tulip\" || gv2gml ? \"up\" : \"down\",\n tool,\n medianNodeSize: graphicsMedian(snapshot, tool === \"gephi\"),\n };\n}\n\n/**\n * Whether Graphviz's gv2gml wrote a GML file: no `Creator` line, and the `version 2` it writes first in the graph\n * (cmd/tools/gv2gml.c gv_to_gml).\n * @param snapshot - the graph the GML importer read\n * @returns true for gv2gml's GML\n */\nexport function writtenByGv2gml(snapshot: GraphSnapshot): boolean {\n if ((snapshot.meta.creator ?? null) !== null || snapshot.graph.has(\"Creator\") || !snapshot.graph.has(\"version\")) {\n return false;\n }\n return Number(snapshot.graph.value(\"version\", 0)) === 2;\n}\n\n/**\n * The median node diameter from the graphics records' `w` and `h`.\n * @param snapshot - the graph\n * @param gephi - whether Gephi wrote the file: its `w` is a node's size, a radius, and its `h` is ignored\n * @returns the median of each node's mean of w and h, or null when no node has both\n */\nfunction graphicsMedian(snapshot: GraphSnapshot, gephi: boolean): number | null {\n const graphics = snapshot.nodes.get(GRAPHICS_COLUMN);\n const sizes: number[] = [];\n for (let row = 0; graphics !== null && row < graphics.length; row++) {\n const g = graphics.isSet(row) ? graphics.value(row) : undefined;\n const { w, h, H } = typeof g === \"object\" && g !== null ? (g as Record<string, unknown>) : {};\n if (gephi && typeof w === \"number\") {\n sizes.push(2 * w);\n } else if (typeof w === \"number\" && typeof (h ?? H) === \"number\") {\n // gv2gml writes the height as H\n sizes.push((w + Number(h ?? H)) / 2);\n }\n }\n return median(sizes);\n}\n","/**\n * The GML lexical layer shared by the importer and the exporter (research note 07 section 2.2,\n * NetworkX readwrite/gml.py as the reference reader): the token list a whole GML text lexes into,\n * the structural validation that guarantees every later walk sees balanced `key value` pairs, the\n * value grammar (int, real, quoted string with `&#NN;` character references, `[ ... ]` record),\n * the NetworkX list conventions (`_networkx_list_start`, `\"[]\"`) and the key charset.\n *\n * Tokens are kept in typed arrays (kind, start, end, line, matching bracket) rather than objects:\n * the token list is the one intermediate structure of the GML importer, and it costs 17 bytes per\n * token instead of an object per node.\n */\n\nimport { SYNTAX_CODE } from \"../../common/codes.js\";\nimport { decodeGmlString } from \"../../common/escape.js\";\nimport { plural } from \"../../common/plural.js\";\n\n/**\n * A bare word: a key, or `INF` / `NAN` at a value position.\n * @category Plugin helpers\n */\nexport const TOKEN_WORD = 0;\n/**\n * An integer literal.\n * @category Plugin helpers\n */\nexport const TOKEN_INT = 1;\n/**\n * A real literal, including the non-finite spellings.\n * @category Plugin helpers\n */\nexport const TOKEN_REAL = 2;\n/**\n * A double-quoted string; start / end delimit the body between the quotes.\n * @category Plugin helpers\n */\nexport const TOKEN_STRING = 3;\n/**\n * `[`.\n * @category Plugin helpers\n */\nexport const TOKEN_OPEN = 4;\n/**\n * `]`.\n * @category Plugin helpers\n */\nexport const TOKEN_CLOSE = 5;\n\n/** The kind of one token. */\ntype TokenKind = 0 | 1 | 2 | 3 | 4 | 5;\n\n/**\n * The NetworkX marker that starts a one-element list written as repeated keys.\n * @category Plugin helpers\n */\nexport const LIST_START_MARKER = \"_networkx_list_start\";\n\n/**\n * The string NetworkX writes for an empty list.\n * @category Plugin helpers\n */\nexport const EMPTY_LIST_TEXT = \"[]\";\n\n/**\n * The string NetworkX writes for an empty tuple, read as an empty list too.\n * @category Plugin helpers\n */\nexport const EMPTY_TUPLE_TEXT = \"()\";\n\n/**\n * The node key the exporter writes a mangled node's original id into (design section 8.5).\n * @category Plugin helpers\n */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/**\n * The text breaks the format's syntax: a word that is not a key or a number, an unclosed string or `[`, a `]` with no\n * open `[`, or a key without a value. The message says where. The import stops.\n * @category Issue and loss codes\n */\nexport const SYNTAX_STRUCTURE_CODE = SYNTAX_CODE;\n/**\n * The code of an untokenizable bare token (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_TOKEN_CODE = SYNTAX_CODE;\n/**\n * The code of an unclosed string (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_STRING_CODE = SYNTAX_CODE;\n/**\n * The code of an unclosed `[` (E_SYNTAX).\n * @category Issue and loss codes\n */\nexport const SYNTAX_BRACKET_CODE = SYNTAX_CODE;\n\nconst KEY_TEXT = /^[A-Za-z_]\\w*$/;\nconst STRICT_KEY_TEXT = /^[A-Za-z]\\w*$/;\nconst INT_TEXT = /^[+-]?\\d+$/;\nconst REAL_TEXT = /^[+-]?(?:(?:\\d+\\.\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?|\\d+[eE][+-]?\\d+)$/;\nconst NON_FINITE_TEXT = /^[+-]?(?:inf|infinity|nan)$/i;\nconst NON_FINITE_WORD = /^(?:inf|infinity|nan)$/i;\n\n/**\n * A lexical or structural error of a GML text, with the 1-based line it was found on. The importer\n * turns it into a fatal parse-error issue.\n * @category Plugin helpers\n */\nexport class GmlSyntaxError extends Error {\n /** The issue code. */\n readonly code: string;\n\n /** The 1-based line. */\n readonly line: number;\n\n /**\n * Create a syntax error.\n * @param code - the issue code\n * @param message - a plain-ASCII message\n * @param line - the 1-based line\n */\n constructor(code: string, message: string, line: number) {\n super(message);\n this.name = \"GmlSyntaxError\";\n this.code = code;\n this.line = line;\n }\n}\n\n/**\n * The tokens of one GML text, structurally validated: every `[` has its matching `]` recorded and\n * every key is followed by a value, so walkers need no error paths.\n * @category Plugin helpers\n */\nexport class GmlTokens {\n /** The source text the offsets index into. */\n readonly text: string;\n\n /** The kind of every token. */\n kind: Uint8Array;\n\n /** The start offset of every token (a string's body start). */\n start: Uint32Array;\n\n /** The end offset (exclusive) of every token (a string's body end). */\n end: Uint32Array;\n\n /** The 1-based line of every token. */\n line: Uint32Array;\n\n /** For an open bracket, the index of its matching close bracket; 0 elsewhere. */\n match: Uint32Array;\n\n /** The number of tokens. */\n count = 0;\n\n /**\n * Whether a backslash escapes the next character inside a string (`\\\"`, `\\\\`): set for files OGDF wrote, whose\n * writer escapes quotes that way. Plain GML has no escape mechanism.\n */\n backslashEscapes = false;\n\n /** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */\n onUnknownEntity: ((entity: string, line: number) => void) | null = null;\n\n /**\n * Create an empty token list over a text.\n * @param text - the source text\n * @param capacity - the initial capacity\n */\n constructor(text: string, capacity = 1024) {\n this.text = text;\n this.kind = new Uint8Array(capacity);\n this.start = new Uint32Array(capacity);\n this.end = new Uint32Array(capacity);\n this.line = new Uint32Array(capacity);\n this.match = new Uint32Array(0);\n }\n\n /**\n * Append a token.\n * @param kind - the kind\n * @param start - the start offset\n * @param end - the end offset\n * @param line - the 1-based line\n */\n push(kind: TokenKind, start: number, end: number, line: number): void {\n if (this.count === this.kind.length) {\n this.grow();\n }\n const i = this.count++;\n this.kind[i] = kind;\n this.start[i] = start;\n this.end[i] = end;\n this.line[i] = line;\n }\n\n /**\n * The raw text of a token (a string's body without the quotes, entities undecoded).\n * @param i - the token index\n * @returns the text\n */\n textOf(i: number): string {\n return this.text.slice(this.start[i], this.end[i]);\n }\n\n /**\n * The decoded value of a string token.\n * @param i - the token index\n * @returns the body with character references decoded\n */\n stringOf(i: number): string {\n let text = this.textOf(i);\n if (text.includes(\"\\r\")) {\n // a line break inside a string is part of it, as LF whatever the file's line ends\n text = text.replaceAll(/\\r\\n?/g, \"\\n\");\n }\n if (this.backslashEscapes && text.includes(\"\\\\\")) {\n text = text.replaceAll(/\\\\([\\s\\S])/g, \"$1\");\n }\n if (!text.includes(\"&\")) {\n return text;\n }\n const report = this.onUnknownEntity;\n return decodeGmlString(\n text,\n report === null\n ? undefined\n : (entity) => {\n report(entity, this.line[i]);\n },\n );\n }\n\n /**\n * Whether a token is a `[` or `]`.\n * @param i - the token index\n * @returns true for a bracket\n */\n isBracket(i: number): boolean {\n return this.kind[i] >= TOKEN_OPEN;\n }\n\n /**\n * The index of the pair following the pair whose key is at `key`.\n * @param key - the index of a key token\n * @returns the index after the pair's value (after the matching `]` for a record)\n */\n nextPair(key: number): number {\n const value = key + 1;\n return this.kind[value] === TOKEN_OPEN ? this.match[value] + 1 : value + 1;\n }\n\n /** Double every array. */\n private grow(): void {\n const capacity = this.kind.length * 2;\n const kind = new Uint8Array(capacity);\n kind.set(this.kind);\n this.kind = kind;\n const start = new Uint32Array(capacity);\n start.set(this.start);\n this.start = start;\n const end = new Uint32Array(capacity);\n end.set(this.end);\n this.end = end;\n const line = new Uint32Array(capacity);\n line.set(this.line);\n this.line = line;\n }\n}\n\n/**\n * Lex and structurally validate a whole GML text.\n *\n * Lexical rules (NetworkX): whitespace separates tokens; `#` outside a string starts a comment\n * that runs to the end of the line; a string is delimited by double quotes and may span lines (a\n * line break inside is part of it, GML draft 3.2.5; there is no escape mechanism; `&#NN;`\n * references are decoded later); a U+FEFF between tokens is whitespace; `[` and `]` are\n * single-character tokens; every other run of characters is a key (`[A-Za-z_][0-9A-Za-z_]*`),\n * an integer (`[+-]?[0-9]+`), a real (with a decimal point or an exponent, or `INF` / `NAN` in\n * any case with an optional sign) or an error.\n *\n * Structural rules: the text is a sequence of `key value` pairs where a value is a number, a\n * string, `INF` / `NAN`, or a bracketed sequence of pairs; every `[` has a `]`.\n * @param text - the GML text\n * @returns the validated tokens; GmlSyntaxError with the line of the first problem\n * @category Plugin helpers\n */\nexport function tokenizeGml(text: string): GmlTokens {\n const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));\n tokens.backslashEscapes = writtenByOgdf(text);\n const lex: GmlLex = { text, tokens, i: 0, line: 1, spanningLine: 0 };\n while (lex.i < text.length) {\n const c = text.codePointAt(lex.i) ?? 0;\n if (c === 34) {\n lexString(lex);\n } else if (c === 91 || c === 93) {\n tokens.push(c === 91 ? TOKEN_OPEN : TOKEN_CLOSE, lex.i, lex.i + 1, lex.line);\n lex.i++;\n } else if (!skipSpace(lex, c)) {\n lexBare(lex);\n }\n }\n validateStructure(tokens);\n return tokens;\n}\n\n/** Where tokenizeGml() is. */\ninterface GmlLex {\n readonly text: string;\n readonly tokens: GmlTokens;\n /** The offset of the next character. */\n i: number;\n /** The line of the next character. */\n line: number;\n /** The opening line of the first string that spans lines: where a missing quote most likely is; 0 for none. */\n spanningLine: number;\n}\n\n/**\n * Skips one line break, space or comment.\n * @param lex - the lexer\n * @param c - the char code at the offset\n * @returns false when the character starts a token\n */\nfunction skipSpace(lex: GmlLex, c: number): boolean {\n const { text } = lex;\n if (c === 10 || c === 13) {\n lex.line++;\n lex.i++;\n if (c === 13 && lex.i < text.length && text.codePointAt(lex.i) === 10) {\n lex.i++;\n }\n } else if (c === 32 || c === 9 || c === 11 || c === 12 || c === 0xfeff) {\n // a BOM left inside by concatenated files is whitespace; the shared text check reports it\n lex.i++;\n } else if (c === 35) {\n lex.i = endOfLine(text, lex.i);\n } else {\n return false;\n }\n return true;\n}\n\n/**\n * Lexes a string starting at the offset (its opening quote).\n * @param lex - the lexer\n */\nfunction lexString(lex: GmlLex): void {\n const { text, tokens, i } = lex;\n const close = tokens.backslashEscapes ? escapedClose(text, i + 1) : text.indexOf('\"', i + 1);\n if (close < 0) {\n const hint =\n lex.spanningLine === 0\n ? \"\"\n : `; the string opened at line ${lex.spanningLine} spans lines, so a quote may be missing there`;\n throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${lex.line}${hint}`, lex.line);\n }\n tokens.push(TOKEN_STRING, i + 1, close, lex.line);\n const opened = lex.line;\n for (let k = i + 1; k < close; k++) {\n const d = text.codePointAt(k);\n if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {\n lex.line++;\n }\n }\n if (lex.line !== opened && lex.spanningLine === 0) {\n lex.spanningLine = opened;\n }\n lex.i = close + 1;\n}\n\n/**\n * Lexes a bare token (a key, a number) starting at the offset.\n * @param lex - the lexer\n */\nfunction lexBare(lex: GmlLex): void {\n const { text, i } = lex;\n let j = i + 1;\n while (j < text.length && !isDelimiter(text.codePointAt(j) ?? 0)) {\n j++;\n }\n lex.tokens.push(classifyBare(text, i, j, lex.line), i, j, lex.line);\n lex.i = j;\n}\n\n/**\n * Whether OGDF wrote the file: its first key is `Creator \"ogdf::...\"`, after any whitespace and\n * comment lines. A plain scan, so a banner of `#` characters costs time linear in its length.\n * @param text - the GML text\n * @returns true when the file opens with an OGDF creator line\n */\nfunction writtenByOgdf(text: string): boolean {\n const end = Math.min(text.length, 512);\n let i = 0;\n while (i < end) {\n const c = text.codePointAt(i);\n if (c === 35) {\n // '#': a comment runs to the next line break\n while (i < end && text.codePointAt(i) !== 10 && text.codePointAt(i) !== 13) {\n i++;\n }\n } else if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12 || c === 11) {\n i++;\n } else {\n break;\n }\n }\n return /^Creator\\s+\"ogdf::/.test(text.slice(i, i + 64));\n}\n\n/**\n * The offset of the quote closing a string whose backslashes escape the next character, or -1.\n * @param text - the text\n * @param from - the offset after the opening quote\n * @returns the offset of the closing quote\n */\nfunction escapedClose(text: string, from: number): number {\n let k = from;\n while (k < text.length) {\n const c = text.codePointAt(k);\n if (c === 34) {\n return k;\n }\n // a backslash escapes the next character\n k += c === 92 ? 2 : 1;\n }\n return -1;\n}\n\n/**\n * The offset of the line terminator at or after `from`, or the text length.\n * @param text - the text\n * @param from - the offset to search from\n * @returns the offset of the next `\\n` or `\\r`\n */\nfunction endOfLine(text: string, from: number): number {\n const n = text.length;\n for (let i = from; i < n; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || c === 13) {\n return i;\n }\n }\n return n;\n}\n\n/**\n * Whether a character ends a bare token.\n * @param c - the char code\n * @returns true for whitespace, brackets, a quote or `#`\n */\nfunction isDelimiter(c: number): boolean {\n return (\n c === 32 ||\n c === 9 ||\n c === 10 ||\n c === 13 ||\n c === 11 ||\n c === 12 ||\n c === 91 ||\n c === 93 ||\n c === 34 ||\n c === 35\n );\n}\n\n/**\n * Classify a bare token.\n * @param text - the text\n * @param start - the token start\n * @param end - the token end\n * @param line - the token line, for the error\n * @returns WORD, INT or REAL; GmlSyntaxError for anything else\n */\nfunction classifyBare(text: string, start: number, end: number, line: number): TokenKind {\n const token = text.slice(start, end);\n if (KEY_TEXT.test(token)) {\n return TOKEN_WORD;\n }\n if (INT_TEXT.test(token)) {\n return TOKEN_INT;\n }\n if (REAL_TEXT.test(token) || NON_FINITE_TEXT.test(token)) {\n return TOKEN_REAL;\n }\n // the message is ASCII: a character outside it is shown as \\uXXXX and named, since it may look\n // like something else (a no-break space pasted from a web page looks like a space)\n const hex = (c: string): string => (c.codePointAt(0) ?? 0).toString(16).toUpperCase().padStart(4, \"0\");\n const head = token.length > 20 ? `${token.slice(0, 20)}...` : token;\n const shown = head.replaceAll(/[^\\x20-\\x7e]/gu, (c) => String.raw`\\u` + hex(c));\n const odd = /[^\\x21-\\x7e]/u.exec(token);\n const note = odd === null ? \"\" : ` (it holds U+${hex(odd[0])}, which GML allows only inside a string)`;\n throw new GmlSyntaxError(SYNTAX_TOKEN_CODE, `cannot tokenize \"${shown}\" at line ${line}${note}`, line);\n}\n\n/**\n * Check the `key value` structure and record the matching bracket of every `[`.\n * @param tokens - the lexed tokens\n */\nfunction validateStructure(tokens: GmlTokens): void {\n const { count, kind } = tokens;\n const match = new Uint32Array(count);\n const stack: number[] = [];\n let i = 0;\n while (i < count) {\n const k = kind[i];\n if (k === TOKEN_CLOSE) {\n const open = stack.pop();\n if (open === undefined) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `unexpected \"]\" at line ${tokens.line[i]}: no open \"[\"`,\n tokens.line[i],\n );\n }\n match[open] = i;\n i++;\n continue;\n }\n if (k !== TOKEN_WORD) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a key at line ${tokens.line[i]}, found ${describeToken(tokens, i)}`,\n tokens.line[i],\n );\n }\n const value = i + 1;\n if (value >= count) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `key \"${tokens.textOf(i)}\" at line ${tokens.line[i]} has no value`,\n tokens.line[i],\n );\n }\n if (checkValue(tokens, i) === TOKEN_OPEN) {\n stack.push(value);\n }\n i = value + 1;\n }\n if (stack.length > 0) {\n const open = stack[stack.length - 1];\n throw new GmlSyntaxError(\n SYNTAX_BRACKET_CODE,\n `unexpected end of input: ${stack.length} bracket${plural(stack.length)} still open, the last opened at line ${tokens.line[open]}`,\n tokens.line[open],\n );\n }\n tokens.match = match;\n}\n\n/**\n * Checks the value of a key: a number, a string, `INF` / `NAN` or an opening bracket. Gephi writes its name\n * unquoted (`Creator Gephi`): the word is read as the string it means.\n * @param tokens - the lexed tokens\n * @param key - the key's token index (its value follows it)\n * @returns the value's kind\n */\nfunction checkValue(tokens: GmlTokens, key: number): TokenKind {\n const { kind } = tokens;\n const value = key + 1;\n const word = kind[value] === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value));\n if (word && tokens.textOf(key) === \"Creator\") {\n kind[value] = TOKEN_STRING;\n return TOKEN_STRING;\n }\n if (kind[value] === TOKEN_CLOSE || word) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a value for key \"${tokens.textOf(key)}\" at line ${tokens.line[key]}, found ${describeToken(tokens, value)}`,\n tokens.line[value],\n );\n }\n return kind[value] as TokenKind;\n}\n\n/**\n * A short description of a token for messages.\n * @param tokens - the tokens\n * @param i - the token index\n * @returns the quoted text or the bracket\n */\nfunction describeToken(tokens: GmlTokens, i: number): string {\n switch (tokens.kind[i]) {\n case TOKEN_OPEN:\n return '\"[\"';\n case TOKEN_CLOSE:\n return '\"]\"';\n case TOKEN_STRING:\n return `the string \"${tokens.textOf(i)}\"`;\n default:\n return `\"${tokens.textOf(i)}\"`;\n }\n}\n\n/**\n * The numeric value of an INT or REAL token (or a WORD that is `INF` / `NAN` at a value position).\n * @param text - the token text\n * @returns the number; Infinity / -Infinity / NaN for the non-finite spellings\n * @category Plugin helpers\n */\nexport function numberOfText(text: string): number {\n if (NON_FINITE_TEXT.test(text)) {\n const lower = text.toLowerCase();\n if (lower.endsWith(\"nan\")) {\n return Number.NaN;\n }\n return lower.startsWith(\"-\") ? -Infinity : Infinity;\n }\n return Number(text);\n}\n\n/**\n * Whether a value token is one of the non-finite bare words (`INF`, `NAN`), which lex as words.\n * @param tokens - the tokens\n * @param i - the value token index\n * @returns true when the word is a real\n * @category Plugin helpers\n */\nexport function isNonFiniteWord(tokens: GmlTokens, i: number): boolean {\n return tokens.kind[i] === TOKEN_WORD && NON_FINITE_WORD.test(tokens.textOf(i));\n}\n\n/**\n * Whether a text is a GML key the strict grammar accepts (`[A-Za-z][0-9A-Za-z_]*`, what NetworkX\n * writes and reads).\n * @param text - the candidate key\n * @returns true when it can be written as a key\n * @category Plugin helpers\n */\nexport function isGmlKey(text: string): boolean {\n return STRICT_KEY_TEXT.test(text);\n}\n\n/**\n * Keys rewritten under sanitizeKeys \"mangle\", or a data column renamed because its key would read back as one of\n * graphty's style values.\n * @category Issue and loss codes\n */\nexport const KEY_MANGLED_CODE = \"W_GML_KEY_MANGLED\";\n\n/**\n * Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading\n * non-letter is prefixed with `x` (the exporter's `sanitizeKeys: \"mangle\"`).\n * @param text - the text\n * @returns a valid key\n * @category Plugin helpers\n */\nexport function mangleGmlKey(text: string): string {\n const body = text.replaceAll(/\\W/g, \"_\");\n return /^[A-Za-z]/.test(body) ? body : `x${body}`;\n}\n\n/** One open record while parseRecord() walks the tokens without recursion. */\ninterface RecordFrame {\n readonly record: Record<string, unknown>;\n listKeys: Set<string> | null;\n /** The index of the record's `]`. */\n readonly close: number;\n /** The next key token to read. */\n next: number;\n /** The key the record is stored under in its parent, or null for the root. */\n readonly key: string | null;\n}\n\n/**\n * Parse a bracketed record into a JSON object (design section 8.5: nested GML records map to\n * `json`). Values follow the value grammar; repeated keys become arrays with the NetworkX\n * conventions: the `_networkx_list_start` marker starts a list so a one-element list survives,\n * `\"[]\"` and `\"()\"` are empty lists, and a key seen twice without the marker becomes a\n * two-element array. Nested records are walked with an explicit stack, so the nesting depth is\n * bounded by memory, not by the call stack.\n * @param tokens - the validated tokens\n * @param open - the index of the record's `[`\n * @returns a null-prototype object\n * @category Plugin helpers\n */\nexport function parseRecord(tokens: GmlTokens, open: number): Record<string, unknown> {\n const root = Object.create(null) as Record<string, unknown>;\n const stack: RecordFrame[] = [\n { record: root, listKeys: null, close: tokens.match[open], next: open + 1, key: null },\n ];\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame.next >= frame.close) {\n stack.pop();\n if (frame.key !== null) {\n storeValue(stack[stack.length - 1], frame.key, frame.record);\n }\n continue;\n }\n const p = frame.next;\n frame.next = tokens.nextPair(p);\n const key = tokens.textOf(p);\n const v = p + 1;\n if (tokens.kind[v] === TOKEN_STRING) {\n storeString(frame, key, tokens.stringOf(v));\n } else if (tokens.kind[v] === TOKEN_OPEN) {\n stack.push({\n record: Object.create(null) as Record<string, unknown>,\n listKeys: null,\n close: tokens.match[v],\n next: v + 1,\n key,\n });\n } else {\n storeValue(frame, key, numberOfText(tokens.textOf(v)));\n }\n }\n return root;\n}\n\n/**\n * Store a string value: the list-start marker opens an empty list for the key, the empty list and\n * tuple texts store an empty list, anything else stores the text.\n * @param frame - the open record\n * @param key - the key\n * @param text - the string\n */\nfunction storeString(frame: RecordFrame, key: string, text: string): void {\n if (text === LIST_START_MARKER) {\n frame.record[key] = [];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n return;\n }\n storeValue(frame, key, text === EMPTY_LIST_TEXT || text === EMPTY_TUPLE_TEXT ? [] : text);\n}\n\n/**\n * Store one value under a key: appended to the key's list when the key is a list, paired with the\n * earlier value when the key repeats, set otherwise.\n * @param frame - the open record\n * @param key - the key\n * @param value - the value\n */\nfunction storeValue(frame: RecordFrame, key: string, value: unknown): void {\n const { record } = frame;\n if (frame.listKeys?.has(key)) {\n (record[key] as unknown[]).push(value);\n } else if (key in record) {\n record[key] = [record[key], value];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n } else {\n record[key] = value;\n }\n}\n\n/**\n * The JSON value of a non-string value token: a number, or a record.\n * @param tokens - the tokens\n * @param v - the value token index (INT, REAL, non-finite WORD or OPEN)\n * @returns the value\n * @category Plugin helpers\n */\nexport function scalarOrRecord(tokens: GmlTokens, v: number): unknown {\n return tokens.kind[v] === TOKEN_OPEN ? parseRecord(tokens, v) : numberOfText(tokens.textOf(v));\n}\n","/**\n * GML styles: each node's and edge's `graphics [ ... ]` and `LabelGraphics [ ... ]` records read the way the program\n * that wrote the file draws them, and a graph's styles written back as yEd GML graphics.\n *\n * GML has one syntax and many vocabularies. The `Creator` line (top level, or inside the graph as Gephi writes it,\n * quoted or not) names the writer: yEd and yFiles, Cytoscape, Gephi, OGDF and igraph are recognized; every other file\n * (NetworkX writes no `Creator`) is read with the keys of the GML draft (Graphlet). A recognized drawing program's\n * defaults go beneath the file's own values; igraph and unknown writers get none.\n *\n * Writing: the yEd keys (`fill`, `outline`, `outlineWidth`, `outlineStyle`, `w`, `h`, `type`; edge `fill`, `width`,\n * `style`, `sourceArrow`, `targetArrow`, `smoothBends`; `LabelGraphics` `text`, `color`, `fontSize`, `fontName`,\n * `fontStyle`) replace every style key any reader here reads, inside the records the graph already has, so positions,\n * bends and other keys stay. The `graphty.styles` block and the per-element values its rules read are keys too,\n * named by the GML writer's rule for names that are not GML keys (`graphty_styles`, `graphty_style_node_<key>`).\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport {\n type BendPoint,\n bendsToPoints,\n canonBends,\n canonNodeOffsets,\n nodeOffsetsToPoints,\n} from \"../../styles/canon/bends.js\";\nimport { canonColor, colorOpacity } from \"../../styles/canon/color.js\";\nimport { canonEnum } from \"../../styles/canon/enums.js\";\nimport { canonNumber, canonSigned, num6 } from \"../../styles/canon/number.js\";\nimport { type CanonSite, MAX_STYLE_VALUE_LENGTH, noteAt, scalarText } from \"../../styles/canon/site.js\";\nimport { canonText } from \"../../styles/canon/text.js\";\nimport { STYLE_ISSUE } from \"../../styles/codes.js\";\nimport { CYTOSCAPE_LEXICON, javaFamily } from \"../../styles/cytoscape/lexicon.js\";\nimport { StyleApproximations } from \"../../styles/io/approximations.js\";\nimport {\n parseStyleBlock,\n STYLE_BLOCK_NAME,\n styleBlockLosses,\n styleTag,\n writeStyleBlock,\n} from \"../../styles/io/block.js\";\nimport { elementValues, takeFromBlock } from \"../../styles/io/round-trip.js\";\nimport { dataRead, type ExporterStyleInput } from \"../../styles/io/writer.js\";\nimport { StyleNotes } from \"../../styles/notes.js\";\nimport { styleFingerprint } from \"../../styles/plan/features.js\";\nimport { plainCell } from \"../../styles/plan/resolve.js\";\nimport type {\n ImporterStyles,\n StyleColumn,\n StyleDialect,\n StyleReadContext,\n StyleTarget,\n StyleTool,\n StyleValue,\n StyleWriteCapabilities,\n} from \"../../styles/types.js\";\nimport type { LossNote } from \"../../types.js\";\nimport { GRAPHVIZ_GLYPH_SHAPES } from \"../dot/drawing.js\";\nimport {\n graphvizArrowValue,\n graphvizHasNoOutline,\n graphvizOutline,\n graphvizRouteBends,\n PERIPHERY_GAP,\n putGlyph,\n SHAPE_PERIPHERIES,\n} from \"../dot/styles.js\";\nimport { gephiRules } from \"../gexf/styles.js\";\nimport {\n configurationOutline,\n FONT_STYLES,\n type ValueColumns,\n valueColumns,\n YED_ARROWS,\n YED_LINES,\n YED_SHAPES,\n yedColor,\n yedFontName,\n yedSpelled,\n yedValue,\n} from \"../graphml/styles-yed.js\";\nimport { writtenByGv2gml } from \"./positions.js\";\nimport { KEY_MANGLED_CODE, mangleGmlKey } from \"./syntax.js\";\n\n/** A GML record as the importer keeps it (a json cell). */\ntype Rec = Record<string, unknown>;\n\n/** The key vocabulary a file's graphics are read with. */\ntype Vocabulary = \"yed\" | \"cytoscape\" | \"ogdf\" | \"graphlet\" | \"graphviz\";\n\n/** Who wrote a GML file, as far as its styles go. */\ninterface GmlWriter {\n /** The dialect recorded in the styles. */\n readonly dialect: StyleDialect;\n /** The program whose defaults apply, or null. */\n readonly tool: StyleTool | null;\n /** The keys its graphics are read with. */\n readonly vocabulary: Vocabulary;\n /** How its colors and names are spelled. */\n readonly spelling: StyleDialect;\n /** The unit of its lengths. */\n readonly units: \"px\" | \"relative\";\n /** Whether it draws the `label` key of an element that has graphics (the GML draft does; yEd and Gephi do not). */\n readonly labelKey: boolean;\n /** Whether the graph is directed, where its edges' arrows depend on it (gv2gml's). */\n readonly directed?: boolean;\n}\n\n/** The writers recognized by their `Creator` text, first match wins. */\nconst WRITERS: readonly (readonly [RegExp, GmlWriter])[] = [\n [\n /^\\s*(yfiles|yed)\\b/i,\n { dialect: \"yed\", tool: \"yed\", vocabulary: \"yed\", spelling: \"yed\", units: \"px\", labelKey: false },\n ],\n [\n /^\\s*cytoscape\\b/i,\n {\n dialect: \"cytoscape\",\n tool: \"cytoscape\",\n vocabulary: \"cytoscape\",\n spelling: \"cytoscape\",\n units: \"px\",\n labelKey: true,\n },\n ],\n [\n /^\\s*gephi\\b/i,\n {\n dialect: \"gephi\",\n tool: \"gephi\",\n vocabulary: \"graphlet\",\n spelling: \"css\",\n units: \"relative\",\n // Gephi's preview draws node labels as the GEXF reader reads them (formats/gexf/styles.ts)\n labelKey: true,\n },\n ],\n [\n /^\\s*ogdf::/i,\n { dialect: \"ogdf\", tool: \"ogdf\", vocabulary: \"ogdf\", spelling: \"css\", units: \"px\", labelKey: true },\n ],\n // igraph writes a Creator line, but no drawing defaults of igraph's are stated by a primary source\n [\n /^\\s*igraph\\b/i,\n { dialect: \"igraph\", tool: null, vocabulary: \"graphlet\", spelling: \"css\", units: \"px\", labelKey: true },\n ],\n];\n\n/** Any other writer (NetworkX, SNDlib, hand-written files): the GML draft's keys, no defaults. */\nconst UNKNOWN_WRITER: GmlWriter = {\n dialect: \"gml\",\n tool: null,\n vocabulary: \"graphlet\",\n spelling: \"css\",\n units: \"px\",\n labelKey: true,\n};\n\n/**\n * Graphviz's gv2gml (no `Creator`; `version 2` inside the graph): Graphviz's attribute values (shape names, colors,\n * arrow names, sizes in points, y up) under GML keys, with Graphviz's defaults beneath.\n */\nconst GV2GML_WRITER: GmlWriter = {\n dialect: \"graphviz\",\n tool: \"graphviz\",\n vocabulary: \"graphviz\",\n spelling: \"graphviz\",\n units: \"px\",\n labelKey: true,\n};\n\n/** A file graphty wrote: yEd keys, and the `graphty.styles` block gives the rules. */\nconst GRAPHTY_WRITER: GmlWriter = { ...WRITERS[0][1], tool: null };\n\n/**\n * The graph key holding the `graphty.styles` block: the block's name under the GML writer's rule for names that are\n * not GML keys.\n * @category Built-in formats\n */\nexport const GML_STYLE_BLOCK_KEY = mangleGmlKey(STYLE_BLOCK_NAME);\n\n/** The key prefix of the per-element style values (`graphty.style.` under the same rule). */\nconst TAG_PREFIX = mangleGmlKey(\"graphty.style.\");\n\n/**\n * The GML key of one style column's per-element values.\n * @param target - nodes or edges\n * @param key - the style column's key\n * @returns the key\n */\nfunction tagKey(target: StyleTarget, key: string): string {\n return mangleGmlKey(styleTag(target, key));\n}\n\n/**\n * A graph value as text, or null.\n * @param snapshot - the graph\n * @param name - the graph column\n * @returns the text\n */\nfunction graphText(snapshot: GraphSnapshot, name: string): string | null {\n if (!snapshot.graph.has(name)) {\n return null;\n }\n const v = plainCell(snapshot.graph.value(name, 0));\n if (typeof v === \"string\") {\n return v;\n }\n return typeof v === \"number\" ? String(v) : null;\n}\n\n/**\n * A node label's `anchor` as a label position: yEd's `n`, `s`, `e`, `w` and the corners `nw`, `ne`, `sw`, `se` place it\n * outside the node; `c` and the inside places `t`, `b`, `l`, `r`, `tl`, `tr`, `bl`, `br` keep it inside, which graphty\n * draws centered.\n */\nconst GML_ANCHORS: ReadonlyMap<string, string> = new Map([\n ...[\"c\", \"t\", \"b\", \"l\", \"r\", \"tl\", \"tr\", \"bl\", \"br\"].map((a): [string, string] => [a, \"center\"]),\n [\"n\", \"top\"],\n [\"s\", \"bottom\"],\n [\"e\", \"right\"],\n [\"w\", \"left\"],\n [\"nw\", \"top-left\"],\n [\"ne\", \"top-right\"],\n [\"sw\", \"bottom-left\"],\n [\"se\", \"bottom-right\"],\n]);\n\n/** Node keys only yEd writes: its group hierarchy. */\nconst YED_NODE_KEYS: readonly string[] = [\"isGroup\", \"gid\"];\n\n/**\n * Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), graphty when\n * the file holds a `graphty.styles` block, or yEd when a file with no `Creator` holds keys only yEd writes (`isGroup`,\n * `gid`, the graph's `hierarchic`).\n * @param snapshot - the graph\n * @returns the writer\n */\nfunction writerOf(snapshot: GraphSnapshot): GmlWriter {\n if (snapshot.graph.has(GML_STYLE_BLOCK_KEY)) {\n return GRAPHTY_WRITER;\n }\n const creator = snapshot.meta.creator ?? graphText(snapshot, \"Creator\") ?? \"\";\n for (const [pattern, writer] of WRITERS) {\n if (pattern.test(creator)) {\n return writer;\n }\n }\n // keys only yEd writes name it even without a Creator line (BioNetGen writes yEd GML with none)\n if (\n creator.trim() === \"\" &&\n (YED_NODE_KEYS.some((k) => snapshot.nodes.has(k)) || snapshot.graph.has(\"hierarchic\"))\n ) {\n return WRITERS[0][1];\n }\n return creator.trim() === \"\" && writtenByGv2gml(snapshot) ? GV2GML_WRITER : UNKNOWN_WRITER;\n}\n\n// ============================================================ reading\n\n/** One element's canonical value of a property; null leaves it unset. */\ntype Put = (property: string, value: StyleValue | null) => void;\n\n/** Where a value of an element was read, by property. */\ntype At = (property: string) => CanonSite;\n\n/** The edge's `arrow` key of the GML draft: which ends have an arrow. */\nconst ARROW_ENDS: ReadonlyMap<string, readonly [string, string]> = new Map([\n [\"none\", [\"none\", \"none\"]],\n [\"last\", [\"none\", \"triangle\"]],\n [\"first\", [\"triangle\", \"none\"]],\n [\"both\", [\"triangle\", \"triangle\"]],\n]);\n\n/**\n * The node shape names Cytoscape's GML reader knows (NodeShapeVisualProperty, any case, with Cytoscape 2.x's `rect`\n * and `round_rect`); any other name it ignores, so its default style's shape is drawn.\n */\nconst CYTOSCAPE_GML_SHAPES: ReadonlyMap<string, string> = new Map([\n [\"ellipse\", \"ellipse\"],\n [\"round_rectangle\", \"round-rectangle\"],\n [\"round_rect\", \"round-rectangle\"],\n [\"rectangle\", \"rectangle\"],\n [\"rect\", \"rectangle\"],\n [\"hexagon\", \"hexagon\"],\n [\"octagon\", \"octagon\"],\n [\"parallelogram\", \"parallelogram\"],\n [\"triangle\", \"triangle\"],\n [\"vee\", \"vee\"],\n [\"diamond\", \"diamond\"],\n]);\n\n/** OGDF's stroke types (`stipple`): by number as older OGDF writes them, or by name as GraphIO::writeGML does. */\nconst OGDF_STROKES: readonly string[] = [\"none\", \"solid\", \"dashed\", \"dotted\", \"dash-dot\", \"dash-dot\"];\nconst OGDF_STROKE_NAMES: ReadonlyMap<string, string> = new Map([\n [\"none\", \"none\"],\n [\"solid\", \"solid\"],\n [\"dash\", \"dashed\"],\n [\"dot\", \"dotted\"],\n [\"dashdot\", \"dash-dot\"],\n [\"dashdotdot\", \"dash-dot\"],\n]);\n\n/** OGDF's shape names the common table does not know (an Image node without its image draws as its box). */\nconst OGDF_SHAPES: ReadonlyMap<string, string> = new Map([\n [\"rect\", \"rectangle\"],\n [\"roundedrect\", \"round-rectangle\"],\n [\"rhomb\", \"diamond\"],\n [\"image\", \"rectangle\"],\n]);\n\n/**\n * OGDF's shapes that GraphIO::drawSVG draws as polygons no named shape matches, with their corners as `shapePoints`\n * (fractions of the half width and height, y up), measured in its drawing of\n * graph-io/test/fidelity/specimens/gml/specimen-node-shapes-p5.gml: the triangles, the pentagon, the hexagon and the\n * octagon are regular, their corners on the ellipse of the node's box (so they are drawn where the points say, not\n * stretched to the box: `OGDF_REGULAR`); the trapezes and parallelograms fill the box, their short side half its width.\n */\nconst OGDF_POLYGONS: ReadonlyMap<string, string> = new Map([\n [\"triangle\", \"0,1 0.866,-0.5 -0.866,-0.5\"],\n [\"invtriangle\", \"0,-1 0.866,0.5 -0.866,0.5\"],\n [\"pentagon\", \"0,1 0.951,0.309 0.588,-0.809 -0.588,-0.809 -0.951,0.309\"],\n [\"hexagon\", \"1,0 0.5,0.866 -0.5,0.866 -1,0 -0.5,-0.866 0.5,-0.866\"],\n [\n \"octagon\",\n \"0.924,0.383 0.383,0.924 -0.383,0.924 -0.924,0.383 -0.924,-0.383 -0.383,-0.924 0.383,-0.924 0.924,-0.383\",\n ],\n [\"trapeze\", \"-1,-1 1,-1 0.5,1 -0.5,1\"],\n [\"invtrapeze\", \"-1,1 1,1 0.5,-1 -0.5,-1\"],\n [\"parallelogram\", \"-1,-1 0.5,-1 1,1 -0.5,1\"],\n [\"invparallelogram\", \"-1,1 0.5,1 1,-1 -0.5,-1\"],\n]);\n\n/** OGDF's regular polygons, whose corners lie on the ellipse of the node's box rather than reaching its sides. */\nconst OGDF_REGULAR: ReadonlySet<string> = new Set([\"triangle\", \"invtriangle\", \"pentagon\", \"hexagon\", \"octagon\"]);\n\n/** Keys only yEd writes in a label record: its `fill` is the label's background, not the text color. */\nconst YED_LABEL_KEYS: readonly string[] = [\n \"outline\",\n \"autoSizePolicy\",\n \"model\",\n \"configuration\",\n \"borderDistance\",\n \"modelName\",\n \"modelPosition\",\n];\n\n/** Cytoscape's legacy numbered arrows (`source_arrow 3`), read as Cytoscape reads them. */\nconst cytoscapeArrow = CYTOSCAPE_LEXICON.edge.get(\"targetArrow\")?.[0]?.[1];\n\n/**\n * A short sample of a value for a note.\n * @param raw - the value\n * @returns its text, or \"a record\" for a record\n */\nfunction sampleOf(raw: unknown): string {\n return typeof raw === \"string\" || typeof raw === \"number\"\n ? String(raw).slice(0, MAX_STYLE_VALUE_LENGTH)\n : \"a record\";\n}\n\n/**\n * Whether a value is a GML record.\n * @param v - the value\n * @returns true for a non-array object\n */\nfunction isRec(v: unknown): v is Rec {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * The first defined value of some keys of a record.\n * @param r - the record\n * @param keys - the keys, in order of preference\n * @returns the value, or undefined\n */\nfunction first(r: Rec, ...keys: string[]): unknown {\n for (const k of keys) {\n if (Object.hasOwn(r, k) && r[k] !== undefined) {\n return r[k];\n }\n }\n return undefined;\n}\n\n/**\n * Reads a color and its alpha.\n * @param raw - the value\n * @param property - the color property\n * @param opacity - its opacity property, or null\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readColor(raw: unknown, property: string, opacity: string | null, writer: GmlWriter, put: Put, at: At): void {\n if (raw === undefined) {\n return;\n }\n const c = canonColor(raw, writer.spelling, at(property));\n if (c === null) {\n return;\n }\n put(property, c.color);\n const alpha = colorOpacity(c, null, at(property), opacity !== null);\n if (opacity !== null) {\n put(opacity, alpha);\n }\n}\n\n/**\n * A stroke style: OGDF's numbered `stipple`, or a line type name.\n * @param raw - the value\n * @param kind - border or line style\n * @param writer - the writer\n * @param at - the site\n * @returns the style, or null\n */\nfunction strokeStyle(raw: unknown, kind: \"borderStyle\" | \"lineStyle\", writer: GmlWriter, at: CanonSite): string | null {\n if (raw === undefined) {\n return null;\n }\n if (writer.vocabulary === \"ogdf\") {\n const stroke = ogdfStroke(raw);\n if (stroke === undefined) {\n noteAt(at, STYLE_ISSUE.UNKNOWN_VALUE, sampleOf(raw));\n return null;\n }\n // stroke \"none\" draws no line at all: the callers turn the border or the edge off\n return stroke === \"none\" ? null : stroke;\n }\n return canonEnum(kind, raw, writer.spelling, at);\n}\n\n/**\n * An OGDF `stipple`: a StrokeType by number or by name.\n * @param raw - the value\n * @returns the line style, \"none\", or undefined for a value OGDF does not know\n */\nfunction ogdfStroke(raw: unknown): string | undefined {\n const text = typeof raw === \"string\" || typeof raw === \"number\" ? String(raw).trim() : \"\";\n return /^\\d+$/.test(text) ? OGDF_STROKES[Number(text)] : OGDF_STROKE_NAMES.get(text.toLowerCase());\n}\n\n/**\n * Reads an OGDF node `type` (a Shape name): a polygon where OGDF draws one, else the shape it names.\n * @param raw - the value\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readOgdfShape(raw: string, writer: GmlWriter, put: Put, at: At): void {\n const name = raw.trim().toLowerCase();\n const points = OGDF_POLYGONS.get(name);\n if (points !== undefined) {\n put(\"shape\", \"polygon\");\n put(\"shapePoints\", points);\n if (OGDF_REGULAR.has(name)) {\n put(\"shapePointsStretch\", false);\n }\n return;\n }\n put(\"shape\", canonEnum(\"shape\", OGDF_SHAPES.get(name) ?? raw, writer.spelling, at(\"shape\")));\n}\n\n/**\n * Reads one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeGraphics(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n if (v === \"graphviz\") {\n readGv2gmlNode(g, writer, put, at);\n return;\n }\n readNodeFill(g, writer, put, at);\n readNodeOutline(g, writer, put, at);\n put(\n \"borderStyle\",\n strokeStyle(v === \"ogdf\" ? g.stipple : g.outlineStyle, \"borderStyle\", writer, at(\"borderStyle\")),\n );\n if (v === \"ogdf\" && g.stipple !== undefined && ogdfStroke(g.stipple) === \"none\") {\n put(\"borderWidth\", 0);\n }\n readNodeSize(g, writer, put, at);\n if (v === \"ogdf\") {\n readOgdfLabelOffset(g.label, put, at);\n }\n readNodeShape(g, writer, put, at);\n}\n\n/**\n * Reads a node's size from its `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeSize(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n if (writer.tool === \"gephi\") {\n // Gephi's w is a node's size, a radius: its disc is twice as wide, and its h is never read\n const size = g.w === undefined ? null : canonNumber(g.w, at(\"width\"));\n put(\"width\", size === null ? null : 2 * size);\n put(\"height\", size === null ? null : 2 * size);\n } else {\n put(\"width\", g.w === undefined ? null : canonNumber(g.w, at(\"width\")));\n put(\"height\", g.h === undefined ? null : canonNumber(g.h, at(\"height\")));\n }\n}\n\n/**\n * Reads a node's shape from its `graphics` record, in the writer's vocabulary.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeShape(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n if (v === \"ogdf\" && typeof g.type === \"string\") {\n readOgdfShape(g.type, writer, put, at);\n } else if (v === \"cytoscape\" && g.type !== undefined) {\n const name = scalarText(g.type, at(\"shape\"))?.trim().toLowerCase() ?? \"\";\n const shape = CYTOSCAPE_GML_SHAPES.get(name);\n if (shape === undefined) {\n noteAt(at(\"shape\"), STYLE_ISSUE.UNKNOWN_VALUE, name.slice(0, MAX_STYLE_VALUE_LENGTH));\n }\n put(\"shape\", shape ?? null);\n } else if (g.type !== undefined) {\n put(\"shape\", canonEnum(\"shape\", g.type, writer.spelling, at(\"shape\")));\n } else if (v === \"yed\" && typeof g.customconfiguration === \"string\") {\n // yEd's flowchart palette keeps a node's shape as a configuration, not a `type`.\n const outline = configurationOutline(g.customconfiguration);\n put(\"shape\", outline?.shape ?? null);\n if (outline?.points !== undefined) {\n put(\"shapePoints\", outline.points);\n }\n }\n}\n\n/**\n * Reads where OGDF draws a node's label: GraphIO::writeGML writes the label's center as an offset from the node's\n * center (`graphics [ label [ x y z ] ]`, GraphAttributes::xLabel / yLabel, y down), and GraphIO::drawSVG draws it there.\n * @param label - the graphics record's `label` value\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readOgdfLabelOffset(label: unknown, put: Put, at: At): void {\n if (typeof label !== \"object\" || label === null || Array.isArray(label)) {\n return;\n }\n const { x, y } = label as Rec;\n put(\"labelOffsetX\", x === undefined ? null : canonSigned(x, at(\"labelOffsetX\")));\n put(\"labelOffsetY\", y === undefined ? null : canonSigned(y, at(\"labelOffsetY\")));\n}\n\n/**\n * Reads one node's `graphics` record as Graphviz's gv2gml writes it (cmd/tools/gv2gml.c emitNodeAttrs): `fill` is the\n * node's `fillcolor` (or its `color`), drawn only where `hasFill 1` says `style=filled`; `outline` its pen color,\n * `width` its pen width, `w` and `H` its size in points, `type` its Graphviz shape, `visible 0` its `style=invis`.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readGv2gmlNode(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const shape = typeof g.type === \"string\" ? g.type.trim().toLowerCase() : \"\";\n if (Number(g.hasFill) === 1 || shape === \"point\") {\n // filled: the opacity is stated even when opaque, over Graphviz's default of no fill\n const c = canonColor(g.fill ?? \"black\", writer.spelling, at(\"fill\"), { use: \"fill\" });\n put(\"fill\", c?.color ?? null);\n put(\"fillOpacity\", c?.alpha ?? null);\n } else if (g.fill !== undefined) {\n // Graphviz draws an unfilled node's inside see-through (the tool default), whatever its color\n noteAt(at(\"fill\"), STYLE_ISSUE.UNFILLED, sampleOf(g.fill));\n }\n if (graphvizHasNoOutline(shape)) {\n put(\"borderWidth\", 0);\n } else {\n readColor(g.outline, \"borderColor\", null, writer, put, at);\n put(\"borderWidth\", g.width === undefined ? null : canonNumber(g.width, at(\"borderWidth\")));\n }\n const borderStyle = strokeStyle(g.outlineStyle, \"borderStyle\", writer, at(\"borderStyle\"));\n put(\"borderStyle\", borderStyle);\n readGv2gmlRings(g, shape, borderStyle, writer, put, at);\n // gv2gml's w and H are the node's outer size: Graphviz draws each further outline PERIPHERY_GAP outside the one\n // within, so graphty's node (the innermost outline, its ring outside it) is that much smaller\n const rings = 2 * PERIPHERY_GAP * ((SHAPE_PERIPHERIES.get(shape) ?? 1) - 1);\n const inner = (raw: unknown, property: string): number | null => {\n const n = raw === undefined ? null : canonNumber(raw, at(property));\n return n === null ? null : Math.max(0, n - rings);\n };\n put(\"width\", inner(g.w, \"width\"));\n // gv2gml writes the height as H (gv2gml.c emitReal(\"H\", ...)); h where a later edit spelled it as GML does\n put(\"height\", inner(first(g, \"H\", \"h\"), \"height\"));\n if (Number(g.visible) === 0 && g.visible !== undefined) {\n put(\"visible\", false);\n }\n const outline = graphvizOutline(shape);\n if (shape === \"polygon\") {\n // ponytail: Graphviz's polygon is a box unless its sides, skew or distortion say otherwise; gv2gml copies\n // those as node keys beside graphics, which this record does not see. Read them when a file has them.\n put(\"shape\", \"rectangle\");\n } else if (outline !== undefined) {\n put(\"shape\", \"polygon\");\n put(\"shapePoints\", outline);\n // a Graphviz polygon's corners are where Graphviz draws them, as the DOT reader reads them\n put(\"shapePointsStretch\", false);\n } else if (GRAPHVIZ_GLYPH_SHAPES.has(shape)) {\n const size = (raw: unknown, property: string): number | null =>\n raw === undefined ? null : canonNumber(raw, at(property));\n putGlyph(\n shape,\n size(g.w, \"width\"),\n size(first(g, \"H\", \"h\"), \"height\"),\n put,\n () => {\n const pen = g.width === undefined ? 1 : Number(g.width);\n return Number.isFinite(pen) ? Math.max(0, pen) : 1;\n },\n () =>\n canonColor(g.outline ?? \"black\", writer.spelling, at(\"outerBorderColor\"), { use: \"line\" })?.color ??\n null,\n );\n } else if (g.type !== undefined) {\n put(\"shape\", canonEnum(\"shape\", g.type, \"graphviz\", at(\"shape\")));\n }\n}\n\n/**\n * Reads the second outline Graphviz draws round a `doublecircle`, `doubleoctagon` or `tripleoctagon` (shapes.c):\n * `PERIPHERY_GAP` points outside the first, in its color, width and dashes, as the DOT reader reads it. graphty draws\n * one outer ring, so a third outline is noted as not carried.\n * @param g - the record\n * @param shape - its Graphviz shape, lowercase\n * @param style - its outline's dashes, as read\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readGv2gmlRings(g: Rec, shape: string, style: string | null, writer: GmlWriter, put: Put, at: At): void {\n // ponytail: gv2gml copies a `peripheries` attribute as a node key beside graphics, which this record does not\n // see; the shapes' own outlines are read. Read the key when a file sets it.\n const count = SHAPE_PERIPHERIES.get(shape) ?? 1;\n if (count < 2) {\n return;\n }\n const c = canonColor(g.outline ?? \"black\", writer.spelling, at(\"outerBorderColor\"), { use: \"line\" });\n if (c !== null && c.alpha === 0) {\n return;\n }\n const parsed = g.width === undefined ? 1 : Number(g.width);\n const pen = Number.isFinite(parsed) ? Math.max(0, parsed) : 1;\n put(\"outerBorderColor\", c?.color ?? \"#000000\");\n put(\"outerBorderOpacity\", c !== null && c.alpha < 1 ? c.alpha : null);\n put(\"outerBorderWidth\", pen);\n // the gap between the outline's outer edge and the ring's inner edge\n put(\"outerBorderOffset\", Math.max(0, PERIPHERY_GAP - pen));\n if (style === \"dashed\" || style === \"dotted\") {\n put(\"outerBorderStyle\", style);\n }\n if (count > 2) {\n noteAt(at(\"outerBorderWidth\"), STYLE_ISSUE.NOT_CARRIED, `type ${shape}`);\n }\n}\n\n/**\n * Reads the fill of one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeFill(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n if (writer.vocabulary === \"yed\" && Number(g.hasFill) === 0) {\n noteAt(at(\"fill\"), STYLE_ISSUE.NO_FILL, \"hasFill 0\");\n put(\"fillOpacity\", 0);\n return;\n }\n readColor(g.fill, \"fill\", \"fillOpacity\", writer, put, at);\n if (g.fill2 !== undefined) {\n noteAt(at(\"fill\"), STYLE_ISSUE.GRADIENT, sampleOf(g.fill2));\n }\n}\n\n/**\n * Reads the outline color and width of one node's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readNodeOutline(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n if (v === \"yed\" && Number(g.hasOutline) === 0) {\n put(\"borderWidth\", 0);\n return;\n }\n // OGDF's GraphIO::writeGML writes the stroke color as `outline`; older OGDF wrote `line`\n readColor(v === \"ogdf\" ? first(g, \"outline\", \"line\") : g.outline, \"borderColor\", null, writer, put, at);\n const width = outlineWidthOf(g, v);\n put(\"borderWidth\", width === undefined ? null : canonNumber(width, at(\"borderWidth\")));\n}\n\n/**\n * The outline width of a node's `graphics` record, under the key its writer uses.\n * @param g - the record\n * @param v - the writer's vocabulary\n * @returns the raw width, or undefined\n */\nfunction outlineWidthOf(g: Rec, v: GmlWriter[\"vocabulary\"]): unknown {\n switch (v) {\n case \"yed\":\n return g.outlineWidth;\n case \"cytoscape\":\n return first(g, \"outline_width\", \"width\");\n case \"ogdf\":\n return g.lineWidth;\n default:\n return first(g, \"width\", \"outlineWidth\");\n }\n}\n\n/**\n * Reads one edge's `graphics` record.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdgeGraphics(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n const v = writer.vocabulary;\n if (v === \"graphviz\") {\n readGv2gmlEdge(g, writer, put, at);\n return;\n }\n readColor(g.fill, \"color\", \"opacity\", writer, put, at);\n const width = v === \"ogdf\" ? first(g, \"lineWidth\", \"width\") : g.width;\n put(\"width\", width === undefined ? null : canonNumber(width, at(\"width\")));\n put(\"lineStyle\", strokeStyle(v === \"ogdf\" ? g.stipple : g.style, \"lineStyle\", writer, at(\"lineStyle\")));\n if (v === \"ogdf\" && g.stipple !== undefined && ogdfStroke(g.stipple) === \"none\") {\n put(\"visible\", false);\n }\n readEdgeArrows(g, writer, put, at);\n if (v === \"yed\") {\n readYedCurve(g, put);\n }\n}\n\n/**\n * Reads an edge's arrows from its `graphics` record: `arrow` names the ends that have one, and `sourceArrow` and\n * `targetArrow` (or their snake-case spellings) name each end's arrow.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readEdgeArrows(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n if (typeof g.arrow === \"string\") {\n const ends = ARROW_ENDS.get(g.arrow.trim().toLowerCase());\n if (ends === undefined) {\n noteAt(at(\"targetArrow\"), STYLE_ISSUE.UNKNOWN_VALUE, g.arrow.slice(0, MAX_STYLE_VALUE_LENGTH));\n } else {\n put(\"sourceArrow\", ends[0]);\n put(\"targetArrow\", ends[1]);\n }\n }\n for (const [keys, property] of [\n [[\"sourceArrow\", \"source_arrow\"], \"sourceArrow\"],\n [[\"targetArrow\", \"target_arrow\"], \"targetArrow\"],\n ] as const) {\n const raw = first(g, ...keys);\n if (raw === undefined) {\n continue;\n }\n put(\n property,\n writer.vocabulary === \"cytoscape\" && cytoscapeArrow !== undefined\n ? cytoscapeArrow(raw, at(property))\n : canonEnum(\"arrow\", raw, writer.spelling, at(property)),\n );\n }\n}\n\n/** gv2gml's `arrow`, from Graphviz's `dir`: `first` is `dir=forward` (the head's arrow), `last` is `dir=back`. */\nconst GV2GML_DIRECTIONS: ReadonlyMap<string, readonly [boolean, boolean]> = new Map([\n [\"first\", [false, true]],\n [\"last\", [true, false]],\n [\"both\", [true, true]],\n [\"none\", [false, false]],\n]);\n\n/**\n * Reads one edge's `graphics` record as Graphviz's gv2gml writes it (gv2gml.c emitEdgeAttrs): `fill` its color,\n * `width` its pen width (2 for `style=bold`), `style` its dashes, `visible 0` its `style=invis`, `targetArrow` and\n * `sourceArrow` its `arrowhead` and `arrowtail`, and `arrow` its `dir`. With none of the arrow keys an edge of a\n * directed graph has Graphviz's default arrowhead, and one of an undirected graph none.\n * @param g - the record\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readGv2gmlEdge(g: Rec, writer: GmlWriter, put: Put, at: At): void {\n readColor(g.fill, \"color\", \"opacity\", writer, put, at);\n put(\"width\", g.width === undefined ? null : canonNumber(g.width, at(\"width\")));\n put(\"lineStyle\", strokeStyle(g.style, \"lineStyle\", writer, at(\"lineStyle\")));\n if (Number(g.visible) === 0 && g.visible !== undefined) {\n put(\"visible\", false);\n }\n const ends = gv2gmlArrowEnds(g, writer.directed === true);\n if (ends === null) {\n return;\n }\n for (const [end, raw, on] of [\n [\"target\", g.targetArrow, ends[1]],\n [\"source\", g.sourceArrow, ends[0]],\n ] as const) {\n const name = typeof raw === \"string\" ? raw : \"normal\";\n const arrow = on ? graphvizArrowValue(name, at(`${end}Arrow`)) : null;\n put(`${end}Arrow`, arrow === null ? \"none\" : arrow.value);\n if (arrow?.side !== null && arrow?.side !== undefined) {\n put(`${end}ArrowSide`, arrow.side);\n }\n }\n}\n\n/**\n * Which ends of a gv2gml edge Graphviz draws an arrow at, as its `dir` says (forward in a directed graph when the\n * record names no arrow), or null for an undirected graph's edge that names none.\n * @param g - the edge's `graphics` record\n * @param directed - whether the graph is directed (its `dir` defaults to forward)\n * @returns [source, target], or null\n */\nfunction gv2gmlArrowEnds(g: Rec, directed: boolean): readonly [boolean, boolean] | null {\n if (g.arrow === undefined && g.targetArrow === undefined && g.sourceArrow === undefined) {\n // Graphviz's dir is forward in a digraph and its arrowhead normal: gv2gml writes neither when unset\n return directed ? [false, true] : null;\n }\n let dir = directed ? \"first\" : \"none\";\n if (typeof g.arrow === \"string\") {\n dir = g.arrow.trim().toLowerCase();\n }\n return GV2GML_DIRECTIONS.get(dir) ?? null;\n}\n\n/**\n * Reads whether yEd draws an edge curved: `smoothBends` rounds the bends of its `Line`, whose points run from the\n * source through the bends to the target, so a line of two points (or none) stays straight.\n * @param g - the edge's `graphics` record\n * @param put - receives the value\n */\nfunction readYedCurve(g: Rec, put: Put): void {\n if (g.smoothBends !== undefined) {\n const points = isRec(g.Line) ? g.Line.point : undefined;\n put(\"curved\", Number(g.smoothBends) === 1 && Array.isArray(points) && points.length > 2);\n }\n}\n\n/**\n * Reads an element's label records: the first visible one with text; further visible ones are noted.\n * @param raw - the `LabelGraphics` value (one record or several)\n * @param writer - the writer\n * @param node - whether the label is a node's: its `anchor` places it (`c`, `n`, `t`, `se`, ...)\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readLabelGraphics(raw: unknown, writer: GmlWriter, node: boolean, put: Put, at: At): void {\n const visible = (Array.isArray(raw) ? raw : [raw]).filter((l): l is Rec => isRec(l) && Number(l.visible) !== 0);\n const lg = visible.at(0);\n if (lg === undefined) {\n return;\n }\n const extra = visible.slice(1).filter((l) => l.text !== undefined).length;\n if (extra > 0) {\n noteAt(at(\"label\"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);\n }\n if (lg.text !== undefined) {\n put(\n \"label\",\n writer.vocabulary === \"graphviz\" ? graphvizText(lg.text, at(\"label\")) : canonText(lg.text, at(\"label\")),\n );\n }\n // the GML draft's `fill` is the text color; yEd's is the label's background box, its `color` the text color\n const yedLabel = writer.vocabulary === \"yed\" || YED_LABEL_KEYS.some((k) => Object.hasOwn(lg, k));\n if (lg.color !== undefined || lg.fontColor !== undefined) {\n // gv2gml writes a label's fontcolor as fontColor (as color with -y); yEd's #RRGGBBAA alpha is the words'\n readColor(lg.color ?? lg.fontColor, \"labelColor\", \"labelOpacity\", writer, put, at);\n } else if (lg.fill !== undefined && !yedLabel) {\n readColor(lg.fill, \"labelColor\", null, writer, put, at);\n }\n if (lg.fill !== undefined && yedLabel) {\n noteAt(at(\"label\"), STYLE_ISSUE.NOT_CARRIED, \"label background\");\n }\n // yEd and Cytoscape are Java programs: a Java logical font (Dialog, SansSerif, ...) is drawn in Java's face for it\n readLabelFont(lg, yedLabel || writer.vocabulary === \"cytoscape\", put, at);\n if (node && lg.anchor !== undefined) {\n const anchor = scalarText(lg.anchor, at(\"labelPosition\"))?.trim().toLowerCase() ?? \"\";\n const known = GML_ANCHORS.get(anchor);\n if (known === undefined) {\n noteAt(at(\"labelPosition\"), STYLE_ISSUE.UNKNOWN_VALUE, anchor.slice(0, MAX_STYLE_VALUE_LENGTH));\n }\n put(\"labelPosition\", known ?? null);\n }\n}\n\n/**\n * A label's text as Graphviz draws it: gv2gml copies a DOT label as written, so its line breaks are still the escapes\n * `\\n`, `\\l` and `\\r` (centered, left and right lines, drawn here as plain line breaks).\n * @param raw - the text\n * @param at - the site\n * @returns the text\n */\nfunction graphvizText(raw: unknown, at: CanonSite): string | null {\n const text = canonText(raw, at);\n return text === null ? null : text.replaceAll(/\\\\[nlr]/g, \"\\n\").replace(/\\n$/, \"\");\n}\n\n/**\n * Reads a label record's font: its size, name, weight and slant.\n * @param lg - the record\n * @param java - whether a Java program wrote it, whose logical font names are drawn in Java's faces\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readLabelFont(lg: Rec, java: boolean, put: Put, at: At): void {\n put(\"labelSize\", lg.fontSize === undefined ? null : canonNumber(lg.fontSize, at(\"labelSize\")));\n const font = lg.fontName === undefined ? null : canonText(lg.fontName, at(\"labelFont\"));\n put(\"labelFont\", java && typeof font === \"string\" ? javaFamily(font) : font);\n const style = scalarText(lg.fontStyle, at(\"labelWeight\"))?.trim().toLowerCase();\n if (style !== undefined) {\n const known = FONT_STYLES.get(style);\n if (known === undefined) {\n noteAt(at(\"labelWeight\"), STYLE_ISSUE.UNKNOWN_VALUE, style.slice(0, MAX_STYLE_VALUE_LENGTH));\n } else {\n put(\"labelWeight\", known[0]);\n put(\"labelItalic\", known[1]);\n }\n }\n}\n\n/**\n * Reads one element: its `graphics` and `LabelGraphics`, and the `label` key where the writer draws it.\n * @param target - nodes or edges\n * @param g - the graphics value\n * @param lg - the LabelGraphics value\n * @param label - the `label` key's value\n * @param writer - the writer\n * @param put - receives the values\n * @param at - the sites\n */\nfunction readElement(\n target: StyleTarget,\n g: unknown,\n lg: unknown,\n label: unknown,\n writer: GmlWriter,\n put: Put,\n at: At,\n): void {\n let text = false;\n const putLabel: Put = (property, value) => {\n text ||= property === \"label\" && value !== null;\n put(property, value);\n };\n if (isRec(g)) {\n (target === \"node\" ? readNodeGraphics : readEdgeGraphics)(g, writer, put, at);\n }\n if (lg !== null && lg !== undefined) {\n readLabelGraphics(lg, writer, target === \"node\", putLabel, at);\n }\n // the GML draft draws the label key; Cytoscape reads it as the node's name, which its default style shows\n const drawn =\n writer.vocabulary === \"cytoscape\" ? target === \"node\" : writer.labelKey && (isRec(g) || lg !== undefined);\n if (!text && drawn && label !== null && label !== undefined) {\n put(\n \"label\",\n writer.vocabulary === \"graphviz\" ? graphvizText(label, at(\"label\")) : canonText(label, at(\"label\")),\n );\n // the GML draft names no place for a node's label; a plain GML file's is centered on its node, as OGDF and\n // Cytoscape draw it (yEd's GML keeps its own label models, in LabelGraphics)\n if (target === \"node\" && writer.tool === null && writer.vocabulary === \"graphlet\") {\n put(\"labelPosition\", \"center\");\n }\n }\n}\n\n/** The font size GraphIO::drawSVG draws every label in (SVGSettings), by which it sets a cluster's label off its box. */\nconst OGDF_SVG_FONT_SIZE = 10;\n\n/**\n * Places each OGDF cluster's label where GraphIO::drawSVG draws it (SvgPrinter::drawCluster): one font size below the\n * cluster's box where more of the drawing lies below it than above, else above it; starting at the box's left side\n * where more of the drawing lies left of it than right, else ending at its right side. The importer reads a cluster as\n * a group node with the id `cluster<id>`; its box is its center and its `w` and `h`.\n * @param snapshot - the graph\n * @param values - the node values read so far, given the label's place\n */\nfunction placeOgdfClusterLabels(snapshot: GraphSnapshot, values: ValueColumns): void {\n const n = snapshot.nodeCount;\n const boxOf = (i: number): [number, number, number, number] => {\n const [x, y] = centerOf(snapshot, i);\n const [w, h] = sizeOf(snapshot, i);\n return [x - w / 2, y - h / 2, x + w / 2, y + h / 2];\n };\n // ponytail: drawSVG's bounding box also holds the edges' bends; nodes and clusters decide every sheet so far\n const all = [Infinity, Infinity, -Infinity, -Infinity];\n for (let i = 0; i < n; i++) {\n const b = boxOf(i);\n if (b.every(Number.isFinite)) {\n all[0] = Math.min(all[0], b[0]);\n all[1] = Math.min(all[1], b[1]);\n all[2] = Math.max(all[2], b[2]);\n all[3] = Math.max(all[3], b[3]);\n }\n }\n const put = (property: string, i: number, value: StyleValue): void => {\n values[property] ??= new Array<StyleValue | null>(n).fill(null);\n values[property][i] = value;\n };\n for (let i = 0; i < n; i++) {\n const id = snapshot.ids.idOf(i);\n const [x0, y0, x1, y1] = boxOf(i);\n if (typeof id !== \"string\" || !id.startsWith(\"cluster\") || ![x0, y0, x1, y1].every(Number.isFinite)) {\n continue;\n }\n const below = all[3] - y1 > y0 - all[1];\n const start = x0 - all[0] > all[2] - x1;\n put(\"labelPosition\", i, \"center\");\n put(\"labelOffsetX\", i, ((start ? -1 : 1) * (x1 - x0)) / 2);\n put(\"labelShiftX\", i, start ? 0.5 : -0.5);\n put(\"labelOffsetY\", i, (below ? 1 : -1) * ((y1 - y0) / 2 + OGDF_SVG_FONT_SIZE));\n }\n}\n\n/**\n * An element's `label` key. Cytoscape's GML reader names a node by its label and, where the label is empty or\n * missing, by its id, and its default style draws that name.\n * @param snapshot - the graph\n * @param writer - the writer\n * @param target - nodes or edges\n * @param i - the row\n * @returns the label\n */\nfunction labelOf(snapshot: GraphSnapshot, writer: GmlWriter, target: StyleTarget, i: number): unknown {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const label = cellOf(table, \"label\", i);\n if (writer.vocabulary === \"cytoscape\" && target === \"node\" && (label === undefined || label === \"\")) {\n return String(snapshot.ids.idOf(i));\n }\n return label;\n}\n\n/**\n * The value of a column, or undefined when the table has no such column.\n * @param table - the node or edge table\n * @param name - the column\n * @param i - the row\n * @returns the value\n */\nfunction cellOf(table: GraphSnapshot[\"nodes\"], name: string, i: number): unknown {\n if (!table.has(name)) {\n return undefined;\n }\n const v = plainCell(table.value(name, i));\n return v ?? undefined;\n}\n\n/**\n * A node's center: the `graphics` `x` and `y` the importer moved into the position column.\n * @param snapshot - the graph\n * @param i - the node's index\n * @returns the center; NaN where the node has none\n */\nfunction centerOf(snapshot: GraphSnapshot, i: number): BendPoint {\n const column = snapshot.nodes.byRole(\"position\");\n const v = column?.isSet(i) === true ? (column.value(i) as ArrayLike<number>) : null;\n return v === null ? [Number.NaN, Number.NaN] : [v[0], v[1]];\n}\n\n/**\n * A node's width and height: its `graphics` `w` and `h`.\n * @param snapshot - the graph\n * @param i - the node's index\n * @returns the size; NaN where the node has none\n */\nfunction sizeOf(snapshot: GraphSnapshot, i: number): BendPoint {\n const g = cellOf(snapshot.nodes, \"graphics\", i);\n return isRec(g) ? [Number(g.w ?? Number.NaN), Number(g.h ?? Number.NaN)] : [Number.NaN, Number.NaN];\n}\n\n/**\n * An edge's route from its `graphics` `Line`, whose first and last points are where it attaches to its source and\n * target (its ports: the centers unless yEd moved them) and whose points between are its bends: the bends relative to\n * the two node centers (a self-loop's to its node's size), and each port off its node's center relative to the node.\n * OGDF's `Line` holds the bends alone (GraphIO::writeGML writes no end point).\n * @param snapshot - the graph\n * @param g - the edge's `graphics` value\n * @param e - the edge's row\n * @param bendsOnly - whether the points are the bends alone (OGDF)\n * @param put - receives the values\n */\nfunction readLineRoute(\n snapshot: GraphSnapshot,\n g: unknown,\n e: number,\n bendsOnly: boolean,\n put: (property: string, value: string) => void,\n): void {\n const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;\n const list = isRec(raw) ? [raw] : raw;\n if (!Array.isArray(list) || list.length < (bendsOnly ? 1 : 2)) {\n return;\n }\n const all = list.map((p): BendPoint => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));\n const [s, t] = [snapshot.edgeSource(e), snapshot.edgeTarget(e)];\n const points = bendsOnly ? all : all.slice(1, -1);\n const bends =\n s === t\n ? canonNodeOffsets(centerOf(snapshot, s), sizeOf(snapshot, s), points, true)\n : canonBends(centerOf(snapshot, s), centerOf(snapshot, t), points, true);\n if (bends !== null) {\n put(\"bends\", bends);\n }\n if (bendsOnly) {\n return;\n }\n for (const [property, k, end] of [\n [\"sourcePort\", s, all[0]],\n [\"targetPort\", t, all.at(-1) ?? all[0]],\n ] as const) {\n const center = centerOf(snapshot, k);\n const port =\n end[0] === center[0] && end[1] === center[1]\n ? null\n : canonNodeOffsets(center, sizeOf(snapshot, k), [end], true);\n if (port !== null) {\n put(property, port);\n }\n }\n}\n\n/**\n * A gv2gml edge's route: its `Line` is the edge's Graphviz `pos`, the B-spline's `3n + 1` control points from the tail\n * to the head (y up), with the arrow tips Graphviz keeps apart (`s,` and `e,`) written as plain first and last points;\n * the points beyond `3n + 1` are those tips (the source's first when there are two or it has the arrow). A route on\n * the line between the centers is the straight edge it looks like and gives no bends.\n * @param snapshot - the graph\n * @param g - the edge's `graphics` value\n * @param e - the edge's row\n * @param put - receives the values\n */\nfunction readGv2gmlRoute(\n snapshot: GraphSnapshot,\n g: unknown,\n e: number,\n put: (property: string, value: string) => void,\n): void {\n const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;\n const list = isRec(raw) ? [raw] : raw;\n if (!Array.isArray(list) || !isRec(g)) {\n return;\n }\n let points = list.map((p): BendPoint => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));\n const tips = (points.length - 1) % 3;\n const sourceTip = tips === 2 || (tips === 1 && gv2gmlArrowEnds(g, snapshot.directed)?.[0] === true);\n points = points.slice(sourceTip ? 1 : 0, points.length - (tips === 2 || (tips === 1 && !sourceTip) ? 1 : 0));\n const bends = graphvizRouteBends(\n centerOf(snapshot, snapshot.edgeSource(e)),\n centerOf(snapshot, snapshot.edgeTarget(e)),\n [points],\n );\n if (bends !== null) {\n put(\"bends\", bends);\n }\n}\n\n/**\n * Where graphty-element hangs an edge's label on a route drawn through these points (its centers and bends): the\n * middle of its middle segment, or the joint between its two middle ones; `labelOffsetX` / `labelOffsetY` move it\n * from there.\n * @param points - the route, from the source's center to the target's\n * @returns the point\n */\nfunction routeMiddle(points: readonly BendPoint[]): BendPoint {\n const m = points.length - 1;\n if (m % 2 === 0) {\n return points[m / 2];\n }\n const [a, b] = [points[(m - 1) / 2], points[(m + 1) / 2]];\n return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n}\n\n/**\n * Puts an edge label's offset from where graphty-element hangs it, when the program draws it elsewhere.\n * @param at - the label's center, in the file's coordinates\n * @param middle - where graphty-element hangs it, in the same coordinates\n * @param yUp - whether the file's y grows upward\n * @param put - receives the values\n */\nfunction putEdgeLabelOffset(\n at: BendPoint,\n middle: BendPoint,\n yUp: boolean,\n put: (property: string, value: StyleValue) => void,\n): void {\n const dx = num6(at[0] - middle[0]);\n const dy = num6((yUp ? -1 : 1) * (at[1] - middle[1]));\n if (Number.isFinite(dx) && Number.isFinite(dy) && (dx !== 0 || dy !== 0)) {\n // moved from the line's middle itself, not from graphty's default place beside the line\n put(\"labelPosition\", \"center\");\n put(\"labelOffsetX\", dx);\n put(\"labelOffsetY\", dy);\n }\n}\n\n/**\n * A gv2gml edge label's place: gv2gml copies Graphviz's `lp` (the label's center, in points, y up) as a plain edge\n * key, and Graphviz draws the label there, beside its line rather than on it.\n * @param snapshot - the graph\n * @param e - the edge's row\n * @param bent - whether its route has bends\n * @param put - receives the values\n */\nfunction readGv2gmlLabelPlace(\n snapshot: GraphSnapshot,\n e: number,\n bent: boolean,\n put: (property: string, value: StyleValue) => void,\n): void {\n const lp = cellOf(snapshot.edges, \"lp\", e);\n const m = typeof lp === \"string\" ? /^\\s*(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)\\s*$/.exec(lp) : null;\n // ponytail: a curved route's middle is where graphty-element samples its curve; only a straight one is placed\n if (m === null || bent) {\n return;\n }\n const [s, t] = [centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e))];\n putEdgeLabelOffset([Number(m[1]), Number(m[2])], routeMiddle([s, t]), true, put);\n}\n\n/**\n * An OGDF edge label's place: GraphIO::drawSVG (SvgPrinter::drawEdge) draws it at the middle of the route's first\n * segment, from the source's center to its first bend, not at the route's middle.\n * @param snapshot - the graph\n * @param g - the edge's `graphics` value\n * @param e - the edge's row\n * @param put - receives the values\n */\nfunction readOgdfLabelPlace(\n snapshot: GraphSnapshot,\n g: unknown,\n e: number,\n put: (property: string, value: StyleValue) => void,\n): void {\n const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;\n const list = isRec(raw) ? [raw] : raw;\n const [s, t] = [centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e))];\n if (!Array.isArray(list) || snapshot.edgeSource(e) === snapshot.edgeTarget(e)) {\n return;\n }\n const same = (a: BendPoint, b: BendPoint): boolean => Math.hypot(a[0] - b[0], a[1] - b[1]) < 1e-6;\n // the Line OGDF writes may start and end at the centers\n const bends = list\n .map((p): BendPoint => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]))\n .filter((p) => !same(p, s) && !same(p, t));\n if (bends.length === 0) {\n return;\n }\n const route = [s, ...bends, t];\n putEdgeLabelOffset(\n [(route[0][0] + route[1][0]) / 2, (route[0][1] + route[1][1]) / 2],\n routeMiddle(route),\n false,\n put,\n );\n}\n\n/**\n * Hides the edges Gephi's own GML importer leaves out: an edge whose `directed` key disagrees with the graph's\n * `directed` header (Gephi 0.11 loads 4 of `specimen-arrows-p6`'s 5 edges). A file with no header is read as mixed and\n * every edge is loaded. The edge and its data stay; Gephi draws nothing there, so graphty draws nothing.\n * @param snapshot - the graph\n * @param values - the edge values read so far, given `visible`\n */\nfunction hideGephiDroppedEdges(snapshot: GraphSnapshot, values: ValueColumns): void {\n const header = (snapshot.meta.extra.gml as Record<string, unknown> | undefined)?.directed;\n const directed = snapshot.edges.byRole(\"directed\");\n // with no `directed` header Gephi reads a mixed graph and loads every edge (Gephi Toolkit 0.11.3, checked)\n if (directed === null || header === undefined) {\n return;\n }\n const graphDirected = Number(header) === 1;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n const v = plainCell(directed.value(e));\n if (typeof v === \"boolean\" && v !== graphDirected) {\n values.visible ??= new Array<StyleValue | null>(snapshot.edgeCount).fill(null);\n values.visible[e] = false;\n }\n }\n}\n\n/**\n * Every element's values, read with a writer's vocabulary.\n * @param snapshot - the graph\n * @param writer - the writer\n * @param notes - where problems are noted\n * @param context - the work budget\n * @returns the values per target, and whether anything was read\n */\nfunction readValues(\n snapshot: GraphSnapshot,\n writer: GmlWriter,\n notes: StyleNotes,\n context: Pick<StyleReadContext, \"budget\">,\n): { readonly node: ValueColumns; readonly edge: ValueColumns; readonly found: boolean } {\n let found = false;\n const read = (target: StyleTarget): ValueColumns => {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const out = valueColumns(n);\n if (!table.has(\"graphics\") && !table.has(\"LabelGraphics\") && writer.vocabulary !== \"cytoscape\") {\n return out.values;\n }\n for (let i = 0; i < n; i++) {\n context.budget.spend(target, 1);\n const at: At = (property) => ({ notes, target, property, element: i, budget: context.budget });\n readElement(\n target,\n cellOf(table, \"graphics\", i),\n cellOf(table, \"LabelGraphics\", i),\n labelOf(snapshot, writer, target, i),\n writer,\n (property, value) => {\n if (value !== null) {\n found = true;\n out.put(i, property, value);\n }\n },\n at,\n );\n if (target === \"edge\" && writer.vocabulary === \"graphviz\") {\n let bent = false;\n readGv2gmlRoute(snapshot, cellOf(table, \"graphics\", i), i, (property, value) => {\n found = true;\n bent ||= property === \"bends\";\n out.put(i, property, value);\n });\n readGv2gmlLabelPlace(snapshot, i, bent, (property, value) => {\n out.put(i, property, value);\n });\n } else if (target === \"edge\" && writer.vocabulary === \"ogdf\") {\n readOgdfLabelPlace(snapshot, cellOf(table, \"graphics\", i), i, (property, value) => {\n out.put(i, property, value);\n });\n }\n if (target === \"edge\" && writer.vocabulary !== \"graphviz\") {\n readLineRoute(\n snapshot,\n cellOf(table, \"graphics\", i),\n i,\n writer.vocabulary === \"ogdf\",\n (property, value) => {\n found = true;\n out.put(i, property, value);\n },\n );\n }\n }\n return out.values;\n };\n const node = read(\"node\");\n const edge = read(\"edge\");\n return { node, edge, found };\n}\n\n/**\n * The `graphty.styles` block of a file graphty wrote, with the per-element values its rules read moved inside it from\n * their `graphty_style_*` keys; the block as written when it is ignored anyway (graph-io then says why).\n * @param snapshot - the graph\n * @param text - the block's text\n * @returns the block's text for graph-io to read\n */\nfunction blockWithValues(snapshot: GraphSnapshot, text: string): string {\n const parsed = parseStyleBlock(text, styleFingerprint(snapshot));\n if (!parsed.ok || parsed.block.values !== undefined) {\n return text;\n }\n const node = tagValues(snapshot, \"node\", parsed.block.columns.node);\n const edge = tagValues(snapshot, \"edge\", parsed.block.columns.edge);\n if (node === null || edge === null) {\n // a style column is missing: graph-io ignores the block with a note\n return text;\n }\n const raw = JSON.parse(text) as Record<string, unknown>;\n return JSON.stringify({ ...raw, values: { node, edge } });\n}\n\n/**\n * The per-element values of a target's style columns, read from their `graphty_style_*` keys.\n * @param snapshot - the graph\n * @param target - nodes or edges\n * @param keys - the style columns the block names\n * @returns the values by key, or null when a key is missing\n */\nfunction tagValues(\n snapshot: GraphSnapshot,\n target: StyleTarget,\n keys: readonly string[],\n): Record<string, StyleColumn> | null {\n const table = target === \"node\" ? snapshot.nodes : snapshot.edges;\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const values: Record<string, StyleColumn> = {};\n for (const key of keys) {\n const name = tagKey(target, key);\n if (!table.has(name)) {\n return null;\n }\n values[key] = Array.from({ length: n }, (_, i) => {\n const v = plainCell(table.value(name, i));\n return typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\" ? v : null;\n });\n }\n return values;\n}\n\n/**\n * The columns of a table that hold styles: the graphics records and graphty's per-element style values.\n * @param table - the node or edge table\n * @returns the column names\n */\nfunction styleColumns(table: GraphSnapshot[\"nodes\"]): string[] {\n return [...table.names()].filter((c) => c === \"graphics\" || c === \"LabelGraphics\" || c.startsWith(TAG_PREFIX));\n}\n\n/**\n * The styles of a GML file, read the way the program that wrote it draws them, with that program's defaults beneath:\n * yEd, Cytoscape, Gephi and OGDF are recognized by the `Creator` line; igraph and every other writer get the GML\n * draft's keys and no defaults. A file graphty wrote gives back its `graphty.styles` block.\n * @param snapshot - the graph the import built\n * @param context - the work budget\n * @returns the styles, or null when the file has none\n */\nexport function gmlStyles(snapshot: GraphSnapshot, context: StyleReadContext): ImporterStyles | null {\n const notes = new StyleNotes();\n const writer = { ...writerOf(snapshot), directed: snapshot.directed };\n const values = readValues(snapshot, writer, notes, context);\n if (writer.vocabulary === \"ogdf\") {\n placeOgdfClusterLabels(snapshot, values.node);\n }\n const blockText = graphText(snapshot, GML_STYLE_BLOCK_KEY);\n const block = blockText === null ? null : blockWithValues(snapshot, blockText);\n if (block !== null) {\n exactFromBlock(snapshot, block, values);\n }\n if (writer.tool === null && !values.found && block === null) {\n return null;\n }\n if (writer.tool === \"gephi\" && block === null) {\n // Gephi draws every edge in its end nodes' mixed color (EdgeColor MIXED), whatever its own\n delete values.edge.color;\n // and as thick as its weight, the `value` Gephi writes, also where the reader kept `value` as plain data\n if (snapshot.edges.byRole(\"weight\") === null && snapshot.edges.has(\"value\")) {\n values.edge.width = Array.from({ length: snapshot.edgeCount }, (_, e) => {\n const w = cellOf(snapshot.edges, \"value\", e);\n if (typeof w !== \"number\" || !Number.isFinite(w)) {\n return null;\n }\n // a weight of 0 or below is drawn 1 wide, so the edge stays visible\n return w > 0 ? w : 1;\n });\n }\n hideGephiDroppedEdges(snapshot, values.edge);\n }\n const none = { rules: [], columns: new Map<string, StyleColumn>() };\n const gephi =\n writer.tool === \"gephi\"\n ? gephiRules(\n snapshot,\n { fill: values.node.fill, width: values.node.width },\n { color: values.edge.color, width: values.edge.width },\n context.budget,\n )\n : { node: none, edge: none };\n return {\n canonical: true,\n dialect: writer.dialect,\n tool: writer.tool,\n units: writer.units,\n node: { values: values.node, ...gephi.node },\n edge: { values: values.edge, ...gephi.edge },\n notes: notes.list(),\n opacityInColor: true,\n block,\n // the graphics records and the per-element style values of a file graphty wrote hold styles, not data\n readFrom: { node: styleColumns(snapshot.nodes), edge: styleColumns(snapshot.edges) },\n };\n}\n\n// ============================================================ writing\n\n/**\n * What the GML writer holds natively: yEd GML `graphics` and `LabelGraphics`. The `graphty.styles` block and the\n * per-element values its rules read are keys of the graph and of each element.\n * @category Built-in formats\n */\nexport const GML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({\n tool: \"yed\",\n node: Object.freeze([\n \"fill\",\n \"fillOpacity\",\n \"borderColor\",\n \"borderWidth\",\n \"borderStyle\",\n \"shape\",\n \"width\",\n \"height\",\n \"label\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"labelWeight\",\n \"labelItalic\",\n ] as const),\n edge: Object.freeze([\n \"color\",\n \"opacity\",\n \"width\",\n \"lineStyle\",\n \"sourceArrow\",\n \"targetArrow\",\n \"curved\",\n \"bends\",\n \"sourcePort\",\n \"targetPort\",\n \"label\",\n \"labelColor\",\n \"labelSize\",\n \"labelFont\",\n \"labelWeight\",\n \"labelItalic\",\n ] as const),\n block: \"native\",\n});\n\n/** Every style key a reader here reads, per record: the writer replaces them all. */\nconst OWNED: Readonly<Record<\"node\" | \"edge\" | \"label\", ReadonlySet<string>>> = {\n node: new Set([\n \"fill\",\n \"fill2\",\n \"hasFill\",\n \"outline\",\n \"hasOutline\",\n \"outlineWidth\",\n \"outline_width\",\n \"outlineStyle\",\n \"width\",\n \"line\",\n \"lineWidth\",\n \"stipple\",\n \"w\",\n \"h\",\n \"type\",\n ]),\n edge: new Set([\n \"fill\",\n \"width\",\n \"lineWidth\",\n \"style\",\n \"stipple\",\n \"arrow\",\n \"sourceArrow\",\n \"targetArrow\",\n \"source_arrow\",\n \"target_arrow\",\n \"smoothBends\",\n ]),\n label: new Set([\"text\", \"color\", \"fill\", \"fontSize\", \"fontName\", \"fontStyle\", \"visible\"]),\n};\n\n/** One element's value of a property. */\ntype Get = (property: string) => StyleValue | null;\n\n/** Records a value written as the nearest one yEd has. */\ntype Approximate = (property: string, value: StyleValue) => void;\n\n/**\n * A node's yEd `graphics` keys from its values.\n * @param get - the node's values\n * @param approximate - records approximations\n * @returns the keys\n */\nfunction nodeGraphics(get: Get, approximate: Approximate): Rec {\n const g: Rec = {};\n const width = get(\"width\");\n const height = get(\"height\");\n if (typeof width === \"number\") {\n g.w = width;\n }\n if (typeof height === \"number\") {\n g.h = height;\n }\n const shape = get(\"shape\");\n if (typeof shape === \"string\") {\n const w = yedValue(YED_SHAPES, shape, shape === \"vee\" ? \"triangle\" : \"rectangle\");\n if (!w.exact) {\n approximate(\"shape\", shape);\n }\n g.type = w.value;\n }\n const fill = get(\"fill\");\n const fillOpacity = get(\"fillOpacity\");\n if (typeof fill === \"string\") {\n g.fill = yedColor(fill, fillOpacity);\n } else if (fillOpacity === 0) {\n g.hasFill = 0;\n }\n const borderColor = get(\"borderColor\");\n const borderWidth = get(\"borderWidth\");\n const borderStyle = get(\"borderStyle\");\n if (typeof borderColor === \"string\") {\n g.outline = borderColor.toUpperCase();\n }\n if (typeof borderStyle === \"string\") {\n const w = yedValue(YED_LINES, borderStyle, \"line\");\n if (!w.exact) {\n approximate(\"borderStyle\", borderStyle);\n }\n g.outlineStyle = w.value;\n }\n if (borderWidth === 0) {\n g.hasOutline = 0;\n } else if (typeof borderWidth === \"number\") {\n g.outlineWidth = borderWidth;\n }\n return g;\n}\n\n/**\n * An edge's yEd `graphics` keys from its values.\n * @param get - the edge's values\n * @param approximate - records approximations\n * @returns the keys\n */\nfunction edgeGraphics(get: Get, approximate: Approximate): Rec {\n const g: Rec = {};\n const color = get(\"color\");\n if (typeof color === \"string\") {\n g.fill = yedColor(color, get(\"opacity\"));\n }\n const width = get(\"width\");\n if (typeof width === \"number\") {\n g.width = width;\n }\n const lineStyle = get(\"lineStyle\");\n if (typeof lineStyle === \"string\") {\n g.style = yedSpelled(\n YED_LINES,\n lineStyle,\n lineStyle === \"long-dash\" ? \"dashed\" : \"line\",\n \"lineStyle\",\n approximate,\n );\n }\n for (const property of [\"sourceArrow\", \"targetArrow\"]) {\n const arrow = get(property);\n if (typeof arrow === \"string\") {\n g[property] = yedSpelled(YED_ARROWS, arrow, \"standard\", property, approximate);\n }\n }\n const curved = get(\"curved\");\n if (typeof curved === \"boolean\") {\n g.smoothBends = curved ? 1 : 0;\n }\n return g;\n}\n\n/**\n * An element's yEd `LabelGraphics` keys from its values, or null when it has no label text.\n * @param get - the element's values\n * @returns the keys\n */\nfunction labelGraphics(get: Get): Rec | null {\n const text = get(\"label\");\n if (typeof text !== \"string\" || text.trim().length === 0) {\n return null;\n }\n const lg: Rec = { text };\n const color = get(\"labelColor\");\n if (typeof color === \"string\") {\n lg.color = color.toUpperCase();\n }\n const size = get(\"labelSize\");\n if (typeof size === \"number\") {\n lg.fontSize = size;\n }\n const font = get(\"labelFont\");\n if (typeof font === \"string\") {\n // a Java face is written back as the logical font yEd draws in it\n lg.fontName = yedFontName(font);\n }\n const weight = get(\"labelWeight\");\n const italic = get(\"labelItalic\");\n if (weight !== null || italic !== null) {\n const style = (weight === \"bold\" ? \"bold\" : \"\") + (italic === true ? \"italic\" : \"\");\n lg.fontStyle = style.length === 0 ? \"plain\" : style;\n }\n return lg;\n}\n\n/**\n * A record with the style keys replaced: the kept keys of the old record, then the written ones.\n * @param old - the record the element had, or anything else\n * @param owned - the style keys\n * @param written - the new style keys\n * @returns the record, or undefined (an unset cell) when it is empty\n */\nfunction merged(old: unknown, owned: ReadonlySet<string>, written: Rec): Rec | undefined {\n const out: Rec = {};\n if (isRec(old)) {\n for (const [k, v] of Object.entries(old)) {\n if (!owned.has(k)) {\n out[k] = v;\n }\n }\n }\n Object.assign(out, written);\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\n/**\n * An element's `LabelGraphics` value with its first label's style keys replaced; further labels are kept.\n * @param old - the value the element had\n * @param written - the new label keys, or null for no label\n * @returns the value, or undefined (an unset cell)\n */\nfunction mergedLabels(old: unknown, written: Rec | null): unknown {\n const labels = Array.isArray(old) ? old : [old];\n const head = merged(labels[0], OWNED.label, written ?? {});\n const rest = labels.slice(1).filter((l) => l !== null && l !== undefined);\n if (rest.length === 0) {\n return head;\n }\n return head === undefined ? rest : [head, ...rest];\n}\n\n/**\n * For a file graphty wrote: where a value read from the graphics is what the writer writes for the block's own value\n * (a pentagon written as a rectangle, an opacity rounded to 255 steps), the block's exact value is the truth, so a\n * re-import gives back the same rules; a value another program changed since stays the truth.\n * @param snapshot - the graph\n * @param text - the block's text\n * @param read - the values read, changed in place\n * @param read.node - the node values\n * @param read.edge - the edge values\n */\nfunction exactFromBlock(\n snapshot: GraphSnapshot,\n text: string,\n read: { readonly node: ValueColumns; readonly edge: ValueColumns },\n): void {\n const notes = new StyleNotes();\n takeFromBlock(snapshot, text, \"gml\", (target) => ({\n values: read[target],\n properties: GML_STYLE_CAPABILITIES[target],\n writes: GML_STYLE_CAPABILITIES[target],\n readBack: (_i, want) => {\n const back = writtenAndReadBack(target, want, notes);\n return (property) => back.get(property) ?? null;\n },\n }));\n}\n\n/**\n * An element's values written as the writer writes them and read back as the reader reads them.\n * @param target - nodes or edges\n * @param want - its values\n * @param notes - a scratch for the notes the round trip makes\n * @returns the values read back, by property\n */\nfunction writtenAndReadBack(target: StyleTarget, want: Get, notes: StyleNotes): Map<string, StyleValue> {\n const ignore: Approximate = () => undefined;\n const g = target === \"node\" ? nodeGraphics(want, ignore) : edgeGraphics(want, ignore);\n const back = new Map<string, StyleValue>();\n readElement(\n target,\n g,\n labelGraphics(want) ?? undefined,\n undefined,\n GRAPHTY_WRITER,\n (property, value) => {\n if (value !== null) {\n back.set(property, value);\n }\n },\n (property) => ({ notes, target, property }),\n );\n return back;\n}\n\n/** A GML export with styles worked out. */\ninterface GmlStyledExport {\n /** The graph to write: yEd graphics written from the styles, the block and the per-element style values added. */\n readonly snapshot: GraphSnapshot;\n /** W_STYLE_APPROXIMATED for every value written as the nearest one yEd has. */\n readonly notes: readonly LossNote[];\n}\n\n/**\n * Works out a GML export with styles: every node's and edge's `graphics` and `LabelGraphics` records get yEd's keys\n * for what graphty draws in place of every style key they had (positions, bends and other keys stay), the\n * `graphty.styles` block becomes the graph key `graphty_styles` and the per-element values its rules read become\n * element keys. Should two style columns map to one key, the values go inside the block instead.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles, or undefined when none are written\n * @returns the styled export, or null without styles\n */\nexport function gmlStyledExport(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput | undefined,\n): GmlStyledExport | null {\n if (input === undefined) {\n return null;\n }\n const approximated = new StyleApproximations();\n const out = snapshot.withColumns();\n const renames: LossNote[] = [];\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n writeGraphicsColumns(snapshot, input, target, table, approximated);\n // the per-element style values of an earlier write go; a data column the rules read, or any other whose key\n // would read back as a style value, is renamed out of the keys the style values take\n const read = dataRead(input.rules.styles.rules, target);\n for (const name of table.names().filter((c) => mangleGmlKey(c).startsWith(TAG_PREFIX))) {\n const col = table.get(name);\n table.remove(name);\n if (col !== null && !(name.startsWith(TAG_PREFIX) && !read.has(name))) {\n renames.push(renameDataColumn(table, target, name, col));\n }\n }\n }\n let { block } = input;\n const keys = [...input.rules.columns.node.keys()].map((k) => tagKey(\"node\", k));\n const edgeKeys = [...input.rules.columns.edge.keys()].map((k) => tagKey(\"edge\", k));\n if (new Set(keys).size !== keys.length || new Set(edgeKeys).size !== edgeKeys.length) {\n block = writeStyleBlock(input.rules, { inlineColumns: true, snapshot });\n } else {\n setTagColumns(out, input);\n }\n out.graph.set(GML_STYLE_BLOCK_KEY, [block], { dtype: \"string\" });\n const notes: LossNote[] = [\n ...renames,\n ...(block === input.block ? [] : styleBlockLosses(block, input.rules.styles.rules.length, \"size\")),\n ...approximated.notes(\"yEd's GML\"),\n ];\n return { snapshot: out, notes };\n}\n\n/**\n * Writes every element's `graphics` and `LabelGraphics` records of a target with yEd's keys for what graphty draws,\n * keeping the keys that are not style keys.\n * @param snapshot - the graph handed to the exporter\n * @param input - the styles\n * @param target - nodes or edges\n * @param table - the target's table being written, changed in place\n * @param approximated - where approximations are counted\n */\nfunction writeGraphicsColumns(\n snapshot: GraphSnapshot,\n input: ExporterStyleInput,\n target: StyleTarget,\n table: GraphSnapshot[\"nodes\"],\n approximated: StyleApproximations,\n): void {\n const n = target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount;\n const approximate: Approximate = (property, value) => {\n approximated.add(target, property, value);\n };\n const get = elementValues((t, p) => input.picture(t, p as never), target, GML_STYLE_CAPABILITIES[target]);\n const getNode = elementValues((t, p) => input.picture(t, p as never), \"node\", GML_STYLE_CAPABILITIES.node);\n const size = (k: number): BendPoint => {\n const [w, h] = [getNode(k)(\"width\"), getNode(k)(\"height\")];\n return typeof w === \"number\" && typeof h === \"number\" ? [w, h] : sizeOf(snapshot, k);\n };\n const graphics: unknown[] = [];\n const labels: unknown[] = [];\n for (let i = 0; i < n; i++) {\n const g = target === \"node\" ? nodeGraphics(get(i), approximate) : edgeGraphics(get(i), approximate);\n if (target === \"edge\") {\n const line = routeLine(snapshot, get(i), i, size);\n if (line !== null) {\n g.Line = line;\n }\n }\n graphics.push(merged(cellOf(table, \"graphics\", i), OWNED[target], g));\n labels.push(mergedLabels(cellOf(table, \"LabelGraphics\", i), labelGraphics(get(i))));\n }\n for (const [name, cells] of [\n [\"graphics\", graphics],\n [\"LabelGraphics\", labels],\n ] as const) {\n if (cells.some((c) => c !== undefined)) {\n table.set(name, cells, { dtype: \"json\", nullable: true });\n } else if (table.has(name)) {\n table.remove(name);\n }\n }\n}\n\n/**\n * An edge's `Line` from its `bends`, `sourcePort` and `targetPort` values: from its source port (the node's center\n * without one) through the bends placed between the node centers (a self-loop's around its node) to its target port,\n * so the route reads back as written.\n * @param snapshot - the graph handed to the exporter\n * @param get - the edge's values\n * @param e - the edge's row\n * @param size - each node's written width and height\n * @returns the `Line` record, or null without a value or without both centers\n */\nfunction routeLine(snapshot: GraphSnapshot, get: Get, e: number, size: (k: number) => BendPoint): Rec | null {\n const [s, t] = [snapshot.edgeSource(e), snapshot.edgeTarget(e)];\n const source = centerOf(snapshot, s);\n const target = centerOf(snapshot, t);\n if (![...source, ...target].every(Number.isFinite)) {\n return null;\n }\n const bends = get(\"bends\");\n let points: BendPoint[] | null = null;\n if (typeof bends === \"string\") {\n points =\n s === t ? nodeOffsetsToPoints(source, size(s), bends, true) : bendsToPoints(source, target, bends, true);\n }\n const port = (property: string, k: number, center: BendPoint): BendPoint | null => {\n const value = get(property);\n return typeof value === \"string\" ? (nodeOffsetsToPoints(center, size(k), value, true)?.[0] ?? null) : null;\n };\n const from = port(\"sourcePort\", s, source);\n const to = port(\"targetPort\", t, target);\n if (points === null && from === null && to === null) {\n return null;\n }\n return { point: [from ?? source, ...(points ?? []), to ?? target].map(([x, y]) => ({ x, y })) };\n}\n\n/**\n * Writes a data column under a name out of the keys the style values take.\n * @param table - the table, changed in place\n * @param target - nodes or edges\n * @param name - the column's name\n * @param col - the column\n * @returns the note saying so\n */\nfunction renameDataColumn(\n table: GraphSnapshot[\"nodes\"],\n target: StyleTarget,\n name: string,\n col: NonNullable<ReturnType<GraphSnapshot[\"nodes\"][\"get\"]>>,\n): LossNote {\n let renamed = `data_${name}`;\n let k = 2;\n while (table.has(renamed)) {\n renamed = `data_${name}_${String(k)}`;\n k++;\n }\n table.set(renamed, col);\n return Object.freeze({\n code: KEY_MANGLED_CODE,\n message: `${target} column \"${name}\" is written as \"${renamed}\": keys starting with ${TAG_PREFIX} hold graphty's style values`,\n column: name,\n count: null,\n });\n}\n\n/**\n * Sets the per-element values the rules read as element keys.\n * @param out - the graph, changed in place\n * @param input - the styles\n */\nfunction setTagColumns(out: GraphSnapshot, input: ExporterStyleInput): void {\n for (const target of [\"node\", \"edge\"] as const) {\n const table = target === \"node\" ? out.nodes : out.edges;\n for (const [key, col] of input.rules.columns[target]) {\n const kinds = new Set(col.filter((v) => v !== null).map((v) => typeof v));\n const text = kinds.size > 1 || kinds.has(\"string\");\n let dtype: \"string\" | \"bool\" | \"f64\" = kinds.has(\"boolean\") ? \"bool\" : \"f64\";\n if (text) {\n dtype = \"string\";\n }\n table.set(tagKey(target, key), text ? col.map((v) => (v === null ? null : String(v))) : col, { dtype });\n }\n }\n}\n","/**\n * The GML exporter (design section 8.5, research note 07 sections 2.2 and 9): writes a snapshot in\n * the NetworkX dialect of GML. Node ids must be integers (`idCharset: \"integer\"`; `sanitizeIds:\n * \"mangle\"` renumbers the others and keeps the original in a `graphty_originalId` key the importer\n * restores); columns are written per dtype (`int` for the integer dtypes, `real` with a decimal\n * point guaranteed for f32 / f64 so the dtype survives a re-import, quoted strings with `&#NN;`\n * references, repeated keys for lists with the `_networkx_list_start` marker for one-element\n * lists and `\"[]\"` for empty ones, nested records for json objects); the position role becomes\n * `graphics [ x y z ]` merged with the node's `graphics` json record; graph columns are written\n * inside `graph [ ]` (or at the top level when the importer found them there); `Creator` and\n * `Version` come from the metadata.\n *\n * check() reports, before anything is written, the capability gaps of the common check plus the\n * GML-specific ones: json columns holding numbers (JSON cannot keep the int / real distinction:\n * `W_GML_RECORD_NUMBER_TYPE`), booleans (written 1 / 0) or nulls (omitted), arrays nested in\n * arrays (no GML spelling; export() throws), column names and record keys that are not GML keys\n * or collide with the structural keys (`E_GML_INVALID_KEY` / `E_GML_RESERVED_KEY`, or\n * `W_GML_KEY_MANGLED` under `sanitizeKeys: \"mangle\"`), and graphics / position overlaps.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n GraphFormatError,\n type GraphSnapshot,\n type JsonColumn,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { DICT_SAMPLE_ROWS, DictHeuristic } from \"../../common/attributes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteGmlString } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n countMixedEdges,\n LOSS,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatGmlReal, formatInteger } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { agree, plural } from \"../../common/plural.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport type { ExporterStyleOptions } from \"../../styles/io/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { GML_STYLE_CAPABILITIES, gmlStyledExport } from \"./styles.js\";\nimport {\n EMPTY_LIST_TEXT,\n isGmlKey,\n KEY_MANGLED_CODE,\n LIST_START_MARKER,\n mangleGmlKey,\n ORIGINAL_ID_KEY,\n} from \"./syntax.js\";\n\n/** What the writer takes: the format's options, the common ones and the styles. */\ntype GmlWriteOptions = GmlExportOptions & CommonExportOptions & ExporterStyleOptions;\n\n/**\n * The format-specific options of the GML exporter.\n * @category Built-in formats\n */\nexport interface GmlExportOptions extends CommonExportOptions {\n /**\n * The edge key the weights are written under. The default is the key a GML import read them\n * from, else `value`.\n * @defaultValue as read, else \"value\"\n */\n weightKey?: string | undefined;\n /**\n * What to do with an attribute name or record key that GML cannot write: one that is not a GML\n * key (letters, digits and `_`, starting with a letter, so `Edge Label` is not one), or one that\n * GML uses itself in that record: `id` for a node attribute; `source`, `target` and `directed`\n * for an edge attribute; `node`, `edge`, `directed` and `multigraph` for a graph attribute. A node\n * attribute named `source` is fine. \"error\" makes the save fail, \"mangle\" rewrites the name (`.`\n * and other characters become `_`, a clash gets a `_2` suffix) and checkExport() lists each\n * rename. An options object shared by saves to several formats that include GML should set it.\n * @defaultValue \"error\"\n */\n sanitizeKeys?: \"error\" | \"mangle\" | undefined;\n}\n\n/**\n * A nested (json) attribute holds numbers; GML records do not keep the difference between integers and decimals.\n * @category Issue and loss codes\n */\nexport const RECORD_NUMBER_TYPE_CODE = \"W_GML_RECORD_NUMBER_TYPE\";\n/**\n * A json column holds booleans, written as 1 / 0.\n * @category Issue and loss codes\n */\nexport const RECORD_BOOLEAN_CODE = \"W_GML_RECORD_BOOLEAN\";\n/**\n * A json column holds nulls, which GML cannot write; the key (or the row) is omitted.\n * @category Issue and loss codes\n */\nexport const RECORD_NULL_CODE = \"W_GML_RECORD_NULL\";\n/**\n * An attribute holds an array inside an array, which GML cannot write; the save fails.\n * @category Issue and loss codes\n */\nexport const NESTED_ARRAY_CODE = \"E_GML_NESTED_ARRAY\";\n/**\n * A nested (json) attribute holds arrays; they are written as repeated keys and read back as a list attribute.\n * @category Issue and loss codes\n */\nexport const JSON_ARRAY_CODE = \"W_GML_JSON_ARRAY\";\n/**\n * A column name or record key is not a GML key; export() throws unless sanitizeKeys is \"mangle\".\n * @category Issue and loss codes\n */\nexport const INVALID_KEY_CODE = \"E_GML_INVALID_KEY\";\n/**\n * A column name collides with a structural GML key; export() throws unless sanitizeKeys is \"mangle\".\n * @category Issue and loss codes\n */\nexport const RESERVED_KEY_CODE = \"E_GML_RESERVED_KEY\";\nexport { KEY_MANGLED_CODE } from \"./syntax.js\";\n/**\n * A position column with more than three components; x, y and z are written.\n * @category Issue and loss codes\n */\nexport const POSITION_COMPONENTS_CODE = \"W_GML_POSITION_COMPONENTS\";\n/**\n * A node's graphics record has x / y / z keys the position column replaces.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_OVERRIDDEN_CODE = \"W_GML_GRAPHICS_OVERRIDDEN\";\n/**\n * A node's graphics value is not a record and cannot hold the position; export() throws.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_CONFLICT_CODE = \"E_GML_GRAPHICS_CONFLICT\";\n\n/**\n * The default weight key (design section 8.4: GML weights are read from `value` by default).\n * @category Plugin helpers\n */\nexport const DEFAULT_WEIGHT_KEY = \"value\";\n\n/** The roles GML has a key for (`label`, the edge `id` and `key`); every other role is reported. */\nconst KEPT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"key\"]);\n\n/** The key the importer maps each kept role back from (the column name after re-import). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"label\",\n id: \"id\",\n key: \"key\",\n});\n\nconst GML_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"integer\",\n dtypes: [\"i32\", \"f64\", \"string\", \"dict\", \"json\"],\n components: false,\n lists: true,\n json: true,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** Roles whose columns are never written as attributes (structural, or dropped per the capabilities). */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\nconst NODE_RESERVED: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_RESERVED: ReadonlySet<string> = new Set([\"source\", \"target\", \"directed\"]);\nconst GRAPH_RESERVED: ReadonlySet<string> = new Set([\"node\", \"edge\", \"directed\", \"multigraph\"]);\nconst TOP_RESERVED: ReadonlySet<string> = new Set([\"graph\"]);\nconst NUMBER_TEXT = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/;\n\n/** The resolved options of one export. */\ninterface GmlExportPlan {\n readonly common: ResolvedExportOptions;\n readonly weightKey: string;\n readonly mangle: boolean;\n}\n\n/** What one json column holds that GML cannot write exactly. */\ninterface JsonStats {\n numbers: number;\n booleans: number;\n nulls: number;\n nestedArrays: number;\n arrays: number;\n invalidKeys: number;\n}\n\n/** The kinds of value already counted for one row while inspecting a json value. */\ninterface SeenFlags {\n numbers: boolean;\n booleans: boolean;\n nulls: boolean;\n nested: boolean;\n}\n\n/** The columns of one table selected for writing, with their keys. */\ninterface WrittenColumn {\n readonly column: Column;\n readonly key: string;\n}\n\n/**\n * Resolve the options of one export call.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planOf(snapshot: GraphSnapshot, options: (GmlExportOptions & CommonExportOptions) | undefined): GmlExportPlan {\n const common = resolveExportOptions(options);\n const mode = options?.sanitizeKeys ?? \"error\";\n if (mode !== \"error\" && mode !== \"mangle\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option sanitizeKeys: ${JSON.stringify(mode)} is not \"error\" or \"mangle\"`,\n {\n option: \"sanitizeKeys\",\n found: mode,\n },\n );\n }\n let weightKey = options?.weightKey;\n if (weightKey === undefined) {\n const origin = snapshot.meta.weightOrigin;\n weightKey = origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : DEFAULT_WEIGHT_KEY;\n } else if (typeof weightKey !== \"string\" || !isGmlKey(weightKey)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option weightKey: ${JSON.stringify(weightKey)} is not a GML key`, {\n option: \"weightKey\",\n found: weightKey,\n });\n }\n return { common, weightKey, mangle: mode === \"mangle\" };\n}\n\n/**\n * Whether a column is written as an attribute (its role is neither structural nor dropped).\n * @param column - the column\n * @returns true when written\n */\nfunction isWritten(column: Column): boolean {\n const { role } = column.meta;\n return role === null || !SKIPPED_ROLES.has(role);\n}\n\n/**\n * The key a column is written under.\n * @param meta - the column metadata\n * @returns origin.id when the column came from GML under that key (its name is the key, or the importer's\n * `<key>#...` rename of it), else the name: a column renamed since it was read is written under its new name\n */\nfunction preferredKey(meta: ColumnMeta): string {\n const { origin, name } = meta;\n if (origin?.format !== \"gml\" || origin.id === null) {\n return name;\n }\n return name === origin.id || name.startsWith(`${origin.id}#`) ? origin.id : name;\n}\n\n/**\n * Whether a snapshot has explicit weights to write.\n * @param snapshot - the snapshot\n * @returns true when weighted\n */\nfunction hasWeights(snapshot: GraphSnapshot): boolean {\n return snapshot.flags.weighted;\n}\n\n/**\n * Whether the graph column is a top-level key (the importer's `extra.gmlTopLevel`).\n * @param column - the column\n * @returns true for a top-level key\n */\nfunction isTopLevel(column: Column): boolean {\n return column.meta.extra.gmlTopLevel === true;\n}\n\n/**\n * The text of a `Version` value: bare when it is a number text, quoted otherwise.\n * @param text - the version text\n * @returns the GML value\n */\nfunction versionText(text: string): string {\n return NUMBER_TEXT.test(text) ? text : quoteGmlString(text);\n}\n\n/**\n * A node or edge table's label role column, which is written under \"label\" (the key the importer\n * gives the role back to): the key is marked used so a plain column of that name cannot have it.\n * @param columns - the written columns\n * @param label - the table name\n * @param used - the keys already taken, gaining \"label\" when there is a label role column\n * @returns the label role column, or undefined\n */\nfunction labelRoleColumn(columns: readonly Column[], label: string, used: Set<string>): Column | undefined {\n if (label !== \"node\" && label !== \"edge\") {\n return undefined;\n }\n const column = columns.find((c) => c.meta.role === \"label\");\n if (column !== undefined) {\n used.add(\"label\");\n }\n return column;\n}\n\n/**\n * Select the written columns of a table and assign their keys, recording invalid and reserved\n * keys as notes (or rewriting them under mangle).\n * @param table - the columns\n * @param reserved - the structural keys of the table\n * @param label - the table name for messages\n * @param plan - the export plan\n * @param notes - where to record\n * @param filter - an extra selection predicate\n * @returns the written columns with their keys\n */\nfunction selectColumns(\n table: Iterable<Column>,\n reserved: ReadonlySet<string>,\n label: string,\n plan: GmlExportPlan,\n notes: LossNote[] | null,\n filter: (column: Column) => boolean = (): boolean => true,\n): WrittenColumn[] {\n const used = new Set<string>(reserved);\n const out: WrittenColumn[] = [];\n const columns = [...table].filter((c) => isWritten(c) && filter(c));\n const labelRole = labelRoleColumn(columns, label, used);\n for (const column of columns) {\n const preferred = column === labelRole ? \"label\" : preferredKey(column.meta);\n let key = preferred;\n const valid = isGmlKey(preferred);\n const taken = column !== labelRole && used.has(preferred);\n if (!valid || taken) {\n const code = valid ? RESERVED_KEY_CODE : INVALID_KEY_CODE;\n let why = \"is not a GML key\";\n if (valid) {\n why = reserved.has(preferred) ? \"collides with a structural GML key\" : \"repeats another column's key\";\n }\n if (!plan.mangle) {\n if (notes === null) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `${label} column \"${column.meta.name}\" ${why}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column: column.meta.name,\n key: preferred,\n },\n );\n }\n notes.push(\n note(\n code,\n `${label} column \"${column.meta.name}\" ${why}; the save fails unless sanitizeKeys is \"mangle\"`,\n column.meta.name,\n ),\n );\n continue;\n }\n key = uniqueKey(valid ? preferred : mangleGmlKey(preferred), used);\n notes?.push(\n note(\n KEY_MANGLED_CODE,\n `${label} column \"${column.meta.name}\" is written as \"${key}\"`,\n column.meta.name,\n ),\n );\n }\n used.add(key);\n out.push({ column, key });\n }\n return out;\n}\n\n/**\n * A key not yet used: the base, else base_2, base_3...\n * @param base - a valid key\n * @param used - the keys taken\n * @returns a free key\n */\nfunction uniqueKey(base: string, used: ReadonlySet<string>): string {\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n return candidate;\n}\n\n/**\n * Build a frozen note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n * @returns the note\n */\nfunction note(code: string, message: string, column: string | null = null, count: number | null = null): LossNote {\n return Object.freeze({ code, message, column, count });\n}\n\n/**\n * Count a kind of json value once per row.\n * @param seen - the flags already counted for this row\n * @param flag - the flag of the kind\n * @param stats - the counters\n * @param counter - the counter of the kind\n */\nfunction countOnce(seen: SeenFlags, flag: keyof SeenFlags, stats: JsonStats, counter: keyof JsonStats): void {\n if (!seen[flag]) {\n seen[flag] = true;\n stats[counter]++;\n }\n}\n\n/**\n * Inspect a JSON value for what GML cannot write exactly.\n * @param value - the value\n * @param stats - the counters to update (each counted at most once per call for numbers / booleans / nulls)\n * @param inArray - whether the value is an array item\n * @param seen - the flags already counted for this row\n */\nfunction inspectJson(value: unknown, stats: JsonStats, inArray: boolean, seen: SeenFlags): void {\n if (value === null) {\n countOnce(seen, \"nulls\", stats, \"nulls\");\n return;\n }\n switch (typeof value) {\n case \"number\":\n countOnce(seen, \"numbers\", stats, \"numbers\");\n return;\n case \"boolean\":\n countOnce(seen, \"booleans\", stats, \"booleans\");\n return;\n case \"string\":\n return;\n default:\n break;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n countOnce(seen, \"nested\", stats, \"nestedArrays\");\n }\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n return;\n }\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!isGmlKey(key)) {\n stats.invalidKeys++;\n }\n inspectJson(record[key], stats, false, seen);\n }\n}\n\n/**\n * A row count in words.\n * @param count - the count\n * @returns the count and the word row, pluralised\n */\nfunction rowCount(count: number): string {\n return `${count} row${plural(count)}`;\n}\n\n/**\n * Record a note for a counter that is not zero.\n * @param notes - where to record\n * @param count - the counter\n * @param code - the note code\n * @param text - the note message\n * @param column - the column name\n */\nfunction pushCounted(notes: LossNote[], count: number, code: string, text: string, column: string): void {\n if (count > 0) {\n notes.push(note(code, text, column, count));\n }\n}\n\n/**\n * The GML-specific notes of one table's json columns.\n * @param columns - the written columns\n * @param label - the table name\n * @param plan - the export plan\n * @param notes - where to record\n */\nfunction jsonNotes(columns: readonly WrittenColumn[], label: string, plan: GmlExportPlan, notes: LossNote[]): void {\n for (const { column } of columns) {\n const stats = jsonStatsOf(column);\n if (stats === null) {\n continue;\n }\n const { name } = column.meta;\n const where = `${label} column \"${name}\"`;\n const counted = (count: number, code: string, text: string): void => {\n pushCounted(notes, count, code, text, name);\n };\n counted(\n stats.numbers,\n RECORD_NUMBER_TYPE_CODE,\n `${where} holds numbers in ${rowCount(stats.numbers)}; GML records cannot keep the int / real distinction`,\n );\n counted(\n stats.booleans,\n RECORD_BOOLEAN_CODE,\n `${where} holds booleans in ${rowCount(stats.booleans)}; written as 1 / 0`,\n );\n counted(\n stats.nulls,\n RECORD_NULL_CODE,\n `${where} holds nulls in ${rowCount(stats.nulls)}; GML has no null, the key is omitted`,\n );\n counted(\n stats.arrays,\n JSON_ARRAY_CODE,\n `${where} holds arrays as values in ${rowCount(stats.arrays)}; written as repeated keys, they re-import as a list`,\n );\n counted(\n stats.nestedArrays,\n NESTED_ARRAY_CODE,\n `${where} holds arrays nested in arrays in ${rowCount(stats.nestedArrays)}; GML cannot write them and the save fails`,\n );\n const keys = `${stats.invalidKeys} record key${plural(stats.invalidKeys)} ${agree(stats.invalidKeys, \"is\", \"are\")} not GML keys`;\n counted(\n stats.invalidKeys,\n plan.mangle ? KEY_MANGLED_CODE : INVALID_KEY_CODE,\n plan.mangle\n ? `${where}: ${keys} and are rewritten`\n : `${where}: ${keys}; the save fails unless sanitizeKeys is \"mangle\"`,\n );\n }\n}\n\n/**\n * The json statistics of a json column, or of a list column with json items; null for other dtypes.\n * @param column - the column\n * @returns the stats, or null\n */\nfunction jsonStatsOf(column: Column): JsonStats | null {\n const stats: JsonStats = { numbers: 0, booleans: 0, nulls: 0, nestedArrays: 0, arrays: 0, invalidKeys: 0 };\n if (column.dtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const value = column.values[r];\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n if (Array.isArray(value)) {\n stats.arrays++;\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n } else {\n inspectJson(value, stats, false, seen);\n }\n }\n return stats;\n }\n if (column.dtype === \"list\" && column.meta.itemDtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n for (const item of column.sliceOf(r)) {\n inspectJson(item, stats, true, seen);\n }\n }\n return stats;\n }\n return null;\n}\n\n/**\n * The node position column when it can be mapped to graphics x / y / z: a numeric scalar column\n * with the position role.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction positionColumn(snapshot: GraphSnapshot): Column | null {\n const column = snapshot.nodes.byRole(\"position\");\n if (column === null) {\n return null;\n }\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return column;\n default:\n return null;\n }\n}\n\n/**\n * The node `graphics` json column, when present.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction graphicsColumn(snapshot: GraphSnapshot): JsonColumn | null {\n return snapshot.nodes.typed(\"graphics\", \"json\");\n}\n\n/**\n * The GML-specific notes about the position / graphics mapping.\n * @param snapshot - the snapshot\n * @param notes - where to record\n */\nfunction graphicsNotes(snapshot: GraphSnapshot, notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n if (position.meta.components > 3) {\n notes.push(\n note(\n POSITION_COMPONENTS_CODE,\n `node column \"${position.meta.name}\" has ${position.meta.components} components; only x, y and z are written`,\n position.meta.name,\n position.length - position.nullCount,\n ),\n );\n }\n const graphics = graphicsColumn(snapshot);\n if (graphics === null) {\n return;\n }\n let overridden = 0;\n let conflicts = 0;\n for (let r = 0; r < snapshot.nodeCount; r++) {\n if (!position.isSet(r) || !graphics.isSet(r)) {\n continue;\n }\n const value = graphics.values[r];\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n conflicts++;\n } else if (\"x\" in value || \"y\" in value || \"z\" in value) {\n overridden++;\n }\n }\n if (overridden > 0) {\n notes.push(\n note(\n GRAPHICS_OVERRIDDEN_CODE,\n `${overridden} node graphics record${plural(overridden)} ${agree(overridden, \"has\", \"have\")} x / y / z keys the position column replaces`,\n \"graphics\",\n overridden,\n ),\n );\n }\n if (conflicts > 0) {\n notes.push(\n note(\n GRAPHICS_CONFLICT_CODE,\n `${conflicts} node graphics value${plural(conflicts)} ${agree(conflicts, \"is\", \"are\")} not records and cannot hold the position; the save fails`,\n \"graphics\",\n conflicts,\n ),\n );\n }\n}\n\n/**\n * What the importer's own rules change on re-import of the written columns: an all-unset column\n * vanishes (GML writes cells, never declarations), a role-less column named like a role key\n * gains the role, and the dictionary heuristic of design section 5.4 turns a low-cardinality\n * string column into a dict (or a wide dict into a string).\n * @param columns - the written columns\n * @param domain - node or edge\n * @param notes - where to record\n */\nfunction reimportNotes(columns: readonly WrittenColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, key } of columns) {\n const { meta } = column;\n const set = column.length - column.nullCount;\n if (set === 0) {\n notes.push(\n note(\n LOSS.EMPTY_COLUMN,\n `${domain} column \"${meta.name}\" has no set cell and is not written: GML writes cells, never declarations`,\n meta.name,\n 0,\n ),\n );\n continue;\n }\n if (meta.role === null && (key === \"label\" || (domain === \"edge\" && (key === \"id\" || key === \"key\")))) {\n notes.push(\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${meta.name}\" is written under \"${key}\" and reads back with the ${key === \"label\" ? \"label\" : key} role`,\n meta.name,\n set,\n ),\n );\n continue;\n }\n if (column.dtype === \"list\" || !(column.dtype === \"string\" || column.dtype === \"dict\")) {\n continue;\n }\n const heuristic = new DictHeuristic(DICT_SAMPLE_ROWS);\n for (let r = 0; r < column.length && !heuristic.decided; r++) {\n if (column.isSet(r)) {\n heuristic.observe(column.value(r) as string);\n }\n }\n const readsAsDict = heuristic.decide() === \"dict\";\n if (column.dtype === \"string\" && readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as dict (low cardinality)`,\n meta.name,\n null,\n ),\n );\n } else if (column.dtype === \"dict\" && !readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as string (cardinality too high for a dict)`,\n meta.name,\n null,\n ),\n );\n }\n }\n}\n\n/**\n * The importer names the graphics-derived position column `position`, or `position#graphics`\n * when a plain `position` key is written next to it (design section 5.6); a position column\n * named otherwise reads back under that name.\n * @param snapshot - the snapshot\n * @param nodeColumns - the written node columns\n * @param notes - where to record\n */\nfunction positionNameNote(snapshot: GraphSnapshot, nodeColumns: readonly WrittenColumn[], notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n const { name } = position.meta;\n const plainPosition = nodeColumns.some((c) => c.key === \"position\");\n const reimportName = plainPosition ? \"position#graphics\" : \"position\";\n if (name !== reimportName) {\n notes.push(\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `node column \"${name}\" (position) is written as the graphics x / y / z keys and reads back as \"${reimportName}\"`,\n name,\n position.length - position.nullCount,\n ),\n );\n }\n}\n\n/**\n * Pre-flight: the common capability notes plus the GML-specific ones.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\nfunction check(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planOf(snapshot, options);\n const notes = checkCapabilities(snapshot, GML_CAPABILITIES, plan.common, {\n positionDtype: \"f64\",\n roles: KEPT_ROLES,\n roleNames: ROLE_NAMES,\n });\n const nodeReserved = new Set(NODE_RESERVED);\n if (\n (plan.common.sanitizeIds === \"mangle\" && countMangled(snapshot) > 0) ||\n snapshot.nodes.byRole(\"originalId\") !== null\n ) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n const nodeColumns = selectColumns(snapshot.nodes, nodeReserved, \"node\", plan, notes);\n const edgeColumns = selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, notes, (c) => c !== edgeIds);\n const graphColumns = selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, notes, (c) => !isTopLevel(c));\n const topColumns = selectColumns(snapshot.graph, topReserved, \"top-level\", plan, notes, isTopLevel);\n jsonNotes(nodeColumns, \"node\", plan, notes);\n jsonNotes(edgeColumns, \"edge\", plan, notes);\n jsonNotes(graphColumns, \"graph\", plan, notes);\n jsonNotes(topColumns, \"top-level\", plan, notes);\n graphicsNotes(snapshot, notes);\n positionNameNote(snapshot, nodeColumns, notes);\n reimportNotes(nodeColumns, \"node\", notes);\n reimportNotes(edgeColumns, \"edge\", notes);\n if (!hasWeights(snapshot)) {\n const clash = edgeColumns.find((c) => c.key === plan.weightKey);\n if (clash !== undefined) {\n notes.push(\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${clash.column.meta.name}\" is written under \"${plan.weightKey}\", the key the importer reads edge weights from; it reads back as the weight, not as a column`,\n clash.column.meta.name,\n clash.column.length - clash.column.nullCount,\n ),\n );\n }\n }\n const folding = pairFolding(snapshot);\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, \"is\", \"are\")} written as two directed edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n ),\n );\n }\n return Object.freeze(notes);\n}\n\n/**\n * The structural keys of the edge table: source, target, the weight key when weights are written,\n * and `id` when a role-id column is written as the edge id.\n * @param snapshot - the snapshot\n * @param plan - the export plan\n * @param edgeIds - the role-id edge column, or null\n * @returns the reserved keys\n */\nfunction edgeReservedKeys(snapshot: GraphSnapshot, plan: GmlExportPlan, edgeIds: Column | null): Set<string> {\n const reserved = new Set(EDGE_RESERVED);\n if (hasWeights(snapshot)) {\n reserved.add(plan.weightKey);\n }\n if (edgeIds !== null) {\n reserved.add(\"id\");\n }\n return reserved;\n}\n\n/**\n * The structural keys of the top level: graph, plus Creator and Version when the metadata writes them.\n * @param snapshot - the snapshot\n * @returns the reserved keys\n */\nfunction topReservedKeys(snapshot: GraphSnapshot): Set<string> {\n const reserved = new Set(TOP_RESERVED);\n if (snapshot.meta.creator !== null) {\n reserved.add(\"Creator\");\n }\n if (snapshot.meta.sourceFormat === \"gml\" && snapshot.meta.sourceVersion !== null) {\n reserved.add(\"Version\");\n }\n return reserved;\n}\n\n/**\n * How many node ids are not safe integers (what sanitizeIds \"mangle\" rewrites).\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countMangled(snapshot: GraphSnapshot): number {\n let count = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id !== \"number\" || !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n// ============================================================ writing\n\n/**\n * The GML text of a number by the dtype and origin of its column: an integer text for the integer\n * dtypes and for an f64 column that came from GML `int` values, a real text otherwise.\n * @param value - the value\n * @param meta - the column metadata\n * @returns the text\n */\nfunction numberText(value: number, meta: ColumnMeta): string {\n switch (meta.dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return formatGmlReal(value, \"f32\");\n default:\n if (meta.origin?.type === \"int\" && Number.isInteger(value)) {\n return formatInteger(value);\n }\n return formatGmlReal(value, \"f64\");\n }\n}\n\n/**\n * The GML text of a JSON scalar inside a record: integers as int, other numbers as real, strings\n * quoted, booleans as 1 / 0.\n * @param value - the scalar\n * @returns the text\n */\nfunction jsonScalarText(value: number | string | boolean): string {\n switch (typeof value) {\n case \"number\":\n return Number.isInteger(value) ? formatInteger(value) : formatGmlReal(value, \"f64\");\n case \"boolean\":\n return value ? \"1\" : \"0\";\n default:\n return quoteGmlString(value);\n }\n}\n\n/**\n * The GML text of a list item or components lane by the item dtype.\n * @param item - the item\n * @param itemDtype - the list's item dtype\n * @param meta - the list column metadata\n * @returns the text\n */\nfunction itemText(item: unknown, itemDtype: string, meta: ColumnMeta): string {\n switch (typeof item) {\n case \"number\":\n switch (itemDtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(item);\n case \"f32\":\n return formatGmlReal(item, \"f32\");\n case \"json\":\n return jsonScalarText(item);\n default:\n return meta.origin?.type === \"int\" && Number.isInteger(item)\n ? formatInteger(item)\n : formatGmlReal(item, \"f64\");\n }\n case \"boolean\":\n return item ? \"1\" : \"0\";\n case \"string\":\n return quoteGmlString(item);\n default:\n throw new GraphFormatError(\n \"E_COLUMN_TYPE\",\n `column \"${meta.name}\": a ${typeof item} list item cannot be written as GML`,\n {\n column: meta.name,\n found: typeof item,\n },\n );\n }\n}\n\n/** Writes lines with indentation into an array of parts. */\nclass GmlWriter {\n private readonly lines: string[] = [];\n\n private readonly mangle: boolean;\n\n /**\n * Create a writer.\n * @param mangle - whether record keys are rewritten rather than refused\n */\n constructor(mangle: boolean) {\n this.mangle = mangle;\n }\n\n /**\n * Take the lines written so far as one string.\n * @returns the text; the writer is empty afterwards\n */\n take(): string {\n const text = this.lines.join(\"\");\n this.lines.length = 0;\n return text;\n }\n\n /**\n * Write one `key value` line.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value text\n */\n line(indent: string, key: string, value: string): void {\n this.lines.push(`${indent}${key} ${value}\\n`);\n }\n\n /**\n * Write a raw line.\n * @param text - the line without its terminator\n */\n raw(text: string): void {\n this.lines.push(`${text}\\n`);\n }\n\n /**\n * Write one column cell of a row.\n * @param indent - the indentation\n * @param key - the key\n * @param column - the column\n * @param row - the row\n */\n cell(indent: string, key: string, column: Column, row: number): void {\n const { meta, dtype } = column;\n switch (dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const { components } = meta;\n if (components === 1) {\n this.line(indent, key, numberText(column.data[row], meta));\n } else {\n for (let k = 0; k < components; k++) {\n this.line(indent, key, numberText(column.data[row * components + k], meta));\n }\n }\n return;\n }\n case \"bool\":\n this.line(indent, key, column.value(row) === true ? \"1\" : \"0\");\n return;\n case \"dict\":\n case \"string\":\n this.line(indent, key, quoteGmlString(column.value(row) ?? \"\"));\n return;\n case \"list\":\n this.list(indent, key, column.sliceOf(row), meta.itemDtype ?? \"string\", meta);\n return;\n case \"json\":\n this.json(indent, key, column.values[row], meta.name);\n return;\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n }\n\n /**\n * Write a list as repeated keys with the NetworkX conventions.\n * @param indent - the indentation\n * @param key - the key\n * @param items - the items\n * @param itemDtype - the item dtype\n * @param meta - the column metadata\n */\n private list(indent: string, key: string, items: readonly unknown[], itemDtype: string, meta: ColumnMeta): void {\n if (items.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (items.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of items) {\n if (itemDtype === \"json\" && typeof item === \"object\") {\n this.json(indent, key, item, meta.name, true);\n } else {\n this.line(indent, key, itemText(item, itemDtype, meta));\n }\n }\n }\n\n /**\n * Write a JSON value: a record for an object, repeated keys for an array, a scalar otherwise;\n * null writes nothing.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value\n * @param column - the column name, for errors\n * @param inArray - whether the value is an array item (an array here has no GML spelling)\n */\n private json(indent: string, key: string, value: unknown, column: string, inArray = false): void {\n if (value === null || value === undefined) {\n return;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": an array nested in an array cannot be written as GML`,\n {\n reason: \"nested array\",\n column,\n },\n );\n }\n if (value.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (value.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of value) {\n this.json(indent, key, item, column, true);\n }\n return;\n }\n if (typeof value === \"object\") {\n this.record(indent, key, value as Record<string, unknown>, column);\n return;\n }\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") {\n this.line(indent, key, jsonScalarText(value));\n return;\n }\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `column \"${column}\": a ${typeof value} cannot be written as GML`, {\n column,\n found: typeof value,\n });\n }\n\n /**\n * Write a record `key [ ... ]`.\n * @param indent - the indentation\n * @param key - the key\n * @param record - the object\n * @param column - the column name, for errors\n * @param extra - lines to write first (the position of a graphics record), or null\n */\n record(\n indent: string,\n key: string,\n record: Record<string, unknown>,\n column: string,\n extra: readonly [string, string][] | null = null,\n ): void {\n this.raw(`${indent}${key} [`);\n const inner = `${indent} `;\n const used = new Set<string>();\n if (extra !== null) {\n for (const [k, v] of extra) {\n this.line(inner, k, v);\n used.add(k);\n }\n }\n for (const name of Object.keys(record)) {\n if (used.has(name) && extra !== null && (name === \"x\" || name === \"y\" || name === \"z\")) {\n continue;\n }\n const written = this.recordKey(name, used, column);\n used.add(written);\n this.json(inner, written, record[name], column);\n }\n this.raw(`${indent}]`);\n }\n\n /**\n * The key a record field is written under.\n * @param name - the field name\n * @param used - the keys already written in the record\n * @param column - the column name, for errors\n * @returns a valid, unused key; E_UNSUPPORTED for an invalid key unless mangling\n */\n private recordKey(name: string, used: ReadonlySet<string>, column: string): string {\n if (isGmlKey(name) && !used.has(name)) {\n return name;\n }\n if (!this.mangle) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": record key \"${name}\" ${isGmlKey(name) ? \"repeats a key\" : \"is not a GML key\"}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column,\n key: name,\n },\n );\n }\n return uniqueKey(isGmlKey(name) ? name : mangleGmlKey(name), used);\n }\n}\n\n/** Everything the writer needs, resolved once before the first line. */\ninterface WriteContext {\n readonly snapshot: GraphSnapshot;\n readonly plan: GmlExportPlan;\n readonly ids: SanitizedIds;\n readonly writeDirected: boolean;\n readonly foldPairs: boolean;\n readonly nodeColumns: readonly WrittenColumn[];\n readonly edgeColumns: readonly WrittenColumn[];\n readonly graphColumns: readonly WrittenColumn[];\n readonly topColumns: readonly WrittenColumn[];\n readonly position: Column | null;\n readonly graphics: JsonColumn | null;\n readonly originalIds: Column | null;\n readonly edgeIds: Column | null;\n readonly weights: ExplicitWeights;\n readonly folding: PairFolding;\n}\n\n/**\n * Resolve everything export() needs, throwing for what check() reported as an error.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the context\n */\nfunction contextOf(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): WriteContext {\n const plan = planOf(snapshot, options);\n const ids = sanitizeIds(snapshot, \"integer\", plan.common.sanitizeIds);\n const mixed = countMixedEdges(snapshot);\n if (mixed > 0 && plan.common.onMixedDirection === \"error\") {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${mixed} undirected edge${plural(mixed)} in a directed graph, and GML holds one direction per file, so the save fails unless onMixedDirection is \"directed\" or \"undirected\"`,\n {\n reason: \"mixed direction\",\n count: mixed,\n },\n );\n }\n // design 8.5: exporters fold expanded pairs back; under \"directed\" the folded edge is written\n // once, as one directed edge, under \"undirected\" the whole graph is written undirected\n const foldPairs = mixed > 0;\n const writeDirected = snapshot.directed && plan.common.onMixedDirection !== \"undirected\";\n const originalIds = snapshot.nodes.byRole(\"originalId\");\n const nodeReserved = new Set(NODE_RESERVED);\n if (ids.changed > 0 || originalIds !== null) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n return {\n snapshot,\n plan,\n ids,\n writeDirected,\n foldPairs,\n nodeColumns: selectColumns(\n snapshot.nodes,\n nodeReserved,\n \"node\",\n plan,\n null,\n (c) => !(c.meta.name === \"graphics\" && c.dtype === \"json\"),\n ),\n edgeColumns: selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, null, (c) => c !== edgeIds),\n graphColumns: selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, null, (c) => !isTopLevel(c)),\n topColumns: selectColumns(snapshot.graph, topReserved, \"top-level\", plan, null, isTopLevel),\n position: positionColumn(snapshot),\n graphics: graphicsColumn(snapshot),\n originalIds,\n edgeIds,\n weights: explicitWeights(snapshot),\n folding: pairFolding(snapshot),\n };\n}\n\n/**\n * The GML text of an id written into `graphty_originalId`: quoted for a string, a number text\n * otherwise (an integer as int, else real, so the importer restores the same typed value).\n * @param id - the original id\n * @returns the text\n */\nfunction originalIdText(id: NodeId): string {\n if (typeof id === \"string\") {\n return quoteGmlString(id);\n }\n return Number.isSafeInteger(id) ? formatInteger(id) : formatGmlReal(id, \"f64\");\n}\n\n/**\n * The parts of the document.\n * @param context - the resolved context\n * @yields one string per header line, node or edge\n * @returns nothing\n */\nfunction* gmlParts(context: WriteContext): Generator<string, void, undefined> {\n const { snapshot, plan, ids } = context;\n const w = new GmlWriter(plan.mangle);\n const { meta } = snapshot;\n if (meta.creator !== null) {\n w.line(\"\", \"Creator\", quoteGmlString(meta.creator));\n }\n if (meta.sourceFormat === \"gml\" && meta.sourceVersion !== null) {\n w.line(\"\", \"Version\", versionText(meta.sourceVersion));\n }\n for (const { column, key } of context.topColumns) {\n if (column.isSet(0)) {\n w.cell(\"\", key, column, 0);\n }\n }\n w.raw(\"graph [\");\n w.line(\" \", \"directed\", context.writeDirected ? \"1\" : \"0\");\n const multigraph = meta.declaredMultigraph ?? (snapshot.flags.multigraph ? true : null);\n if (multigraph !== null) {\n w.line(\" \", \"multigraph\", multigraph ? \"1\" : \"0\");\n }\n for (const { column, key } of context.graphColumns) {\n if (column.isSet(0)) {\n w.cell(\" \", key, column, 0);\n }\n }\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.raw(\" node [\");\n w.line(\" \", \"id\", formatInteger(ids.idAt(i) as number));\n if (ids.isChanged(i)) {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(ids.originalAt(i)));\n } else if (context.originalIds?.isSet(i)) {\n const original = context.originalIds.value(i);\n if (typeof original === \"string\" || typeof original === \"number\") {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(original));\n }\n }\n for (const { column, key } of context.nodeColumns) {\n if (column.isSet(i)) {\n w.cell(\" \", key, column, i);\n }\n }\n writeGraphics(w, context, i);\n w.raw(\" ]\");\n yield w.take();\n }\n const el = snapshot.edgeList();\n const origin = meta.weightOrigin;\n const integerWeights = origin !== null && origin.type === \"int\";\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (context.foldPairs && context.folding.folded(e)) {\n continue;\n }\n w.raw(\" edge [\");\n w.line(\" \", \"source\", formatInteger(ids.idAt(el.src[e]) as number));\n w.line(\" \", \"target\", formatInteger(ids.idAt(el.dst[e]) as number));\n if (context.edgeIds?.isSet(e)) {\n w.cell(\" \", \"id\", context.edgeIds, e);\n }\n if (context.weights.isExplicit(e)) {\n const weight = context.weights.value(e);\n const text =\n integerWeights && Number.isInteger(weight)\n ? formatInteger(weight)\n : formatGmlReal(weight, context.weights.dtype);\n w.line(\" \", plan.weightKey, text);\n }\n for (const { column, key } of context.edgeColumns) {\n if (column.isSet(e)) {\n w.cell(\" \", key, column, e);\n }\n }\n w.raw(\" ]\");\n yield w.take();\n }\n w.raw(\"]\");\n yield w.take();\n}\n\n/**\n * Write a node's `graphics [ ... ]` record from the position column and the graphics json column.\n * @param w - the writer\n * @param context - the context\n * @param i - the node\n */\nfunction writeGraphics(w: GmlWriter, context: WriteContext, i: number): void {\n const { position, graphics } = context;\n const hasPosition = position?.isSet(i) === true;\n const graphicsValue = graphics?.isSet(i) ? graphics.values[i] : undefined;\n if (!hasPosition) {\n if (graphics !== null && graphicsValue !== undefined) {\n w.cell(\" \", \"graphics\", graphics, i);\n }\n return;\n }\n const numeric = position as Column & { readonly data: ArrayLike<number> };\n const { components } = numeric.meta;\n const lanes = Math.min(components, 3);\n const extra: [string, string][] = [];\n const names = [\"x\", \"y\", \"z\"];\n for (let k = 0; k < lanes; k++) {\n extra.push([names[k], numberText(numeric.data[i * components + k], numeric.meta)]);\n }\n let record: Record<string, unknown> = {};\n if (graphicsValue !== undefined) {\n if (typeof graphicsValue !== \"object\" || graphicsValue === null || Array.isArray(graphicsValue)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `node ${i}: the graphics value is not a record and cannot hold the position`,\n {\n reason: \"graphics conflict\",\n node: i,\n },\n );\n }\n record = graphicsValue as Record<string, unknown>;\n }\n w.record(\" \", \"graphics\", record, \"graphics\", extra);\n}\n\n/**\n * The GML exporter plugin.\n * @category Built-in formats\n */\nexport const gmlExporter: GraphExporter<GmlExportOptions> = Object.freeze({\n format: \"gml\",\n options: Object.freeze([\"sanitizeKeys\", \"weightKey\"]),\n capabilities: GML_CAPABILITIES,\n styles: Object.freeze({ capabilities: GML_STYLE_CAPABILITIES }),\n /**\n * Pre-flight: the common capability notes, the GML-specific ones and, with styles, the values written as the\n * nearest ones yEd's GML has.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: GmlWriteOptions): readonly LossNote[] {\n const styled = gmlStyledExport(snapshot, options?.styles);\n if (styled === null) {\n return check(snapshot, options);\n }\n return Object.freeze([...check(styled.snapshot, options), ...styled.notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks; the context is resolved on the first pull, so the\n * errors check() announced surface from the iteration.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GmlWriteOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(lazyParts(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GmlWriteOptions): Promise<string> {\n return joinText(lazyParts(snapshot, options));\n },\n});\n\n/**\n * The document parts, with the context resolved when iteration starts.\n * @param snapshot - the snapshot\n * @param options - the options\n * @yields the parts\n * @returns nothing\n */\nfunction* lazyParts(snapshot: GraphSnapshot, options: GmlWriteOptions | undefined): Generator<string, void, undefined> {\n yield* gmlParts(contextOf(gmlStyledExport(snapshot, options?.styles)?.snapshot ?? snapshot, options));\n}\n","/**\n * The GML importer (design sections 8.4 and 8.5, research note 07 section 2.2): reads a whole GML\n * text (GML awaits the whole text, 8.4), lexes it once into a typed token list, derives the column\n * schema of every node, edge and graph key in a first walk (GML types are lexical per value, so\n * the column dtype is the union of the value classes seen: `int` -> i32, `real` -> f64, `string`\n * -> string, a nested `[ ]` record -> json, a repeated key -> list; the class is recorded in\n * `origin.type` per column as 8.5 requires), then pushes scalars into the sink in a second walk:\n * every node block first, then every edge block, so node indices follow the file's node order\n * and forward edge references resolve.\n *\n * Conventions honored: NetworkX's `_networkx_list_start` marker and `\"[]\"` empty lists, `&#NN;`\n * character references in strings, `Creator` / `Version` top-level metadata, `directed 0|1` and\n * `multigraph 0|1` graph flags, comments, keys and values on one line or split across lines, and\n * a `graphics [ x y z ]` node record mapped to the `position` role (note 07 section 9) with the\n * remaining graphics keys kept as a json column, yEd's `gid` (the group a node sits in) read\n * into the parent column as well as kept as a plain column, and OGDF's `rootcluster` read as group\n * nodes (`cluster<id>`) holding their vertices through the parent column.\n *\n * Node ids are the `id` keys under `nodeIdFrom: \"id\"`, the `label` under `\"label\"`, and the node's\n * ordinal under `\"index\"`; `source` / `target` always resolve through the `id` keys. The GML spec\n * types ids as integers; a string id (written by NetworkX and Gephi) is accepted under the `ids`\n * rule with one warning per file, and a real or record id is a validation error. A node's\n * `graphty_originalId` key written by the exporter's `sanitizeIds: \"mangle\"` restores the\n * original id under `restoreMangledIds` (the default).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ColumnRole,\n type Dtype,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, DictHeuristic, uniqueColumnName } from \"../../common/attributes.js\";\nimport { importChosenGraph } from \"../../common/choose.js\";\nimport {\n COLUMN_RENAMED_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE as SHARED_NO_GRAPH_CODE,\n PRECISION_CODE as SHARED_PRECISION_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n WIDENED_CODE as SHARED_WIDENED_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n graphChosen,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText, reportWeightPrecision, weightFromValue } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { gmlPositions } from \"./positions.js\";\nimport { gmlStyles } from \"./styles.js\";\nimport {\n EMPTY_LIST_TEXT,\n EMPTY_TUPLE_TEXT,\n GmlSyntaxError,\n type GmlTokens,\n LIST_START_MARKER,\n numberOfText,\n ORIGINAL_ID_KEY,\n parseRecord,\n scalarOrRecord,\n TOKEN_INT,\n TOKEN_OPEN,\n TOKEN_REAL,\n TOKEN_STRING,\n TOKEN_WORD,\n tokenizeGml,\n} from \"./syntax.js\";\n\n/**\n * The format-specific options of the GML importer.\n * @category Built-in formats\n */\nexport interface GmlImportOptions extends GraphChoiceOptions, CommonImportOptions {\n /**\n * Read a node's `graphics [ x y z ]` record as its position; false keeps the whole record as a\n * JSON attribute named `graphics`.\n * @defaultValue true\n */\n positions?: boolean | undefined;\n /**\n * With `positions`, also keep the whole `graphics` record, x / y / z included, as the JSON\n * attribute named `graphics`, so a reader gets both the position and the record as written.\n * @defaultValue false\n */\n keepPositionSource?: boolean | undefined;\n /**\n * Store a text attribute whose values repeat a lot (fewer distinct values than half the rows)\n * as a dictionary column, which uses less memory and reads the same. Such a column reports\n * `meta.dtype` \"dict\" instead of \"string\". A column with a role, such as the `label` column,\n * always stays \"string\".\n * @defaultValue true\n */\n dictionaries?: boolean | undefined;\n}\n\n/**\n * The text holds no `graph [ ... ]` block.\n * @category Issue and loss codes\n */\nexport const NO_GRAPH_CODE = SHARED_NO_GRAPH_CODE;\n/**\n * The text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one.\n * @category Issue and loss codes\n */\nexport const SECOND_GRAPH_CODE = MULTIPLE_GRAPHS_CODE;\n/**\n * A node block has no `id` key.\n * @category Issue and loss codes\n */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n/**\n * A node block has no `label` key under `nodeIdFrom: \"label\"`.\n * @category Issue and loss codes\n */\nexport const MISSING_LABEL_CODE = \"E_GML_MISSING_LABEL\";\n/**\n * An edge block has no `source` or no `target` key.\n * @category Issue and loss codes\n */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n/**\n * An `id`, `source` or `target` value is neither an integer nor a string.\n * @category Issue and loss codes\n */\nexport const ID_TYPE_CODE = \"E_GML_ID_TYPE\";\n/**\n * Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option. Reported\n * once per file.\n * @category Issue and loss codes\n */\nexport const STRING_ID_CODE = \"W_GML_STRING_ID\";\n/**\n * A node id (or label under `nodeIdFrom: \"label\"`) is declared twice; later keys overwrite.\n * @category Issue and loss codes\n */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n/**\n * A structural key (`id`, `source`, `target`) appears twice in one block.\n * @category Issue and loss codes\n */\nexport const REPEATED_KEY_CODE = \"E_GML_REPEATED_KEY\";\n/**\n * A `node` or `edge` key whose value is not a `[ ... ]` block.\n * @category Issue and loss codes\n */\nexport const ELEMENT_TYPE_CODE = \"E_GML_ELEMENT_TYPE\";\n/**\n * A `directed` or `multigraph` flag that is not an integer.\n * @category Issue and loss codes\n */\nexport const FLAG_TYPE_CODE = \"E_GML_FLAG_TYPE\";\n/**\n * A `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or\n * one repeated.\n * @category Issue and loss codes\n */\nexport const FLAG_VALUE_CODE = \"W_GML_FLAG_VALUE\";\n\n/** A flag written as a quoted integer, surrounding spaces allowed. */\nconst QUOTED_INT = /^\\s*[+-]?\\d+\\s*$/;\n/**\n * A named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity, or a numeric reference beyond\n * U+10FFFF; it is kept as written.\n * @category Issue and loss codes\n */\nexport const UNKNOWN_ENTITY_CODE = \"W_GML_UNKNOWN_ENTITY\";\n/**\n * A node's `graphics` value cannot give a position as written (not a record, repeated in the node, or with an x / y /\n * z that is not one number); the value is kept in the graphics json column. Warned once per kind of problem, naming\n * the first node.\n * @category Issue and loss codes\n */\nexport const GRAPHICS_CODE = \"W_GML_GRAPHICS\";\n/**\n * A `graph`, `node` or `edge` record inside a node or edge; kept as a json column, not read as structure.\n * @category Issue and loss codes\n */\nexport const NESTED_ELEMENT_CODE = \"W_GML_NESTED_ELEMENT\";\n/**\n * A yEd `gid` that names no other node: it stays a plain column value and puts the node in no group. Also an OGDF\n * cluster `vertex` that names no node (it is in no cluster), and a cluster whose id a node has (it is read as no group).\n * @category Issue and loss codes\n */\nexport const GROUPS_CODE = \"W_GML_GROUPS\";\n\n/** The parent column yEd's `gid` keys and OGDF's clusters are read into. */\nconst GROUP_PARENT_COLUMN = \"graphty.parent\";\n/**\n * A key whose values mix numbers and strings; the column is string, the numbers kept as written.\n * @category Issue and loss codes\n */\nexport const WIDENED_CODE = SHARED_WIDENED_CODE;\n/**\n * An integer above 2^53 was stored as the nearest JavaScript number, so its last digits may differ. Pass `long:\n * \"string\"` to keep every digit as text.\n * @category Issue and loss codes\n */\nexport const PRECISION_CODE = SHARED_PRECISION_CODE;\n/**\n * Two attributes would have had the same name, so this one was renamed `<name>#<key>`.\n * @category Plugin helpers\n */\nexport const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;\n/**\n * You read into a graph builder that already has an attribute with this role, so this file's attribute is kept without\n * the role.\n * @category Issue and loss codes\n */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n/**\n * Under `nodeIdFrom` \"label\" / \"index\" the integer `id` keys are not kept.\n * @category Issue and loss codes\n */\nexport const ID_DROPPED_CODE = \"W_GML_ID_DROPPED\";\n\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"value\" };\n\nconst KIND_INT = 1;\nconst KIND_REAL = 2;\nconst KIND_STRING = 4;\nconst KIND_RECORD = 8;\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/** How many elements are pushed between abort-signal checks. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"restoreMangledIds\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** The element sequence number of the graph block's own keys. */\nconst GRAPH_SEQ = -1;\n/** The element sequence number of the top-level keys. */\nconst TOP_SEQ = -2;\n\n/** The GML value class a column stores. */\ntype GmlKind = \"int\" | \"real\" | \"string\" | \"record\";\n\n/** What the first walk learns about one key of one table. */\ninterface KeySchema {\n /** The key as written. */\n readonly key: string;\n /** The union of value classes seen (KIND_* bits). */\n kinds: number;\n /** Whether the key repeats within one element, or uses a list marker. */\n list: boolean;\n /** The element sequence the key was last seen in. */\n lastSeq: number;\n /** Whether an integer outside the i32 range was seen. */\n wide: boolean;\n /** Whether an integer beyond 2^53 was seen. */\n unsafe: boolean;\n /** The dictionary heuristic while every value is a string, else null. */\n dict: DictHeuristic | null;\n /** Node `graphics` only: some row has numeric x and y. */\n position: boolean;\n /** Node `graphics` only: some row keeps keys besides the position. */\n rest: boolean;\n}\n\n/** The column a key maps to in the second walk. */\ninterface ColumnPlan {\n /** The key as written. */\n readonly key: string;\n /** The column name (renamed `<name>#<key>` when the sink held the name with another shape). */\n name: string;\n /** The column dtype. */\n readonly dtype: Dtype;\n /** The list item dtype, or null. */\n readonly itemDtype: ScalarDtype | null;\n /** How scalar values (or list items) are converted. */\n readonly kind: GmlKind;\n /** Whether the column is a list. */\n readonly list: boolean;\n /** The role, or null. */\n readonly role: ColumnRole | null;\n /** Whether the values come from the top level of the file (graph table only). */\n readonly top: boolean;\n /** Node `graphics` with the position mapping: the position column plan, or null. */\n readonly position: ColumnPlan | null;\n /** Node `graphics` with the position mapping: the json column of the remaining keys, or null. */\n readonly rest: ColumnPlan | null;\n /** The handle once declared. */\n handle: ColumnHandle;\n /** Whether the declaration was attempted (a failed one reuses the sink's column or is null). */\n declared: boolean;\n /** The list items of the current element. */\n items: unknown[] | null;\n /** The element sequence the items belong to. */\n seq: number;\n}\n\n/** A table's plans by key. */\ntype PlanMap = Map<string, ColumnPlan>;\n\n/** Where a node issue is recorded. */\ninterface IssueWhere {\n readonly line: number;\n readonly element: string;\n}\n\n/** The table a GML key belongs to. */\ntype GmlDomain = \"node\" | \"edge\" | \"graph\";\n\n/**\n * Whether a key is the label of a node or edge (text, never a NetworkX list marker).\n * @param domain - the table\n * @param key - the key\n * @returns true for a node or edge label\n */\nfunction isLabel(domain: GmlDomain, key: string): boolean {\n return roleOf(domain, key) === \"label\";\n}\n\n/**\n * Whether a parsed value is a GML record.\n * @param value - the value\n * @returns true for a record object\n */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Whether a key gets a role in its table (design section 5.6 applied to GML keys).\n * @param domain - the table\n * @param key - the key\n * @returns the role, or null\n */\nfunction roleOf(domain: GmlDomain, key: string): ColumnRole | null {\n if (key === \"label\" && domain !== \"graph\") {\n return \"label\";\n }\n if (domain === \"edge\") {\n if (key === \"id\") {\n return \"id\";\n }\n if (key === \"key\") {\n return \"key\";\n }\n }\n return null;\n}\n\n/** One import call. */\nclass GmlImport {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly positions: boolean;\n\n private readonly keepPositionSource: boolean;\n\n private readonly dictionaries: boolean;\n\n private readonly coercer: IdCoercer;\n\n private tokens: GmlTokens | null = null;\n\n /** How many `graph [ ... ]` blocks the text holds (known after the scan). */\n graphCount = 0;\n\n private resolver: DirectionResolver | null = null;\n\n private readonly nodeSchema = new Map<string, KeySchema>();\n\n private readonly edgeSchema = new Map<string, KeySchema>();\n\n private readonly graphSchema = new Map<string, KeySchema>();\n\n private readonly topSchema = new Map<string, KeySchema>();\n\n private readonly nodePlans: PlanMap = new Map();\n\n private readonly edgePlans: PlanMap = new Map();\n\n private readonly graphPlans: PlanMap = new Map();\n\n private readonly topPlans: PlanMap = new Map();\n\n private readonly graphNames = new Set<string>();\n\n private graphOpen = -1;\n\n private directedToken = -1;\n\n private multigraphToken = -1;\n\n private creatorToken = -1;\n\n private versionToken = -1;\n\n private nodeCount = 0;\n\n private edgeCount = 0;\n\n private weightKinds = 0;\n\n private hasOriginalId = false;\n\n private headerDirected = false;\n\n private seq = 0;\n\n private nodeOrdinal = 0;\n\n private elementsSinceCheck = 0;\n\n /** The sink id every file id maps to when they differ (label / index / restored ids), else null. */\n private idMap: Map<NodeId, NodeId> | null = null;\n\n /** The file ids of node blocks that were skipped: an edge naming one is skipped too, never given a new node. */\n private readonly skippedIds = new Set<NodeId>();\n\n /** Each node's yEd `gid` (its group's file id): the node's index and the value token. */\n private readonly groupRefs: [node: number, token: number][] = [];\n\n /** The `[` of OGDF's `rootcluster` record (its cluster tree, after the graph block), or -1. */\n private rootCluster = -1;\n\n /** The parent column, once a node is given a parent. */\n private parentHandle: ColumnHandle | null = null;\n\n /** How many OGDF clusters were read, which names a cluster without an id. */\n private clusterCount = 0;\n\n /** Node indices declared by a node block of this import, for duplicate detection. */\n private declared = new Uint32Array(64);\n\n /** The list plans touched by the current node or edge. */\n private readonly touched: ColumnPlan[] = [];\n\n /** The list plans touched by the graph table's keys. */\n private readonly graphTouched: ColumnPlan[] = [];\n\n /** The sequence number of the current node or edge, which its list items belong to. */\n private seqNow = 0;\n\n /**\n * Create one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param format - the format-specific options\n * @param which - which `graph [ ... ]` block to read (0: the first)\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n format: GmlImportOptions | undefined,\n private readonly which = 0,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.positions = format?.positions ?? true;\n this.keepPositionSource = format?.keepPositionSource ?? false;\n this.dictionaries = format?.dictionaries ?? true;\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Run the import over the tokens of a text.\n * @param tokens - the whole text, tokenized (tokenize())\n */\n run(tokens: GmlTokens): void {\n this.tokens = tokens;\n tokens.onUnknownEntity = (entity, line) => {\n this.report.warnOnce(\n \"parse-error\",\n UNKNOWN_ENTITY_CODE,\n `character entity ${entity} cannot be decoded; it is kept as written`,\n { line, element: entity },\n `${UNKNOWN_ENTITY_CODE}:${entity}`,\n );\n };\n this.scan();\n this.push();\n }\n\n // ============================================================ pass 1: the schema\n\n /**\n * Walk the top level: find the graph block, the metadata keys and the top-level attributes,\n * and derive every table's schema.\n */\n private scan(): void {\n const t = this.requireTokens();\n let scalarGraph = -1;\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n const record = t.kind[v] === TOKEN_OPEN;\n if (key === \"graph\" && !record && scalarGraph < 0) {\n scalarGraph = v;\n }\n this.scanTopPair(key, record, v);\n }\n if (this.graphOpen < 0) {\n this.failNoGraph(t, scalarGraph);\n }\n }\n\n /**\n * Handle one top-level pair other than a scalar `graph`.\n * @param key - the key\n * @param record - whether the value is a `[ ... ]` block\n * @param v - the value token\n */\n private scanTopPair(key: string, record: boolean, v: number): void {\n if (key === \"graph\" && record) {\n if (this.graphCount++ === this.which) {\n this.graphOpen = v;\n this.scanGraph(v);\n }\n } else if (key === \"Creator\" && !record && this.creatorToken < 0) {\n this.creatorToken = v;\n } else if (key === \"Version\" && !record && this.versionToken < 0) {\n this.versionToken = v;\n } else if (key === \"rootcluster\" && record && this.rootCluster < 0) {\n // OGDF's cluster tree is structure: its clusters are read as group nodes (pushClusters)\n this.rootCluster = v;\n } else {\n this.observe(this.topSchema, \"graph\", key, v, TOP_SEQ);\n }\n }\n\n /**\n * Fail because the input holds no graph block.\n * @param t - the tokens\n * @param scalarGraph - the token of a scalar `graph` key, or -1\n */\n private failNoGraph(t: ReturnType<GmlImport[\"requireTokens\"]>, scalarGraph: number): void {\n if (scalarGraph >= 0) {\n this.report.fail(\n NO_GRAPH_CODE,\n `the graph key at line ${t.line[scalarGraph]} holds ${describeValue(t, scalarGraph)}, not a [ ... ] block; the input contains no graph block`,\n { line: t.line[scalarGraph] },\n );\n }\n this.report.fail(NO_GRAPH_CODE, \"the input contains no graph [ ... ] block\", { line: null });\n }\n\n /**\n * Walk the graph block for the schema.\n * @param open - the index of the block's `[`\n */\n private scanGraph(open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.nodeCount++;\n this.scanElement(\"node\", v);\n }\n break;\n case \"edge\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.edgeCount++;\n this.scanElement(\"edge\", v);\n }\n break;\n case \"directed\":\n if (this.directedToken < 0) {\n this.directedToken = v;\n }\n break;\n case \"multigraph\":\n if (this.multigraphToken < 0) {\n this.multigraphToken = v;\n }\n break;\n default:\n this.observe(this.graphSchema, \"graph\", key, v, GRAPH_SEQ);\n }\n }\n }\n\n /**\n * Walk one node or edge block for the schema.\n * @param domain - node or edge\n * @param open - the block's `[`\n */\n private scanElement(domain: \"node\" | \"edge\", open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n const seq = this.seq++;\n const schema = domain === \"node\" ? this.nodeSchema : this.edgeSchema;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n if (this.skipsKey(domain, key, v)) {\n continue;\n }\n this.observe(schema, domain, key, v, seq);\n }\n }\n\n /**\n * Whether a key of a node or edge block is structural (id, endpoints, weight, original id), not\n * a column; notes the original id and the weight's kinds on the way.\n * @param domain - node or edge\n * @param key - the key\n * @param v - the value token\n * @returns true when the key is not a column\n */\n private skipsKey(domain: \"node\" | \"edge\", key: string, v: number): boolean {\n const { weightFrom, restoreMangledIds } = this.options;\n if (domain === \"node\") {\n if (key === ORIGINAL_ID_KEY && restoreMangledIds) {\n this.hasOriginalId = true;\n return true;\n }\n return key === \"id\";\n }\n if (key === \"source\" || key === \"target\" || key === \"directed\") {\n return true;\n }\n if (key === weightFrom) {\n this.weightKinds |= kindBit(this.requireTokens(), v);\n return true;\n }\n return false;\n }\n\n /**\n * Record one value of one key in a table's schema.\n * @param schema - the table's schema\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n * @param seq - the element sequence number\n */\n private observe(\n schema: Map<string, KeySchema>,\n domain: \"node\" | \"edge\" | \"graph\",\n key: string,\n v: number,\n seq: number,\n ): void {\n const t = this.requireTokens();\n this.noteStructure(domain, key, v);\n let entry = schema.get(key);\n const graphics = domain === \"node\" && key === \"graphics\" && this.positions;\n if (entry === undefined) {\n entry = {\n key,\n kinds: 0,\n list: false,\n lastSeq: seq,\n wide: false,\n unsafe: false,\n dict: this.dictionaries && roleOf(domain, key) === null ? new DictHeuristic() : null,\n position: false,\n rest: false,\n };\n schema.set(key, entry);\n } else if (entry.lastSeq === seq) {\n entry.list = true;\n // a repeated graphics record: the extra records go to the json column\n entry.rest ||= graphics;\n } else {\n entry.lastSeq = seq;\n }\n if (graphics && t.kind[v] !== TOKEN_OPEN) {\n entry.rest = true;\n }\n switch (t.kind[v]) {\n case TOKEN_STRING: {\n const raw = t.textOf(v);\n // a label is text: \"[]\" there is a label, never NetworkX's empty list\n if (\n raw === LIST_START_MARKER ||\n (!isLabel(domain, key) && (raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT))\n ) {\n entry.list = true;\n return;\n }\n entry.kinds |= KIND_STRING;\n if (entry.dict !== null && !entry.dict.decided) {\n entry.dict.observe(raw);\n }\n return;\n }\n case TOKEN_INT: {\n entry.kinds |= KIND_INT;\n const n = Number(t.textOf(v));\n if (n < I32_MIN || n > I32_MAX) {\n entry.wide = true;\n if (!Number.isSafeInteger(n)) {\n entry.unsafe = true;\n }\n }\n return;\n }\n case TOKEN_OPEN:\n entry.kinds |= KIND_RECORD;\n if (domain === \"node\" && key === \"graphics\" && this.positions) {\n this.inspectGraphics(entry, v);\n }\n return;\n default: {\n entry.kinds |= KIND_REAL;\n const text = t.textOf(v);\n if (/\\d/.test(text) && !Number.isFinite(Number(text))) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${domain} key \"${key}\" holds the real ${text}, beyond the f64 range; it is stored as ${numberOfText(text) > 0 ? \"\" : \"-\"}Infinity`,\n { line: t.line[v], element: key },\n `${PRECISION_CODE}:overflow:${domain}:${key}`,\n );\n }\n }\n }\n }\n\n /**\n * Warn about keys of a node or edge whose meaning GML readers give but this import does not:\n * a nested graph / node / edge record.\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n */\n private noteStructure(domain: \"node\" | \"edge\" | \"graph\", key: string, v: number): void {\n const t = this.requireTokens();\n if (domain === \"graph\") {\n return;\n }\n if ((key === \"graph\" || key === \"node\" || key === \"edge\") && t.kind[v] === TOKEN_OPEN) {\n this.report.warnOnce(\n \"unsupported\",\n NESTED_ELEMENT_CODE,\n `a nested ${key} record inside a ${domain} is kept as the json column \"${key}\"; it is not read as structure`,\n { line: t.line[v], element: key },\n `${NESTED_ELEMENT_CODE}:${domain}:${key}`,\n );\n }\n }\n\n /**\n * Note whether a node's graphics record carries a position (numeric x and y) and whether\n * anything besides the position remains.\n * @param entry - the graphics schema entry\n * @param open - the record's `[`\n */\n private inspectGraphics(entry: KeySchema, open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n let x = false;\n let y = false;\n let other = false;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const numeric = t.kind[p + 1] === TOKEN_INT || t.kind[p + 1] === TOKEN_REAL;\n if (key === \"x\" && numeric && !x) {\n x = true;\n } else if (key === \"y\" && numeric && !y) {\n y = true;\n } else if (!(key === \"z\" && numeric)) {\n other = true;\n }\n }\n const positioned = x && y;\n entry.position ||= positioned;\n // with keepPositionSource the whole record, x / y / z included, goes to the json column too\n entry.rest ||= positioned ? other || this.keepPositionSource : true;\n }\n\n // ============================================================ pass 2: the push\n\n /** Declare what the schema needs, set the header and push every element. */\n private push(): void {\n const { sink, report, options } = this;\n const t = this.requireTokens();\n sink.reserve(this.nodeCount, this.edgeCount);\n this.buildPlans();\n this.setMetadata();\n this.headerDirected = this.readFlag(this.directedToken, \"directed\") ?? options.defaultDirected;\n const resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n resolver.setHeader(this.headerDirected, {\n line: this.directedToken >= 0 ? t.line[this.directedToken] : t.line[this.graphOpen],\n });\n this.resolver = resolver;\n if (options.nodeIdFrom !== \"id\" || this.hasOriginalId) {\n this.idMap = new Map();\n }\n if (options.nodeIdFrom !== \"id\") {\n report.loss(\n ID_DROPPED_CODE,\n `node ids taken from the ${options.nodeIdFrom}; the integer id keys are not kept as a column`,\n null,\n this.nodeCount,\n );\n }\n this.pushTopLevel();\n this.pushNodes();\n this.pushGroups();\n this.pushClusters();\n this.pushEdges();\n }\n\n /**\n * Read yEd's group hierarchy into the parent column: a node's `gid` names the group node it sits in. A `gid` that\n * names no node (or the node itself) is warned once and left a plain column value.\n */\n private pushGroups(): void {\n const t = this.requireTokens();\n for (const [node, v] of this.groupRefs) {\n let parent: number = INVALID_INDEX;\n try {\n const fileId = this.coerceFileId(v, this.fileIdOf(v, \"gid\"));\n parent = this.sink.indexOf(this.idMap?.get(fileId) ?? fileId);\n } catch {\n parent = INVALID_INDEX;\n }\n if (parent === INVALID_INDEX || parent === node) {\n this.report.warnOnce(\n \"validation-error\",\n GROUPS_CODE,\n `gid ${t.kind[v] === TOKEN_OPEN ? \"[...]\" : t.textOf(v)} names no other node; it is kept as a plain column value`,\n { line: t.line[v], element: \"gid\" },\n );\n continue;\n }\n this.setParent(node, parent, \"gid\");\n }\n }\n\n /**\n * Put a node in a group: the parent column, declared on first use.\n * @param node - the node's index\n * @param parent - the group node's index\n * @param type - the file key the hierarchy came from (`gid`, `rootcluster`)\n */\n private setParent(node: number, parent: number, type: string): void {\n this.parentHandle ??= this.sink.declareNodeColumn({\n name: uniqueColumnName(GROUP_PARENT_COLUMN, null, (c) => this.sink.nodeColumn(c) !== INVALID_INDEX),\n dtype: \"u32\",\n role: \"parent\",\n refersTo: \"node\",\n nullable: true,\n origin: { format: \"gml\", id: null, title: null, type, namespace: null },\n });\n this.sink.setNodeValue(this.parentHandle, node, parent);\n }\n\n /**\n * Read OGDF's cluster tree (`rootcluster`, GraphIO::writeGML): every cluster below the root becomes a group node\n * (id `cluster<id>`) holding its `vertex` nodes and its child clusters, with its label, its box as the node's\n * center and size, and its graphics as a node's (`color` is the outline, `style` the shape, `stipple` kept as\n * `clusterStipple`, since OGDF draws a cluster's outline solid). The root cluster is\n * the whole graph and draws nothing of its own. A `vertex` that names no node is warned once.\n */\n private pushClusters(): void {\n if (this.rootCluster < 0) {\n return;\n }\n const t = this.requireTokens();\n const stack: [open: number, parent: number][] = [[this.rootCluster, INVALID_INDEX]];\n for (let frame = stack.pop(); frame !== undefined; frame = stack.pop()) {\n const [open, parent] = frame;\n for (let p = open + 1; p < t.match[open]; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n if (key === \"cluster\" && t.kind[v] === TOKEN_OPEN) {\n const cluster = this.addCluster(v, parent);\n if (cluster !== INVALID_INDEX) {\n stack.push([v, cluster]);\n }\n } else if (key === \"vertex\" && parent !== INVALID_INDEX) {\n this.addClusterVertex(v, parent);\n }\n }\n }\n }\n\n /**\n * Put a cluster's `vertex` in it.\n * @param v - the value token, the vertex's id as a string\n * @param cluster - the cluster's group node\n */\n private addClusterVertex(v: number, cluster: number): void {\n const t = this.requireTokens();\n const id = t.kind[v] === TOKEN_STRING ? this.coercer.text(t.stringOf(v)) : null;\n const node = id === null ? INVALID_INDEX : this.sink.indexOf(this.idMap?.get(id) ?? id);\n if (node === INVALID_INDEX || node === cluster) {\n this.report.warnOnce(\n \"validation-error\",\n GROUPS_CODE,\n `cluster vertex ${describeValue(t, v)} names no node; it is in no cluster`,\n { line: t.line[v], element: \"vertex\" },\n );\n return;\n }\n this.setParent(node, cluster, \"rootcluster\");\n }\n\n /**\n * Add one OGDF cluster as a group node: its label, and its graphics box (x, y its top-left corner, width and\n * height) as a node's center, w and h.\n * @param open - the cluster record's `[`\n * @param parent - the group node of the cluster it is in, or INVALID_INDEX under the root\n * @returns the group node's index, or INVALID_INDEX when its id is taken\n */\n private addCluster(open: number, parent: number): number {\n const t = this.requireTokens();\n const record = parseRecord(t, open);\n const ordinal = this.clusterCount++;\n const ownId = typeof record.id === \"number\" || typeof record.id === \"string\" ? String(record.id) : null;\n const fallback = `#${String(ordinal)}`;\n const id = `cluster${ownId ?? fallback}`;\n if (this.sink.indexOf(id) !== INVALID_INDEX) {\n this.report.warnOnce(\n \"validation-error\",\n GROUPS_CODE,\n `cluster ${id} has the id of a node; it is read as no group`,\n { line: t.line[open], element: id },\n );\n return INVALID_INDEX;\n }\n const index = this.sink.addNode(id);\n this.report.counts.nodes++;\n if (parent !== INVALID_INDEX) {\n this.setParent(index, parent, \"rootcluster\");\n }\n const label = this.nodePlans.get(\"label\");\n if (typeof record.label === \"string\" && record.label !== \"\" && label?.kind === \"string\" && !label.list) {\n this.sink.setNodeValue(this.handleOf(label, \"node\"), index, record.label);\n }\n const graphics = this.nodePlans.get(\"graphics\");\n const g = isRecord(record.graphics) ? record.graphics : null;\n if (g === null || graphics?.position === undefined || graphics.position === null) {\n return index;\n }\n // GraphIO::drawSVG draws a cluster's outline solid whatever its stipple: it is kept under a name of its own\n const { x, y, width, height, color, style, stipple, ...rest } = g;\n if (typeof x === \"number\" && typeof y === \"number\" && typeof width === \"number\" && typeof height === \"number\") {\n this.sink.setNodeValue(this.handleOf(graphics.position, \"node\"), index, [x + width / 2, y + height / 2, 0]);\n Object.assign(rest, { w: width, h: height });\n }\n Object.assign(\n rest,\n color === undefined ? {} : { outline: color },\n style === undefined ? {} : { type: style },\n stipple === undefined ? {} : { clusterStipple: stipple },\n );\n if (graphics.rest !== null) {\n this.sink.setNodeValue(this.handleOf(graphics.rest, \"node\"), index, rest);\n }\n return index;\n }\n\n /** Turn every schema entry into a column plan. */\n private buildPlans(): void {\n for (const [key, entry] of this.nodeSchema) {\n this.nodePlans.set(key, this.planOf(\"node\", entry));\n }\n for (const [key, entry] of this.edgeSchema) {\n this.edgePlans.set(key, this.planOf(\"edge\", entry));\n }\n for (const [key, entry] of this.graphSchema) {\n this.graphPlans.set(key, this.planOf(\"graph\", entry));\n }\n for (const [key, entry] of this.topSchema) {\n this.topPlans.set(key, this.planOf(\"graph\", entry, true));\n }\n }\n\n /**\n * Warn about a key that mixes numbers and strings, or holds integers beyond 2^53.\n * @param domain - the table\n * @param entry - the schema entry\n * @param asText - whether the integers are kept as text\n */\n private warnKinds(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, asText: boolean): void {\n if (\n (entry.kinds & KIND_STRING) !== 0 &&\n (entry.kinds & (KIND_INT | KIND_REAL)) !== 0 &&\n (entry.kinds & KIND_RECORD) === 0\n ) {\n this.report.warnOnce(\n \"coercion\",\n WIDENED_CODE,\n `${domain} key \"${entry.key}\" mixes numbers and strings; the column is string and the numbers are kept as written`,\n { element: entry.key },\n `${WIDENED_CODE}:${domain}:${entry.key}`,\n );\n }\n if (entry.unsafe && !asText) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${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)`,\n { element: entry.key },\n `${PRECISION_CODE}:${domain}:${entry.key}`,\n );\n }\n }\n\n /**\n * The plan of a node `graphics` record: the plan plus its position and rest columns.\n * @param plan - the record's plan\n * @param entry - the schema entry\n * @returns the plan with its position (and rest) plans\n */\n private graphicsPlan(plan: ColumnPlan, entry: KeySchema): ColumnPlan {\n const taken = (candidate: string): boolean =>\n this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;\n const position: ColumnPlan = {\n ...plan,\n name: uniqueColumnName(\"position\", \"graphics\", taken),\n dtype: \"f64\",\n itemDtype: null,\n kind: \"real\",\n list: false,\n role: \"position\",\n };\n const rest: ColumnPlan | null = entry.rest\n ? { ...plan, dtype: \"json\", itemDtype: null, kind: \"record\", list: false }\n : null;\n return { ...plan, position, rest };\n }\n\n /**\n * The plan of one schema entry.\n * @param domain - the table\n * @param entry - the schema entry\n * @param top - whether the key is a top-level one (graph table)\n * @returns the plan\n */\n private planOf(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, top = false): ColumnPlan {\n // long: \"string\" keeps every digit of an integer key that holds values beyond 2^53, as text\n const asText = entry.unsafe && this.options.long === \"string\" && kindOf(entry) === \"int\";\n const kind = asText ? \"string\" : kindOf(entry);\n let scalar: ScalarDtype = dtypeOfKind(kind, entry);\n if (\n scalar === \"string\" &&\n !entry.list &&\n entry.dict !== null &&\n entry.kinds === KIND_STRING &&\n entry.dict.decide() === \"dict\"\n ) {\n scalar = \"dict\";\n }\n this.warnKinds(domain, entry, asText);\n const name = domain === \"graph\" ? this.uniqueGraphName(entry.key) : entry.key;\n let itemDtype: ScalarDtype | null = null;\n if (entry.list) {\n itemDtype = scalar === \"dict\" ? \"string\" : scalar;\n }\n const plan: ColumnPlan = {\n key: entry.key,\n name,\n dtype: entry.list ? \"list\" : scalar,\n itemDtype,\n kind,\n list: entry.list,\n role: roleOf(domain, entry.key),\n top,\n position: null,\n rest: null,\n handle: INVALID_INDEX as ColumnHandle,\n declared: false,\n items: null,\n seq: Number.NEGATIVE_INFINITY,\n };\n if (domain === \"node\" && entry.key === \"graphics\" && this.positions && (entry.kinds & KIND_RECORD) !== 0) {\n return this.graphicsPlan(plan, entry);\n }\n return plan;\n }\n\n /**\n * A graph column name not yet used by this import (top-level and in-graph keys share the table).\n * @param key - the key\n * @returns the name\n */\n private uniqueGraphName(key: string): string {\n const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));\n this.graphNames.add(name);\n if (name !== key) {\n this.report.warning(\n \"coercion\",\n COLUMN_RENAMED_CODE_GML,\n `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}\"`,\n { element: key },\n );\n }\n return name;\n }\n\n /** Set the graph metadata: source format, creator, version, multigraph flag, weight origin. */\n private setMetadata(): void {\n const t = this.requireTokens();\n const { sink, options } = this;\n const textOf = (v: number): string => (t.kind[v] === TOKEN_STRING ? t.stringOf(v) : t.textOf(v));\n const multigraph = this.readFlag(this.multigraphToken, \"multigraph\");\n sink.setMeta({\n sourceFormat: \"gml\",\n creator: this.creatorToken >= 0 ? textOf(this.creatorToken) : undefined,\n sourceVersion: this.versionToken >= 0 ? textOf(this.versionToken) : undefined,\n declaredMultigraph: multigraph ?? undefined,\n weightOrigin:\n this.weightKinds !== 0 && options.weightFrom !== null\n ? {\n format: \"gml\",\n id: options.weightFrom,\n title: null,\n type: this.weightKinds === KIND_INT ? \"int\" : \"real\",\n namespace: null,\n }\n : undefined,\n // The header as written, so a reader can say which words set the direction and tell\n // `directed 0` from a file that relies on the specification's default.\n extra: this.directedToken >= 0 ? { gml: { directed: textOf(this.directedToken) } } : undefined,\n });\n }\n\n /**\n * Read a `directed` / `multigraph` flag token.\n * @param v - the value token, or -1 when absent\n * @param name - the flag name, for issues\n * @returns the flag, or null when absent or not an integer\n */\n private readFlag(v: number, name: string): boolean | null {\n if (v < 0) {\n return null;\n }\n const t = this.requireTokens();\n // Files in the wild write the flag as a quoted integer (`directed \"1\"`); read it, with a warning.\n const quoted = t.kind[v] === TOKEN_STRING && QUOTED_INT.test(t.stringOf(v));\n if (quoted) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is written as the string ${describeValue(t, v)}; read as an integer`,\n { line: t.line[v], element: name },\n );\n } else if (t.kind[v] !== TOKEN_INT) {\n this.report.error(\n \"validation-error\",\n FLAG_TYPE_CODE,\n `flag \"${name}\" must be the integer 0 or 1, found ${describeValue(t, v)}`,\n { line: t.line[v], element: name },\n );\n return null;\n }\n const n = Number(quoted ? t.stringOf(v) : t.textOf(v));\n if (n !== 0 && n !== 1) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is ${n}; read as ${n !== 0 ? \"1\" : \"0\"}`,\n { line: t.line[v], element: name },\n );\n }\n return n !== 0;\n }\n\n /** Push the top-level attributes (every top-level key but graph, Creator and Version). */\n private pushTopLevel(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const v = p + 1;\n if (v === this.graphOpen || v === this.creatorToken || v === this.versionToken) {\n continue;\n }\n const plan = this.topPlans.get(t.textOf(p));\n if (plan !== undefined) {\n this.writeGraph(plan, v, TOP_SEQ);\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every node block and the graph block's own attributes, in file order. */\n private pushNodes(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.importNode(v);\n } else {\n this.badElement(\"node\", p);\n this.report.counts.skippedNodes++;\n }\n break;\n case \"edge\":\n break;\n case \"directed\":\n case \"multigraph\":\n if (v !== this.directedToken && v !== this.multigraphToken) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `graph flag \"${key}\" repeated; the first value stands`,\n { line: t.line[p], element: key },\n );\n }\n break;\n default: {\n const plan = this.graphPlans.get(key);\n if (plan !== undefined) {\n this.writeGraph(plan, v, GRAPH_SEQ);\n }\n }\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every edge block, in file order. */\n private pushEdges(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n let ordinal = 0;\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n if (t.textOf(p) !== \"edge\") {\n continue;\n }\n const v = p + 1;\n if (t.kind[v] === TOKEN_OPEN) {\n this.importEdge(v, ordinal);\n } else {\n this.badElement(\"edge\", p);\n this.report.counts.skippedEdges++;\n }\n ordinal++;\n }\n }\n\n /**\n * Record a `node` / `edge` key whose value is not a block.\n * @param what - node or edge\n * @param p - the key token\n */\n private badElement(what: string, p: number): void {\n const t = this.requireTokens();\n this.report.error(\n \"validation-error\",\n ELEMENT_TYPE_CODE,\n `${what} must be a [ ... ] block, found ${describeValue(t, p + 1)}`,\n { line: t.line[p], element: what },\n );\n }\n\n /**\n * Find a node block's id, label and original-id values.\n * @param open - the block's `[`\n * @param close - the block's `]`\n * @returns each key's value token, or -1 when the block has none\n */\n private nodeKeyTokens(open: number, close: number): { idTok: number; labelTok: number; originalTok: number } {\n const t = this.requireTokens();\n let idTok = -1;\n let labelTok = -1;\n let originalTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\") {\n idTok = this.structuralToken(idTok, p, \"id\");\n } else if (key === \"label\") {\n labelTok = labelTok < 0 ? p + 1 : labelTok;\n } else if (key === ORIGINAL_ID_KEY && this.options.restoreMangledIds) {\n originalTok = originalTok < 0 ? p + 1 : originalTok;\n }\n }\n return { idTok, labelTok, originalTok };\n }\n\n /**\n * The id a node is added to the sink under: its restored original id, else its label, its\n * ordinal or its file id, as `nodeIdFrom` says.\n * @param fileId - the node's file id\n * @param labelTok - its label's value token, or -1\n * @param originalTok - its original id's value token, or -1\n * @param ordinal - its position among the file's nodes\n * @returns the sink id\n */\n private nodeSinkId(fileId: NodeId, labelTok: number, originalTok: number, ordinal: number): NodeId {\n if (originalTok >= 0) {\n return this.restoredId(originalTok);\n }\n switch (this.options.nodeIdFrom) {\n case \"label\":\n if (labelTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no label\", {\n reason: \"missing label\",\n });\n }\n return this.coerceValueToken(labelTok);\n case \"index\":\n return ordinal;\n default:\n return fileId;\n }\n }\n\n /**\n * Note which sink id a file id resolves to, warning when a file id is declared twice.\n * @param fileId - the file id\n * @param sinkId - the sink id it now resolves to\n * @param line - the node block's line\n */\n private mapFileId(fileId: NodeId, sinkId: NodeId, line: number): void {\n if (this.idMap === null) {\n return;\n }\n const before = this.idMap.get(fileId);\n if (before !== undefined && before !== sinkId) {\n this.report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `file id ${JSON.stringify(fileId)} is declared twice (nodes ${JSON.stringify(before)} and ${JSON.stringify(sinkId)}); edges to it resolve to the later`,\n { line, element: String(fileId) },\n );\n }\n this.idMap.set(fileId, sinkId);\n }\n\n /**\n * Push one node block.\n * @param open - the block's `[`\n */\n private importNode(open: number): void {\n const t = this.requireTokens();\n const { sink, report } = this;\n const close = t.match[open];\n const line = t.line[open];\n const ordinal = this.nodeOrdinal++;\n this.checkAbort();\n let index: number;\n let sinkId: NodeId;\n let fileId: NodeId | undefined;\n try {\n const { idTok, labelTok, originalTok } = this.nodeKeyTokens(open, close);\n if (idTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no id\", { reason: \"missing id\" });\n }\n // the file id under the ids rule, so `id 1` and `source \"1\"` meet in idMap (except under\n // \"keep\", where the integer 1 and the string \"1\" are different ids by design)\n fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, \"id\"));\n sinkId = this.nodeSinkId(fileId, labelTok, originalTok, ordinal);\n index = sink.addNode(sinkId);\n this.mapFileId(fileId, sinkId, line);\n } catch (err) {\n this.recordNodeError(err, line);\n report.counts.skippedNodes++;\n if (fileId !== undefined) {\n this.skippedIds.add(fileId);\n }\n return;\n }\n if (this.isDeclared(index)) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${JSON.stringify(sinkId)} is declared twice; later keys overwrite`,\n { line, element: String(sinkId) },\n );\n } else {\n this.markDeclared(index);\n report.counts.nodes++;\n }\n this.beginElement(this.seq++);\n try {\n this.writeNodeKeys(open, index, sinkId);\n this.flushLists(\"node\", index);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element: String(sinkId) });\n }\n }\n\n /**\n * Write one node block's keys into its columns: its graphics record into the position plan, a yEd `gid` noted\n * for the group hierarchy, and every other planned key as it is.\n * @param open - the block's `[`\n * @param index - the node's index\n * @param sinkId - the node's id, for the report\n */\n private writeNodeKeys(open: number, index: number, sinkId: NodeId): void {\n const t = this.requireTokens();\n const graphics: number[] = [];\n let graphicsPlan: ColumnPlan | null = null;\n for (let p = open + 1; p < t.match[open]; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\" || (key === ORIGINAL_ID_KEY && this.options.restoreMangledIds)) {\n continue;\n }\n if (key === \"gid\") {\n this.groupRefs.push([index, p + 1]);\n }\n const plan = this.nodePlans.get(key);\n if (plan !== undefined && plan.position !== null) {\n graphicsPlan = plan;\n graphics.push(p + 1);\n } else if (plan !== undefined) {\n this.writeNode(plan, index, p + 1);\n }\n }\n if (graphicsPlan !== null) {\n this.writeGraphics(graphicsPlan, index, graphics, {\n line: t.line[graphics[0]],\n element: String(sinkId),\n });\n }\n }\n\n /**\n * Push one edge block.\n * @param open - the block's `[`\n * @param ordinal - the edge's ordinal among edge blocks, for messages\n */\n private importEdge(open: number, ordinal: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const element = `edge #${ordinal}`;\n this.checkAbort();\n let edge: number;\n try {\n let sourceTok = -1;\n let targetTok = -1;\n let weightTok = -1;\n let directedTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\") {\n sourceTok = this.structuralToken(sourceTok, p, \"source\");\n } else if (key === \"target\") {\n targetTok = this.structuralToken(targetTok, p, \"target\");\n } else if (key === \"directed\") {\n directedTok = this.structuralToken(directedTok, p, \"directed\");\n } else if (key === options.weightFrom) {\n weightTok = p + 1;\n }\n }\n if (sourceTok < 0 || targetTok < 0) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge has no ${sourceTok < 0 ? \"source\" : \"target\"}`, {\n reason: \"missing endpoint\",\n });\n }\n const source = this.endpoint(sourceTok, \"source\");\n const target = this.endpoint(targetTok, \"target\");\n const weight = weightTok >= 0 ? this.weightOf(weightTok) : undefined;\n const before = sink.edgeCount;\n const sourceNew = sink.indexOf(source) === INVALID_INDEX;\n const targetNew = source !== target && sink.indexOf(target) === INVALID_INDEX;\n // an edge-level `directed` key overrides the graph's flag for that edge (mixed graphs)\n const directed = this.readFlag(directedTok, \"directed\") ?? this.headerDirected;\n edge = this.requireResolver().addEdge(source, target, directed ? \"directed\" : \"undirected\", weight, {\n line,\n element,\n });\n report.counts.edges += sink.edgeCount - before;\n // endpoints the file never declares (addMissingNodes) are nodes of the sink too\n report.counts.nodes += (sourceNew ? 1 : 0) + (targetNew ? 1 : 0);\n } catch (err) {\n this.recordEdgeError(err, line, element);\n report.counts.skippedEdges++;\n return;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\" || key === \"target\" || key === \"directed\" || key === options.weightFrom) {\n continue;\n }\n const plan = this.edgePlans.get(key);\n if (plan !== undefined) {\n this.writeEdge(plan, edge, p + 1);\n }\n }\n this.flushLists(\"edge\", edge);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element });\n }\n }\n\n // ============================================================ ids and weights\n\n /**\n * Note a structural key token, refusing a repeat.\n * @param previous - the token seen before, or -1\n * @param p - the key token\n * @param key - the key name\n * @returns the value token\n */\n private structuralToken(previous: number, p: number, key: string): number {\n if (previous >= 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", `key \"${key}\" appears twice in one block`, {\n reason: \"duplicate key\",\n key,\n });\n }\n return p + 1;\n }\n\n /**\n * The value of an id / source / target token: an integer (the GML spec's type) as a number, a\n * string (NetworkX and Gephi write them) as its text with one warning per file.\n * @param v - the value token\n * @param key - the key name, for the error\n * @returns the number or the string\n */\n private fileIdOf(v: number, key: string): number | string {\n const t = this.requireTokens();\n if (t.kind[v] === TOKEN_STRING) {\n this.report.warnOnce(\n \"validation-error\",\n STRING_ID_CODE,\n `${key} is the string \"${t.textOf(v)}\"; GML ids are integers, string ids are kept under the ids rule`,\n { line: t.line[v], element: t.stringOf(v) },\n );\n return t.stringOf(v);\n }\n if (t.kind[v] !== TOKEN_INT) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${key} must be an integer or a string, found ${describeValue(t, v)}`,\n {\n reason: \"not an integer\",\n key,\n value: t.kind[v] === TOKEN_OPEN ? \"[...]\" : t.textOf(v),\n },\n );\n }\n return Number(t.textOf(v));\n }\n\n /**\n * Coerce an id / source / target value under the `ids` rule: a string by its text, an integer\n * through coerceInteger().\n * @param v - the value token\n * @param id - its value (fileIdOf())\n * @returns the id\n */\n private coerceFileId(v: number, id: number | string): NodeId {\n return typeof id === \"string\" ? this.coercer.text(id) : this.coerceInteger(v, id);\n }\n\n /**\n * Coerce an integer id token under the `ids` rule: a safe integer passes as a typed number\n * (so `01` is 1 and `-0` is 0), a larger one goes through the text rule (a string under\n * \"canonical\"), and \"string\" keeps the text as written.\n * @param v - the value token\n * @param n - its numeric value\n * @returns the id\n */\n private coerceInteger(v: number, n: number): NodeId {\n if (Number.isSafeInteger(n) && this.coercer.mode !== \"string\") {\n return this.coercer.value(n);\n }\n return this.coercer.text(this.requireTokens().textOf(v));\n }\n\n /**\n * Coerce a label token under the `ids` rule: a string by its text, a number as a typed value.\n * @param v - the value token\n * @returns the id\n */\n private coerceValueToken(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return this.coercer.text(t.stringOf(v));\n case TOKEN_INT:\n return this.coerceInteger(v, Number(t.textOf(v)));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", \"label must be a string or a number, found a record\", {\n reason: \"record label\",\n });\n default:\n return this.coercer.value(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * The id a `graphty_originalId` key restores: typed, never coerced (the exporter wrote it exactly).\n * @param v - the value token\n * @returns the original id\n */\n private restoredId(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return t.stringOf(v);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", `${ORIGINAL_ID_KEY} must be a string or a number`, {\n reason: \"record original id\",\n });\n default:\n return numberOfText(t.textOf(v));\n }\n }\n\n /**\n * Resolve a source / target token to a sink id.\n * @param v - the value token\n * @param key - source or target\n * @returns the id\n */\n private endpoint(v: number, key: string): NodeId {\n const id = this.coerceFileId(v, this.fileIdOf(v, key));\n const mapped = this.idMap?.get(id);\n if (mapped !== undefined) {\n return mapped;\n }\n if (this.skippedIds.has(id)) {\n // the node block was skipped: creating the endpoint would bring the node back under\n // its raw file id (beside label ids under nodeIdFrom \"label\")\n throw new GraphFormatError(\n \"E_UNKNOWN_NODE\",\n `${key} ${JSON.stringify(id)} names a node block that was skipped after an error`,\n { reason: \"skipped node\", id },\n );\n }\n return id;\n }\n\n /**\n * The weight of an edge from its weight token.\n * @param v - the value token\n * @returns the weight; E_INVALID_WEIGHT for a record or non-numeric text\n */\n private weightOf(v: number): number | undefined {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return parseWeightText(t.stringOf(v), this.report);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"edge weight is a record\", { value: \"[...]\" });\n default: {\n const text = t.textOf(v);\n const weight = weightFromValue(numberOfText(text));\n if (weight !== undefined) {\n reportWeightPrecision(text, weight, this.report);\n }\n return weight;\n }\n }\n }\n\n /**\n * Record a node-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n */\n private recordNodeError(err: unknown, line: number): void {\n const { report } = this;\n if (err instanceof GraphFormatError && err.code === \"E_INVALID_ID\") {\n const { reason } = err.details;\n switch (reason) {\n case \"missing id\":\n report.error(\"missing-value\", MISSING_ID_CODE, err.message, { line, element: \"node\" });\n return;\n case \"missing label\":\n report.error(\"missing-value\", MISSING_LABEL_CODE, err.message, { line, element: \"node\" });\n return;\n case \"duplicate key\":\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element: \"node\" });\n return;\n case \"not an integer\":\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element: \"node\" });\n return;\n default:\n break;\n }\n }\n report.recordError(err, { line, element: \"node\" });\n }\n\n /**\n * Record an edge-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n * @param element - the edge description\n */\n private recordEdgeError(err: unknown, line: number, element: string): void {\n const { report } = this;\n if (err instanceof GraphFormatError) {\n const { reason } = err.details;\n if (err.code === \"E_UNKNOWN_NODE\" && reason === \"missing endpoint\") {\n report.error(\"missing-value\", MISSING_ENDPOINT_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"duplicate key\") {\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"not an integer\") {\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element });\n return;\n }\n }\n report.recordError(err, { line, element });\n }\n\n // ============================================================ values\n\n /**\n * Write one node value.\n * @param plan - the key's plan\n * @param index - the node index\n * @param v - the value token\n */\n private writeNode(plan: ColumnPlan, index: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setNodeValue(this.handleOf(plan, \"node\"), index, this.scalarOf(plan, v));\n }\n\n /**\n * Write one edge value.\n * @param plan - the key's plan\n * @param edge - the edge index\n * @param v - the value token\n */\n private writeEdge(plan: ColumnPlan, edge: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setEdgeValue(this.handleOf(plan, \"edge\"), edge, this.scalarOf(plan, v));\n }\n\n /**\n * Write one graph value.\n * @param plan - the key's plan\n * @param v - the value token\n * @param seq - TOP_SEQ or GRAPH_SEQ\n */\n private writeGraph(plan: ColumnPlan, v: number, seq: number): void {\n if (plan.list) {\n this.collectItem(plan, v, seq, this.graphTouched);\n return;\n }\n const value = this.scalarOf(plan, v);\n this.sink.setGraphValue(plan.name, value, graphDecl(plan));\n if (seq === GRAPH_SEQ && plan.key === \"name\" && typeof value === \"string\") {\n // the graph block's `name` is the graph's name too (snapshot.meta.name, and what graphName matches)\n this.sink.setMeta({ name: value });\n }\n }\n\n /**\n * Write a node's graphics values: the position column from the x / y / z of the first record,\n * everything else (the remaining keys, a value that is not a record, a repeated record) to the\n * json column, with a warning when the value cannot give a position as written.\n * @param plan - the graphics plan\n * @param index - the node index\n * @param vs - the value tokens of the node's graphics keys, in order\n * @param where - the line and the node, for issues\n */\n private writeGraphics(plan: ColumnPlan, index: number, vs: readonly number[], where: IssueWhere): void {\n const t = this.requireTokens();\n const { sink } = this;\n const values = vs.map((v) => (t.kind[v] === TOKEN_OPEN ? parseRecord(t, v) : this.scalarOf(plan, v)));\n const first = values[0];\n const positionPlan = plan.position;\n let rest: unknown = first;\n if (isRecord(first) && positionPlan !== null) {\n const left = this.writePosition(positionPlan, index, this.keepPositionSource ? { ...first } : first, where);\n rest = this.keepPositionSource ? first : left;\n } else if (!isRecord(first)) {\n this.graphicsWarning(\"scalar\", `node ${where.element}'s graphics is not a record`, where);\n }\n if (values.length > 1) {\n this.graphicsWarning(\n \"repeated\",\n `node ${where.element} has ${values.length} graphics records; the position comes from the first`,\n where,\n );\n rest = values;\n }\n if (rest !== undefined && plan.rest !== null) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, rest);\n }\n }\n\n /**\n * Write a node's position from the x / y / z of its graphics record, taking them out of it.\n * @param positionPlan - the position column's plan\n * @param index - the node index\n * @param record - the graphics record\n * @param where - the line and the node, for issues\n * @returns what is left of the record for the json column, or undefined when nothing is\n */\n private writePosition(\n positionPlan: ColumnPlan,\n index: number,\n record: Record<string, unknown>,\n where: IssueWhere,\n ): unknown {\n const { x, y, z } = record;\n let rest: unknown = record;\n if (typeof x === \"number\" && typeof y === \"number\") {\n const depth = typeof z === \"number\" ? z : 0;\n this.sink.setNodeValue(this.handleOf(positionPlan, \"node\"), index, [x, y, depth]);\n delete record.x;\n delete record.y;\n if (typeof z === \"number\") {\n delete record.z;\n }\n rest = Object.keys(record).length > 0 ? record : undefined;\n }\n if (\"x\" in record || \"y\" in record || \"z\" in record) {\n this.graphicsWarning(\n \"coordinate\",\n `node ${where.element}'s graphics x / y / z is not one number each`,\n where,\n );\n }\n return rest;\n }\n\n /**\n * Warn once per kind of graphics problem.\n * @param kind - the problem\n * @param what - the message start, naming the node\n * @param where - the line and the node\n */\n private graphicsWarning(kind: string, what: string, where: IssueWhere): void {\n this.report.warnOnce(\n \"validation-error\",\n GRAPHICS_CODE,\n `${what}; the value is kept in the graphics json column (warned once for every such node)`,\n where,\n `${GRAPHICS_CODE}:${kind}`,\n );\n }\n\n /**\n * Collect one list item.\n * @param plan - the list plan\n * @param v - the value token\n * @param seq - the sequence number of the element the item belongs to\n * @param touched - the plans touched by that element\n */\n private collectItem(plan: ColumnPlan, v: number, seq: number, touched: ColumnPlan[]): void {\n const t = this.requireTokens();\n if (plan.seq !== seq) {\n plan.seq = seq;\n plan.items = [];\n touched.push(plan);\n }\n if (t.kind[v] === TOKEN_STRING) {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n return;\n }\n }\n (plan.items as unknown[]).push(this.scalarOf(plan, v));\n }\n\n /**\n * Start a node or edge: later list items belong to it.\n * @param seq - the element's sequence number\n */\n private beginElement(seq: number): void {\n this.seqNow = seq;\n this.touched.length = 0;\n }\n\n /**\n * Write the lists collected for the current node or edge.\n * @param domain - node or edge\n * @param row - the row\n */\n private flushLists(domain: \"node\" | \"edge\", row: number): void {\n const { sink, touched } = this;\n for (const plan of touched) {\n const handle = this.handleOf(plan, domain);\n if (domain === \"node\") {\n sink.setNodeValue(handle, row, plan.items);\n } else {\n sink.setEdgeValue(handle, row, plan.items);\n }\n plan.items = null;\n }\n touched.length = 0;\n }\n\n /** Write the lists collected for the graph table. */\n private flushGraphLists(): void {\n const { sink, graphTouched } = this;\n for (const plan of graphTouched) {\n sink.setGraphValue(plan.name, plan.items, graphDecl(plan));\n plan.items = null;\n }\n graphTouched.length = 0;\n }\n\n /**\n * The JS value of a scalar value token (or list item) under a plan's storage class.\n * @param plan - the plan\n * @param v - the value token\n * @returns the value to push\n */\n private scalarOf(plan: ColumnPlan, v: number): unknown {\n const t = this.requireTokens();\n const kind = t.kind[v];\n switch (plan.kind) {\n case \"int\":\n return Number(t.textOf(v));\n case \"real\":\n return numberOfText(t.textOf(v));\n case \"string\":\n return kind === TOKEN_STRING ? t.stringOf(v) : t.textOf(v);\n default:\n return kind === TOKEN_STRING ? t.stringOf(v) : scalarOrRecord(t, v);\n }\n }\n\n /**\n * The handle of a plan's column, declaring it on first use. A declaration the sink refuses\n * because a column of the name exists with another declaration falls back to that column\n * (reported once); a taken role is dropped (reported once).\n * @param plan - the plan\n * @param domain - node or edge\n * @returns the handle\n */\n private handleOf(plan: ColumnPlan, domain: \"node\" | \"edge\"): ColumnHandle {\n if (plan.declared) {\n return plan.handle;\n }\n plan.declared = true;\n const { sink, report } = this;\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.role === \"position\") {\n decl.components = 3;\n }\n if (plan.role !== null) {\n decl.role = plan.role;\n }\n const resolved = declareResolved(sink, domain, decl, report, { element: plan.name });\n plan.handle = resolved.handle;\n if (resolved.renamed) {\n plan.name = resolved.decl.name;\n }\n return plan.handle;\n }\n\n // ============================================================ bookkeeping\n\n /**\n * Whether a node index was declared by a node block of this import.\n * @param index - the node index\n * @returns true when declared\n */\n private isDeclared(index: number): boolean {\n const word = index >>> 5;\n return word < this.declared.length && ((this.declared[word] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark a node index as declared.\n * @param index - the node index\n */\n private markDeclared(index: number): void {\n const word = index >>> 5;\n if (word >= this.declared.length) {\n const grown = new Uint32Array(Math.max(word + 1, this.declared.length * 2));\n grown.set(this.declared);\n this.declared = grown;\n }\n this.declared[word] |= 1 << (index & 31);\n }\n\n /** Check the abort signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The tokens, which exist after run() lexed the text.\n * @returns the tokens\n */\n private requireTokens(): GmlTokens {\n if (this.tokens === null) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"the GML text was not lexed\", { reason: \"no tokens\" });\n }\n return this.tokens;\n }\n\n /**\n * The direction resolver, which exists once the header was set.\n * @returns the resolver\n */\n private requireResolver(): DirectionResolver {\n if (this.resolver === null) {\n throw new GraphFormatError(\"E_DIRECTED\", \"the header was not set\", { reason: \"no resolver\" });\n }\n return this.resolver;\n }\n}\n\n/**\n * The KIND_* bit of a value token.\n * @param t - the tokens\n * @param v - the value token\n * @returns the bit\n */\nfunction kindBit(t: GmlTokens, v: number): number {\n switch (t.kind[v]) {\n case TOKEN_INT:\n return KIND_INT;\n case TOKEN_STRING:\n return KIND_STRING;\n case TOKEN_OPEN:\n return KIND_RECORD;\n default:\n return KIND_REAL;\n }\n}\n\n/**\n * The storage class of a schema entry: the widest value class seen.\n * @param entry - the entry\n * @returns the class\n */\nfunction kindOf(entry: KeySchema): GmlKind {\n if ((entry.kinds & KIND_RECORD) !== 0) {\n return \"record\";\n }\n if ((entry.kinds & KIND_STRING) !== 0) {\n return \"string\";\n }\n if ((entry.kinds & KIND_REAL) !== 0) {\n return \"real\";\n }\n return \"int\";\n}\n\n/**\n * The scalar dtype of a storage class.\n * @param kind - the class\n * @param entry - the entry (a wide int keeps origin int but stores f64)\n * @returns the dtype\n */\nfunction dtypeOfKind(kind: GmlKind, entry: KeySchema): ScalarDtype {\n switch (kind) {\n case \"int\":\n return entry.wide ? \"f64\" : \"i32\";\n case \"real\":\n return \"f64\";\n case \"string\":\n return \"string\";\n default:\n return \"json\";\n }\n}\n\n/**\n * The origin.type text of a plan: the GML value class of its values (`int` for wide integers\n * stored as f64 too, so the exporter writes them without a decimal point).\n * @param plan - the plan\n * @returns the type text\n */\nfunction originTypeOf(plan: ColumnPlan): string {\n return plan.kind;\n}\n\n/**\n * The declaration patch of a graph column.\n * @param plan - the plan\n * @returns the decl for setGraphValue\n */\nfunction graphDecl(plan: ColumnPlan): ColumnDecl {\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.top) {\n decl.extra = { gmlTopLevel: true };\n }\n return decl;\n}\n\n/**\n * A short description of a value token for messages.\n * @param t - the tokens\n * @param v - the value token\n * @returns the description\n */\nfunction describeValue(t: GmlTokens, v: number): string {\n switch (t.kind[v]) {\n case TOKEN_OPEN:\n return \"a record\";\n case TOKEN_STRING:\n return `the string \"${t.textOf(v)}\"`;\n case TOKEN_REAL:\n return `the real ${t.textOf(v)}`;\n case TOKEN_WORD:\n return `the word ${t.textOf(v)}`;\n default:\n return t.textOf(v);\n }\n}\n\nconst SNIFF_GRAPH_START = /^(?:\\s|#[^\\n]*\\n)*graph\\s*\\[/;\nconst SNIFF_GRAPH_ANYWHERE = /(?:^|\\s)graph\\s*\\[/;\nconst SNIFF_KEY_START = /^(?:\\s|#[^\\n]*\\n)*[A-Za-z_]\\w*\\s+(?:\"|[+-]?[0-9.]|\\[)/;\n\n/**\n * Confidence that a head of bytes is GML: a `graph [` opener, or key-value text with a `graph [`\n * somewhere in the head.\n * @param head - the first bytes of the input\n * @returns 0.95 for a leading `graph [`, 0.85 for key-value text containing one, 0.4 for key-value text, 0 otherwise\n */\nfunction sniffGml(head: Uint8Array): number {\n let text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n if (text.charCodeAt(0) === 0xfeff) {\n text = text.slice(1);\n }\n if (SNIFF_GRAPH_START.test(text)) {\n return 0.95;\n }\n if (SNIFF_KEY_START.test(text)) {\n return SNIFF_GRAPH_ANYWHERE.test(text) ? 0.85 : 0.4;\n }\n return 0;\n}\n\n/**\n * The GML importer plugin.\n * @category Built-in formats\n */\nexport const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({\n format: \"gml\",\n options: Object.freeze([\"dictionaries\", \"keepPositionSource\", \"positions\"]),\n extensions: Object.freeze([\".gml\"]),\n mimeTypes: Object.freeze([\"text/x-gml\", \"text/plain\"]),\n sniff: sniffGml,\n styles: gmlStyles,\n positions: gmlPositions,\n /**\n * Read a GML text into a sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n if (graphChosen(options)) {\n // the choice is honored here too, not only by the registry\n return importChosenGraph(gmlImporter, input, sink, options);\n }\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const tokens = tokenize(await readText(input, report, resolved), report);\n throwIfAborted(resolved.signal);\n const gml = new GmlImport(sink, report, resolved, options);\n gml.run(tokens);\n if (gml.graphCount > 1) {\n report.warning(\n \"unsupported\",\n SECOND_GRAPH_CODE,\n `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)`,\n );\n }\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every `graph [ ... ]` block of a GML text, each into its own sink; the top-level keys\n * (Creator, Version, ...) apply to each.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph block\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const first = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const tokens = tokenize(await readText(input, first, resolved), first);\n const reports: ImportReport[] = [];\n let count = 1;\n for (let i = 0; i < count; i++) {\n throwIfAborted(resolved.signal);\n const report = i === 0 ? first : new ImportReportBuilder(\"gml\", resolved.errorLimit);\n const sink = sinkFor(i);\n reportSinkOptions(sink, options, report);\n const gml = new GmlImport(sink, report, resolved, options, i);\n gml.run(tokens);\n count = gml.graphCount;\n reports.push(report.finish());\n }\n throwIfAborted(resolved.signal);\n return reports;\n },\n});\n\n/**\n * Tokenize a GML text; a syntax error is fatal.\n * @param text - the whole text\n * @param report - where the syntax error is recorded\n * @returns the tokens\n */\nfunction tokenize(text: string, report: ImportReportBuilder): GmlTokens {\n try {\n return tokenizeGml(text);\n } catch (err) {\n if (err instanceof GmlSyntaxError) {\n report.fail(err.code, err.message, { line: err.line });\n }\n throw err;\n }\n}\n","/**\n * The `@graphty/graph-io/gml` subpath: the GML importer and exporter, their\n * option types, and their issue and loss-note codes grouped in two tables.\n * @module @graphty/graph-io/gml\n */\n\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n COLUMN_RENAMED_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n ELEMENT_ISSUE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n INPUT_ISSUE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MIXED_DIRECTION_CODE,\n OPTION_IGNORED_CODE,\n SINK_OPTION_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport {\n GRAPHICS_CONFLICT_CODE,\n GRAPHICS_OVERRIDDEN_CODE,\n INVALID_KEY_CODE,\n JSON_ARRAY_CODE,\n KEY_MANGLED_CODE,\n NESTED_ARRAY_CODE,\n POSITION_COMPONENTS_CODE,\n RECORD_BOOLEAN_CODE,\n RECORD_NULL_CODE,\n RECORD_NUMBER_TYPE_CODE,\n RESERVED_KEY_CODE,\n} from \"./exporter.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ELEMENT_TYPE_CODE,\n FLAG_TYPE_CODE,\n FLAG_VALUE_CODE,\n GRAPHICS_CODE,\n GROUPS_CODE,\n ID_DROPPED_CODE,\n ID_TYPE_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_LABEL_CODE,\n NESTED_ELEMENT_CODE,\n NO_GRAPH_CODE,\n PRECISION_CODE,\n REPEATED_KEY_CODE,\n ROLE_TAKEN_CODE,\n SECOND_GRAPH_CODE,\n STRING_ID_CODE,\n UNKNOWN_ENTITY_CODE,\n WIDENED_CODE,\n} from \"./importer.js\";\n\nexport { gmlExporter, type GmlExportOptions } from \"./exporter.js\";\nexport { gmlImporter, type GmlImportOptions } from \"./importer.js\";\nexport { GML_STYLE_BLOCK_KEY, GML_STYLE_CAPABILITIES } from \"./styles.js\";\n\n/**\n * The issue codes the GML importer records, by name: the codes shared with\n * the other importers and the GML-specific ones. A key is the code without\n * its severity and format prefixes.\n * @category Built-in formats\n */\nexport const GML_ISSUE = Object.freeze({\n ...INPUT_ISSUE,\n ...ELEMENT_ISSUE,\n /**\n * The text breaks GML's syntax: a word that is not a key or a value, an unclosed string or `[`, a stray `]`, or a\n * key without a value. The import stops.\n */\n SYNTAX: SYNTAX_CODE,\n /** The input is not valid UTF-8. The import stops. */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /**\n * Some bytes are not valid in the encoding that was chosen (by a byte order mark, the file's declaration or the\n * `encoding` option). The import stops.\n */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** There is no `graph [` block. The import stops. */\n NO_GRAPH: NO_GRAPH_CODE,\n /** The file holds more than one `graph` block and only the first was read. It is not added when `graphIndex` or `graphName` chose the graph. */\n MULTIPLE_GRAPHS: SECOND_GRAPH_CODE,\n /** `graphIndex` or `graphName` names no graph of the file; the message lists the graphs it holds. The import stops. */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** `graphName` matches more than one graph; pass `graphIndex`. The import stops. */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** A node without an `id`. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without a `label` under nodeIdFrom \"label\". */\n MISSING_LABEL: MISSING_LABEL_CODE,\n /** An edge without `source` or `target`. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id, source or target that is neither an integer nor a string. */\n ID_TYPE: ID_TYPE_CODE,\n /**\n * Node ids, sources or targets are text, where GML expects integers. They are read under the `ids` option.\n * Reported once per file.\n */\n STRING_ID: STRING_ID_CODE,\n /** A node id declared twice (later keys overwrite). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A structural key repeated in one element. */\n REPEATED_KEY: REPEATED_KEY_CODE,\n /** A `node` / `edge` key whose value is not a record. */\n ELEMENT_TYPE: ELEMENT_TYPE_CODE,\n /** A `directed` / `multigraph` flag that is not an integer. */\n FLAG_TYPE: FLAG_TYPE_CODE,\n /** A `directed` / `multigraph` flag outside 0 / 1, or repeated. */\n FLAG_VALUE: FLAG_VALUE_CODE,\n /** A named entity no table decodes, or a numeric reference beyond U+10FFFF; kept as written. */\n UNKNOWN_ENTITY: UNKNOWN_ENTITY_CODE,\n /** An integer beyond 2^53 was stored as the nearest 64-bit float; pass `long: \"string\"` to keep every digit. */\n PRECISION: PRECISION_CODE,\n /** A node's graphics value that cannot give a position as written; kept in the graphics json column. */\n GRAPHICS: GRAPHICS_CODE,\n /** A graph, node or edge record nested in a node or edge; kept as json, not read as structure. */\n NESTED_ELEMENT: NESTED_ELEMENT_CODE,\n /** A yEd `gid` that names no other node; it stays a plain column value and puts the node in no group. */\n GROUPS: GROUPS_CODE,\n /**\n * An attribute's type was widened because a later value did not fit: an integer above 2^31 in an integer column,\n * or two declared types for one attribute.\n */\n WIDENED: WIDENED_CODE,\n /**\n * An attribute was renamed `<name>#<suffix>` because another attribute already has its name, for example\n * two attributes declared with the same name.\n */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /**\n * You read into a graph builder that already has an id, label or position attribute, so this file's one is kept as\n * a plain attribute.\n */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two different id texts became the same number because `ids` is \"number\", so their nodes were merged. */\n ID_MERGED: ID_MERGED_CODE,\n /** You set an option this format does not use; it had no effect. The message names the option. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /**\n * You read into your own graph builder, which was created with a different `addMissingNodes`, `duplicateEdges`,\n * `selfLoops` or `weightDtype` than the option you passed; the builder's setting applies.\n */\n SINK_OPTION: SINK_OPTION_CODE,\n /**\n * You read into a graph builder whose direction is already set, or which already holds edges, so the file is read\n * with the builder's direction instead of its own.\n */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges of the other direction were read with the direction `onMixedDirection` chose. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /**\n * The graph has both directed and undirected edges and `onMixedDirection` is \"error\". An import stops; a save to a\n * format that holds one direction per file fails with E_DIRECTED. Pass \"directed\" or \"undirected\" to read or write\n * it anyway.\n */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n /**\n * Under `nodeIdFrom: \"label\"` or `\"index\"` the file's integer ids are not kept. It is listed in `report.lossy`, not\n * in `report.issues`.\n */\n ID_DROPPED: ID_DROPPED_CODE,\n});\n\n/**\n * The loss-note codes the GML exporter's check() reports beyond the shared LOSS table, by name.\n * @category Built-in formats\n */\nexport const GML_LOSS = Object.freeze({\n /** A json column holds numbers; GML records cannot keep int versus real. */\n RECORD_NUMBER_TYPE: RECORD_NUMBER_TYPE_CODE,\n /** A json column holds booleans, written 1 / 0. */\n RECORD_BOOLEAN: RECORD_BOOLEAN_CODE,\n /** A json column holds nulls, omitted. */\n RECORD_NULL: RECORD_NULL_CODE,\n /** An attribute holds an array inside an array, which GML cannot write; the save fails. */\n NESTED_ARRAY: NESTED_ARRAY_CODE,\n /** A json row that is an array, written as repeated keys. */\n JSON_ARRAY: JSON_ARRAY_CODE,\n /**\n * An attribute name GML cannot use as a key (keys are letters and digits, starting with a letter). The save fails\n * unless `sanitizeKeys` is \"mangle\".\n */\n INVALID_KEY: INVALID_KEY_CODE,\n /** A column named like a structural key. */\n RESERVED_KEY: RESERVED_KEY_CODE,\n /** A key rewritten under sanitizeKeys \"mangle\", or a column renamed because its key would read back as a style value. */\n KEY_MANGLED: KEY_MANGLED_CODE,\n /** A position column with more than three components. */\n POSITION_COMPONENTS: POSITION_COMPONENTS_CODE,\n /** A graphics record whose x / y / z the position column overrides. */\n GRAPHICS_OVERRIDDEN: GRAPHICS_OVERRIDDEN_CODE,\n /** A graphics record that cannot hold the position. */\n GRAPHICS_CONFLICT: GRAPHICS_CONFLICT_CODE,\n});\n"],"names":["note","SHARED_NO_GRAPH_CODE","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_WIDENED_CODE","SHARED_PRECISION_CODE","SHARED_ROLE_TAKEN_CODE","first"],"mappings":"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"}