@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
@@ -13,22 +13,26 @@
13
13
  * bends and other keys stay. The `graphty.styles` block and the per-element values its rules read are keys too,
14
14
  * named by the GML writer's rule for names that are not GML keys (`graphty_styles`, `graphty_style_node_<key>`).
15
15
  */
16
- import { bendsToPoints, canonBends } from "../../styles/canon/bends.js";
16
+ import { bendsToPoints, canonBends, canonNodeOffsets, nodeOffsetsToPoints, } from "../../styles/canon/bends.js";
17
17
  import { canonColor, colorOpacity } from "../../styles/canon/color.js";
18
18
  import { canonEnum } from "../../styles/canon/enums.js";
19
- import { canonNumber } from "../../styles/canon/number.js";
19
+ import { canonNumber, canonSigned, num6 } from "../../styles/canon/number.js";
20
20
  import { MAX_STYLE_VALUE_LENGTH, noteAt, scalarText } from "../../styles/canon/site.js";
21
21
  import { canonText } from "../../styles/canon/text.js";
22
22
  import { STYLE_ISSUE } from "../../styles/codes.js";
23
- import { CYTOSCAPE_LEXICON } from "../../styles/cytoscape/lexicon.js";
23
+ import { CYTOSCAPE_LEXICON, javaFamily } from "../../styles/cytoscape/lexicon.js";
24
24
  import { StyleApproximations } from "../../styles/io/approximations.js";
25
- import { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME, styleBlockLosses, styleTag, writeStyleBlock, } from "../../styles/io/block.js";
25
+ import { parseStyleBlock, STYLE_BLOCK_NAME, styleBlockLosses, styleTag, writeStyleBlock, } from "../../styles/io/block.js";
26
+ import { elementValues, takeFromBlock } from "../../styles/io/round-trip.js";
26
27
  import { dataRead } from "../../styles/io/writer.js";
27
28
  import { StyleNotes } from "../../styles/notes.js";
28
29
  import { styleFingerprint } from "../../styles/plan/features.js";
29
- import { plainCell, resolveStyles } from "../../styles/plan/resolve.js";
30
+ import { plainCell } from "../../styles/plan/resolve.js";
31
+ import { GRAPHVIZ_GLYPH_SHAPES } from "../dot/drawing.js";
32
+ import { graphvizArrowValue, graphvizHasNoOutline, graphvizOutline, graphvizRouteBends, PERIPHERY_GAP, putGlyph, SHAPE_PERIPHERIES, } from "../dot/styles.js";
30
33
  import { gephiRules } from "../gexf/styles.js";
31
- import { flowchartShape, FONT_STYLES, valueColumns, YED_ARROWS, YED_LINES, YED_SHAPES, yedColor, yedSpelled, yedValue, } from "../graphml/styles-yed.js";
34
+ import { configurationOutline, FONT_STYLES, valueColumns, YED_ARROWS, YED_LINES, YED_SHAPES, yedColor, yedFontName, yedSpelled, yedValue, } from "../graphml/styles-yed.js";
35
+ import { writtenByGv2gml } from "./positions.js";
32
36
  import { KEY_MANGLED_CODE, mangleGmlKey } from "./syntax.js";
33
37
  /** The writers recognized by their `Creator` text, first match wins. */
34
38
  const WRITERS = [
@@ -55,7 +59,8 @@ const WRITERS = [
55
59
  vocabulary: "graphlet",
56
60
  spelling: "css",
57
61
  units: "relative",
58
- labelKey: false,
62
+ // Gephi's preview draws node labels as the GEXF reader reads them (formats/gexf/styles.ts)
63
+ labelKey: true,
59
64
  },
60
65
  ],
61
66
  [
@@ -77,6 +82,18 @@ const UNKNOWN_WRITER = {
77
82
  units: "px",
78
83
  labelKey: true,
79
84
  };
85
+ /**
86
+ * Graphviz's gv2gml (no `Creator`; `version 2` inside the graph): Graphviz's attribute values (shape names, colors,
87
+ * arrow names, sizes in points, y up) under GML keys, with Graphviz's defaults beneath.
88
+ */
89
+ const GV2GML_WRITER = {
90
+ dialect: "graphviz",
91
+ tool: "graphviz",
92
+ vocabulary: "graphviz",
93
+ spelling: "graphviz",
94
+ units: "px",
95
+ labelKey: true,
96
+ };
80
97
  /** A file graphty wrote: yEd keys, and the `graphty.styles` block gives the rules. */
81
98
  const GRAPHTY_WRITER = { ...WRITERS[0][1], tool: null };
82
99
  /**
@@ -113,8 +130,27 @@ function graphText(snapshot, name) {
113
130
  return typeof v === "number" ? String(v) : null;
114
131
  }
115
132
  /**
116
- * Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), or graphty when
117
- * the file holds a `graphty.styles` block.
133
+ * A node label's `anchor` as a label position: yEd's `n`, `s`, `e`, `w` and the corners `nw`, `ne`, `sw`, `se` place it
134
+ * outside the node; `c` and the inside places `t`, `b`, `l`, `r`, `tl`, `tr`, `bl`, `br` keep it inside, which graphty
135
+ * draws centered.
136
+ */
137
+ const GML_ANCHORS = new Map([
138
+ ...["c", "t", "b", "l", "r", "tl", "tr", "bl", "br"].map((a) => [a, "center"]),
139
+ ["n", "top"],
140
+ ["s", "bottom"],
141
+ ["e", "right"],
142
+ ["w", "left"],
143
+ ["nw", "top-left"],
144
+ ["ne", "top-right"],
145
+ ["sw", "bottom-left"],
146
+ ["se", "bottom-right"],
147
+ ]);
148
+ /** Node keys only yEd writes: its group hierarchy. */
149
+ const YED_NODE_KEYS = ["isGroup", "gid"];
150
+ /**
151
+ * Who wrote a GML file: the `Creator` line (top level, or a key of the graph block as Gephi writes it), graphty when
152
+ * the file holds a `graphty.styles` block, or yEd when a file with no `Creator` holds keys only yEd writes (`isGroup`,
153
+ * `gid`, the graph's `hierarchic`).
118
154
  * @param snapshot - the graph
119
155
  * @returns the writer
120
156
  */
@@ -128,7 +164,12 @@ function writerOf(snapshot) {
128
164
  return writer;
129
165
  }
130
166
  }
131
- return UNKNOWN_WRITER;
167
+ // keys only yEd writes name it even without a Creator line (BioNetGen writes yEd GML with none)
168
+ if (creator.trim() === "" &&
169
+ (YED_NODE_KEYS.some((k) => snapshot.nodes.has(k)) || snapshot.graph.has("hierarchic"))) {
170
+ return WRITERS[0][1];
171
+ }
172
+ return creator.trim() === "" && writtenByGv2gml(snapshot) ? GV2GML_WRITER : UNKNOWN_WRITER;
132
173
  }
133
174
  /** The edge's `arrow` key of the GML draft: which ends have an arrow. */
134
175
  const ARROW_ENDS = new Map([
@@ -137,17 +178,63 @@ const ARROW_ENDS = new Map([
137
178
  ["first", ["triangle", "none"]],
138
179
  ["both", ["triangle", "triangle"]],
139
180
  ]);
140
- /** OGDF's stroke types (`stipple`), by number. */
181
+ /**
182
+ * The node shape names Cytoscape's GML reader knows (NodeShapeVisualProperty, any case, with Cytoscape 2.x's `rect`
183
+ * and `round_rect`); any other name it ignores, so its default style's shape is drawn.
184
+ */
185
+ const CYTOSCAPE_GML_SHAPES = new Map([
186
+ ["ellipse", "ellipse"],
187
+ ["round_rectangle", "round-rectangle"],
188
+ ["round_rect", "round-rectangle"],
189
+ ["rectangle", "rectangle"],
190
+ ["rect", "rectangle"],
191
+ ["hexagon", "hexagon"],
192
+ ["octagon", "octagon"],
193
+ ["parallelogram", "parallelogram"],
194
+ ["triangle", "triangle"],
195
+ ["vee", "vee"],
196
+ ["diamond", "diamond"],
197
+ ]);
198
+ /** OGDF's stroke types (`stipple`): by number as older OGDF writes them, or by name as GraphIO::writeGML does. */
141
199
  const OGDF_STROKES = ["none", "solid", "dashed", "dotted", "dash-dot", "dash-dot"];
142
- /** OGDF's shape names the common table does not know. */
200
+ const OGDF_STROKE_NAMES = new Map([
201
+ ["none", "none"],
202
+ ["solid", "solid"],
203
+ ["dash", "dashed"],
204
+ ["dot", "dotted"],
205
+ ["dashdot", "dash-dot"],
206
+ ["dashdotdot", "dash-dot"],
207
+ ]);
208
+ /** OGDF's shape names the common table does not know (an Image node without its image draws as its box). */
143
209
  const OGDF_SHAPES = new Map([
144
210
  ["rect", "rectangle"],
211
+ ["roundedrect", "round-rectangle"],
145
212
  ["rhomb", "diamond"],
146
- ["trapeze", "trapezoid"],
147
- ["invtrapeze", "trapezoid"],
148
- ["invtriangle", "triangle"],
149
- ["invparallelogram", "parallelogram"],
213
+ ["image", "rectangle"],
214
+ ]);
215
+ /**
216
+ * OGDF's shapes that GraphIO::drawSVG draws as polygons no named shape matches, with their corners as `shapePoints`
217
+ * (fractions of the half width and height, y up), measured in its drawing of
218
+ * graph-io/test/fidelity/specimens/gml/specimen-node-shapes-p5.gml: the triangles, the pentagon, the hexagon and the
219
+ * octagon are regular, their corners on the ellipse of the node's box (so they are drawn where the points say, not
220
+ * stretched to the box: `OGDF_REGULAR`); the trapezes and parallelograms fill the box, their short side half its width.
221
+ */
222
+ const OGDF_POLYGONS = new Map([
223
+ ["triangle", "0,1 0.866,-0.5 -0.866,-0.5"],
224
+ ["invtriangle", "0,-1 0.866,0.5 -0.866,0.5"],
225
+ ["pentagon", "0,1 0.951,0.309 0.588,-0.809 -0.588,-0.809 -0.951,0.309"],
226
+ ["hexagon", "1,0 0.5,0.866 -0.5,0.866 -1,0 -0.5,-0.866 0.5,-0.866"],
227
+ [
228
+ "octagon",
229
+ "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",
230
+ ],
231
+ ["trapeze", "-1,-1 1,-1 0.5,1 -0.5,1"],
232
+ ["invtrapeze", "-1,1 1,1 0.5,-1 -0.5,-1"],
233
+ ["parallelogram", "-1,-1 0.5,-1 1,1 -0.5,1"],
234
+ ["invparallelogram", "-1,1 0.5,1 1,-1 -0.5,-1"],
150
235
  ]);
236
+ /** OGDF's regular polygons, whose corners lie on the ellipse of the node's box rather than reaching its sides. */
237
+ const OGDF_REGULAR = new Set(["triangle", "invtriangle", "pentagon", "hexagon", "octagon"]);
151
238
  /** Keys only yEd writes in a label record: its `fill` is the label's background, not the text color. */
152
239
  const YED_LABEL_KEYS = [
153
240
  "outline",
@@ -228,15 +315,45 @@ function strokeStyle(raw, kind, writer, at) {
228
315
  return null;
229
316
  }
230
317
  if (writer.vocabulary === "ogdf") {
231
- const stroke = OGDF_STROKES[Number(raw)];
232
- if (stroke === undefined || stroke === "none") {
318
+ const stroke = ogdfStroke(raw);
319
+ if (stroke === undefined) {
233
320
  noteAt(at, STYLE_ISSUE.UNKNOWN_VALUE, sampleOf(raw));
234
321
  return null;
235
322
  }
236
- return stroke;
323
+ // stroke "none" draws no line at all: the callers turn the border or the edge off
324
+ return stroke === "none" ? null : stroke;
237
325
  }
238
326
  return canonEnum(kind, raw, writer.spelling, at);
239
327
  }
328
+ /**
329
+ * An OGDF `stipple`: a StrokeType by number or by name.
330
+ * @param raw - the value
331
+ * @returns the line style, "none", or undefined for a value OGDF does not know
332
+ */
333
+ function ogdfStroke(raw) {
334
+ const text = typeof raw === "string" || typeof raw === "number" ? String(raw).trim() : "";
335
+ return /^\d+$/.test(text) ? OGDF_STROKES[Number(text)] : OGDF_STROKE_NAMES.get(text.toLowerCase());
336
+ }
337
+ /**
338
+ * Reads an OGDF node `type` (a Shape name): a polygon where OGDF draws one, else the shape it names.
339
+ * @param raw - the value
340
+ * @param writer - the writer
341
+ * @param put - receives the values
342
+ * @param at - the sites
343
+ */
344
+ function readOgdfShape(raw, writer, put, at) {
345
+ const name = raw.trim().toLowerCase();
346
+ const points = OGDF_POLYGONS.get(name);
347
+ if (points !== undefined) {
348
+ put("shape", "polygon");
349
+ put("shapePoints", points);
350
+ if (OGDF_REGULAR.has(name)) {
351
+ put("shapePointsStretch", false);
352
+ }
353
+ return;
354
+ }
355
+ put("shape", canonEnum("shape", OGDF_SHAPES.get(name) ?? raw, writer.spelling, at("shape")));
356
+ }
240
357
  /**
241
358
  * Reads one node's `graphics` record.
242
359
  * @param g - the record
@@ -246,18 +363,190 @@ function strokeStyle(raw, kind, writer, at) {
246
363
  */
247
364
  function readNodeGraphics(g, writer, put, at) {
248
365
  const v = writer.vocabulary;
366
+ if (v === "graphviz") {
367
+ readGv2gmlNode(g, writer, put, at);
368
+ return;
369
+ }
249
370
  readNodeFill(g, writer, put, at);
250
371
  readNodeOutline(g, writer, put, at);
251
372
  put("borderStyle", strokeStyle(v === "ogdf" ? g.stipple : g.outlineStyle, "borderStyle", writer, at("borderStyle")));
252
- put("width", g.w === undefined ? null : canonNumber(g.w, at("width")));
253
- put("height", g.h === undefined ? null : canonNumber(g.h, at("height")));
254
- if (g.type !== undefined) {
255
- const raw = v === "ogdf" && typeof g.type === "string" ? (OGDF_SHAPES.get(g.type.toLowerCase()) ?? g.type) : g.type;
256
- put("shape", canonEnum("shape", raw, writer.spelling, at("shape")));
373
+ if (v === "ogdf" && g.stipple !== undefined && ogdfStroke(g.stipple) === "none") {
374
+ put("borderWidth", 0);
375
+ }
376
+ readNodeSize(g, writer, put, at);
377
+ if (v === "ogdf") {
378
+ readOgdfLabelOffset(g.label, put, at);
379
+ }
380
+ readNodeShape(g, writer, put, at);
381
+ }
382
+ /**
383
+ * Reads a node's size from its `graphics` record.
384
+ * @param g - the record
385
+ * @param writer - the writer
386
+ * @param put - receives the values
387
+ * @param at - the sites
388
+ */
389
+ function readNodeSize(g, writer, put, at) {
390
+ if (writer.tool === "gephi") {
391
+ // Gephi's w is a node's size, a radius: its disc is twice as wide, and its h is never read
392
+ const size = g.w === undefined ? null : canonNumber(g.w, at("width"));
393
+ put("width", size === null ? null : 2 * size);
394
+ put("height", size === null ? null : 2 * size);
395
+ }
396
+ else {
397
+ put("width", g.w === undefined ? null : canonNumber(g.w, at("width")));
398
+ put("height", g.h === undefined ? null : canonNumber(g.h, at("height")));
399
+ }
400
+ }
401
+ /**
402
+ * Reads a node's shape from its `graphics` record, in the writer's vocabulary.
403
+ * @param g - the record
404
+ * @param writer - the writer
405
+ * @param put - receives the values
406
+ * @param at - the sites
407
+ */
408
+ function readNodeShape(g, writer, put, at) {
409
+ const v = writer.vocabulary;
410
+ if (v === "ogdf" && typeof g.type === "string") {
411
+ readOgdfShape(g.type, writer, put, at);
412
+ }
413
+ else if (v === "cytoscape" && g.type !== undefined) {
414
+ const name = scalarText(g.type, at("shape"))?.trim().toLowerCase() ?? "";
415
+ const shape = CYTOSCAPE_GML_SHAPES.get(name);
416
+ if (shape === undefined) {
417
+ noteAt(at("shape"), STYLE_ISSUE.UNKNOWN_VALUE, name.slice(0, MAX_STYLE_VALUE_LENGTH));
418
+ }
419
+ put("shape", shape ?? null);
420
+ }
421
+ else if (g.type !== undefined) {
422
+ put("shape", canonEnum("shape", g.type, writer.spelling, at("shape")));
257
423
  }
258
424
  else if (v === "yed" && typeof g.customconfiguration === "string") {
259
425
  // yEd's flowchart palette keeps a node's shape as a configuration, not a `type`.
260
- put("shape", flowchartShape(g.customconfiguration));
426
+ const outline = configurationOutline(g.customconfiguration);
427
+ put("shape", outline?.shape ?? null);
428
+ if (outline?.points !== undefined) {
429
+ put("shapePoints", outline.points);
430
+ }
431
+ }
432
+ }
433
+ /**
434
+ * Reads where OGDF draws a node's label: GraphIO::writeGML writes the label's center as an offset from the node's
435
+ * center (`graphics [ label [ x y z ] ]`, GraphAttributes::xLabel / yLabel, y down), and GraphIO::drawSVG draws it there.
436
+ * @param label - the graphics record's `label` value
437
+ * @param put - receives the values
438
+ * @param at - the sites
439
+ */
440
+ function readOgdfLabelOffset(label, put, at) {
441
+ if (typeof label !== "object" || label === null || Array.isArray(label)) {
442
+ return;
443
+ }
444
+ const { x, y } = label;
445
+ put("labelOffsetX", x === undefined ? null : canonSigned(x, at("labelOffsetX")));
446
+ put("labelOffsetY", y === undefined ? null : canonSigned(y, at("labelOffsetY")));
447
+ }
448
+ /**
449
+ * Reads one node's `graphics` record as Graphviz's gv2gml writes it (cmd/tools/gv2gml.c emitNodeAttrs): `fill` is the
450
+ * node's `fillcolor` (or its `color`), drawn only where `hasFill 1` says `style=filled`; `outline` its pen color,
451
+ * `width` its pen width, `w` and `H` its size in points, `type` its Graphviz shape, `visible 0` its `style=invis`.
452
+ * @param g - the record
453
+ * @param writer - the writer
454
+ * @param put - receives the values
455
+ * @param at - the sites
456
+ */
457
+ function readGv2gmlNode(g, writer, put, at) {
458
+ const shape = typeof g.type === "string" ? g.type.trim().toLowerCase() : "";
459
+ if (Number(g.hasFill) === 1 || shape === "point") {
460
+ // filled: the opacity is stated even when opaque, over Graphviz's default of no fill
461
+ const c = canonColor(g.fill ?? "black", writer.spelling, at("fill"), { use: "fill" });
462
+ put("fill", c?.color ?? null);
463
+ put("fillOpacity", c?.alpha ?? null);
464
+ }
465
+ else if (g.fill !== undefined) {
466
+ // Graphviz draws an unfilled node's inside see-through (the tool default), whatever its color
467
+ noteAt(at("fill"), STYLE_ISSUE.UNFILLED, sampleOf(g.fill));
468
+ }
469
+ if (graphvizHasNoOutline(shape)) {
470
+ put("borderWidth", 0);
471
+ }
472
+ else {
473
+ readColor(g.outline, "borderColor", null, writer, put, at);
474
+ put("borderWidth", g.width === undefined ? null : canonNumber(g.width, at("borderWidth")));
475
+ }
476
+ const borderStyle = strokeStyle(g.outlineStyle, "borderStyle", writer, at("borderStyle"));
477
+ put("borderStyle", borderStyle);
478
+ readGv2gmlRings(g, shape, borderStyle, writer, put, at);
479
+ // gv2gml's w and H are the node's outer size: Graphviz draws each further outline PERIPHERY_GAP outside the one
480
+ // within, so graphty's node (the innermost outline, its ring outside it) is that much smaller
481
+ const rings = 2 * PERIPHERY_GAP * ((SHAPE_PERIPHERIES.get(shape) ?? 1) - 1);
482
+ const inner = (raw, property) => {
483
+ const n = raw === undefined ? null : canonNumber(raw, at(property));
484
+ return n === null ? null : Math.max(0, n - rings);
485
+ };
486
+ put("width", inner(g.w, "width"));
487
+ // gv2gml writes the height as H (gv2gml.c emitReal("H", ...)); h where a later edit spelled it as GML does
488
+ put("height", inner(first(g, "H", "h"), "height"));
489
+ if (Number(g.visible) === 0 && g.visible !== undefined) {
490
+ put("visible", false);
491
+ }
492
+ const outline = graphvizOutline(shape);
493
+ if (shape === "polygon") {
494
+ // ponytail: Graphviz's polygon is a box unless its sides, skew or distortion say otherwise; gv2gml copies
495
+ // those as node keys beside graphics, which this record does not see. Read them when a file has them.
496
+ put("shape", "rectangle");
497
+ }
498
+ else if (outline !== undefined) {
499
+ put("shape", "polygon");
500
+ put("shapePoints", outline);
501
+ // a Graphviz polygon's corners are where Graphviz draws them, as the DOT reader reads them
502
+ put("shapePointsStretch", false);
503
+ }
504
+ else if (GRAPHVIZ_GLYPH_SHAPES.has(shape)) {
505
+ const size = (raw, property) => raw === undefined ? null : canonNumber(raw, at(property));
506
+ putGlyph(shape, size(g.w, "width"), size(first(g, "H", "h"), "height"), put, () => {
507
+ const pen = g.width === undefined ? 1 : Number(g.width);
508
+ return Number.isFinite(pen) ? Math.max(0, pen) : 1;
509
+ }, () => canonColor(g.outline ?? "black", writer.spelling, at("outerBorderColor"), { use: "line" })?.color ??
510
+ null);
511
+ }
512
+ else if (g.type !== undefined) {
513
+ put("shape", canonEnum("shape", g.type, "graphviz", at("shape")));
514
+ }
515
+ }
516
+ /**
517
+ * Reads the second outline Graphviz draws round a `doublecircle`, `doubleoctagon` or `tripleoctagon` (shapes.c):
518
+ * `PERIPHERY_GAP` points outside the first, in its color, width and dashes, as the DOT reader reads it. graphty draws
519
+ * one outer ring, so a third outline is noted as not carried.
520
+ * @param g - the record
521
+ * @param shape - its Graphviz shape, lowercase
522
+ * @param style - its outline's dashes, as read
523
+ * @param writer - the writer
524
+ * @param put - receives the values
525
+ * @param at - the sites
526
+ */
527
+ function readGv2gmlRings(g, shape, style, writer, put, at) {
528
+ // ponytail: gv2gml copies a `peripheries` attribute as a node key beside graphics, which this record does not
529
+ // see; the shapes' own outlines are read. Read the key when a file sets it.
530
+ const count = SHAPE_PERIPHERIES.get(shape) ?? 1;
531
+ if (count < 2) {
532
+ return;
533
+ }
534
+ const c = canonColor(g.outline ?? "black", writer.spelling, at("outerBorderColor"), { use: "line" });
535
+ if (c !== null && c.alpha === 0) {
536
+ return;
537
+ }
538
+ const parsed = g.width === undefined ? 1 : Number(g.width);
539
+ const pen = Number.isFinite(parsed) ? Math.max(0, parsed) : 1;
540
+ put("outerBorderColor", c?.color ?? "#000000");
541
+ put("outerBorderOpacity", c !== null && c.alpha < 1 ? c.alpha : null);
542
+ put("outerBorderWidth", pen);
543
+ // the gap between the outline's outer edge and the ring's inner edge
544
+ put("outerBorderOffset", Math.max(0, PERIPHERY_GAP - pen));
545
+ if (style === "dashed" || style === "dotted") {
546
+ put("outerBorderStyle", style);
547
+ }
548
+ if (count > 2) {
549
+ noteAt(at("outerBorderWidth"), STYLE_ISSUE.NOT_CARRIED, `type ${shape}`);
261
550
  }
262
551
  }
263
552
  /**
@@ -291,7 +580,8 @@ function readNodeOutline(g, writer, put, at) {
291
580
  put("borderWidth", 0);
292
581
  return;
293
582
  }
294
- readColor(v === "ogdf" ? g.line : g.outline, "borderColor", null, writer, put, at);
583
+ // OGDF's GraphIO::writeGML writes the stroke color as `outline`; older OGDF wrote `line`
584
+ readColor(v === "ogdf" ? first(g, "outline", "line") : g.outline, "borderColor", null, writer, put, at);
295
585
  const width = outlineWidthOf(g, v);
296
586
  put("borderWidth", width === undefined ? null : canonNumber(width, at("borderWidth")));
297
587
  }
@@ -322,10 +612,31 @@ function outlineWidthOf(g, v) {
322
612
  */
323
613
  function readEdgeGraphics(g, writer, put, at) {
324
614
  const v = writer.vocabulary;
615
+ if (v === "graphviz") {
616
+ readGv2gmlEdge(g, writer, put, at);
617
+ return;
618
+ }
325
619
  readColor(g.fill, "color", "opacity", writer, put, at);
326
620
  const width = v === "ogdf" ? first(g, "lineWidth", "width") : g.width;
327
621
  put("width", width === undefined ? null : canonNumber(width, at("width")));
328
622
  put("lineStyle", strokeStyle(v === "ogdf" ? g.stipple : g.style, "lineStyle", writer, at("lineStyle")));
623
+ if (v === "ogdf" && g.stipple !== undefined && ogdfStroke(g.stipple) === "none") {
624
+ put("visible", false);
625
+ }
626
+ readEdgeArrows(g, writer, put, at);
627
+ if (v === "yed") {
628
+ readYedCurve(g, put);
629
+ }
630
+ }
631
+ /**
632
+ * Reads an edge's arrows from its `graphics` record: `arrow` names the ends that have one, and `sourceArrow` and
633
+ * `targetArrow` (or their snake-case spellings) name each end's arrow.
634
+ * @param g - the record
635
+ * @param writer - the writer
636
+ * @param put - receives the values
637
+ * @param at - the sites
638
+ */
639
+ function readEdgeArrows(g, writer, put, at) {
329
640
  if (typeof g.arrow === "string") {
330
641
  const ends = ARROW_ENDS.get(g.arrow.trim().toLowerCase());
331
642
  if (ends === undefined) {
@@ -344,13 +655,68 @@ function readEdgeGraphics(g, writer, put, at) {
344
655
  if (raw === undefined) {
345
656
  continue;
346
657
  }
347
- put(property, v === "cytoscape" && cytoscapeArrow !== undefined
658
+ put(property, writer.vocabulary === "cytoscape" && cytoscapeArrow !== undefined
348
659
  ? cytoscapeArrow(raw, at(property))
349
660
  : canonEnum("arrow", raw, writer.spelling, at(property)));
350
661
  }
351
- if (v === "yed") {
352
- readYedCurve(g, put);
662
+ }
663
+ /** gv2gml's `arrow`, from Graphviz's `dir`: `first` is `dir=forward` (the head's arrow), `last` is `dir=back`. */
664
+ const GV2GML_DIRECTIONS = new Map([
665
+ ["first", [false, true]],
666
+ ["last", [true, false]],
667
+ ["both", [true, true]],
668
+ ["none", [false, false]],
669
+ ]);
670
+ /**
671
+ * Reads one edge's `graphics` record as Graphviz's gv2gml writes it (gv2gml.c emitEdgeAttrs): `fill` its color,
672
+ * `width` its pen width (2 for `style=bold`), `style` its dashes, `visible 0` its `style=invis`, `targetArrow` and
673
+ * `sourceArrow` its `arrowhead` and `arrowtail`, and `arrow` its `dir`. With none of the arrow keys an edge of a
674
+ * directed graph has Graphviz's default arrowhead, and one of an undirected graph none.
675
+ * @param g - the record
676
+ * @param writer - the writer
677
+ * @param put - receives the values
678
+ * @param at - the sites
679
+ */
680
+ function readGv2gmlEdge(g, writer, put, at) {
681
+ readColor(g.fill, "color", "opacity", writer, put, at);
682
+ put("width", g.width === undefined ? null : canonNumber(g.width, at("width")));
683
+ put("lineStyle", strokeStyle(g.style, "lineStyle", writer, at("lineStyle")));
684
+ if (Number(g.visible) === 0 && g.visible !== undefined) {
685
+ put("visible", false);
686
+ }
687
+ const ends = gv2gmlArrowEnds(g, writer.directed === true);
688
+ if (ends === null) {
689
+ return;
690
+ }
691
+ for (const [end, raw, on] of [
692
+ ["target", g.targetArrow, ends[1]],
693
+ ["source", g.sourceArrow, ends[0]],
694
+ ]) {
695
+ const name = typeof raw === "string" ? raw : "normal";
696
+ const arrow = on ? graphvizArrowValue(name, at(`${end}Arrow`)) : null;
697
+ put(`${end}Arrow`, arrow === null ? "none" : arrow.value);
698
+ if (arrow?.side !== null && arrow?.side !== undefined) {
699
+ put(`${end}ArrowSide`, arrow.side);
700
+ }
701
+ }
702
+ }
703
+ /**
704
+ * Which ends of a gv2gml edge Graphviz draws an arrow at, as its `dir` says (forward in a directed graph when the
705
+ * record names no arrow), or null for an undirected graph's edge that names none.
706
+ * @param g - the edge's `graphics` record
707
+ * @param directed - whether the graph is directed (its `dir` defaults to forward)
708
+ * @returns [source, target], or null
709
+ */
710
+ function gv2gmlArrowEnds(g, directed) {
711
+ if (g.arrow === undefined && g.targetArrow === undefined && g.sourceArrow === undefined) {
712
+ // Graphviz's dir is forward in a digraph and its arrowhead normal: gv2gml writes neither when unset
713
+ return directed ? [false, true] : null;
714
+ }
715
+ let dir = directed ? "first" : "none";
716
+ if (typeof g.arrow === "string") {
717
+ dir = g.arrow.trim().toLowerCase();
353
718
  }
719
+ return GV2GML_DIRECTIONS.get(dir) ?? null;
354
720
  }
355
721
  /**
356
722
  * Reads whether yEd draws an edge curved: `smoothBends` rounds the bends of its `Line`, whose points run from the
@@ -368,10 +734,11 @@ function readYedCurve(g, put) {
368
734
  * Reads an element's label records: the first visible one with text; further visible ones are noted.
369
735
  * @param raw - the `LabelGraphics` value (one record or several)
370
736
  * @param writer - the writer
737
+ * @param node - whether the label is a node's: its `anchor` places it (`c`, `n`, `t`, `se`, ...)
371
738
  * @param put - receives the values
372
739
  * @param at - the sites
373
740
  */
374
- function readLabelGraphics(raw, writer, put, at) {
741
+ function readLabelGraphics(raw, writer, node, put, at) {
375
742
  const visible = (Array.isArray(raw) ? raw : [raw]).filter((l) => isRec(l) && Number(l.visible) !== 0);
376
743
  const lg = visible.at(0);
377
744
  if (lg === undefined) {
@@ -382,12 +749,13 @@ function readLabelGraphics(raw, writer, put, at) {
382
749
  noteAt(at("label"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);
383
750
  }
384
751
  if (lg.text !== undefined) {
385
- put("label", canonText(lg.text, at("label")));
752
+ put("label", writer.vocabulary === "graphviz" ? graphvizText(lg.text, at("label")) : canonText(lg.text, at("label")));
386
753
  }
387
754
  // the GML draft's `fill` is the text color; yEd's is the label's background box, its `color` the text color
388
755
  const yedLabel = writer.vocabulary === "yed" || YED_LABEL_KEYS.some((k) => Object.hasOwn(lg, k));
389
- if (lg.color !== undefined) {
390
- readColor(lg.color, "labelColor", null, writer, put, at);
756
+ if (lg.color !== undefined || lg.fontColor !== undefined) {
757
+ // gv2gml writes a label's fontcolor as fontColor (as color with -y); yEd's #RRGGBBAA alpha is the words'
758
+ readColor(lg.color ?? lg.fontColor, "labelColor", "labelOpacity", writer, put, at);
391
759
  }
392
760
  else if (lg.fill !== undefined && !yedLabel) {
393
761
  readColor(lg.fill, "labelColor", null, writer, put, at);
@@ -395,17 +763,39 @@ function readLabelGraphics(raw, writer, put, at) {
395
763
  if (lg.fill !== undefined && yedLabel) {
396
764
  noteAt(at("label"), STYLE_ISSUE.NOT_CARRIED, "label background");
397
765
  }
398
- readLabelFont(lg, put, at);
766
+ // yEd and Cytoscape are Java programs: a Java logical font (Dialog, SansSerif, ...) is drawn in Java's face for it
767
+ readLabelFont(lg, yedLabel || writer.vocabulary === "cytoscape", put, at);
768
+ if (node && lg.anchor !== undefined) {
769
+ const anchor = scalarText(lg.anchor, at("labelPosition"))?.trim().toLowerCase() ?? "";
770
+ const known = GML_ANCHORS.get(anchor);
771
+ if (known === undefined) {
772
+ noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, anchor.slice(0, MAX_STYLE_VALUE_LENGTH));
773
+ }
774
+ put("labelPosition", known ?? null);
775
+ }
776
+ }
777
+ /**
778
+ * A label's text as Graphviz draws it: gv2gml copies a DOT label as written, so its line breaks are still the escapes
779
+ * `\n`, `\l` and `\r` (centered, left and right lines, drawn here as plain line breaks).
780
+ * @param raw - the text
781
+ * @param at - the site
782
+ * @returns the text
783
+ */
784
+ function graphvizText(raw, at) {
785
+ const text = canonText(raw, at);
786
+ return text === null ? null : text.replaceAll(/\\[nlr]/g, "\n").replace(/\n$/, "");
399
787
  }
400
788
  /**
401
789
  * Reads a label record's font: its size, name, weight and slant.
402
790
  * @param lg - the record
791
+ * @param java - whether a Java program wrote it, whose logical font names are drawn in Java's faces
403
792
  * @param put - receives the values
404
793
  * @param at - the sites
405
794
  */
406
- function readLabelFont(lg, put, at) {
795
+ function readLabelFont(lg, java, put, at) {
407
796
  put("labelSize", lg.fontSize === undefined ? null : canonNumber(lg.fontSize, at("labelSize")));
408
- put("labelFont", lg.fontName === undefined ? null : canonText(lg.fontName, at("labelFont")));
797
+ const font = lg.fontName === undefined ? null : canonText(lg.fontName, at("labelFont"));
798
+ put("labelFont", java && typeof font === "string" ? javaFamily(font) : font);
409
799
  const style = scalarText(lg.fontStyle, at("labelWeight"))?.trim().toLowerCase();
410
800
  if (style !== undefined) {
411
801
  const known = FONT_STYLES.get(style);
@@ -438,13 +828,81 @@ function readElement(target, g, lg, label, writer, put, at) {
438
828
  (target === "node" ? readNodeGraphics : readEdgeGraphics)(g, writer, put, at);
439
829
  }
440
830
  if (lg !== null && lg !== undefined) {
441
- readLabelGraphics(lg, writer, putLabel, at);
831
+ readLabelGraphics(lg, writer, target === "node", putLabel, at);
442
832
  }
443
833
  // the GML draft draws the label key; Cytoscape reads it as the node's name, which its default style shows
444
834
  const drawn = writer.vocabulary === "cytoscape" ? target === "node" : writer.labelKey && (isRec(g) || lg !== undefined);
445
835
  if (!text && drawn && label !== null && label !== undefined) {
446
- put("label", canonText(label, at("label")));
836
+ put("label", writer.vocabulary === "graphviz" ? graphvizText(label, at("label")) : canonText(label, at("label")));
837
+ // the GML draft names no place for a node's label; a plain GML file's is centered on its node, as OGDF and
838
+ // Cytoscape draw it (yEd's GML keeps its own label models, in LabelGraphics)
839
+ if (target === "node" && writer.tool === null && writer.vocabulary === "graphlet") {
840
+ put("labelPosition", "center");
841
+ }
842
+ }
843
+ }
844
+ /** The font size GraphIO::drawSVG draws every label in (SVGSettings), by which it sets a cluster's label off its box. */
845
+ const OGDF_SVG_FONT_SIZE = 10;
846
+ /**
847
+ * Places each OGDF cluster's label where GraphIO::drawSVG draws it (SvgPrinter::drawCluster): one font size below the
848
+ * cluster's box where more of the drawing lies below it than above, else above it; starting at the box's left side
849
+ * where more of the drawing lies left of it than right, else ending at its right side. The importer reads a cluster as
850
+ * a group node with the id `cluster<id>`; its box is its center and its `w` and `h`.
851
+ * @param snapshot - the graph
852
+ * @param values - the node values read so far, given the label's place
853
+ */
854
+ function placeOgdfClusterLabels(snapshot, values) {
855
+ const n = snapshot.nodeCount;
856
+ const boxOf = (i) => {
857
+ const [x, y] = centerOf(snapshot, i);
858
+ const [w, h] = sizeOf(snapshot, i);
859
+ return [x - w / 2, y - h / 2, x + w / 2, y + h / 2];
860
+ };
861
+ // ponytail: drawSVG's bounding box also holds the edges' bends; nodes and clusters decide every sheet so far
862
+ const all = [Infinity, Infinity, -Infinity, -Infinity];
863
+ for (let i = 0; i < n; i++) {
864
+ const b = boxOf(i);
865
+ if (b.every(Number.isFinite)) {
866
+ all[0] = Math.min(all[0], b[0]);
867
+ all[1] = Math.min(all[1], b[1]);
868
+ all[2] = Math.max(all[2], b[2]);
869
+ all[3] = Math.max(all[3], b[3]);
870
+ }
871
+ }
872
+ const put = (property, i, value) => {
873
+ values[property] ?? (values[property] = new Array(n).fill(null));
874
+ values[property][i] = value;
875
+ };
876
+ for (let i = 0; i < n; i++) {
877
+ const id = snapshot.ids.idOf(i);
878
+ const [x0, y0, x1, y1] = boxOf(i);
879
+ if (typeof id !== "string" || !id.startsWith("cluster") || ![x0, y0, x1, y1].every(Number.isFinite)) {
880
+ continue;
881
+ }
882
+ const below = all[3] - y1 > y0 - all[1];
883
+ const start = x0 - all[0] > all[2] - x1;
884
+ put("labelPosition", i, "center");
885
+ put("labelOffsetX", i, ((start ? -1 : 1) * (x1 - x0)) / 2);
886
+ put("labelShiftX", i, start ? 0.5 : -0.5);
887
+ put("labelOffsetY", i, (below ? 1 : -1) * ((y1 - y0) / 2 + OGDF_SVG_FONT_SIZE));
888
+ }
889
+ }
890
+ /**
891
+ * An element's `label` key. Cytoscape's GML reader names a node by its label and, where the label is empty or
892
+ * missing, by its id, and its default style draws that name.
893
+ * @param snapshot - the graph
894
+ * @param writer - the writer
895
+ * @param target - nodes or edges
896
+ * @param i - the row
897
+ * @returns the label
898
+ */
899
+ function labelOf(snapshot, writer, target, i) {
900
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
901
+ const label = cellOf(table, "label", i);
902
+ if (writer.vocabulary === "cytoscape" && target === "node" && (label === undefined || label === "")) {
903
+ return String(snapshot.ids.idOf(i));
447
904
  }
905
+ return label;
448
906
  }
449
907
  /**
450
908
  * The value of a column, or undefined when the table has no such column.
@@ -472,20 +930,180 @@ function centerOf(snapshot, i) {
472
930
  return v === null ? [Number.NaN, Number.NaN] : [v[0], v[1]];
473
931
  }
474
932
  /**
475
- * An edge's bends: the points of its `graphics` `Line` between the first and the last, which are where it leaves
476
- * the source and meets the target.
933
+ * A node's width and height: its `graphics` `w` and `h`.
934
+ * @param snapshot - the graph
935
+ * @param i - the node's index
936
+ * @returns the size; NaN where the node has none
937
+ */
938
+ function sizeOf(snapshot, i) {
939
+ const g = cellOf(snapshot.nodes, "graphics", i);
940
+ return isRec(g) ? [Number(g.w ?? Number.NaN), Number(g.h ?? Number.NaN)] : [Number.NaN, Number.NaN];
941
+ }
942
+ /**
943
+ * An edge's route from its `graphics` `Line`, whose first and last points are where it attaches to its source and
944
+ * target (its ports: the centers unless yEd moved them) and whose points between are its bends: the bends relative to
945
+ * 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.
946
+ * OGDF's `Line` holds the bends alone (GraphIO::writeGML writes no end point).
477
947
  * @param snapshot - the graph
478
948
  * @param g - the edge's `graphics` value
479
949
  * @param e - the edge's row
480
- * @returns the `bends` value, or null without bends
950
+ * @param bendsOnly - whether the points are the bends alone (OGDF)
951
+ * @param put - receives the values
481
952
  */
482
- function lineBends(snapshot, g, e) {
953
+ function readLineRoute(snapshot, g, e, bendsOnly, put) {
483
954
  const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;
484
- if (!Array.isArray(raw) || raw.length < 3) {
485
- return null;
955
+ const list = isRec(raw) ? [raw] : raw;
956
+ if (!Array.isArray(list) || list.length < (bendsOnly ? 1 : 2)) {
957
+ return;
958
+ }
959
+ const all = list.map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));
960
+ const [s, t] = [snapshot.edgeSource(e), snapshot.edgeTarget(e)];
961
+ const points = bendsOnly ? all : all.slice(1, -1);
962
+ const bends = s === t
963
+ ? canonNodeOffsets(centerOf(snapshot, s), sizeOf(snapshot, s), points, true)
964
+ : canonBends(centerOf(snapshot, s), centerOf(snapshot, t), points, true);
965
+ if (bends !== null) {
966
+ put("bends", bends);
967
+ }
968
+ if (bendsOnly) {
969
+ return;
970
+ }
971
+ for (const [property, k, end] of [
972
+ ["sourcePort", s, all[0]],
973
+ ["targetPort", t, all.at(-1) ?? all[0]],
974
+ ]) {
975
+ const center = centerOf(snapshot, k);
976
+ const port = end[0] === center[0] && end[1] === center[1]
977
+ ? null
978
+ : canonNodeOffsets(center, sizeOf(snapshot, k), [end], true);
979
+ if (port !== null) {
980
+ put(property, port);
981
+ }
982
+ }
983
+ }
984
+ /**
985
+ * A gv2gml edge's route: its `Line` is the edge's Graphviz `pos`, the B-spline's `3n + 1` control points from the tail
986
+ * to the head (y up), with the arrow tips Graphviz keeps apart (`s,` and `e,`) written as plain first and last points;
987
+ * the points beyond `3n + 1` are those tips (the source's first when there are two or it has the arrow). A route on
988
+ * the line between the centers is the straight edge it looks like and gives no bends.
989
+ * @param snapshot - the graph
990
+ * @param g - the edge's `graphics` value
991
+ * @param e - the edge's row
992
+ * @param put - receives the values
993
+ */
994
+ function readGv2gmlRoute(snapshot, g, e, put) {
995
+ const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;
996
+ const list = isRec(raw) ? [raw] : raw;
997
+ if (!Array.isArray(list) || !isRec(g)) {
998
+ return;
999
+ }
1000
+ let points = list.map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));
1001
+ const tips = (points.length - 1) % 3;
1002
+ const sourceTip = tips === 2 || (tips === 1 && gv2gmlArrowEnds(g, snapshot.directed)?.[0] === true);
1003
+ points = points.slice(sourceTip ? 1 : 0, points.length - (tips === 2 || (tips === 1 && !sourceTip) ? 1 : 0));
1004
+ const bends = graphvizRouteBends(centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e)), [points]);
1005
+ if (bends !== null) {
1006
+ put("bends", bends);
1007
+ }
1008
+ }
1009
+ /**
1010
+ * Where graphty-element hangs an edge's label on a route drawn through these points (its centers and bends): the
1011
+ * middle of its middle segment, or the joint between its two middle ones; `labelOffsetX` / `labelOffsetY` move it
1012
+ * from there.
1013
+ * @param points - the route, from the source's center to the target's
1014
+ * @returns the point
1015
+ */
1016
+ function routeMiddle(points) {
1017
+ const m = points.length - 1;
1018
+ if (m % 2 === 0) {
1019
+ return points[m / 2];
1020
+ }
1021
+ const [a, b] = [points[(m - 1) / 2], points[(m + 1) / 2]];
1022
+ return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];
1023
+ }
1024
+ /**
1025
+ * Puts an edge label's offset from where graphty-element hangs it, when the program draws it elsewhere.
1026
+ * @param at - the label's center, in the file's coordinates
1027
+ * @param middle - where graphty-element hangs it, in the same coordinates
1028
+ * @param yUp - whether the file's y grows upward
1029
+ * @param put - receives the values
1030
+ */
1031
+ function putEdgeLabelOffset(at, middle, yUp, put) {
1032
+ const dx = num6(at[0] - middle[0]);
1033
+ const dy = num6((yUp ? -1 : 1) * (at[1] - middle[1]));
1034
+ if (Number.isFinite(dx) && Number.isFinite(dy) && (dx !== 0 || dy !== 0)) {
1035
+ // moved from the line's middle itself, not from graphty's default place beside the line
1036
+ put("labelPosition", "center");
1037
+ put("labelOffsetX", dx);
1038
+ put("labelOffsetY", dy);
1039
+ }
1040
+ }
1041
+ /**
1042
+ * A gv2gml edge label's place: gv2gml copies Graphviz's `lp` (the label's center, in points, y up) as a plain edge
1043
+ * key, and Graphviz draws the label there, beside its line rather than on it.
1044
+ * @param snapshot - the graph
1045
+ * @param e - the edge's row
1046
+ * @param bent - whether its route has bends
1047
+ * @param put - receives the values
1048
+ */
1049
+ function readGv2gmlLabelPlace(snapshot, e, bent, put) {
1050
+ const lp = cellOf(snapshot.edges, "lp", e);
1051
+ const m = typeof lp === "string" ? /^\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*$/.exec(lp) : null;
1052
+ // ponytail: a curved route's middle is where graphty-element samples its curve; only a straight one is placed
1053
+ if (m === null || bent) {
1054
+ return;
1055
+ }
1056
+ const [s, t] = [centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e))];
1057
+ putEdgeLabelOffset([Number(m[1]), Number(m[2])], routeMiddle([s, t]), true, put);
1058
+ }
1059
+ /**
1060
+ * An OGDF edge label's place: GraphIO::drawSVG (SvgPrinter::drawEdge) draws it at the middle of the route's first
1061
+ * segment, from the source's center to its first bend, not at the route's middle.
1062
+ * @param snapshot - the graph
1063
+ * @param g - the edge's `graphics` value
1064
+ * @param e - the edge's row
1065
+ * @param put - receives the values
1066
+ */
1067
+ function readOgdfLabelPlace(snapshot, g, e, put) {
1068
+ const raw = isRec(g) && isRec(g.Line) ? g.Line.point : undefined;
1069
+ const list = isRec(raw) ? [raw] : raw;
1070
+ const [s, t] = [centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e))];
1071
+ if (!Array.isArray(list) || snapshot.edgeSource(e) === snapshot.edgeTarget(e)) {
1072
+ return;
1073
+ }
1074
+ const same = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1]) < 1e-6;
1075
+ // the Line OGDF writes may start and end at the centers
1076
+ const bends = list
1077
+ .map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]))
1078
+ .filter((p) => !same(p, s) && !same(p, t));
1079
+ if (bends.length === 0) {
1080
+ return;
1081
+ }
1082
+ const route = [s, ...bends, t];
1083
+ putEdgeLabelOffset([(route[0][0] + route[1][0]) / 2, (route[0][1] + route[1][1]) / 2], routeMiddle(route), false, put);
1084
+ }
1085
+ /**
1086
+ * Hides the edges Gephi's own GML importer leaves out: an edge whose `directed` key disagrees with the graph's
1087
+ * `directed` header (Gephi 0.11 loads 4 of `specimen-arrows-p6`'s 5 edges). A file with no header is read as mixed and
1088
+ * every edge is loaded. The edge and its data stay; Gephi draws nothing there, so graphty draws nothing.
1089
+ * @param snapshot - the graph
1090
+ * @param values - the edge values read so far, given `visible`
1091
+ */
1092
+ function hideGephiDroppedEdges(snapshot, values) {
1093
+ const header = snapshot.meta.extra.gml?.directed;
1094
+ const directed = snapshot.edges.byRole("directed");
1095
+ // with no `directed` header Gephi reads a mixed graph and loads every edge (Gephi Toolkit 0.11.3, checked)
1096
+ if (directed === null || header === undefined) {
1097
+ return;
1098
+ }
1099
+ const graphDirected = Number(header) === 1;
1100
+ for (let e = 0; e < snapshot.edgeCount; e++) {
1101
+ const v = plainCell(directed.value(e));
1102
+ if (typeof v === "boolean" && v !== graphDirected) {
1103
+ values.visible ?? (values.visible = new Array(snapshot.edgeCount).fill(null));
1104
+ values.visible[e] = false;
1105
+ }
486
1106
  }
487
- const points = raw.slice(1, -1).map((p) => (isRec(p) ? [Number(p.x), Number(p.y)] : [Number.NaN, 0]));
488
- return canonBends(centerOf(snapshot, snapshot.edgeSource(e)), centerOf(snapshot, snapshot.edgeTarget(e)), points, true);
489
1107
  }
490
1108
  /**
491
1109
  * Every element's values, read with a writer's vocabulary.
@@ -507,18 +1125,33 @@ function readValues(snapshot, writer, notes, context) {
507
1125
  for (let i = 0; i < n; i++) {
508
1126
  context.budget.spend(target, 1);
509
1127
  const at = (property) => ({ notes, target, property, element: i, budget: context.budget });
510
- readElement(target, cellOf(table, "graphics", i), cellOf(table, "LabelGraphics", i), cellOf(table, "label", i), writer, (property, value) => {
1128
+ readElement(target, cellOf(table, "graphics", i), cellOf(table, "LabelGraphics", i), labelOf(snapshot, writer, target, i), writer, (property, value) => {
511
1129
  if (value !== null) {
512
1130
  found = true;
513
1131
  out.put(i, property, value);
514
1132
  }
515
1133
  }, at);
516
- if (target === "edge") {
517
- const bends = lineBends(snapshot, cellOf(table, "graphics", i), i);
518
- if (bends !== null) {
1134
+ if (target === "edge" && writer.vocabulary === "graphviz") {
1135
+ let bent = false;
1136
+ readGv2gmlRoute(snapshot, cellOf(table, "graphics", i), i, (property, value) => {
519
1137
  found = true;
520
- out.put(i, "bends", bends);
521
- }
1138
+ bent || (bent = property === "bends");
1139
+ out.put(i, property, value);
1140
+ });
1141
+ readGv2gmlLabelPlace(snapshot, i, bent, (property, value) => {
1142
+ out.put(i, property, value);
1143
+ });
1144
+ }
1145
+ else if (target === "edge" && writer.vocabulary === "ogdf") {
1146
+ readOgdfLabelPlace(snapshot, cellOf(table, "graphics", i), i, (property, value) => {
1147
+ out.put(i, property, value);
1148
+ });
1149
+ }
1150
+ if (target === "edge" && writer.vocabulary !== "graphviz") {
1151
+ readLineRoute(snapshot, cellOf(table, "graphics", i), i, writer.vocabulary === "ogdf", (property, value) => {
1152
+ found = true;
1153
+ out.put(i, property, value);
1154
+ });
522
1155
  }
523
1156
  }
524
1157
  return out.values;
@@ -589,8 +1222,11 @@ function styleColumns(table) {
589
1222
  */
590
1223
  export function gmlStyles(snapshot, context) {
591
1224
  const notes = new StyleNotes();
592
- const writer = writerOf(snapshot);
1225
+ const writer = { ...writerOf(snapshot), directed: snapshot.directed };
593
1226
  const values = readValues(snapshot, writer, notes, context);
1227
+ if (writer.vocabulary === "ogdf") {
1228
+ placeOgdfClusterLabels(snapshot, values.node);
1229
+ }
594
1230
  const blockText = graphText(snapshot, GML_STYLE_BLOCK_KEY);
595
1231
  const block = blockText === null ? null : blockWithValues(snapshot, blockText);
596
1232
  if (block !== null) {
@@ -599,16 +1235,33 @@ export function gmlStyles(snapshot, context) {
599
1235
  if (writer.tool === null && !values.found && block === null) {
600
1236
  return null;
601
1237
  }
1238
+ if (writer.tool === "gephi" && block === null) {
1239
+ // Gephi draws every edge in its end nodes' mixed color (EdgeColor MIXED), whatever its own
1240
+ delete values.edge.color;
1241
+ // and as thick as its weight, the `value` Gephi writes, also where the reader kept `value` as plain data
1242
+ if (snapshot.edges.byRole("weight") === null && snapshot.edges.has("value")) {
1243
+ values.edge.width = Array.from({ length: snapshot.edgeCount }, (_, e) => {
1244
+ const w = cellOf(snapshot.edges, "value", e);
1245
+ if (typeof w !== "number" || !Number.isFinite(w)) {
1246
+ return null;
1247
+ }
1248
+ // a weight of 0 or below is drawn 1 wide, so the edge stays visible
1249
+ return w > 0 ? w : 1;
1250
+ });
1251
+ }
1252
+ hideGephiDroppedEdges(snapshot, values.edge);
1253
+ }
1254
+ const none = { rules: [], columns: new Map() };
602
1255
  const gephi = writer.tool === "gephi"
603
- ? gephiRules(snapshot, values.node.fill, values.edge.color, context.budget, values.edge.width)
604
- : { rules: [], columns: new Map() };
1256
+ ? gephiRules(snapshot, { fill: values.node.fill, width: values.node.width }, { color: values.edge.color, width: values.edge.width }, context.budget)
1257
+ : { node: none, edge: none };
605
1258
  return {
606
1259
  canonical: true,
607
1260
  dialect: writer.dialect,
608
1261
  tool: writer.tool,
609
1262
  units: writer.units,
610
- node: { values: values.node },
611
- edge: { values: values.edge, rules: gephi.rules, columns: gephi.columns },
1263
+ node: { values: values.node, ...gephi.node },
1264
+ edge: { values: values.edge, ...gephi.edge },
612
1265
  notes: notes.list(),
613
1266
  opacityInColor: true,
614
1267
  block,
@@ -623,6 +1276,7 @@ export function gmlStyles(snapshot, context) {
623
1276
  * @category Built-in formats
624
1277
  */
625
1278
  export const GML_STYLE_CAPABILITIES = Object.freeze({
1279
+ tool: "yed",
626
1280
  node: Object.freeze([
627
1281
  "fill",
628
1282
  "fillOpacity",
@@ -648,6 +1302,8 @@ export const GML_STYLE_CAPABILITIES = Object.freeze({
648
1302
  "targetArrow",
649
1303
  "curved",
650
1304
  "bends",
1305
+ "sourcePort",
1306
+ "targetPort",
651
1307
  "label",
652
1308
  "labelColor",
653
1309
  "labelSize",
@@ -797,7 +1453,8 @@ function labelGraphics(get) {
797
1453
  }
798
1454
  const font = get("labelFont");
799
1455
  if (typeof font === "string") {
800
- lg.fontName = font;
1456
+ // a Java face is written back as the logical font yEd draws in it
1457
+ lg.fontName = yedFontName(font);
801
1458
  }
802
1459
  const weight = get("labelWeight");
803
1460
  const italic = get("labelItalic");
@@ -841,19 +1498,6 @@ function mergedLabels(old, written) {
841
1498
  }
842
1499
  return head === undefined ? rest : [head, ...rest];
843
1500
  }
844
- /**
845
- * Each element's values of the properties the writer writes, as a getter per element.
846
- * @param picture - each element's value of a property
847
- * @param target - nodes or edges
848
- * @returns the getter
849
- */
850
- function getter(picture, target) {
851
- const columns = new Map();
852
- for (const p of GML_STYLE_CAPABILITIES[target]) {
853
- columns.set(p, picture(target, p));
854
- }
855
- return (i) => (property) => columns.get(property)?.[i] ?? null;
856
- }
857
1501
  /**
858
1502
  * For a file graphty wrote: where a value read from the graphics is what the writer writes for the block's own value
859
1503
  * (a pentagon written as a rectangle, an opacity rounded to 255 steps), the block's exact value is the truth, so a
@@ -865,29 +1509,16 @@ function getter(picture, target) {
865
1509
  * @param read.edge - the edge values
866
1510
  */
867
1511
  function exactFromBlock(snapshot, text, read) {
868
- const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
869
- const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "gml") : null;
870
- if (ex === null) {
871
- return;
872
- }
873
1512
  const notes = new StyleNotes();
874
- for (const target of ["node", "edge"]) {
875
- const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
876
- const get = getter((t, p) => resolveStyles(ex, t, p, snapshot), target);
877
- const values = read[target];
878
- for (let i = 0; i < n; i++) {
879
- const want = get(i);
1513
+ takeFromBlock(snapshot, text, "gml", (target) => ({
1514
+ values: read[target],
1515
+ properties: GML_STYLE_CAPABILITIES[target],
1516
+ writes: GML_STYLE_CAPABILITIES[target],
1517
+ readBack: (_i, want) => {
880
1518
  const back = writtenAndReadBack(target, want, notes);
881
- for (const property of GML_STYLE_CAPABILITIES[target]) {
882
- const native = values[property]?.[i] ?? null;
883
- const w = want(property);
884
- if (native !== w && native === (back.get(property) ?? null)) {
885
- values[property] ?? (values[property] = new Array(n).fill(null));
886
- values[property][i] = w;
887
- }
888
- }
889
- }
890
- }
1519
+ return (property) => back.get(property) ?? null;
1520
+ },
1521
+ }));
891
1522
  }
892
1523
  /**
893
1524
  * An element's values written as the writer writes them and read back as the reader reads them.
@@ -968,13 +1599,18 @@ function writeGraphicsColumns(snapshot, input, target, table, approximated) {
968
1599
  const approximate = (property, value) => {
969
1600
  approximated.add(target, property, value);
970
1601
  };
971
- const get = getter((t, p) => input.picture(t, p), target);
1602
+ const get = elementValues((t, p) => input.picture(t, p), target, GML_STYLE_CAPABILITIES[target]);
1603
+ const getNode = elementValues((t, p) => input.picture(t, p), "node", GML_STYLE_CAPABILITIES.node);
1604
+ const size = (k) => {
1605
+ const [w, h] = [getNode(k)("width"), getNode(k)("height")];
1606
+ return typeof w === "number" && typeof h === "number" ? [w, h] : sizeOf(snapshot, k);
1607
+ };
972
1608
  const graphics = [];
973
1609
  const labels = [];
974
1610
  for (let i = 0; i < n; i++) {
975
1611
  const g = target === "node" ? nodeGraphics(get(i), approximate) : edgeGraphics(get(i), approximate);
976
1612
  if (target === "edge") {
977
- const line = bendsLine(snapshot, get(i)("bends"), i);
1613
+ const line = routeLine(snapshot, get(i), i, size);
978
1614
  if (line !== null) {
979
1615
  g.Line = line;
980
1616
  }
@@ -995,21 +1631,38 @@ function writeGraphicsColumns(snapshot, input, target, table, approximated) {
995
1631
  }
996
1632
  }
997
1633
  /**
998
- * An edge's `Line` from its `bends` value: the node centers it is written between, with the bends placed between them,
999
- * so the bends read back as written.
1634
+ * An edge's `Line` from its `bends`, `sourcePort` and `targetPort` values: from its source port (the node's center
1635
+ * without one) through the bends placed between the node centers (a self-loop's around its node) to its target port,
1636
+ * so the route reads back as written.
1000
1637
  * @param snapshot - the graph handed to the exporter
1001
- * @param bends - the edge's `bends` value
1638
+ * @param get - the edge's values
1002
1639
  * @param e - the edge's row
1640
+ * @param size - each node's written width and height
1003
1641
  * @returns the `Line` record, or null without a value or without both centers
1004
1642
  */
1005
- function bendsLine(snapshot, bends, e) {
1006
- const source = centerOf(snapshot, snapshot.edgeSource(e));
1007
- const target = centerOf(snapshot, snapshot.edgeTarget(e));
1008
- const points = typeof bends === "string" ? bendsToPoints(source, target, bends, true) : null;
1009
- if (points === null || ![...source, ...target].every(Number.isFinite)) {
1643
+ function routeLine(snapshot, get, e, size) {
1644
+ const [s, t] = [snapshot.edgeSource(e), snapshot.edgeTarget(e)];
1645
+ const source = centerOf(snapshot, s);
1646
+ const target = centerOf(snapshot, t);
1647
+ if (![...source, ...target].every(Number.isFinite)) {
1648
+ return null;
1649
+ }
1650
+ const bends = get("bends");
1651
+ let points = null;
1652
+ if (typeof bends === "string") {
1653
+ points =
1654
+ s === t ? nodeOffsetsToPoints(source, size(s), bends, true) : bendsToPoints(source, target, bends, true);
1655
+ }
1656
+ const port = (property, k, center) => {
1657
+ const value = get(property);
1658
+ return typeof value === "string" ? (nodeOffsetsToPoints(center, size(k), value, true)?.[0] ?? null) : null;
1659
+ };
1660
+ const from = port("sourcePort", s, source);
1661
+ const to = port("targetPort", t, target);
1662
+ if (points === null && from === null && to === null) {
1010
1663
  return null;
1011
1664
  }
1012
- return { point: [source, ...points, target].map(([x, y]) => ({ x, y })) };
1665
+ return { point: [from ?? source, ...(points ?? []), to ?? target].map(([x, y]) => ({ x, y })) };
1013
1666
  }
1014
1667
  /**
1015
1668
  * Writes a data column under a name out of the keys the style values take.