@graphty/graph-io 0.3.48 → 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 (570) hide show
  1. package/dist/chunks/{approximations-C2riR4NT.js → approximations-Bzn3L-je.js} +2 -2
  2. package/dist/chunks/{approximations-C2riR4NT.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-Cu22ewuS.js → block-iptrlMBb.js} +906 -164
  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-CV_Bhcyi.js → codes-BE2xir2k.js} +6 -2
  10. package/dist/chunks/codes-BE2xir2k.js.map +1 -0
  11. package/dist/chunks/{constants-D0LqcsLJ.js → constants-CKkYLPtt.js} +2 -2
  12. package/dist/chunks/{constants-D0LqcsLJ.js.map → constants-CKkYLPtt.js.map} +1 -1
  13. package/dist/chunks/{context-cgmmOxZ2.js → context-C3p0RQxR.js} +5 -4
  14. package/dist/chunks/{context-cgmmOxZ2.js.map → context-C3p0RQxR.js.map} +1 -1
  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-BiQsnMTb.js → credentials-DXHx7nwR.js} +16 -14
  18. package/dist/chunks/credentials-DXHx7nwR.js.map +1 -0
  19. package/dist/chunks/{cx-export-BEeF6ymo.js → cx-export-Bt6NoqTQ.js} +3 -3
  20. package/dist/chunks/{cx-export-BEeF6ymo.js.map → cx-export-Bt6NoqTQ.js.map} +1 -1
  21. package/dist/chunks/descriptor-B28U25x4.js +60 -0
  22. package/dist/chunks/descriptor-B28U25x4.js.map +1 -0
  23. package/dist/chunks/{descriptor-BJ-W0Jd-.js → descriptor-DLA5kINx.js} +7 -2
  24. package/dist/chunks/descriptor-DLA5kINx.js.map +1 -0
  25. package/dist/chunks/{emit-CD8xnY8s.js → emit-BwHQkZle.js} +1660 -133
  26. package/dist/chunks/emit-BwHQkZle.js.map +1 -0
  27. package/dist/chunks/{escape-DH2Egt-l.js → escape-CuCIzNMB.js} +8 -8
  28. package/dist/chunks/{escape-DH2Egt-l.js.map → escape-CuCIzNMB.js.map} +1 -1
  29. package/dist/chunks/{export-CZ7VRm4I.js → export-Cha4dRFz.js} +45 -387
  30. package/dist/chunks/export-Cha4dRFz.js.map +1 -0
  31. package/dist/chunks/{exporter-Dcw7Ldtq.js → exporter-BP6otMO6.js} +6 -6
  32. package/dist/chunks/{exporter-Dcw7Ldtq.js.map → exporter-BP6otMO6.js.map} +1 -1
  33. package/dist/chunks/{exporter-bxxjOrDZ.js → exporter-D2CETOMK.js} +1222 -156
  34. package/dist/chunks/exporter-D2CETOMK.js.map +1 -0
  35. package/dist/chunks/{exporter-BIdaoIgh.js → exporter-D9yMtocA.js} +7 -7
  36. package/dist/chunks/{exporter-BIdaoIgh.js.map → exporter-D9yMtocA.js.map} +1 -1
  37. package/dist/chunks/{exporter-DtVU80Fa.js → exporter-_jrBTnos.js} +9 -8
  38. package/dist/chunks/{exporter-DtVU80Fa.js.map → exporter-_jrBTnos.js.map} +1 -1
  39. package/dist/chunks/{exporter-ChjL5fmP.js → exporter-nDfxIK5D.js} +9 -8
  40. package/dist/chunks/{exporter-ChjL5fmP.js.map → exporter-nDfxIK5D.js.map} +1 -1
  41. package/dist/chunks/format-BXiAb-1h.js +408 -0
  42. package/dist/chunks/format-BXiAb-1h.js.map +1 -0
  43. package/dist/chunks/{generic-CP6YD34u.js → generic-ymWCETAJ.js} +387 -31
  44. package/dist/chunks/generic-ymWCETAJ.js.map +1 -0
  45. package/dist/chunks/{importer-e3huMZbm.js → importer-B92x1xY5.js} +14 -10
  46. package/dist/chunks/importer-B92x1xY5.js.map +1 -0
  47. package/dist/chunks/{importer-B87_fmVx.js → importer-CT9mJ1nn.js} +326 -84
  48. package/dist/chunks/importer-CT9mJ1nn.js.map +1 -0
  49. package/dist/chunks/{importer-CB_zV5_L.js → importer-DaLTjbds.js} +116 -1102
  50. package/dist/chunks/importer-DaLTjbds.js.map +1 -0
  51. package/dist/chunks/{importer-DPZDN40-.js → importer-GREKMdIf.js} +25 -17
  52. package/dist/chunks/importer-GREKMdIf.js.map +1 -0
  53. package/dist/chunks/{importer-Bji2MeWr.js → importer-PqaaKKnY.js} +13 -10
  54. package/dist/chunks/{importer-Bji2MeWr.js.map → importer-PqaaKKnY.js.map} +1 -1
  55. package/dist/chunks/{importer-Cyy6UseH.js → importer-Vn5QvmmJ.js} +66 -13
  56. package/dist/chunks/importer-Vn5QvmmJ.js.map +1 -0
  57. package/dist/chunks/{importer-CVT-JyDE.js → importer-vRq4h3j5.js} +1469 -356
  58. package/dist/chunks/importer-vRq4h3j5.js.map +1 -0
  59. package/dist/chunks/{input-Ccg9I22A.js → input-CAxt_aV-.js} +4 -4
  60. package/dist/chunks/{input-Ccg9I22A.js.map → input-CAxt_aV-.js.map} +1 -1
  61. package/dist/chunks/{json-elements-By172SVq.js → json-elements-Cq76WjnZ.js} +4 -4
  62. package/dist/chunks/{json-elements-By172SVq.js.map → json-elements-Cq76WjnZ.js.map} +1 -1
  63. package/dist/chunks/{lexicon-u2SI5xcx.js → lexicon-Clf4QIyl.js} +282 -74
  64. package/dist/chunks/lexicon-Clf4QIyl.js.map +1 -0
  65. package/dist/chunks/{ontology-export-BwgMyuF0.js → ontology-export-OMo91mb0.js} +4 -4
  66. package/dist/chunks/{ontology-export-BwgMyuF0.js.map → ontology-export-OMo91mb0.js.map} +1 -1
  67. package/dist/chunks/{records-Cgvxz-Vx.js → records-NJiYvekn.js} +2 -2
  68. package/dist/chunks/{records-Cgvxz-Vx.js.map → records-NJiYvekn.js.map} +1 -1
  69. package/dist/chunks/{report-CgdsL9Hb.js → report-CwMfYa9J.js} +23 -23
  70. package/dist/chunks/{report-CgdsL9Hb.js.map → report-CwMfYa9J.js.map} +1 -1
  71. package/dist/chunks/round-trip-Zm3_ivgq.js +79 -0
  72. package/dist/chunks/round-trip-Zm3_ivgq.js.map +1 -0
  73. package/dist/chunks/{sigv4-LkAzsLAu.js → sigv4-EokFic1V.js} +5 -5
  74. package/dist/chunks/sigv4-EokFic1V.js.map +1 -0
  75. package/dist/chunks/{styles-CaABMoO1.js → styles-CCs214_3.js} +1237 -138
  76. package/dist/chunks/styles-CCs214_3.js.map +1 -0
  77. package/dist/chunks/styles-Cm62yyQX.js +2812 -0
  78. package/dist/chunks/styles-Cm62yyQX.js.map +1 -0
  79. package/dist/chunks/styles-DPQQIig4.js +1928 -0
  80. package/dist/chunks/styles-DPQQIig4.js.map +1 -0
  81. package/dist/chunks/{styles-yed-Cs1nmrjn.js → styles-yed-UMFdNqze.js} +503 -172
  82. package/dist/chunks/styles-yed-UMFdNqze.js.map +1 -0
  83. package/dist/chunks/{text-BuKQVMz2.js → text-ystE2bYi.js} +2 -2
  84. package/dist/chunks/{text-BuKQVMz2.js.map → text-ystE2bYi.js.map} +1 -1
  85. package/dist/csv.js +7 -7
  86. package/dist/cx.js +2 -2
  87. package/dist/cx2.js +2 -2
  88. package/dist/cys.js +1 -1
  89. package/dist/dot.js +5 -4
  90. package/dist/dot.js.map +1 -1
  91. package/dist/gexf.js +42 -12
  92. package/dist/gexf.js.map +1 -1
  93. package/dist/gml.js +847 -193
  94. package/dist/gml.js.map +1 -1
  95. package/dist/graph-io.js +232 -220
  96. package/dist/graph-io.js.map +1 -1
  97. package/dist/graphml.js +3 -3
  98. package/dist/json.js +3 -2
  99. package/dist/neo4j.js +6 -6
  100. package/dist/obo.js +1 -1
  101. package/dist/pajek.js +1 -1
  102. package/dist/positions.js +45 -3
  103. package/dist/positions.js.map +1 -1
  104. package/dist/sources-cypher.js +138 -23
  105. package/dist/sources-cypher.js.map +1 -1
  106. package/dist/sources-ndex.js +2 -2
  107. package/dist/sources-rest.js +16 -6
  108. package/dist/sources-rest.js.map +1 -1
  109. package/dist/sources-sparql.d.ts +1 -0
  110. package/dist/sources-sparql.js +405 -0
  111. package/dist/sources-sparql.js.map +1 -0
  112. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  113. package/dist/src/formats/cx/importer.js +5 -1
  114. package/dist/src/formats/cx/importer.js.map +1 -1
  115. package/dist/src/formats/cx/styles.d.ts +24 -1
  116. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  117. package/dist/src/formats/cx/styles.js +117 -11
  118. package/dist/src/formats/cx/styles.js.map +1 -1
  119. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  120. package/dist/src/formats/cx2/importer.js +1 -0
  121. package/dist/src/formats/cx2/importer.js.map +1 -1
  122. package/dist/src/formats/cx2/styles.d.ts.map +1 -1
  123. package/dist/src/formats/cx2/styles.js +3 -1
  124. package/dist/src/formats/cx2/styles.js.map +1 -1
  125. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cys/importer.js +1 -0
  127. package/dist/src/formats/cys/importer.js.map +1 -1
  128. package/dist/src/formats/cys/styles.d.ts +2 -0
  129. package/dist/src/formats/cys/styles.d.ts.map +1 -1
  130. package/dist/src/formats/cys/styles.js +15 -7
  131. package/dist/src/formats/cys/styles.js.map +1 -1
  132. package/dist/src/formats/dot/drawing.d.ts +98 -0
  133. package/dist/src/formats/dot/drawing.d.ts.map +1 -0
  134. package/dist/src/formats/dot/drawing.js +734 -0
  135. package/dist/src/formats/dot/drawing.js.map +1 -0
  136. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  137. package/dist/src/formats/dot/importer.js +108 -31
  138. package/dist/src/formats/dot/importer.js.map +1 -1
  139. package/dist/src/formats/dot/label-places.d.ts +34 -0
  140. package/dist/src/formats/dot/label-places.d.ts.map +1 -0
  141. package/dist/src/formats/dot/label-places.js +179 -0
  142. package/dist/src/formats/dot/label-places.js.map +1 -0
  143. package/dist/src/formats/dot/record.d.ts +50 -0
  144. package/dist/src/formats/dot/record.d.ts.map +1 -0
  145. package/dist/src/formats/dot/record.js +275 -0
  146. package/dist/src/formats/dot/record.js.map +1 -0
  147. package/dist/src/formats/dot/styles.d.ts +62 -2
  148. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  149. package/dist/src/formats/dot/styles.js +1454 -119
  150. package/dist/src/formats/dot/styles.js.map +1 -1
  151. package/dist/src/formats/gexf/dialog-metrics.d.ts +15 -0
  152. package/dist/src/formats/gexf/dialog-metrics.d.ts.map +1 -0
  153. package/dist/src/formats/gexf/dialog-metrics.js +59 -0
  154. package/dist/src/formats/gexf/dialog-metrics.js.map +1 -0
  155. package/dist/src/formats/gexf/importer.d.ts +7 -0
  156. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  157. package/dist/src/formats/gexf/importer.js +41 -5
  158. package/dist/src/formats/gexf/importer.js.map +1 -1
  159. package/dist/src/formats/gexf/preview.d.ts +77 -0
  160. package/dist/src/formats/gexf/preview.d.ts.map +1 -0
  161. package/dist/src/formats/gexf/preview.js +191 -0
  162. package/dist/src/formats/gexf/preview.js.map +1 -0
  163. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  164. package/dist/src/formats/gexf/schema.js +2 -1
  165. package/dist/src/formats/gexf/schema.js.map +1 -1
  166. package/dist/src/formats/gexf/styles.d.ts +58 -31
  167. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  168. package/dist/src/formats/gexf/styles.js +848 -225
  169. package/dist/src/formats/gexf/styles.js.map +1 -1
  170. package/dist/src/formats/gml/importer.d.ts +5 -2
  171. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  172. package/dist/src/formats/gml/importer.js +258 -71
  173. package/dist/src/formats/gml/importer.js.map +1 -1
  174. package/dist/src/formats/gml/index.d.ts +1 -1
  175. package/dist/src/formats/gml/index.d.ts.map +1 -1
  176. package/dist/src/formats/gml/index.js +1 -1
  177. package/dist/src/formats/gml/index.js.map +1 -1
  178. package/dist/src/formats/gml/positions.d.ts +7 -0
  179. package/dist/src/formats/gml/positions.d.ts.map +1 -1
  180. package/dist/src/formats/gml/positions.js +29 -7
  181. package/dist/src/formats/gml/positions.js.map +1 -1
  182. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  183. package/dist/src/formats/gml/styles.js +753 -101
  184. package/dist/src/formats/gml/styles.js.map +1 -1
  185. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  186. package/dist/src/formats/graphml/styles-plain.js +6 -10
  187. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  188. package/dist/src/formats/graphml/styles-yed.d.ts +21 -15
  189. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  190. package/dist/src/formats/graphml/styles-yed.js +692 -161
  191. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  192. package/dist/src/formats/graphml/styles-yfiles3.d.ts +1 -1
  193. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
  194. package/dist/src/formats/graphml/styles-yfiles3.js +429 -64
  195. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
  196. package/dist/src/formats/graphml/yfiles.d.ts +3 -3
  197. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  198. package/dist/src/formats/graphml/yfiles.js +16 -6
  199. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  200. package/dist/src/formats/json/dialect.d.ts +3 -2
  201. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  202. package/dist/src/formats/json/dialect.js +39 -5
  203. package/dist/src/formats/json/dialect.js.map +1 -1
  204. package/dist/src/formats/json/importer.d.ts +13 -2
  205. package/dist/src/formats/json/importer.d.ts.map +1 -1
  206. package/dist/src/formats/json/importer.js +42 -6
  207. package/dist/src/formats/json/importer.js.map +1 -1
  208. package/dist/src/formats/json/index.d.ts +1 -1
  209. package/dist/src/formats/json/index.d.ts.map +1 -1
  210. package/dist/src/formats/json/index.js +1 -1
  211. package/dist/src/formats/json/index.js.map +1 -1
  212. package/dist/src/formats/json/positions.d.ts +5 -2
  213. package/dist/src/formats/json/positions.d.ts.map +1 -1
  214. package/dist/src/formats/json/positions.js +20 -4
  215. package/dist/src/formats/json/positions.js.map +1 -1
  216. package/dist/src/formats/json/styles.d.ts +12 -1
  217. package/dist/src/formats/json/styles.d.ts.map +1 -1
  218. package/dist/src/formats/json/styles.js +1755 -136
  219. package/dist/src/formats/json/styles.js.map +1 -1
  220. package/dist/src/formats/pajek/draw.d.ts +96 -0
  221. package/dist/src/formats/pajek/draw.d.ts.map +1 -0
  222. package/dist/src/formats/pajek/draw.js +372 -0
  223. package/dist/src/formats/pajek/draw.js.map +1 -0
  224. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  225. package/dist/src/formats/pajek/exporter.js +70 -51
  226. package/dist/src/formats/pajek/exporter.js.map +1 -1
  227. package/dist/src/formats/pajek/importer.d.ts +9 -0
  228. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  229. package/dist/src/formats/pajek/importer.js +233 -102
  230. package/dist/src/formats/pajek/importer.js.map +1 -1
  231. package/dist/src/formats/pajek/index.d.ts +1 -0
  232. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  233. package/dist/src/formats/pajek/index.js.map +1 -1
  234. package/dist/src/formats/pajek/styles.d.ts +15 -7
  235. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  236. package/dist/src/formats/pajek/styles.js +1278 -114
  237. package/dist/src/formats/pajek/styles.js.map +1 -1
  238. package/dist/src/formats/pajek/syntax.d.ts +10 -1
  239. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  240. package/dist/src/formats/pajek/syntax.js +26 -2
  241. package/dist/src/formats/pajek/syntax.js.map +1 -1
  242. package/dist/src/formats/xgmml/emit.d.ts +1 -0
  243. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  244. package/dist/src/formats/xgmml/emit.js +65 -5
  245. package/dist/src/formats/xgmml/emit.js.map +1 -1
  246. package/dist/src/formats/xgmml/styles.d.ts +23 -3
  247. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  248. package/dist/src/formats/xgmml/styles.js +277 -60
  249. package/dist/src/formats/xgmml/styles.js.map +1 -1
  250. package/dist/src/index.d.ts +4 -3
  251. package/dist/src/index.d.ts.map +1 -1
  252. package/dist/src/index.js +4 -3
  253. package/dist/src/index.js.map +1 -1
  254. package/dist/src/positions/convert.d.ts.map +1 -1
  255. package/dist/src/positions/convert.js +11 -1
  256. package/dist/src/positions/convert.js.map +1 -1
  257. package/dist/src/positions/extract.d.ts.map +1 -1
  258. package/dist/src/positions/extract.js +53 -1
  259. package/dist/src/positions/extract.js.map +1 -1
  260. package/dist/src/positions/index.d.ts +1 -1
  261. package/dist/src/positions/index.d.ts.map +1 -1
  262. package/dist/src/positions/types.d.ts +59 -0
  263. package/dist/src/positions/types.d.ts.map +1 -1
  264. package/dist/src/sources/builtins.d.ts +1 -1
  265. package/dist/src/sources/builtins.d.ts.map +1 -1
  266. package/dist/src/sources/builtins.js +8 -2
  267. package/dist/src/sources/builtins.js.map +1 -1
  268. package/dist/src/sources/context.d.ts.map +1 -1
  269. package/dist/src/sources/context.js +1 -0
  270. package/dist/src/sources/context.js.map +1 -1
  271. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -1
  272. package/dist/src/sources/cypher/descriptor.js +5 -0
  273. package/dist/src/sources/cypher/descriptor.js.map +1 -1
  274. package/dist/src/sources/cypher/index.d.ts.map +1 -1
  275. package/dist/src/sources/cypher/index.js +124 -18
  276. package/dist/src/sources/cypher/index.js.map +1 -1
  277. package/dist/src/sources/cypher/params.d.ts +1 -1
  278. package/dist/src/sources/cypher/params.d.ts.map +1 -1
  279. package/dist/src/sources/cypher/query-builder.d.ts +17 -0
  280. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -1
  281. package/dist/src/sources/cypher/query-builder.js +31 -0
  282. package/dist/src/sources/cypher/query-builder.js.map +1 -1
  283. package/dist/src/sources/ids.d.ts +5 -0
  284. package/dist/src/sources/ids.d.ts.map +1 -1
  285. package/dist/src/sources/ids.js +5 -0
  286. package/dist/src/sources/ids.js.map +1 -1
  287. package/dist/src/sources/params.d.ts +3 -0
  288. package/dist/src/sources/params.d.ts.map +1 -1
  289. package/dist/src/sources/rest/descriptor.d.ts.map +1 -1
  290. package/dist/src/sources/rest/descriptor.js +5 -0
  291. package/dist/src/sources/rest/descriptor.js.map +1 -1
  292. package/dist/src/sources/rest/source.d.ts.map +1 -1
  293. package/dist/src/sources/rest/source.js +15 -0
  294. package/dist/src/sources/rest/source.js.map +1 -1
  295. package/dist/src/sources/sigv4.d.ts +5 -3
  296. package/dist/src/sources/sigv4.d.ts.map +1 -1
  297. package/dist/src/sources/sigv4.js +6 -4
  298. package/dist/src/sources/sigv4.js.map +1 -1
  299. package/dist/src/sources/sparql/descriptor.d.ts +10 -0
  300. package/dist/src/sources/sparql/descriptor.d.ts.map +1 -0
  301. package/dist/src/sources/sparql/descriptor.js +64 -0
  302. package/dist/src/sources/sparql/descriptor.js.map +1 -0
  303. package/dist/src/sources/sparql/index.d.ts +28 -0
  304. package/dist/src/sources/sparql/index.d.ts.map +1 -0
  305. package/dist/src/sources/sparql/index.js +314 -0
  306. package/dist/src/sources/sparql/index.js.map +1 -0
  307. package/dist/src/sources/sparql/ntriples.d.ts +69 -0
  308. package/dist/src/sources/sparql/ntriples.d.ts.map +1 -0
  309. package/dist/src/sources/sparql/ntriples.js +180 -0
  310. package/dist/src/sources/sparql/ntriples.js.map +1 -0
  311. package/dist/src/sources/sparql/params.d.ts +27 -0
  312. package/dist/src/sources/sparql/params.d.ts.map +1 -0
  313. package/dist/src/sources/sparql/params.js +5 -0
  314. package/dist/src/sources/sparql/params.js.map +1 -0
  315. package/dist/src/sources/sparql/query.d.ts +72 -0
  316. package/dist/src/sources/sparql/query.d.ts.map +1 -0
  317. package/dist/src/sources/sparql/query.js +113 -0
  318. package/dist/src/sources/sparql/query.js.map +1 -0
  319. package/dist/src/sources/types.d.ts +31 -0
  320. package/dist/src/sources/types.d.ts.map +1 -1
  321. package/dist/src/styles/annotations.d.ts +61 -5
  322. package/dist/src/styles/annotations.d.ts.map +1 -1
  323. package/dist/src/styles/annotations.js +130 -22
  324. package/dist/src/styles/annotations.js.map +1 -1
  325. package/dist/src/styles/canon/bends.d.ts +46 -0
  326. package/dist/src/styles/canon/bends.d.ts.map +1 -1
  327. package/dist/src/styles/canon/bends.js +123 -0
  328. package/dist/src/styles/canon/bends.js.map +1 -1
  329. package/dist/src/styles/canon/color-tables.d.ts +6 -1
  330. package/dist/src/styles/canon/color-tables.d.ts.map +1 -1
  331. package/dist/src/styles/canon/color-tables.js +10 -4
  332. package/dist/src/styles/canon/color-tables.js.map +1 -1
  333. package/dist/src/styles/canon/color.d.ts +3 -1
  334. package/dist/src/styles/canon/color.d.ts.map +1 -1
  335. package/dist/src/styles/canon/color.js +103 -3
  336. package/dist/src/styles/canon/color.js.map +1 -1
  337. package/dist/src/styles/canon/enums.d.ts +2 -2
  338. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  339. package/dist/src/styles/canon/enums.js +81 -7
  340. package/dist/src/styles/canon/enums.js.map +1 -1
  341. package/dist/src/styles/canon/graphviz.d.ts +12 -3
  342. package/dist/src/styles/canon/graphviz.d.ts.map +1 -1
  343. package/dist/src/styles/canon/graphviz.js +57 -9
  344. package/dist/src/styles/canon/graphviz.js.map +1 -1
  345. package/dist/src/styles/canon/number.d.ts +8 -0
  346. package/dist/src/styles/canon/number.d.ts.map +1 -1
  347. package/dist/src/styles/canon/number.js +18 -0
  348. package/dist/src/styles/canon/number.js.map +1 -1
  349. package/dist/src/styles/canon/text.d.ts +29 -2
  350. package/dist/src/styles/canon/text.d.ts.map +1 -1
  351. package/dist/src/styles/canon/text.js +156 -16
  352. package/dist/src/styles/canon/text.js.map +1 -1
  353. package/dist/src/styles/codes.d.ts +2 -0
  354. package/dist/src/styles/codes.d.ts.map +1 -1
  355. package/dist/src/styles/codes.js +2 -0
  356. package/dist/src/styles/codes.js.map +1 -1
  357. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  358. package/dist/src/styles/cyjs/cascade.js +1015 -79
  359. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  360. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  361. package/dist/src/styles/cyjs/defaults-table.js +3 -0
  362. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  363. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  364. package/dist/src/styles/cyjs/emit.js +202 -9
  365. package/dist/src/styles/cyjs/emit.js.map +1 -1
  366. package/dist/src/styles/cyjs/face.d.ts +20 -0
  367. package/dist/src/styles/cyjs/face.d.ts.map +1 -0
  368. package/dist/src/styles/cyjs/face.js +332 -0
  369. package/dist/src/styles/cyjs/face.js.map +1 -0
  370. package/dist/src/styles/cyjs/mappers.d.ts +44 -1
  371. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  372. package/dist/src/styles/cyjs/mappers.js +461 -26
  373. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  374. package/dist/src/styles/cyjs/routes.d.ts +53 -0
  375. package/dist/src/styles/cyjs/routes.d.ts.map +1 -0
  376. package/dist/src/styles/cyjs/routes.js +360 -0
  377. package/dist/src/styles/cyjs/routes.js.map +1 -0
  378. package/dist/src/styles/cytoscape/charts.d.ts +23 -0
  379. package/dist/src/styles/cytoscape/charts.d.ts.map +1 -0
  380. package/dist/src/styles/cytoscape/charts.js +560 -0
  381. package/dist/src/styles/cytoscape/charts.js.map +1 -0
  382. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  383. package/dist/src/styles/cytoscape/emit.js +156 -48
  384. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  385. package/dist/src/styles/cytoscape/lexicon.d.ts +91 -3
  386. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  387. package/dist/src/styles/cytoscape/lexicon.js +387 -77
  388. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  389. package/dist/src/styles/cytoscape/mappings.d.ts +30 -0
  390. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -1
  391. package/dist/src/styles/cytoscape/mappings.js +92 -0
  392. package/dist/src/styles/cytoscape/mappings.js.map +1 -1
  393. package/dist/src/styles/cytoscape/resolve.d.ts +42 -2
  394. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  395. package/dist/src/styles/cytoscape/resolve.js +623 -17
  396. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  397. package/dist/src/styles/defaults.d.ts +46 -26
  398. package/dist/src/styles/defaults.d.ts.map +1 -1
  399. package/dist/src/styles/defaults.js +308 -71
  400. package/dist/src/styles/defaults.js.map +1 -1
  401. package/dist/src/styles/index.d.ts +4 -3
  402. package/dist/src/styles/index.d.ts.map +1 -1
  403. package/dist/src/styles/index.js +3 -2
  404. package/dist/src/styles/index.js.map +1 -1
  405. package/dist/src/styles/internal.d.ts +1 -0
  406. package/dist/src/styles/internal.d.ts.map +1 -1
  407. package/dist/src/styles/internal.js +1 -0
  408. package/dist/src/styles/internal.js.map +1 -1
  409. package/dist/src/styles/io/generic.d.ts.map +1 -1
  410. package/dist/src/styles/io/generic.js +56 -16
  411. package/dist/src/styles/io/generic.js.map +1 -1
  412. package/dist/src/styles/io/round-trip.d.ts +56 -0
  413. package/dist/src/styles/io/round-trip.d.ts.map +1 -0
  414. package/dist/src/styles/io/round-trip.js +138 -0
  415. package/dist/src/styles/io/round-trip.js.map +1 -0
  416. package/dist/src/styles/io/writer.d.ts.map +1 -1
  417. package/dist/src/styles/io/writer.js +6 -1
  418. package/dist/src/styles/io/writer.js.map +1 -1
  419. package/dist/src/styles/notes.d.ts.map +1 -1
  420. package/dist/src/styles/notes.js +1 -0
  421. package/dist/src/styles/notes.js.map +1 -1
  422. package/dist/src/styles/plan/features.d.ts +1 -1
  423. package/dist/src/styles/plan/features.d.ts.map +1 -1
  424. package/dist/src/styles/plan/features.js +22 -2
  425. package/dist/src/styles/plan/features.js.map +1 -1
  426. package/dist/src/styles/plan/index.d.ts +1 -1
  427. package/dist/src/styles/plan/index.d.ts.map +1 -1
  428. package/dist/src/styles/plan/index.js +1 -1
  429. package/dist/src/styles/plan/index.js.map +1 -1
  430. package/dist/src/styles/plan/plan.d.ts.map +1 -1
  431. package/dist/src/styles/plan/plan.js +61 -4
  432. package/dist/src/styles/plan/plan.js.map +1 -1
  433. package/dist/src/styles/plan/resolve.d.ts +11 -0
  434. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  435. package/dist/src/styles/plan/resolve.js +40 -4
  436. package/dist/src/styles/plan/resolve.js.map +1 -1
  437. package/dist/src/styles/slots.d.ts +14 -0
  438. package/dist/src/styles/slots.d.ts.map +1 -0
  439. package/dist/src/styles/slots.js +20 -0
  440. package/dist/src/styles/slots.js.map +1 -0
  441. package/dist/src/styles/types.d.ts +622 -6
  442. package/dist/src/styles/types.d.ts.map +1 -1
  443. package/dist/src/styles/vocabulary.d.ts +3 -2
  444. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  445. package/dist/src/styles/vocabulary.js +203 -0
  446. package/dist/src/styles/vocabulary.js.map +1 -1
  447. package/dist/styles.js +30 -239
  448. package/dist/styles.js.map +1 -1
  449. package/dist/xgmml.js +3 -3
  450. package/package.json +27 -7
  451. package/src/formats/cx/importer.ts +6 -1
  452. package/src/formats/cx/styles.ts +143 -9
  453. package/src/formats/cx2/importer.ts +1 -0
  454. package/src/formats/cx2/styles.ts +3 -1
  455. package/src/formats/cys/importer.ts +1 -0
  456. package/src/formats/cys/styles.ts +27 -5
  457. package/src/formats/dot/drawing.ts +799 -0
  458. package/src/formats/dot/importer.ts +120 -35
  459. package/src/formats/dot/label-places.ts +228 -0
  460. package/src/formats/dot/record.ts +336 -0
  461. package/src/formats/dot/styles.ts +1654 -153
  462. package/src/formats/gexf/dialog-metrics.ts +61 -0
  463. package/src/formats/gexf/importer.ts +50 -5
  464. package/src/formats/gexf/preview.ts +217 -0
  465. package/src/formats/gexf/schema.ts +2 -1
  466. package/src/formats/gexf/styles.ts +1099 -245
  467. package/src/formats/gml/importer.ts +291 -76
  468. package/src/formats/gml/index.ts +1 -1
  469. package/src/formats/gml/positions.ts +29 -7
  470. package/src/formats/gml/styles.ts +851 -109
  471. package/src/formats/graphml/styles-plain.ts +6 -15
  472. package/src/formats/graphml/styles-yed.ts +762 -173
  473. package/src/formats/graphml/styles-yfiles3.ts +485 -63
  474. package/src/formats/graphml/yfiles.ts +19 -6
  475. package/src/formats/json/dialect.ts +41 -5
  476. package/src/formats/json/importer.ts +59 -7
  477. package/src/formats/json/index.ts +1 -0
  478. package/src/formats/json/positions.ts +22 -5
  479. package/src/formats/json/styles.ts +2041 -185
  480. package/src/formats/pajek/draw.ts +458 -0
  481. package/src/formats/pajek/exporter.ts +81 -49
  482. package/src/formats/pajek/importer.ts +278 -103
  483. package/src/formats/pajek/index.ts +1 -0
  484. package/src/formats/pajek/styles.ts +1381 -133
  485. package/src/formats/pajek/syntax.ts +27 -2
  486. package/src/formats/xgmml/emit.ts +73 -5
  487. package/src/formats/xgmml/styles.ts +330 -71
  488. package/src/index.ts +5 -1
  489. package/src/positions/convert.ts +12 -1
  490. package/src/positions/extract.ts +55 -1
  491. package/src/positions/index.ts +1 -0
  492. package/src/positions/types.ts +60 -0
  493. package/src/sources/builtins.ts +8 -1
  494. package/src/sources/context.ts +1 -0
  495. package/src/sources/cypher/descriptor.ts +7 -1
  496. package/src/sources/cypher/index.ts +148 -18
  497. package/src/sources/cypher/params.ts +1 -1
  498. package/src/sources/cypher/query-builder.ts +33 -0
  499. package/src/sources/ids.ts +6 -0
  500. package/src/sources/params.ts +3 -0
  501. package/src/sources/rest/descriptor.ts +5 -0
  502. package/src/sources/rest/source.ts +16 -0
  503. package/src/sources/sigv4.ts +6 -4
  504. package/src/sources/sparql/descriptor.ts +67 -0
  505. package/src/sources/sparql/index.ts +356 -0
  506. package/src/sources/sparql/ntriples.ts +219 -0
  507. package/src/sources/sparql/params.ts +28 -0
  508. package/src/sources/sparql/query.ts +162 -0
  509. package/src/sources/types.ts +35 -0
  510. package/src/styles/annotations.ts +201 -27
  511. package/src/styles/canon/bends.ts +137 -0
  512. package/src/styles/canon/color-tables.ts +10 -4
  513. package/src/styles/canon/color.ts +105 -3
  514. package/src/styles/canon/enums.ts +98 -8
  515. package/src/styles/canon/graphviz.ts +71 -10
  516. package/src/styles/canon/number.ts +19 -0
  517. package/src/styles/canon/text.ts +187 -16
  518. package/src/styles/codes.ts +2 -0
  519. package/src/styles/cyjs/cascade.ts +1160 -84
  520. package/src/styles/cyjs/defaults-table.ts +3 -0
  521. package/src/styles/cyjs/emit.ts +233 -13
  522. package/src/styles/cyjs/face.ts +372 -0
  523. package/src/styles/cyjs/mappers.ts +492 -27
  524. package/src/styles/cyjs/routes.ts +432 -0
  525. package/src/styles/cytoscape/charts.ts +684 -0
  526. package/src/styles/cytoscape/emit.ts +170 -48
  527. package/src/styles/cytoscape/lexicon.ts +431 -78
  528. package/src/styles/cytoscape/mappings.ts +108 -0
  529. package/src/styles/cytoscape/resolve.ts +741 -17
  530. package/src/styles/defaults.ts +417 -108
  531. package/src/styles/index.ts +5 -0
  532. package/src/styles/internal.ts +1 -0
  533. package/src/styles/io/generic.ts +79 -23
  534. package/src/styles/io/round-trip.ts +202 -0
  535. package/src/styles/io/writer.ts +6 -1
  536. package/src/styles/notes.ts +1 -0
  537. package/src/styles/plan/features.ts +23 -2
  538. package/src/styles/plan/index.ts +1 -1
  539. package/src/styles/plan/plan.ts +69 -5
  540. package/src/styles/plan/resolve.ts +47 -4
  541. package/src/styles/slots.ts +25 -0
  542. package/src/styles/types.ts +633 -5
  543. package/src/styles/vocabulary.ts +211 -2
  544. package/dist/chunks/block-Cu22ewuS.js.map +0 -1
  545. package/dist/chunks/choose-Cdx6Enl2.js +0 -57
  546. package/dist/chunks/choose-Cdx6Enl2.js.map +0 -1
  547. package/dist/chunks/codes-CV_Bhcyi.js.map +0 -1
  548. package/dist/chunks/convert-BcQ8_jMo.js.map +0 -1
  549. package/dist/chunks/credentials-BiQsnMTb.js.map +0 -1
  550. package/dist/chunks/descriptor-BJ-W0Jd-.js.map +0 -1
  551. package/dist/chunks/emit-CD8xnY8s.js.map +0 -1
  552. package/dist/chunks/export-CZ7VRm4I.js.map +0 -1
  553. package/dist/chunks/exporter-bxxjOrDZ.js.map +0 -1
  554. package/dist/chunks/format-BMS-1Nxb.js +0 -64
  555. package/dist/chunks/format-BMS-1Nxb.js.map +0 -1
  556. package/dist/chunks/generic-CP6YD34u.js.map +0 -1
  557. package/dist/chunks/importer-B87_fmVx.js.map +0 -1
  558. package/dist/chunks/importer-CB_zV5_L.js.map +0 -1
  559. package/dist/chunks/importer-CVT-JyDE.js.map +0 -1
  560. package/dist/chunks/importer-Cyy6UseH.js.map +0 -1
  561. package/dist/chunks/importer-DPZDN40-.js.map +0 -1
  562. package/dist/chunks/importer-e3huMZbm.js.map +0 -1
  563. package/dist/chunks/lexicon-u2SI5xcx.js.map +0 -1
  564. package/dist/chunks/sigv4-LkAzsLAu.js.map +0 -1
  565. package/dist/chunks/styles-CaABMoO1.js.map +0 -1
  566. package/dist/chunks/styles-P_gmFAOi.js +0 -770
  567. package/dist/chunks/styles-P_gmFAOi.js.map +0 -1
  568. package/dist/chunks/styles-yed-Cs1nmrjn.js.map +0 -1
  569. package/dist/chunks/writer-DvHTl36J.js +0 -449
  570. package/dist/chunks/writer-DvHTl36J.js.map +0 -1
@@ -471,7 +471,7 @@ export function isIntervalToken(token: string): boolean {
471
471
  }
472
472
 
473
473
  /**
474
- * Parse a Pajek time interval token into spells: `[1-5,7-*]` is `[[1, 5], [7, Infinity]]`, a
474
+ * Parse a Pajek time interval token into spells: `[1-5,7-*]` (or `[1-5/7-*]`) is `[[1, 5], [7, Infinity]]`, a
475
475
  * single time point `[3]` is `[[3, 3]]`, `*` at either end is the corresponding infinity, blanks
476
476
  * around the parts are ignored and an empty `[]` is no spell at all.
477
477
  * @param token - a token isIntervalToken() accepted
@@ -484,7 +484,9 @@ export function parseIntervals(token: string): [number, number][] {
484
484
  return [];
485
485
  }
486
486
  const spells: [number, number][] = [];
487
- for (const part of body.split(",")) {
487
+ // the manual separates intervals with ","; Pajek's own course data writes "/" too (lin-rel4.net:
488
+ // `[141-383/669-670]`), which no other part of the token uses
489
+ for (const part of body.split(/[,/]/)) {
488
490
  spells.push(parseSpell(token, part));
489
491
  }
490
492
  return spells;
@@ -609,3 +611,26 @@ export function isParameterKey(text: string): boolean {
609
611
  // a number, or a non-finite spelling, at that place reads as a coordinate or the line value
610
612
  return !/^[+-]?(\.\d|\d)/.test(text) && !/^[+-]?(?:nan|inf|infinity)$/i.test(text);
611
613
  }
614
+
615
+ /**
616
+ * The vertex parameters that, written first on a vertex line that names no shape, make Pajek 6.02 draw the line with
617
+ * none of its parameters (`s_size 2 ic Red`, `bw 3 ic Blue`: a vertex of the default size and colors); a line that
618
+ * starts with `ic`, `x_fact` or `y_fact` is read whole. Probed in Pajek 6.02's SVG export one key at a time
619
+ * (`pajek-specimen-node-sizes-opacity` `s-size-no-shape`; the probe files of the third fix round). ponytail: probed
620
+ * on lines with coordinates only; a line without them, or one that starts with a key Pajek does not know, is read
621
+ * as written.
622
+ */
623
+ export const VOIDING_KEYS: ReadonlySet<string> = new Set([
624
+ "bc",
625
+ "bw",
626
+ "s_size",
627
+ "phi",
628
+ "r",
629
+ "q",
630
+ "lc",
631
+ "la",
632
+ "lr",
633
+ "lphi",
634
+ "fos",
635
+ "font",
636
+ ]);
@@ -449,7 +449,7 @@ export class XgmmlEmitter {
449
449
  }
450
450
  const containment = new Containment(this);
451
451
  containment.resolve(this.rowList, this.groupTest());
452
- this.writeNodeExtras(graph);
452
+ this.writeNodeExtras(graph, (index) => containment.parentsOf(index));
453
453
  this.addEdges(members.edges, header);
454
454
  this.finishAliases();
455
455
  this.writeGraph(graph);
@@ -815,8 +815,9 @@ export class XgmmlEmitter {
815
815
  * Write the per-node values: label, attributes, XML attributes, graphics, positions, nested
816
816
  * network pointers and subgraph memberships.
817
817
  * @param graph - the subnetwork, or null
818
+ * @param parentsOf - each node's group nodes, by node index
818
819
  */
819
- private writeNodeExtras(graph: GraphRec | null): void {
820
+ private writeNodeExtras(graph: GraphRec | null, parentsOf: (index: number) => readonly number[]): void {
820
821
  const labels: (string | undefined)[] = [];
821
822
  const positions = new Positions(this, this.dialect.cytoscape ? this.settings.zAs : "position");
822
823
  const graphics = new JsonColumn(this, "node", GRAPHICS_COLUMN, XGMML_ORIGIN_NAMESPACE, "graphics");
@@ -840,7 +841,7 @@ export class XgmmlEmitter {
840
841
  this.checkAbort();
841
842
  }
842
843
  this.writeLabels("node", labels, (row) => this.rowList[row].index);
843
- positions.write();
844
+ positions.write(parentsOf);
844
845
  pointers.write();
845
846
  if (graph === null) {
846
847
  this.writeNetworks();
@@ -1440,6 +1441,9 @@ class JsonColumn {
1440
1441
  class Positions {
1441
1442
  private readonly values = new Map<number, [number, number, number]>();
1442
1443
 
1444
+ /** Cytoscape's stored group locations by node index: per group network, a group's center or a member's offset. */
1445
+ private readonly locations = new Map<number, Map<string, [number, number]>>();
1446
+
1443
1447
  private readonly zValues = new Map<number, number>();
1444
1448
 
1445
1449
  private hasZ = false;
@@ -1460,6 +1464,12 @@ class Positions {
1460
1464
  * @param record - the record
1461
1465
  */
1462
1466
  add(row: NodeRow, record: NodeRec): void {
1467
+ // a member stores its offset in its own atts, a group its center in its nested graph's
1468
+ const locations =
1469
+ row.index < 0 ? null : groupLocations([...record.atts, ...record.nested.flatMap((g) => g.atts)]);
1470
+ if (locations !== null) {
1471
+ this.locations.set(row.index, locations);
1472
+ }
1463
1473
  if (row.index < 0 || (record.x === null && record.y === null && record.z === null)) {
1464
1474
  return;
1465
1475
  }
@@ -1501,8 +1511,34 @@ class Positions {
1501
1511
  return n;
1502
1512
  }
1503
1513
 
1504
- /** Declare and write the position and z columns. */
1505
- write(): void {
1514
+ /**
1515
+ * Places the members of a collapsed Cytoscape group, which the file stores with no coordinates of their own, where
1516
+ * Cytoscape puts them when the group is expanded: the group's stored center in that group network plus the
1517
+ * member's stored offset (`__xLocation`, `__yLocation`, per `__groupNetworks.SUID`).
1518
+ * @param parentsOf - each node's group nodes, by node index
1519
+ */
1520
+ private followGroups(parentsOf: (index: number) => readonly number[]): void {
1521
+ for (const [index, own] of this.locations) {
1522
+ if (this.values.has(index)) {
1523
+ continue;
1524
+ }
1525
+ const at = parentsOf(index)
1526
+ .flatMap((p) =>
1527
+ [...own].map(([network, [dx, dy]]) => ({ center: this.locations.get(p)?.get(network), dx, dy })),
1528
+ )
1529
+ .find((c) => c.center !== undefined);
1530
+ if (at?.center !== undefined) {
1531
+ this.values.set(index, [at.center[0] + at.dx, flipY(at.center[1] + at.dy), 0]);
1532
+ }
1533
+ }
1534
+ }
1535
+
1536
+ /**
1537
+ * Declare and write the position and z columns.
1538
+ * @param parentsOf - each node's group nodes, by node index
1539
+ */
1540
+ write(parentsOf: (index: number) => readonly number[]): void {
1541
+ this.followGroups(parentsOf);
1506
1542
  const sink = this.emitter.target;
1507
1543
  if (this.values.size > 0) {
1508
1544
  const handle = this.emitter.declare("node", {
@@ -1542,6 +1578,29 @@ class Positions {
1542
1578
  }
1543
1579
  }
1544
1580
 
1581
+ /**
1582
+ * A node's stored Cytoscape group locations: `__xLocation` and `__yLocation` lists, item by item, keyed by the group
1583
+ * network `__groupNetworks.SUID` names at the same index.
1584
+ * @param atts - the node's atts
1585
+ * @returns network to location, or null when the node stores none
1586
+ */
1587
+ function groupLocations(atts: readonly AttRec[]): Map<string, [number, number]> | null {
1588
+ const list = (name: string): (string | null)[] =>
1589
+ atts.find((a) => a.name === name)?.children.map((c) => c.value) ?? [];
1590
+ const networks = list("__groupNetworks.SUID");
1591
+ const xs = list("__xLocation");
1592
+ const ys = list("__yLocation");
1593
+ const out = new Map<string, [number, number]>();
1594
+ networks.forEach((network, i) => {
1595
+ const x = Number(xs[i] ?? Number.NaN);
1596
+ const y = Number(ys[i] ?? Number.NaN);
1597
+ if (network !== null && Number.isFinite(x) && Number.isFinite(y)) {
1598
+ out.set(network, [x, y]);
1599
+ }
1600
+ });
1601
+ return out.size > 0 ? out : null;
1602
+ }
1603
+
1545
1604
  /**
1546
1605
  * Nested-network pointers: a node-nested graph that is not a group names a network.
1547
1606
  */
@@ -1751,6 +1810,15 @@ class Containment {
1751
1810
  return false;
1752
1811
  }
1753
1812
 
1813
+ /**
1814
+ * A node's group nodes.
1815
+ * @param index - the node's index
1816
+ * @returns the group nodes' indices
1817
+ */
1818
+ parentsOf(index: number): readonly number[] {
1819
+ return this.parents.get(index) ?? [];
1820
+ }
1821
+
1754
1822
  /** Declare and write the parent (or parents) and subgraph columns. */
1755
1823
  write(): void {
1756
1824
  const sink = this.emitter.target;
@@ -7,6 +7,7 @@
7
7
 
8
8
  import type { GraphSnapshot } from "@graphty/graph-format";
9
9
 
10
+ import { type BendPoint, canonBends } from "../../styles/canon/bends.js";
10
11
  import { STYLE_ISSUE } from "../../styles/codes.js";
11
12
  import {
12
13
  type CytoscapeDialect,
@@ -14,13 +15,19 @@ import {
14
15
  cytoscapeWritableProperties,
15
16
  } from "../../styles/cytoscape/emit.js";
16
17
  import { normalizeVisualProperties } from "../../styles/cytoscape/lexicon.js";
17
- import { emptyCytoscapeStyle } from "../../styles/cytoscape/mappings.js";
18
- import { cytoscapeBackground, type CytoscapeBypass, resolveCytoscapeBypasses } from "../../styles/cytoscape/resolve.js";
19
- import { blockStyles, parseStyleBlock, STYLE_BLOCK_NAME } from "../../styles/io/block.js";
18
+ import { type CytoscapeStyle, emptyCytoscapeStyle } from "../../styles/cytoscape/mappings.js";
19
+ import {
20
+ cytoscapeBackground,
21
+ type CytoscapeBypass,
22
+ type CytoscapeElements,
23
+ edgeEnds,
24
+ resolveCytoscapeBypasses,
25
+ } from "../../styles/cytoscape/resolve.js";
26
+ import { STYLE_BLOCK_NAME } from "../../styles/io/block.js";
27
+ import { takeFromBlock } from "../../styles/io/round-trip.js";
20
28
  import type { ExporterStyleInput } from "../../styles/io/writer.js";
21
29
  import { StyleNotes } from "../../styles/notes.js";
22
- import { styleFingerprint } from "../../styles/plan/features.js";
23
- import { plainCell, resolveStyles } from "../../styles/plan/resolve.js";
30
+ import { plainCell } from "../../styles/plan/resolve.js";
24
31
  import type {
25
32
  EdgeStyleProperty,
26
33
  GraphStyle,
@@ -37,7 +44,7 @@ import type {
37
44
  } from "../../styles/types.js";
38
45
  import type { LossNote } from "../../types.js";
39
46
  import { lossOf } from "../cx/styles.js";
40
- import { GRAPHICS_COLUMN, XGMML_ORIGIN_NAMESPACE } from "./constants.js";
47
+ import { GRAPHICS_COLUMN, SUBGRAPH_COLUMN, XGMML_ORIGIN_NAMESPACE } from "./constants.js";
41
48
 
42
49
  type Table = GraphSnapshot["nodes"];
43
50
 
@@ -118,9 +125,14 @@ export function readXgmmlStyles(
118
125
  const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
119
126
  const maps = graphicsBypasses(table, target, n, notes);
120
127
  const values = maps.some((m) => m !== null)
121
- ? resolveCytoscapeBypasses(target, maps, { notes, budget: context.budget })
128
+ ? resolveCytoscapeBypasses(target, maps, {
129
+ notes,
130
+ budget: context.budget,
131
+ value: (column, i) => (table.has(column) ? plainCell(table.value(column, i)) : null),
132
+ ...(target === "edge" ? { ends: edgeEnds(snapshot, out.node.values) } : {}),
133
+ })
122
134
  : {};
123
- hiddenToVisible(table, settings.hiddenColumn ?? null, n, values);
135
+ drawnAsDesktop(snapshot, target, out.node.values, values, settings);
124
136
  exactFromBlock(snapshot, target, values);
125
137
  out[target] = { values: nonEmpty(values) };
126
138
  }
@@ -136,6 +148,95 @@ export function readXgmmlStyles(
136
148
  };
137
149
  }
138
150
 
151
+ /**
152
+ * What Cytoscape desktop draws of an XGMML file's resolved values: hidden elements, the groups it hides and the
153
+ * edges of every node it does not draw not visible, nodes with no label labeled by their names, and edge bends at the
154
+ * network origin.
155
+ * @param snapshot - the graph
156
+ * @param target - nodes or edges
157
+ * @param nodes - the node values per property (read for edges)
158
+ * @param values - the values per property, changed in place
159
+ * @param settings - the tool and the hidden-state column
160
+ */
161
+ function drawnAsDesktop(
162
+ snapshot: GraphSnapshot,
163
+ target: StyleTarget,
164
+ nodes: Partial<Record<string, StyleColumn>>,
165
+ values: Partial<Record<string, StyleColumn>>,
166
+ settings: XgmmlStyleSettings,
167
+ ): void {
168
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
169
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
170
+ const desktop = settings.tool === "cytoscape";
171
+ if (target === "edge" && desktop) {
172
+ bendsAtOrigin(snapshot, values);
173
+ }
174
+ hiddenToVisible(table, settings.hiddenColumn ?? null, n, values);
175
+ hideWhatCytoscapeHides(snapshot, target, nodes, values);
176
+ if (target === "node") {
177
+ if (desktop && values.label === undefined && !snapshot.graph.has(STYLE_BLOCK_NAME)) {
178
+ nameLabels(table, n, values);
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Every bend of an edge where Cytoscape desktop draws it from an XGMML file: at the network's origin. Its XGMML reader
185
+ * turns each `EDGE_BEND` handle (`cos,sin,ratio`, relative to the line between the two nodes) into a point while
186
+ * every node is still at the origin and keeps that point, so each handle of each edge is drawn at (0, 0) of the
187
+ * network, wherever the nodes then go (measured on Cytoscape 3.10.5's own SVG of an XGMML file with handles; its CX
188
+ * reader places the same handles along their lines). An edge whose nodes have no position keeps its handles.
189
+ * @param snapshot - the graph
190
+ * @param values - the edge values per property, changed in place
191
+ */
192
+ function bendsAtOrigin(snapshot: GraphSnapshot, values: Partial<Record<string, StyleColumn>>): void {
193
+ const { bends } = values;
194
+ const position = snapshot.nodes.byRole("position");
195
+ if (bends === undefined || position === null) {
196
+ return;
197
+ }
198
+ const center = (i: number): BendPoint | null => {
199
+ const v = position.isSet(i) ? (position.value(i) as ArrayLike<number>) : null;
200
+ return v === null ? null : [v[0], v[1]];
201
+ };
202
+ const { src, dst } = snapshot.edgeList();
203
+ values.bends = bends.map((v, e) => {
204
+ const [s, t] = [center(src[e]), center(dst[e])];
205
+ if (typeof v !== "string" || s === null || t === null) {
206
+ return v;
207
+ }
208
+ const handles = v.trim().split(/\s+/).length;
209
+ return (
210
+ canonBends(
211
+ s,
212
+ t,
213
+ Array.from({ length: handles }, (): BendPoint => [0, 0]),
214
+ false,
215
+ ) ?? v
216
+ );
217
+ });
218
+ }
219
+
220
+ /**
221
+ * The labels Cytoscape shows for nodes whose graphics state none: its default style labels a node by its name, and
222
+ * a node with no `name` att is named by its `label=` (Cytoscape 2.x files often carry only that). Not for a file
223
+ * graphty wrote: its block says what to draw.
224
+ * @param table - the node table
225
+ * @param n - the node count
226
+ * @param values - the values per property, changed in place
227
+ */
228
+ function nameLabels(table: Table, n: number, values: Partial<Record<string, StyleColumn>>): void {
229
+ const label = table.byRole("label")?.meta.name ?? null;
230
+ const text = (column: string | null, i: number): string | null => {
231
+ const v = column !== null && table.has(column) ? plainCell(table.value(column, i)) : null;
232
+ return typeof v === "string" || typeof v === "number" ? String(v) : null;
233
+ };
234
+ const labels = Array.from({ length: n }, (_v, i) => text("name", i) ?? text(label, i));
235
+ if (labels.some((v) => v !== null)) {
236
+ values.label = labels;
237
+ }
238
+ }
239
+
139
240
  /**
140
241
  * The styles of an XGMML file: its elements' resolved values, with Cytoscape desktop's default style beneath.
141
242
  * @param snapshot - the graph
@@ -155,71 +256,71 @@ export function readXgmmlFileStyles(snapshot: GraphSnapshot, context: StyleReadC
155
256
  * @param target - nodes or edges
156
257
  * @param values - the values per property, changed in place
157
258
  * @param dialect - the Cytoscape dialect the file's values are written in
259
+ * @param created - the order desktop creates the elements in, when the file is read with it (CX version 1)
158
260
  */
159
261
  export function exactFromBlock(
160
262
  snapshot: GraphSnapshot,
161
263
  target: StyleTarget,
162
264
  values: Partial<Record<string, StyleColumn>>,
163
265
  dialect: CytoscapeDialect = "desktop",
266
+ created?: NonNullable<CytoscapeElements["ends"]>["created"],
164
267
  ): void {
165
268
  const text = snapshot.graph.has(STYLE_BLOCK_NAME) ? plainCell(snapshot.graph.value(STYLE_BLOCK_NAME, 0)) : null;
166
269
  if (typeof text !== "string") {
167
270
  return;
168
271
  }
169
- const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
170
- const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "xgmml") : null;
171
- if (ex === null) {
172
- return;
173
- }
174
- const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
175
- const want = new Map<string, readonly (StyleValue | null)[]>();
176
- const exact = (property: string): readonly (StyleValue | null)[] => {
177
- let held = want.get(property);
178
- if (held === undefined) {
179
- held = resolveStyles(ex, target, property as StyleProperty, snapshot);
180
- want.set(property, held);
272
+ takeFromBlock(snapshot, text, "xgmml", (t, block) => {
273
+ if (t !== target) {
274
+ return null;
181
275
  }
182
- return held;
183
- };
184
- // What each element's exact values are written as, read back the way the file is read.
185
- const written = Array.from({ length: n }, (_v, i) =>
186
- cytoscapeElementProperties(
187
- target,
188
- (property) => exact(property)[i] ?? null,
189
- dialect,
190
- () => undefined,
191
- ),
192
- );
193
- const readBack = resolveCytoscapeBypasses(target, written, { notes: new StyleNotes() });
194
- for (const [property, native] of Object.entries(values)) {
195
- const back = readBack[property];
196
- if (native !== undefined && back !== undefined) {
197
- values[property] = withBlockValues(native, back, exact(property));
198
- }
199
- }
276
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
277
+ // What each element's exact values are written as, read back the way the file is read.
278
+ const written = Array.from({ length: n }, (_v, i) =>
279
+ cytoscapeElementProperties(
280
+ target,
281
+ (property) => block(target, property)[i] ?? null,
282
+ dialect,
283
+ () => undefined,
284
+ ),
285
+ );
286
+ // Desktop fans the curved edges between the same two nodes by the nodes' size, as the file is read
287
+ const ends =
288
+ target === "edge"
289
+ ? {
290
+ ends: {
291
+ ...edgeEnds(snapshot, {
292
+ width: block("node", "width"),
293
+ height: block("node", "height"),
294
+ borderWidth: block("node", "borderWidth"),
295
+ }),
296
+ ...(created === undefined ? {} : { created }),
297
+ },
298
+ }
299
+ : {};
300
+ const readBack = resolveCytoscapeBypasses(target, written, { notes: new StyleNotes(), ...ends });
301
+ return {
302
+ values,
303
+ properties: Object.keys(values).filter((p) => values[p] !== undefined && readBack[p] !== undefined),
304
+ readBack: (i) => (property) => readBack[property]?.[i] ?? null,
305
+ // a fan spacing, a curve or a loop's handles only desktop's fanning and looping give (graphty wrote none:
306
+ // EDGE_CURVED defaults to true there) is graphty's own default again, and so is a label's place beside its
307
+ // node, which desktop's anchors spell as an offset and a shift
308
+ take: (property, wanted) => wanted !== null || BLOCK_DEFAULTED.has(property),
309
+ };
310
+ });
200
311
  }
201
312
 
202
- /**
203
- * A property's values with the block's exact value wherever the file's value is what the writer wrote for it.
204
- * @param native - the file's values
205
- * @param back - what the writer wrote for the block's values, read back
206
- * @param w - the block's values
207
- * @returns the values, the file's own array when none changes
208
- */
209
- function withBlockValues(
210
- native: StyleColumn,
211
- back: readonly (StyleValue | null)[],
212
- w: readonly (StyleValue | null)[],
213
- ): StyleColumn {
214
- let changed: (StyleValue | null)[] | null = null;
215
- for (let i = 0; i < native.length; i++) {
216
- if (w[i] !== null && native[i] !== w[i] && native[i] === back[i]) {
217
- changed ??= [...native];
218
- changed[i] = w[i];
219
- }
220
- }
221
- return changed ?? native;
222
- }
313
+ /** What a file graphty wrote leaves unset where Cytoscape's reading of it gives a value. */
314
+ const BLOCK_DEFAULTED: ReadonlySet<string> = new Set([
315
+ "fanSpacing",
316
+ "curved",
317
+ "bends",
318
+ "bendCurve",
319
+ "labelOffsetX",
320
+ "labelOffsetY",
321
+ "labelShiftX",
322
+ "labelShiftY",
323
+ ]);
223
324
 
224
325
  /**
225
326
  * Marks the elements a hidden-state column holds true as not visible.
@@ -249,6 +350,145 @@ export function hiddenToVisible(
249
350
  }
250
351
  }
251
352
 
353
+ /**
354
+ * Marks not visible what Cytoscape does not draw of its groups: an expanded group's own node (its members are drawn
355
+ * in its place), and every node inside a collapsed group (the group's node is drawn in their place). A group is
356
+ * collapsed when its nested graph's `__groupCollapsed.SUID` names the network being read. A file graphty wrote is
357
+ * left alone: its block says what to draw.
358
+ * @param snapshot - the graph
359
+ * @param values - the node values per property, changed in place
360
+ */
361
+ function hideGroupsCytoscapeHides(snapshot: GraphSnapshot, values: Partial<Record<string, StyleColumn>>): void {
362
+ const parent = snapshot.nodes.byRole("parent");
363
+ if (parent === null || snapshot.graph.has(STYLE_BLOCK_NAME)) {
364
+ return;
365
+ }
366
+ const n = snapshot.nodeCount;
367
+ const members = membersOf(parent, n);
368
+ if (members.size === 0) {
369
+ return;
370
+ }
371
+ const network = (snapshot.meta.extra as { xgmml?: { graphId?: unknown } } | undefined)?.xgmml?.graphId;
372
+ const visible = values.visible === undefined ? new Array<StyleValue | null>(n).fill(null) : [...values.visible];
373
+ for (const [group, inside] of members) {
374
+ if (!collapsedIn(snapshot, group, network)) {
375
+ visible[group] = false;
376
+ continue;
377
+ }
378
+ for (const i of insideAtAnyDepth(group, inside, members)) {
379
+ visible[i] = false;
380
+ }
381
+ }
382
+ values.visible = visible;
383
+ }
384
+
385
+ /**
386
+ * Marks not visible what Cytoscape does not draw of its groups, and the edges of every node it does not draw.
387
+ * @param snapshot - the graph
388
+ * @param target - nodes or edges
389
+ * @param nodes - the node values per property (read for edges)
390
+ * @param values - the target's values per property, changed in place
391
+ */
392
+ export function hideWhatCytoscapeHides(
393
+ snapshot: GraphSnapshot,
394
+ target: StyleTarget,
395
+ nodes: Partial<Record<string, StyleColumn>>,
396
+ values: Partial<Record<string, StyleColumn>>,
397
+ ): void {
398
+ if (target === "node") {
399
+ hideGroupsCytoscapeHides(snapshot, values);
400
+ } else {
401
+ hideEdgesOfHiddenNodes(snapshot, nodes, values);
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Marks not visible every edge with an end Cytoscape does not draw: a collapsed group's members' own edges (the
407
+ * group's meta-edges are drawn in their place), an expanded group node's meta-edges, and a hidden node's edges. A
408
+ * file graphty wrote is left alone: its block says what to draw.
409
+ * @param snapshot - the graph
410
+ * @param nodes - the node values per property
411
+ * @param values - the edge values per property, changed in place
412
+ */
413
+ function hideEdgesOfHiddenNodes(
414
+ snapshot: GraphSnapshot,
415
+ nodes: Partial<Record<string, StyleColumn>>,
416
+ values: Partial<Record<string, StyleColumn>>,
417
+ ): void {
418
+ const shown = nodes.visible;
419
+ if (shown === undefined || !shown.includes(false) || snapshot.graph.has(STYLE_BLOCK_NAME)) {
420
+ return;
421
+ }
422
+ const { src, dst } = snapshot.edgeList();
423
+ const visible =
424
+ values.visible === undefined ? new Array<StyleValue | null>(src.length).fill(null) : [...values.visible];
425
+ for (let e = 0; e < src.length; e++) {
426
+ if (shown[src[e]] === false || shown[dst[e]] === false) {
427
+ visible[e] = false;
428
+ }
429
+ }
430
+ values.visible = visible;
431
+ }
432
+
433
+ /**
434
+ * Each group node's direct members.
435
+ * @param parent - the node parent column
436
+ * @param n - the node count
437
+ * @returns group node to its members
438
+ */
439
+ function membersOf(
440
+ parent: NonNullable<ReturnType<GraphSnapshot["nodes"]["byRole"]>>,
441
+ n: number,
442
+ ): Map<number, number[]> {
443
+ const members = new Map<number, number[]>();
444
+ for (let i = 0; i < n; i++) {
445
+ const g = parent.isSet(i) ? plainCell(parent.value(i)) : null;
446
+ if (typeof g === "number" && g !== i) {
447
+ members.set(g, [...(members.get(g) ?? []), i]);
448
+ }
449
+ }
450
+ return members;
451
+ }
452
+
453
+ /**
454
+ * Every node inside a group, at any depth.
455
+ * @param group - the group node
456
+ * @param inside - its direct members
457
+ * @param members - each group node's direct members
458
+ * @returns the nodes inside
459
+ */
460
+ function insideAtAnyDepth(group: number, inside: readonly number[], members: Map<number, number[]>): Set<number> {
461
+ const stack = [...inside];
462
+ const seen = new Set<number>([group]);
463
+ const out = new Set<number>();
464
+ for (let i = stack.pop(); i !== undefined; i = stack.pop()) {
465
+ if (!seen.has(i)) {
466
+ seen.add(i);
467
+ out.add(i);
468
+ stack.push(...(members.get(i) ?? []));
469
+ }
470
+ }
471
+ return out;
472
+ }
473
+
474
+ /**
475
+ * Whether a group node's nested graph says the group is collapsed in a network (`__groupCollapsed.SUID` lists it).
476
+ * @param snapshot - the graph
477
+ * @param group - the group node
478
+ * @param network - the id of the network being read, or anything else when unknown
479
+ * @returns true when collapsed there
480
+ */
481
+ function collapsedIn(snapshot: GraphSnapshot, group: number, network: unknown): boolean {
482
+ if (typeof network !== "string" || !snapshot.nodes.has(SUBGRAPH_COLUMN)) {
483
+ return false;
484
+ }
485
+ const sub = plainCell(snapshot.nodes.value(SUBGRAPH_COLUMN, group));
486
+ const atts = sub !== null && typeof sub === "object" ? (sub as { atts?: unknown }).atts : null;
487
+ const collapsed =
488
+ atts !== null && typeof atts === "object" ? (atts as Record<string, unknown>)["__groupCollapsed.SUID"] : null;
489
+ return Array.isArray(collapsed) && collapsed.some((v) => String(v) === network);
490
+ }
491
+
252
492
  /**
253
493
  * The properties with at least one value.
254
494
  * @param values - per property, each element's value
@@ -265,27 +505,46 @@ export function nonEmpty(values: Partial<Record<string, StyleColumn>>): Partial<
265
505
  }
266
506
 
267
507
  /**
268
- * The graph's background from its own graphics (`NETWORK_BACKGROUND_PAINT`).
508
+ * The graph's background: its own graphics' `NETWORK_BACKGROUND_PAINT`, the locked one (`lockedVisualProperties`, a
509
+ * session view's bypass) on top, over the style's own.
269
510
  * @param snapshot - the graph
270
511
  * @param notes - where a bad value is noted
512
+ * @param style - the style whose network defaults the graph's graphics override, or none
271
513
  * @returns the graph style
514
+ * @category Styles
272
515
  */
273
- function graphStyleOf(snapshot: GraphSnapshot, notes: StyleNotes): GraphStyle {
274
- const name = graphicsColumnOf(snapshot.graph);
275
- const g = name === null ? null : plainCell(snapshot.graph.value(name, 0));
276
- if (g === null || typeof g !== "object") {
277
- return {};
516
+ export function graphStyleOf(snapshot: GraphSnapshot, notes: StyleNotes, style?: CytoscapeStyle): GraphStyle {
517
+ const merged = emptyCytoscapeStyle();
518
+ for (const [k, v] of style?.network.defaults ?? []) {
519
+ merged.network.defaults.set(k, v);
278
520
  }
279
- const style = emptyCytoscapeStyle();
280
- for (const [k, v] of normalizeVisualProperties("node", g, notes)) {
281
- if (k.startsWith("NETWORK_")) {
282
- style.network.defaults.set(k, v);
283
- }
521
+ for (const [k, v] of networkBypasses(snapshot, notes)) {
522
+ merged.network.defaults.set(k, v);
284
523
  }
285
- const background = cytoscapeBackground(style, notes);
524
+ const background = cytoscapeBackground(merged, notes);
286
525
  return background === null ? {} : { background };
287
526
  }
288
527
 
528
+ /**
529
+ * The network visual properties a graph's own graphics set, the locked ones (`lockedVisualProperties`) last.
530
+ * @param snapshot - the graph
531
+ * @param notes - where too-deep nesting is noted
532
+ * @returns visual property name to raw value, in the order they apply
533
+ */
534
+ function networkBypasses(snapshot: GraphSnapshot, notes: StyleNotes): [string, unknown][] {
535
+ const name = graphicsColumnOf(snapshot.graph);
536
+ const g = name === null ? null : plainCell(snapshot.graph.value(name, 0));
537
+ if (g === null || typeof g !== "object" || Array.isArray(g)) {
538
+ return [];
539
+ }
540
+ const locked = Object.hasOwn(g, "lockedVisualProperties")
541
+ ? (g as Record<string, unknown>).lockedVisualProperties
542
+ : undefined;
543
+ return [g, locked].flatMap((layer) =>
544
+ [...normalizeVisualProperties("node", layer, notes)].filter(([k]) => k.startsWith("NETWORK_")),
545
+ );
546
+ }
547
+
289
548
  // ------------------------------------------------------------------ writing
290
549
 
291
550
  /**