@graphty/graph-io 0.3.42 → 0.3.44

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 (674) hide show
  1. package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
  2. package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
  3. package/dist/chunks/block-JQiwViEt.js +2777 -0
  4. package/dist/chunks/block-JQiwViEt.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
  8. package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DCwFLts5.js +3456 -0
  12. package/dist/chunks/emit-DCwFLts5.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
  14. package/dist/chunks/escape-B1rMftd9.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
  16. package/dist/chunks/export-D7IGzTG4.js.map +1 -0
  17. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
  18. package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
  19. package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
  20. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
  22. package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
  23. package/dist/chunks/{exporter-CpRyHZ3H.js → exporter-quPUCBiC.js} +1807 -288
  24. package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
  25. package/dist/chunks/format-GDmO6m6Q.js +676 -0
  26. package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
  27. package/dist/chunks/generic-BL06jrJf.js +1347 -0
  28. package/dist/chunks/generic-BL06jrJf.js.map +1 -0
  29. package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
  30. package/dist/chunks/importer-B7r2owVf.js.map +1 -0
  31. package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
  32. package/dist/chunks/importer-BFmOP96W.js.map +1 -0
  33. package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
  34. package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
  35. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
  36. package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
  37. package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
  38. package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
  39. package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
  40. package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
  41. package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
  42. package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
  43. package/dist/chunks/index-B9fdNpTA.js +4310 -0
  44. package/dist/chunks/index-B9fdNpTA.js.map +1 -0
  45. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
  46. package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
  47. package/dist/chunks/lexicon-B-knUi-l.js +508 -0
  48. package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
  49. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
  50. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
  51. package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
  52. package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
  53. package/dist/chunks/styles-Brt9JMfs.js +690 -0
  54. package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
  55. package/dist/chunks/styles-_N-C8S-U.js +2102 -0
  56. package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
  57. package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
  58. package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
  59. package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
  60. package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
  61. package/dist/chunks/units-XMZFIFe1.js +19 -0
  62. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +295 -414
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +8 -3031
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +354 -240
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1484 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +23 -7
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +441 -265
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +790 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +603 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +80 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +596 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1741 -0
  571. package/src/formats/gexf/exporter.ts +30 -13
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +543 -323
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +951 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +656 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +745 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-CpRyHZ3H.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -154,6 +154,12 @@ export class GmlTokens {
154
154
  /** The number of tokens. */
155
155
  count = 0;
156
156
 
157
+ /**
158
+ * Whether a backslash escapes the next character inside a string (`\"`, `\\`): set for files OGDF wrote, whose
159
+ * writer escapes quotes that way. Plain GML has no escape mechanism.
160
+ */
161
+ backslashEscapes = false;
162
+
157
163
  /** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */
158
164
  onUnknownEntity: ((entity: string, line: number) => void) | null = null;
159
165
 
@@ -209,6 +215,9 @@ export class GmlTokens {
209
215
  // a line break inside a string is part of it, as LF whatever the file's line ends
210
216
  text = text.replaceAll(/\r\n?/g, "\n");
211
217
  }
218
+ if (this.backslashEscapes && text.includes("\\")) {
219
+ text = text.replaceAll(/\\([\s\S])/g, "$1");
220
+ }
212
221
  if (!text.includes("&")) {
213
222
  return text;
214
223
  }
@@ -279,67 +288,144 @@ export class GmlTokens {
279
288
  */
280
289
  export function tokenizeGml(text: string): GmlTokens {
281
290
  const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));
282
- const n = text.length;
291
+ tokens.backslashEscapes = writtenByOgdf(text);
292
+ const lex: GmlLex = { text, tokens, i: 0, line: 1, spanningLine: 0 };
293
+ while (lex.i < text.length) {
294
+ const c = text.codePointAt(lex.i) ?? 0;
295
+ if (c === 34) {
296
+ lexString(lex);
297
+ } else if (c === 91 || c === 93) {
298
+ tokens.push(c === 91 ? TOKEN_OPEN : TOKEN_CLOSE, lex.i, lex.i + 1, lex.line);
299
+ lex.i++;
300
+ } else if (!skipSpace(lex, c)) {
301
+ lexBare(lex);
302
+ }
303
+ }
304
+ validateStructure(tokens);
305
+ return tokens;
306
+ }
307
+
308
+ /** Where tokenizeGml() is. */
309
+ interface GmlLex {
310
+ readonly text: string;
311
+ readonly tokens: GmlTokens;
312
+ /** The offset of the next character. */
313
+ i: number;
314
+ /** The line of the next character. */
315
+ line: number;
316
+ /** The opening line of the first string that spans lines: where a missing quote most likely is; 0 for none. */
317
+ spanningLine: number;
318
+ }
319
+
320
+ /**
321
+ * Skips one line break, space or comment.
322
+ * @param lex - the lexer
323
+ * @param c - the char code at the offset
324
+ * @returns false when the character starts a token
325
+ */
326
+ function skipSpace(lex: GmlLex, c: number): boolean {
327
+ const { text } = lex;
328
+ if (c === 10 || c === 13) {
329
+ lex.line++;
330
+ lex.i++;
331
+ if (c === 13 && lex.i < text.length && text.codePointAt(lex.i) === 10) {
332
+ lex.i++;
333
+ }
334
+ } else if (c === 32 || c === 9 || c === 11 || c === 12 || c === 0xfeff) {
335
+ // a BOM left inside by concatenated files is whitespace; the shared text check reports it
336
+ lex.i++;
337
+ } else if (c === 35) {
338
+ lex.i = endOfLine(text, lex.i);
339
+ } else {
340
+ return false;
341
+ }
342
+ return true;
343
+ }
344
+
345
+ /**
346
+ * Lexes a string starting at the offset (its opening quote).
347
+ * @param lex - the lexer
348
+ */
349
+ function lexString(lex: GmlLex): void {
350
+ const { text, tokens, i } = lex;
351
+ const close = tokens.backslashEscapes ? escapedClose(text, i + 1) : text.indexOf('"', i + 1);
352
+ if (close < 0) {
353
+ const hint =
354
+ lex.spanningLine === 0
355
+ ? ""
356
+ : `; the string opened at line ${lex.spanningLine} spans lines, so a quote may be missing there`;
357
+ throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${lex.line}${hint}`, lex.line);
358
+ }
359
+ tokens.push(TOKEN_STRING, i + 1, close, lex.line);
360
+ const opened = lex.line;
361
+ for (let k = i + 1; k < close; k++) {
362
+ const d = text.codePointAt(k);
363
+ if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {
364
+ lex.line++;
365
+ }
366
+ }
367
+ if (lex.line !== opened && lex.spanningLine === 0) {
368
+ lex.spanningLine = opened;
369
+ }
370
+ lex.i = close + 1;
371
+ }
372
+
373
+ /**
374
+ * Lexes a bare token (a key, a number) starting at the offset.
375
+ * @param lex - the lexer
376
+ */
377
+ function lexBare(lex: GmlLex): void {
378
+ const { text, i } = lex;
379
+ let j = i + 1;
380
+ while (j < text.length && !isDelimiter(text.codePointAt(j) ?? 0)) {
381
+ j++;
382
+ }
383
+ lex.tokens.push(classifyBare(text, i, j, lex.line), i, j, lex.line);
384
+ lex.i = j;
385
+ }
386
+
387
+ /**
388
+ * Whether OGDF wrote the file: its first key is `Creator "ogdf::..."`, after any whitespace and
389
+ * comment lines. A plain scan, so a banner of `#` characters costs time linear in its length.
390
+ * @param text - the GML text
391
+ * @returns true when the file opens with an OGDF creator line
392
+ */
393
+ function writtenByOgdf(text: string): boolean {
394
+ const end = Math.min(text.length, 512);
283
395
  let i = 0;
284
- let line = 1;
285
- // the opening line of the first string that spans lines: where a missing quote most likely is
286
- let spanningLine = 0;
287
- while (i < n) {
288
- const c = text.charCodeAt(i);
289
- if (c === 10) {
290
- line++;
291
- i++;
292
- } else if (c === 13) {
293
- line++;
294
- i++;
295
- if (i < n && text.charCodeAt(i) === 10) {
396
+ while (i < end) {
397
+ const c = text.codePointAt(i);
398
+ if (c === 35) {
399
+ // '#': a comment runs to the next line break
400
+ while (i < end && text.codePointAt(i) !== 10 && text.codePointAt(i) !== 13) {
296
401
  i++;
297
402
  }
298
- } else if (c === 32 || c === 9 || c === 11 || c === 12) {
299
- i++;
300
- } else if (c === 0xfeff) {
301
- // a BOM left inside by concatenated files is whitespace; the shared text check reports it
403
+ } else if (c === 32 || c === 9 || c === 10 || c === 13 || c === 12 || c === 11) {
302
404
  i++;
303
- } else if (c === 35) {
304
- i = endOfLine(text, i);
305
- } else if (c === 91) {
306
- tokens.push(TOKEN_OPEN, i, i + 1, line);
307
- i++;
308
- } else if (c === 93) {
309
- tokens.push(TOKEN_CLOSE, i, i + 1, line);
310
- i++;
311
- } else if (c === 34) {
312
- const close = text.indexOf('"', i + 1);
313
- if (close < 0) {
314
- const hint =
315
- spanningLine === 0
316
- ? ""
317
- : `; the string opened at line ${spanningLine} spans lines, so a quote may be missing there`;
318
- throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string opened at line ${line}${hint}`, line);
319
- }
320
- tokens.push(TOKEN_STRING, i + 1, close, line);
321
- const opened = line;
322
- for (let k = i + 1; k < close; k++) {
323
- const d = text.codePointAt(k);
324
- if (d === 10 || (d === 13 && text.codePointAt(k + 1) !== 10)) {
325
- line++;
326
- }
327
- }
328
- if (line !== opened && spanningLine === 0) {
329
- spanningLine = opened;
330
- }
331
- i = close + 1;
332
405
  } else {
333
- let j = i + 1;
334
- while (j < n && !isDelimiter(text.charCodeAt(j))) {
335
- j++;
336
- }
337
- tokens.push(classifyBare(text, i, j, line), i, j, line);
338
- i = j;
406
+ break;
339
407
  }
340
408
  }
341
- validateStructure(tokens);
342
- return tokens;
409
+ return /^Creator\s+"ogdf::/.test(text.slice(i, i + 64));
410
+ }
411
+
412
+ /**
413
+ * The offset of the quote closing a string whose backslashes escape the next character, or -1.
414
+ * @param text - the text
415
+ * @param from - the offset after the opening quote
416
+ * @returns the offset of the closing quote
417
+ */
418
+ function escapedClose(text: string, from: number): number {
419
+ let k = from;
420
+ while (k < text.length) {
421
+ const c = text.codePointAt(k);
422
+ if (c === 34) {
423
+ return k;
424
+ }
425
+ // a backslash escapes the next character
426
+ k += c === 92 ? 2 : 1;
427
+ }
428
+ return -1;
343
429
  }
344
430
 
345
431
  /**
@@ -447,15 +533,8 @@ function validateStructure(tokens: GmlTokens): void {
447
533
  tokens.line[i],
448
534
  );
449
535
  }
450
- const vk = kind[value];
451
- if (vk === TOKEN_OPEN) {
536
+ if (checkValue(tokens, i) === TOKEN_OPEN) {
452
537
  stack.push(value);
453
- } else if (vk === TOKEN_CLOSE || (vk === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value)))) {
454
- throw new GmlSyntaxError(
455
- SYNTAX_STRUCTURE_CODE,
456
- `expected a value for key "${tokens.textOf(i)}" at line ${tokens.line[i]}, found ${describeToken(tokens, value)}`,
457
- tokens.line[value],
458
- );
459
538
  }
460
539
  i = value + 1;
461
540
  }
@@ -470,6 +549,31 @@ function validateStructure(tokens: GmlTokens): void {
470
549
  tokens.match = match;
471
550
  }
472
551
 
552
+ /**
553
+ * Checks the value of a key: a number, a string, `INF` / `NAN` or an opening bracket. Gephi writes its name
554
+ * unquoted (`Creator Gephi`): the word is read as the string it means.
555
+ * @param tokens - the lexed tokens
556
+ * @param key - the key's token index (its value follows it)
557
+ * @returns the value's kind
558
+ */
559
+ function checkValue(tokens: GmlTokens, key: number): TokenKind {
560
+ const { kind } = tokens;
561
+ const value = key + 1;
562
+ const word = kind[value] === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value));
563
+ if (word && tokens.textOf(key) === "Creator") {
564
+ kind[value] = TOKEN_STRING;
565
+ return TOKEN_STRING;
566
+ }
567
+ if (kind[value] === TOKEN_CLOSE || word) {
568
+ throw new GmlSyntaxError(
569
+ SYNTAX_STRUCTURE_CODE,
570
+ `expected a value for key "${tokens.textOf(key)}" at line ${tokens.line[key]}, found ${describeToken(tokens, value)}`,
571
+ tokens.line[value],
572
+ );
573
+ }
574
+ return kind[value] as TokenKind;
575
+ }
576
+
473
577
  /**
474
578
  * A short description of a token for messages.
475
579
  * @param tokens - the tokens
@@ -528,6 +632,13 @@ export function isGmlKey(text: string): boolean {
528
632
  return STRICT_KEY_TEXT.test(text);
529
633
  }
530
634
 
635
+ /**
636
+ * Keys rewritten under sanitizeKeys "mangle", or a data column renamed because its key would read back as one of
637
+ * graphty's style values.
638
+ * @category Issue and loss codes
639
+ */
640
+ export const KEY_MANGLED_CODE = "W_GML_KEY_MANGLED";
641
+
531
642
  /**
532
643
  * Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading
533
644
  * non-letter is prefixed with `x` (the exporter's `sanitizeKeys: "mangle"`).
@@ -45,6 +45,7 @@ import {
45
45
  UNKNOWN_ENCODING_CODE,
46
46
  UNKNOWN_PARENT_CODE,
47
47
  UNKNOWN_XML_ATTRIBUTE_CODE,
48
+ XML_NESTING_CODE,
48
49
  XML_SYNTAX_CODE,
49
50
  } from "../../common/codes.js";
50
51
 
@@ -190,6 +191,8 @@ export const GRAPHML_ISSUE = Object.freeze({
190
191
  COLUMN_TYPE: COLUMN_TYPE_CODE,
191
192
  /** The input is not well-formed XML. The import stops. */
192
193
  XML_SYNTAX: XML_SYNTAX_CODE,
194
+ /** Elements are nested more than 100,000 deep. The import stops. */
195
+ XML_NESTING: XML_NESTING_CODE,
193
196
  /** The input is not valid UTF-8. The import stops. */
194
197
  INVALID_UTF8: INVALID_UTF8_CODE,
195
198
  /**
@@ -245,6 +248,8 @@ export const GRAPHML_ISSUE = Object.freeze({
245
248
  HYPEREDGE_DATA_DROPPED: "W_GRAPHML_HYPEREDGE_DATA_DROPPED",
246
249
  /** Nested elements in the `<data>` of a typed (non-yfiles) key. */
247
250
  DATA_NESTED: "E_GRAPHML_DATA_NESTED",
251
+ /** Nested elements in the `<data>` of an untyped key; they are kept as their XML text. */
252
+ DATA_STRUCTURED: "W_GRAPHML_DATA_STRUCTURED",
248
253
  /** A `<node>` declared twice. */
249
254
  DUPLICATE_NODE: DUPLICATE_NODE_CODE,
250
255
  /** An edge id already used by another edge. */
@@ -37,6 +37,7 @@ import { agree, plural } from "../../common/plural.js";
37
37
  import { type ExplicitWeights, explicitWeights } from "../../common/weights.js";
38
38
  import { encodeChunks, joinText } from "../../common/writer.js";
39
39
  import { xmlIllegalTextNotes } from "../../common/xml.js";
40
+ import type { ExporterStyleOptions } from "../../styles/io/writer.js";
40
41
  import { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from "../../types.js";
41
42
  import {
42
43
  EDGE_ID_COLUMN,
@@ -56,9 +57,13 @@ import {
56
57
  XSI_NAMESPACE,
57
58
  YFILES_NAMESPACE,
58
59
  } from "./constants.js";
60
+ import { GRAPHML_STYLE_CAPABILITIES, graphmlStyledExport } from "./styles-yed.js";
59
61
  import { treeProblem, writeXmlTree } from "./tree.js";
60
62
  import { isGraphicsColumn, staleGraphicsRows } from "./yfiles.js";
61
63
 
64
+ /** What the writer takes: the format's options, the common ones and the styles. */
65
+ type GraphmlWriteOptions = GraphmlExportOptions & CommonExportOptions & ExporterStyleOptions;
66
+
62
67
  /**
63
68
  * The format-specific options of the GraphML exporter.
64
69
  * @category Built-in formats
@@ -236,6 +241,8 @@ interface Plan {
236
241
  readonly hierarchy: Hierarchy;
237
242
  readonly meta: GraphmlMeta | null;
238
243
  readonly needsOriginalIdKey: boolean;
244
+ /** Styles are written: the `y` prefix is yEd's namespace, whatever the file the graph came from bound it to. */
245
+ readonly yedGraphics?: boolean;
239
246
  }
240
247
 
241
248
  /** The resolved format-specific options. */
@@ -301,9 +308,15 @@ function graphmlMetaOf(snapshot: GraphSnapshot): GraphmlMeta | null {
301
308
  * @param snapshot - the snapshot
302
309
  * @param options - the resolved common options
303
310
  * @param format - the resolved format options
311
+ * @param keyOrdered - write each element's data in the order of the keys (styled exports)
304
312
  * @returns the plan
305
313
  */
306
- function planExport(snapshot: GraphSnapshot, options: ResolvedExportOptions, format: FormatOptions): Plan {
314
+ function planExport(
315
+ snapshot: GraphSnapshot,
316
+ options: ResolvedExportOptions,
317
+ format: FormatOptions,
318
+ keyOrdered = false,
319
+ ): Plan {
307
320
  // the generic json note is replaced by planTable()'s (yfiles trees are kept, other json is
308
321
  // text); columns mapped from a yfiles tree are never written: planTable() notes the ones
309
322
  // that no longer match their tree, the rest lose nothing
@@ -325,6 +338,16 @@ function planExport(snapshot: GraphSnapshot, options: ResolvedExportOptions, for
325
338
  const nodeColumns = planTable(snapshot.nodes, "node", notes, note);
326
339
  const edgeColumns = planTable(snapshot.edges, "edge", notes, note);
327
340
  const keys = planKeys([...graphColumns, ...nodeColumns, ...edgeColumns], keyIds);
341
+ if (keyOrdered) {
342
+ // an element's data in the order of its keys, as a re-import orders its columns, so that exporting what a
343
+ // styled export reads back gives the same bytes. ponytail: styled exports only, so an export without
344
+ // styles keeps its bytes; extend it to every export when that change is wanted on its own.
345
+ const keyOrder = new Map(keys.map((k, i) => [k.id, i]));
346
+ const byKey = (a: ColumnPlan, b: ColumnPlan): number =>
347
+ (keyOrder.get(a.keyId) ?? 0) - (keyOrder.get(b.keyId) ?? 0);
348
+ nodeColumns.sort(byKey);
349
+ edgeColumns.sort(byKey);
350
+ }
328
351
  reservedNameNotes(nodeColumns, RESERVED_NODE_NAMES, note);
329
352
  reservedNameNotes(edgeColumns, RESERVED_EDGE_NAMES, note);
330
353
  const weight = planWeight(snapshot, edgeColumns, keyIds, keys, note);
@@ -1193,7 +1216,9 @@ function keyElement(key: KeyPlan, indent: string): string {
1193
1216
  text += ` attr.type="${escapeXmlAttribute(key.attrType)}"`;
1194
1217
  }
1195
1218
  if (key.yfilesType !== null) {
1196
- text += ` yfiles.type="${escapeXmlAttribute(key.yfilesType)}"`;
1219
+ // a yFiles 3 key is identified by its attr.uri, which the importer keeps as the column's type
1220
+ const uri = key.yfilesType.includes("://");
1221
+ text += ` ${uri ? "y:attr.uri" : "yfiles.type"}="${escapeXmlAttribute(key.yfilesType)}"`;
1197
1222
  }
1198
1223
  const { column } = key;
1199
1224
  const desc = column?.meta.extra.desc;
@@ -1274,25 +1299,7 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
1274
1299
  const step = plan.pretty ? " " : "";
1275
1300
 
1276
1301
  yield '<?xml version="1.0" encoding="UTF-8"?>\n';
1277
- let root = `<graphml xmlns="${GRAPHML_NAMESPACE}"`;
1278
- const namespaces: Record<string, string> = { ...plan.meta?.namespaces };
1279
- if (
1280
- (plan.nodeColumns.some((c) => c.yfiles) ||
1281
- plan.edgeColumns.some((c) => c.yfiles) ||
1282
- plan.graphColumns.some((c) => c.yfiles)) &&
1283
- !Object.values(namespaces).includes(YFILES_NAMESPACE)
1284
- ) {
1285
- namespaces.y = YFILES_NAMESPACE;
1286
- }
1287
- if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {
1288
- namespaces.xsi = XSI_NAMESPACE;
1289
- }
1290
- for (const [prefix, uri] of Object.entries(namespaces)) {
1291
- root += ` xmlns:${prefix}="${escapeXmlAttribute(uri)}"`;
1292
- }
1293
- const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? "xsi";
1294
- root += ` ${xsiPrefix}:schemaLocation="${SCHEMA_LOCATION}">\n`;
1295
- yield root;
1302
+ yield rootElement(plan);
1296
1303
 
1297
1304
  for (const key of plan.keys) {
1298
1305
  yield keyElement(key, i1);
@@ -1329,54 +1336,116 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
1329
1336
 
1330
1337
  // edges: primaries only, in index order
1331
1338
  const list = snapshot.edgeList();
1332
- const { folding } = plan;
1333
1339
  for (let e = 0; e < snapshot.edgeCount; e++) {
1334
- if (folding.folded(e)) {
1335
- continue;
1340
+ if (!plan.folding.folded(e)) {
1341
+ const start = edgeStartTag(snapshot, plan, e, String(ids.idAt(list.src[e])), String(ids.idAt(list.dst[e])));
1342
+ yield edgeElement(plan, e, edgeIds[e], start, [i2, i3]);
1336
1343
  }
1337
- const parts: string[] = [`\n${i2}<edge`];
1338
- const id = edgeIds[e];
1339
- if (id !== null) {
1340
- parts.push(` id="${escapeXmlAttribute(id)}"`);
1341
- }
1342
- parts.push(
1343
- ` source="${escapeXmlAttribute(String(ids.idAt(list.src[e])))}" target="${escapeXmlAttribute(String(ids.idAt(list.dst[e])))}"`,
1344
- );
1345
- const directed = snapshot.directed && isDirectedEdge(folding, e);
1346
- if (directed !== (plan.edgedefault === "directed")) {
1347
- parts.push(` directed="${directed ? "true" : "false"}"`);
1348
- }
1349
- const sourcePort = portText(plan.sourcePortColumn, e);
1350
- if (sourcePort !== null) {
1351
- parts.push(` sourceport="${escapeXmlAttribute(sourcePort)}"`);
1352
- }
1353
- const targetPort = portText(plan.targetPortColumn, e);
1354
- if (targetPort !== null) {
1355
- parts.push(` targetport="${escapeXmlAttribute(targetPort)}"`);
1356
- }
1357
- const open = parts.length;
1358
- if (plan.weight !== null) {
1359
- const { keyId, attrType } = plan.weight;
1360
- const weight = plan.weight.weights.text(e, attrType === "int" || attrType === "long");
1361
- if (weight !== null) {
1362
- parts.push(`\n${i3}<data key="${keyId}">${escapeXmlText(weight)}</data>`);
1363
- }
1364
- }
1365
- for (const column of plan.edgeColumns) {
1366
- writeData(column, e, i3, parts);
1367
- }
1368
- if (parts.length === open) {
1369
- parts.push("/>");
1370
- } else {
1371
- parts.splice(open, 0, ">");
1372
- parts.push(`\n${i2}</edge>`);
1373
- }
1374
- yield parts.join("");
1375
1344
  }
1376
1345
 
1377
1346
  yield `\n${i1}</graph>\n</graphml>\n`;
1378
1347
  }
1379
1348
 
1349
+ /**
1350
+ * The opening `<graphml>` tag with its namespaces: the kept ones, yFiles' where graphics or yFiles columns are written,
1351
+ * and XML Schema's for the schema location.
1352
+ * @param plan - the plan
1353
+ * @returns the tag
1354
+ */
1355
+ function rootElement(plan: Plan): string {
1356
+ const namespaces: Record<string, string> = { ...plan.meta?.namespaces };
1357
+ const yfilesColumns =
1358
+ plan.nodeColumns.some((c) => c.yfiles) ||
1359
+ plan.edgeColumns.some((c) => c.yfiles) ||
1360
+ plan.graphColumns.some((c) => c.yfiles);
1361
+ if (
1362
+ plan.yedGraphics === true ||
1363
+ (yfilesColumns &&
1364
+ !Object.values(namespaces).includes(YFILES_NAMESPACE) &&
1365
+ // a yFiles 3 file binds `y` to its own namespace, which its kept trees are written in
1366
+ namespaces.y === undefined)
1367
+ ) {
1368
+ namespaces.y = YFILES_NAMESPACE;
1369
+ }
1370
+ if (!Object.values(namespaces).includes(XSI_NAMESPACE)) {
1371
+ namespaces.xsi = XSI_NAMESPACE;
1372
+ }
1373
+ let root = `<graphml xmlns="${GRAPHML_NAMESPACE}"`;
1374
+ for (const [prefix, uri] of Object.entries(namespaces)) {
1375
+ root += ` xmlns:${prefix}="${escapeXmlAttribute(uri)}"`;
1376
+ }
1377
+ const xsiPrefix = Object.entries(namespaces).find(([, uri]) => uri === XSI_NAMESPACE)?.[0] ?? "xsi";
1378
+ return `${root} ${xsiPrefix}:schemaLocation="${SCHEMA_LOCATION}">\n`;
1379
+ }
1380
+
1381
+ /**
1382
+ * An edge's attributes after `<edge`: its source and target, a `directed` that differs from the default, its ports.
1383
+ * @param snapshot - the snapshot
1384
+ * @param plan - the plan
1385
+ * @param e - the edge
1386
+ * @param source - the source's written id
1387
+ * @param target - the target's written id
1388
+ * @returns the attribute text
1389
+ */
1390
+ function edgeStartTag(snapshot: GraphSnapshot, plan: Plan, e: number, source: string, target: string): string {
1391
+ let text = ` source="${escapeXmlAttribute(source)}" target="${escapeXmlAttribute(target)}"`;
1392
+ const directed = snapshot.directed && isDirectedEdge(plan.folding, e);
1393
+ if (directed !== (plan.edgedefault === "directed")) {
1394
+ text += ` directed="${directed ? "true" : "false"}"`;
1395
+ }
1396
+ const sourcePort = portText(plan.sourcePortColumn, e);
1397
+ if (sourcePort !== null) {
1398
+ text += ` sourceport="${escapeXmlAttribute(sourcePort)}"`;
1399
+ }
1400
+ const targetPort = portText(plan.targetPortColumn, e);
1401
+ if (targetPort !== null) {
1402
+ text += ` targetport="${escapeXmlAttribute(targetPort)}"`;
1403
+ }
1404
+ return text;
1405
+ }
1406
+
1407
+ /**
1408
+ * One `<edge>` element with its weight and data.
1409
+ * @param plan - the plan
1410
+ * @param e - the edge
1411
+ * @param id - its written id, or null
1412
+ * @param start - its attributes after the id
1413
+ * @param indents - the edge's indentation and its data's
1414
+ * @returns the element text
1415
+ */
1416
+ function edgeElement(
1417
+ plan: Plan,
1418
+ e: number,
1419
+ id: string | null,
1420
+ start: string,
1421
+ indents: readonly [string, string],
1422
+ ): string {
1423
+ const [i2, i3] = indents;
1424
+ const parts: string[] = [`\n${i2}<edge`];
1425
+ if (id !== null) {
1426
+ parts.push(` id="${escapeXmlAttribute(id)}"`);
1427
+ }
1428
+ parts.push(start);
1429
+ const open = parts.length;
1430
+ if (plan.weight !== null) {
1431
+ const { keyId, attrType } = plan.weight;
1432
+ const weight = plan.weight.weights.text(e, attrType === "int" || attrType === "long");
1433
+ if (weight !== null) {
1434
+ parts.push(`\n${i3}<data key="${keyId}">${escapeXmlText(weight)}</data>`);
1435
+ }
1436
+ }
1437
+ for (const column of plan.edgeColumns) {
1438
+ writeData(column, e, i3, parts);
1439
+ }
1440
+ if (parts.length === open) {
1441
+ parts.push("/>");
1442
+ } else {
1443
+ parts.splice(open, 0, ">");
1444
+ parts.push(`\n${i2}</edge>`);
1445
+ }
1446
+ return parts.join("");
1447
+ }
1448
+
1380
1449
  /**
1381
1450
  * The text of a port reference cell.
1382
1451
  * @param column - the sourcePort / targetPort column, or null
@@ -1497,15 +1566,16 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
1497
1566
  format: FORMAT,
1498
1567
  options: Object.freeze(["edgedefault", "pretty"]),
1499
1568
  capabilities: CAPABILITIES,
1569
+ styles: Object.freeze({ capabilities: GRAPHML_STYLE_CAPABILITIES }),
1500
1570
  /**
1501
1571
  * Pre-flight: every loss the export would incur.
1502
1572
  * @param snapshot - the snapshot
1503
1573
  * @param options - format-specific and common options
1504
1574
  * @returns the notes
1505
1575
  */
1506
- check(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): readonly LossNote[] {
1507
- const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));
1508
- return Object.freeze(plan.notes);
1576
+ check(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): readonly LossNote[] {
1577
+ const { plan, styled } = prepare(snapshot, options);
1578
+ return Object.freeze([...plan.notes, ...(styled?.notes ?? [])]);
1509
1579
  },
1510
1580
  /**
1511
1581
  * Write the document as UTF-8 chunks.
@@ -1513,9 +1583,9 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
1513
1583
  * @param options - format-specific and common options
1514
1584
  * @returns the chunks
1515
1585
  */
1516
- export(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {
1517
- const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));
1518
- return encodeChunks(writeGraphml(snapshot, plan));
1586
+ export(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): AsyncIterable<Uint8Array> {
1587
+ const { plan, written } = prepare(snapshot, options);
1588
+ return encodeChunks(writeGraphml(written, plan));
1519
1589
  },
1520
1590
  /**
1521
1591
  * Write the document as one string.
@@ -1523,8 +1593,30 @@ export const graphmlExporter: GraphExporter<GraphmlExportOptions> = Object.freez
1523
1593
  * @param options - format-specific and common options
1524
1594
  * @returns the document
1525
1595
  */
1526
- exportToString(snapshot: GraphSnapshot, options?: GraphmlExportOptions & CommonExportOptions): Promise<string> {
1527
- const plan = planExport(snapshot, resolveExportOptions(options), resolveFormatOptions(options));
1528
- return joinText(writeGraphml(snapshot, plan));
1596
+ exportToString(snapshot: GraphSnapshot, options?: GraphmlWriteOptions): Promise<string> {
1597
+ const { plan, written } = prepare(snapshot, options);
1598
+ return joinText(writeGraphml(written, plan));
1529
1599
  },
1530
1600
  });
1601
+
1602
+ /**
1603
+ * The plan of an export, with styles: the graph to write with yEd graphics in place of its yFiles columns.
1604
+ * @param snapshot - the snapshot
1605
+ * @param options - format-specific and common options
1606
+ * @returns the plan, the graph to write and the styled export (null without styles)
1607
+ */
1608
+ function prepare(
1609
+ snapshot: GraphSnapshot,
1610
+ options: GraphmlWriteOptions | undefined,
1611
+ ): { plan: Plan; written: GraphSnapshot; styled: ReturnType<typeof graphmlStyledExport> } {
1612
+ const styled = graphmlStyledExport(snapshot, options?.styles);
1613
+ const written = styled?.snapshot ?? snapshot;
1614
+ const plan = planExport(written, resolveExportOptions(options), resolveFormatOptions(options), styled !== null);
1615
+ if (styled === null) {
1616
+ return { plan, written, styled };
1617
+ }
1618
+ // the yEd graphics carry each node's position in its y:Geometry, so the position column is not lost
1619
+ const position = written.nodes.byRole("position")?.meta.name;
1620
+ const notes = plan.notes.filter((n) => n.code !== LOSS.POSITIONS || n.column !== position);
1621
+ return { plan: { ...plan, notes, yedGraphics: true }, written, styled };
1622
+ }