@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
@@ -7,14 +7,17 @@
7
7
  * The tree helpers here are shared with the yFiles 3 reader.
8
8
  */
9
9
  import { toFilePositions, toNeutral } from "../../positions/convert.js";
10
- import { bendsToPoints, canonBends } from "../../styles/canon/bends.js";
10
+ import { bendsToPoints, canonBends, canonNodeOffsets, flattenCubic, flattenQuadSpline, nodeOffsetsToPoints, } from "../../styles/canon/bends.js";
11
11
  import { canonColor, colorOpacity } from "../../styles/canon/color.js";
12
12
  import { canonEnum } from "../../styles/canon/enums.js";
13
- import { canonNumber } from "../../styles/canon/number.js";
13
+ import { canonNumber, canonSigned } from "../../styles/canon/number.js";
14
14
  import { MAX_STYLE_VALUE_LENGTH, noteAt } from "../../styles/canon/site.js";
15
15
  import { canonText } from "../../styles/canon/text.js";
16
16
  import { STYLE_ISSUE } from "../../styles/codes.js";
17
+ import { JAVA_MONO, JAVA_SANS, JAVA_SERIF, javaFamily } from "../../styles/cytoscape/lexicon.js";
17
18
  import { StyleApproximations } from "../../styles/io/approximations.js";
19
+ import { elementValues, takeFromBlock } from "../../styles/io/round-trip.js";
20
+ import { StyleNotes } from "../../styles/notes.js";
18
21
  import { plainCell } from "../../styles/plan/resolve.js";
19
22
  /**
20
23
  * Whether a value is a tree object.
@@ -197,32 +200,167 @@ function activeRealizer(proxy) {
197
200
  return all[Number.isInteger(active) && active >= 0 && active < all.length ? active : 0] ?? null;
198
201
  }
199
202
  /**
200
- * yEd's flowchart palette (`com.yworks.flowchart.<name>`), by name, to the shape each draws. Matched whole, before
201
- * the words below: "data" is a parallelogram, but "storedData" and "directData" are not.
203
+ * Points along an elliptical arc, as `x,y` text: center (cx, cy), radii (rx, ry), from angle `from` to `to` (radians,
204
+ * counter-clockwise, y up), both ends included.
205
+ * @param cx - center x
206
+ * @param cy - center y
207
+ * @param rx - x radius
208
+ * @param ry - y radius
209
+ * @param from - first angle
210
+ * @param to - last angle
211
+ * @param steps - segments
212
+ * @returns the points
202
213
  */
203
- const FLOWCHART_SHAPES = new Map([
204
- ["process", "rectangle"],
205
- ["decision", "diamond"],
206
- ["terminator", "round-rectangle"],
207
- ["start1", "ellipse"],
208
- ["start2", "ellipse"],
209
- ["data", "parallelogram"],
210
- ["preparation", "hexagon"],
214
+ function arcPoints(cx, cy, rx, ry, from, to, steps = 12) {
215
+ return Array.from({ length: steps + 1 }, (_, i) => {
216
+ const t = from + ((to - from) * i) / steps;
217
+ return pointText(cx + rx * Math.cos(t), cy + ry * Math.sin(t));
218
+ });
219
+ }
220
+ /**
221
+ * Points along a wave y = y0 + amp * sin(pi * x), x from `x0` to `x1`.
222
+ * @param y0 - the wave's middle
223
+ * @param amp - its height
224
+ * @param x0 - first x
225
+ * @param x1 - last x
226
+ * @returns the points
227
+ */
228
+ function wavePoints(y0, amp, x0, x1) {
229
+ const steps = 16;
230
+ return Array.from({ length: steps + 1 }, (_, i) => {
231
+ const x = x0 + ((x1 - x0) * i) / steps;
232
+ return pointText(x, y0 + amp * Math.sin(Math.PI * x));
233
+ });
234
+ }
235
+ /**
236
+ * One corner as `x,y`, rounded to three decimals.
237
+ * @param x - x
238
+ * @param y - y
239
+ * @returns the text
240
+ */
241
+ function pointText(x, y) {
242
+ const r = (v) => String(Math.round(v * 1000) / 1000 + 0);
243
+ return `${r(x)},${r(y)}`;
244
+ }
245
+ const HALF_PI = Math.PI / 2;
246
+ /** A cloud: a circle of bumps, stretched to the box. */
247
+ const CLOUD = Array.from({ length: 72 }, (_, i) => {
248
+ const t = (2 * Math.PI * i) / 72;
249
+ const r = 0.86 + 0.14 * Math.abs(Math.cos(4 * t));
250
+ return pointText(r * Math.cos(t), r * Math.sin(t));
251
+ }).join(" ");
252
+ /** A stadium: a box whose ends are half circles (a pill). */
253
+ const STADIUM = [
254
+ ...arcPoints(0.5, 0, 0.5, 1, -HALF_PI, HALF_PI),
255
+ ...arcPoints(-0.5, 0, 0.5, 1, HALF_PI, 3 * HALF_PI),
256
+ ].join(" ");
257
+ /**
258
+ * The shape each configuration of yEd's GenericNode palettes draws (flowchart, entity relationship, BPMN, SBGN), by
259
+ * its name after `com.yworks.` without a `.withShadow` suffix, lowercase. Matched whole, before the words below:
260
+ * "data" is a parallelogram, but "storedData" and "directData" are not. A shape no neutral one names is the polygon
261
+ * yEd draws it as (curves as short segments); the lines some draw inside (predefined process, internal storage) are
262
+ * not drawn. Left out until a drawing by yEd itself shows them (ISSUES.md): the BPMN artifact, whose `type` property
263
+ * picks among a data object, a data store, a message and others, and the SBGN nucleic acid feature and perturbing
264
+ * agent, which draw.io, the stand-in, draws as plain boxes.
265
+ */
266
+ const YED_CONFIGURATIONS = new Map([
267
+ ["flowchart.process", { shape: "rectangle" }],
268
+ ["flowchart.predefinedprocess", { shape: "rectangle" }],
269
+ ["flowchart.internalstorage", { shape: "rectangle" }],
270
+ ["flowchart.decision", { shape: "diamond" }],
271
+ ["flowchart.terminator", { shape: "round-rectangle" }],
272
+ ["flowchart.start1", { shape: "ellipse" }],
273
+ ["flowchart.start2", { shape: "ellipse" }],
274
+ ["flowchart.onpagereference", { shape: "ellipse" }],
275
+ ["flowchart.sequentialdata", { shape: "ellipse" }],
276
+ ["flowchart.data", { shape: "parallelogram" }],
277
+ ["flowchart.preparation", { shape: "hexagon" }],
278
+ ["flowchart.database", { shape: "other:database" }],
279
+ ["flowchart.looplimit", { shape: "polygon", points: "-1,-1 1,-1 1,0.5 0.8,1 -0.8,1 -1,0.5" }],
280
+ ["flowchart.looplimitend", { shape: "polygon", points: "-1,1 -1,-0.5 -0.8,-1 0.8,-1 1,-0.5 1,1" }],
281
+ ["flowchart.manualinput", { shape: "polygon", points: "-1,-1 1,-1 1,1 -1,0.4" }],
282
+ ["flowchart.card", { shape: "polygon", points: "-1,-1 1,-1 1,1 -0.6,1 -1,0.6" }],
283
+ ["flowchart.manualoperation", { shape: "polygon", points: "-1,1 -0.7,-1 0.7,-1 1,1" }],
284
+ ["flowchart.offpagereference", { shape: "polygon", points: "-1,1 -1,0 0,-1 1,0 1,1" }],
285
+ ["flowchart.usermessage", { shape: "polygon", points: "-1,1 -1,-1 0.6,-1 1,0 0.6,1" }],
286
+ ["flowchart.networkmessage", { shape: "polygon", points: "-1,1 -0.6,0 -1,-1 1,-1 1,1" }],
287
+ ["flowchart.document", { shape: "polygon", points: ["-1,1", ...wavePoints(-0.75, 0.2, -1, 1), "1,1"].join(" ") }],
288
+ [
289
+ "flowchart.papertype",
290
+ {
291
+ shape: "polygon",
292
+ points: [...wavePoints(-0.8, 0.2, -1, 1), ...wavePoints(0.8, 0.2, 1, -1)].join(" "),
293
+ },
294
+ ],
295
+ [
296
+ "flowchart.delay",
297
+ { shape: "polygon", points: ["-1,-1", ...arcPoints(0, 0, 1, 1, -HALF_PI, HALF_PI), "-1,1"].join(" ") },
298
+ ],
299
+ [
300
+ "flowchart.display",
301
+ {
302
+ shape: "polygon",
303
+ points: ["-1,0", "-0.6,-1", ...arcPoints(0.6, 0, 0.4, 1, -HALF_PI, HALF_PI), "-0.6,1"].join(" "),
304
+ },
305
+ ],
306
+ [
307
+ "flowchart.storeddata",
308
+ {
309
+ shape: "polygon",
310
+ points: [
311
+ ...arcPoints(1, 0, -0.2, 1, -HALF_PI, HALF_PI),
312
+ ...arcPoints(-0.8, 0, 0.2, 1, HALF_PI, 3 * HALF_PI),
313
+ ].join(" "),
314
+ },
315
+ ],
316
+ [
317
+ "flowchart.directdata",
318
+ {
319
+ shape: "polygon",
320
+ points: [
321
+ ...arcPoints(0.8, 0, 0.2, 1, -HALF_PI, HALF_PI),
322
+ ...arcPoints(-0.8, 0, 0.2, 1, HALF_PI, 3 * HALF_PI),
323
+ ].join(" "),
324
+ },
325
+ ],
326
+ ["flowchart.cloud", { shape: "polygon", points: CLOUD }],
327
+ ["entityrelationship.relationship", { shape: "diamond" }],
328
+ ["entityrelationship.attribute", { shape: "ellipse" }],
329
+ ["bpmn.conversation", { shape: "hexagon" }],
330
+ ["sbgn.unspecifiedentity", { shape: "ellipse" }],
331
+ ["sbgn.simplechemical", { shape: "ellipse" }],
332
+ ["sbgn.emptyset", { shape: "ellipse" }],
333
+ ["sbgn.operator", { shape: "ellipse" }],
334
+ ["sbgn.macromolecule", { shape: "round-rectangle" }],
335
+ ["sbgn.phenotype", { shape: "hexagon" }],
336
+ ["sbgn.process", { shape: "rectangle" }],
337
+ ["sbgn.submap", { shape: "rectangle" }],
338
+ ["sbgn.unitofinformation", { shape: "rectangle" }],
339
+ ["sbgn.statevariable", { shape: "polygon", points: STADIUM }],
340
+ ["sbgn.tag", { shape: "polygon", points: "-1,1 -1,-1 0.6,-1 1,0 0.6,1" }],
211
341
  ]);
212
- const FLOWCHART_PREFIX = "com.yworks.flowchart.";
213
342
  /**
214
- * The shape a yEd flowchart configuration draws: a GraphML GenericNode's `configuration`, or a yEd GML node's
343
+ * The shape a yEd GenericNode configuration draws: a GraphML GenericNode's `configuration`, or a yEd GML node's
215
344
  * `customconfiguration`.
216
345
  * @param configuration - the configuration
217
- * @returns the neutral shape, or null for a configuration that is not one of the flowchart shapes known here
346
+ * @returns the shape, with its corners where it is a polygon, or null for a configuration not known here
218
347
  */
219
- export function flowchartShape(configuration) {
220
- return configuration.startsWith(FLOWCHART_PREFIX)
221
- ? (FLOWCHART_SHAPES.get(configuration.slice(FLOWCHART_PREFIX.length)) ?? null)
222
- : null;
348
+ export function configurationOutline(configuration) {
349
+ const key = configuration
350
+ .slice(0, MAX_STYLE_VALUE_LENGTH)
351
+ .toLowerCase()
352
+ .replace(/^com\.yworks\./, "")
353
+ .replace(/\.withshadow$/, "");
354
+ return YED_CONFIGURATIONS.get(key) ?? null;
223
355
  }
224
356
  /** GenericNode configurations, by a word they contain, to the shape they draw; the first match wins. */
225
357
  const GENERIC_SHAPES = [
358
+ // yEd's BPMN and entity-relationship palettes: a task is a rounded box, an event a circle, a
359
+ // gateway a diamond, an attribute an ellipse
360
+ ["bpmn.activity", "round-rectangle"],
361
+ ["bpmn.event", "ellipse"],
362
+ ["bpmn.gateway", "diamond"],
363
+ ["entityrelationship.attribute", "ellipse"],
226
364
  ["ellipse", "ellipse"],
227
365
  ["circle", "ellipse"],
228
366
  ["oval", "ellipse"],
@@ -235,7 +373,11 @@ const GENERIC_SHAPES = [
235
373
  ["process", "rectangle"],
236
374
  ["box", "rectangle"],
237
375
  ];
238
- /** yEd's label positions (`modelPosition` of the internal, sides and eight-position models). */
376
+ /**
377
+ * yEd's label positions (`modelPosition` of the internal, sides, sandwich, corners and eight-position models). The
378
+ * internal model's `t` (inside the top of the box: a group's title) is `inside-top`; its other inside positions have
379
+ * no neutral value and read as the nearest side or corner.
380
+ */
239
381
  const YED_POSITIONS = new Map([
240
382
  ["c", "center"],
241
383
  ["t", "top"],
@@ -288,8 +430,9 @@ function readColor(raw, property, opacity, put, at) {
288
430
  * @param node - whether they are node labels (which have a position)
289
431
  * @param put - receives the values
290
432
  * @param at - the sites
433
+ * @param geometry - a node label's node `y:Geometry`, which places the label inside or outside the node
291
434
  */
292
- function readLabels(labels, node, put, at) {
435
+ function readLabels(labels, node, put, at, geometry) {
293
436
  let label = undefined;
294
437
  let text = "";
295
438
  let extra = 0;
@@ -313,19 +456,32 @@ function readLabels(labels, node, put, at) {
313
456
  noteAt(at("label"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);
314
457
  }
315
458
  put("label", canonText(text, at("label")));
316
- readLabelLook(label, node, put, at);
459
+ readLabelLook(label, node, put, at, geometry);
317
460
  }
318
461
  /**
319
- * Reads a label's look: its color, font and, for a node label, its position.
462
+ * Reads a label's look: its color, background box and its border, font and, for a node label, its position.
320
463
  * @param label - the label element
321
464
  * @param node - whether it is a node label
322
465
  * @param put - receives the values
323
466
  * @param at - the sites
467
+ * @param geometry - a node label's node `y:Geometry`
324
468
  */
325
- function readLabelLook(label, node, put, at) {
469
+ function readLabelLook(label, node, put, at, geometry) {
326
470
  readColor(treeAttr(label, "textColor"), "labelColor", null, put, at);
471
+ // yEd draws a box behind the words in `backgroundColor` unless `hasBackgroundColor` is false
472
+ if (treeAttr(label, "hasBackgroundColor") !== "false") {
473
+ readColor(treeAttr(label, "backgroundColor"), "labelBackground", null, put, at);
474
+ }
475
+ // and a one-pixel line round that box in `lineColor` unless `hasLineColor` is false
476
+ if (treeAttr(label, "hasLineColor") !== "false" && treeAttr(label, "lineColor") !== undefined) {
477
+ readColor(treeAttr(label, "lineColor"), "labelBorderColor", null, put, at);
478
+ put("labelBorderWidth", 1);
479
+ }
327
480
  put("labelSize", canonNumber(treeAttr(label, "fontSize"), at("labelSize")));
328
- put("labelFont", canonText(treeAttr(label, "fontFamily"), at("labelFont")));
481
+ // yEd is a Java program: its logical fonts (Dialog, SansSerif, Monospaced, ...) are drawn in the faces Java gives
482
+ // them, and a font it does not have in Dialog's
483
+ const font = canonText(treeAttr(label, "fontFamily"), at("labelFont"));
484
+ put("labelFont", font === null ? null : javaFamily(font));
329
485
  const style = treeAttr(label, "fontStyle");
330
486
  if (style !== undefined) {
331
487
  const known = FONT_STYLES.get(style.trim().toLowerCase());
@@ -337,15 +493,243 @@ function readLabelLook(label, node, put, at) {
337
493
  put("labelItalic", known[1]);
338
494
  }
339
495
  }
340
- const position = node ? treeAttr(label, "modelPosition") : undefined;
341
- if (position !== undefined) {
342
- const known = YED_POSITIONS.get(position.trim().toLowerCase());
343
- if (known === undefined) {
344
- noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, position.slice(0, MAX_STYLE_VALUE_LENGTH));
496
+ readRotation(label, put, at);
497
+ if (node) {
498
+ const position = nodeLabelPosition(label, geometry, at);
499
+ put("labelPosition", position);
500
+ readInsideInset(label, geometry, position, put);
501
+ readOutsideOffset(label, geometry, position, put);
502
+ }
503
+ }
504
+ /**
505
+ * Reads a label's `rotationAngle`: yEd is a Java2D program, whose angles turn clockwise on screen (y down), as the
506
+ * neutral `labelRotation` does.
507
+ * @param label - the label element
508
+ * @param put - receives the values
509
+ * @param at - the sites
510
+ */
511
+ function readRotation(label, put, at) {
512
+ const angle = canonSigned(treeAttr(label, "rotationAngle"), at("labelRotation"));
513
+ if (angle === null) {
514
+ return;
515
+ }
516
+ const turn = ((angle % 360) + 360) % 360;
517
+ put("labelRotation", turn === 0 ? null : turn);
518
+ }
519
+ /**
520
+ * How far from where its position puts it a label outside its node, or placed freely, is drawn: yEd writes every
521
+ * label's box as it draws it, so an outside label keeps its model's distance from the node (4 by default) and a
522
+ * free label its offset. Across the side it is beside, the label is moved by the gap between the node and its box;
523
+ * along that side (and on both axes for a free label over the node), by how far its box's middle is from the node's.
524
+ * A turned label's box is not its words' box, so it is left where its position puts it.
525
+ * @param label - the label element
526
+ * @param geometry - the node's `y:Geometry`
527
+ * @param position - where the label is placed
528
+ * @param put - receives the values
529
+ */
530
+ function readOutsideOffset(label, geometry, position, put) {
531
+ const model = treeAttr(label, "modelName");
532
+ const free = position === "center" && model !== undefined && model !== "internal";
533
+ if (position === null || position.startsWith("inside-") || (position === "center" && !free)) {
534
+ return;
535
+ }
536
+ if (Number(treeAttr(label, "rotationAngle") ?? 0) % 360 !== 0) {
537
+ return;
538
+ }
539
+ const num = (o, k) => Number(treeAttr(o, k) ?? Number.NaN);
540
+ const [x, y, w, h] = ["x", "y", "width", "height"].map((k) => num(label, k));
541
+ const [nw, nh] = [num(geometry, "width"), num(geometry, "height")];
542
+ if (![x, y, w, h, nw, nh].every(Number.isFinite)) {
543
+ return;
544
+ }
545
+ const signed = (value) => {
546
+ const r = Math.round(value * 1000) / 1000;
547
+ return r === 0 ? null : r;
548
+ };
549
+ // across a side: the gap between the node and the box; along it: the box's middle against the node's
550
+ const offset = (lo, size, extent, before, after) => {
551
+ if (before) {
552
+ return signed(lo + size);
345
553
  }
346
- put("labelPosition", known ?? null);
554
+ return after ? signed(lo - extent) : signed(lo + size / 2 - extent / 2);
555
+ };
556
+ put("labelOffsetX", offset(x, w, nw, position.includes("left"), position.includes("right")));
557
+ put("labelOffsetY", offset(y, h, nh, position.includes("top"), position.includes("bottom")));
558
+ }
559
+ /**
560
+ * How far in from the sides it is drawn against yEd puts a label inside its node (its internal model's insets, 4 by
561
+ * default), from the label's stored box, for a label sized to its words: the label is moved that far right of a left side, left of a right side, down
562
+ * from the top and up from the bottom.
563
+ * @param label - the label element
564
+ * @param geometry - the node's `y:Geometry`
565
+ * @param position - where the label is placed
566
+ * @param put - receives the values
567
+ */
568
+ function readInsideInset(label, geometry, position, put) {
569
+ // a label sized to its node (a group's header band) has a box that is not its words'
570
+ const sized = treeAttr(label, "autoSizePolicy")?.startsWith("node_") === true;
571
+ if (position?.startsWith("inside-") !== true || sized) {
572
+ return;
347
573
  }
574
+ const num = (o, k) => Number(treeAttr(o, k) ?? Number.NaN);
575
+ const [x, y, w, h] = ["x", "y", "width", "height"].map((k) => num(label, k));
576
+ const [nw, nh] = [num(geometry, "width"), num(geometry, "height")];
577
+ const inset = (value) => Number.isFinite(value) && value > 0 ? Math.round(value * 1000) / 1000 : null;
578
+ if (position.includes("left")) {
579
+ put("labelOffsetX", inset(x));
580
+ }
581
+ else if (position.includes("right")) {
582
+ const gap = inset(nw - x - w);
583
+ put("labelOffsetX", gap === null ? null : -gap);
584
+ }
585
+ if (position.includes("top")) {
586
+ put("labelOffsetY", inset(y));
587
+ }
588
+ else if (position.includes("bottom")) {
589
+ const gap = inset(nh - y - h);
590
+ put("labelOffsetY", gap === null ? null : -gap);
591
+ }
592
+ }
593
+ /**
594
+ * Where yEd draws a node label: from the label's box, which every model yEd writes stores relative to the node's
595
+ * top-left corner (a label entirely beside the node is outside it on that side), else from its model. A label inside
596
+ * the node is placed by its model: yEd's `internal` model puts it against a side or in a corner (`t`, `bl`, ...), or
597
+ * in the middle (`c`); any other model's label inside the node is in its middle.
598
+ * @param label - the label element
599
+ * @param geometry - the node's `y:Geometry`
600
+ * @param at - the sites
601
+ * @returns the position, or null
602
+ */
603
+ function nodeLabelPosition(label, geometry, at) {
604
+ const outside = boxPosition(label, geometry);
605
+ if (outside !== null && outside !== "center") {
606
+ return outside;
607
+ }
608
+ const position = treeAttr(label, "modelPosition");
609
+ const model = treeAttr(label, "modelName");
610
+ if (model === "internal") {
611
+ return insidePosition(label, position);
612
+ }
613
+ if (model === "custom") {
614
+ return customPosition(label, outside, at);
615
+ }
616
+ if (outside !== null || position === undefined) {
617
+ return outside;
618
+ }
619
+ const known = YED_POSITIONS.get(position.trim().toLowerCase());
620
+ if (known === undefined) {
621
+ noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, position.slice(0, MAX_STYLE_VALUE_LENGTH));
622
+ }
623
+ return known ?? null;
348
624
  }
625
+ /**
626
+ * Where a SmartNodeLabelModel (`custom`) label is drawn: where its stored box puts it, as for any other model, and
627
+ * where its ratios put it when the file stores no box (a label hung from the node's top edge into it is a header
628
+ * along its top). A box beside the node is handled before this.
629
+ * @param label - the label element
630
+ * @param outside - the box's position against the node, `center` or null
631
+ * @param at - the sites
632
+ * @returns the position, or null
633
+ */
634
+ function customPosition(label, outside, at) {
635
+ const smart = treeChild(treeChild(label, "ModelParameter"), "SmartNodeLabelModelParameter");
636
+ if (smart === undefined) {
637
+ noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, "custom");
638
+ return outside;
639
+ }
640
+ // the stored box is where yEd drew the label; the ratios place it only when the file stores no box
641
+ return outside ?? smartPosition(smart);
642
+ }
643
+ /**
644
+ * The nearest neutral position of a SmartNodeLabelModel placement. yEd puts the point `labelRatio` of the label
645
+ * (-0.5..0.5 of its size from its center) on the point `nodeRatio` of the node; the offsets are ignored. On each axis
646
+ * a node ratio below or above zero is that side, zero is the middle. A label on the node's top edge that hangs down
647
+ * into it (labelRatioY at or below zero) is `inside-top`; every other edge or corner placement is the outside side
648
+ * or corner, the nearest neutral value (an inside bottom or side has none).
649
+ * @param smart - the `y:SmartNodeLabelModelParameter` element
650
+ * @returns the position
651
+ */
652
+ function smartPosition(smart) {
653
+ const ratio = (name) => {
654
+ const n = Number(treeAttr(smart, name));
655
+ return Number.isFinite(n) ? n : 0;
656
+ };
657
+ const h = sideOf(ratio("nodeRatioX"), "left", "right");
658
+ const v = sideOf(ratio("nodeRatioY"), "top", "bottom");
659
+ if (v === "top" && h === "" && ratio("labelRatioY") <= 0) {
660
+ return "inside-top";
661
+ }
662
+ if (v === "" || h === "") {
663
+ return v + h || "center";
664
+ }
665
+ return `${v}-${h}`;
666
+ }
667
+ /**
668
+ * One axis of a SmartNodeLabelModel node ratio.
669
+ * @param ratio - the ratio, -0.5..0.5
670
+ * @param low - the side below zero
671
+ * @param high - the side above zero
672
+ * @returns the side, or "" for the middle
673
+ */
674
+ function sideOf(ratio, low, high) {
675
+ if (ratio < 0) {
676
+ return low;
677
+ }
678
+ return ratio > 0 ? high : "";
679
+ }
680
+ /**
681
+ * Where a label's box lies against its node: beside a side or a corner, or `center` when it overlaps the node.
682
+ * @param label - the label element
683
+ * @param geometry - the node's `y:Geometry`
684
+ * @returns the position, or null when the label or the node has no box
685
+ */
686
+ function boxPosition(label, geometry) {
687
+ const num = (o, k) => Number(treeAttr(o, k) ?? Number.NaN);
688
+ const [x, y, w, h] = ["x", "y", "width", "height"].map((k) => num(label, k));
689
+ const [nw, nh] = [num(geometry, "width"), num(geometry, "height")];
690
+ if (![x, y, w, h, nw, nh].every(Number.isFinite)) {
691
+ return null;
692
+ }
693
+ const side = (lo, size, extent) => {
694
+ if (lo + size <= 0) {
695
+ return -1;
696
+ }
697
+ return lo >= extent ? 1 : 0;
698
+ };
699
+ return BOX_POSITIONS[side(y, h, nh) + 1][side(x, w, nw) + 1];
700
+ }
701
+ /**
702
+ * Where yEd's internal model draws a label: in the middle, or inside the node against the side or in the corner its
703
+ * `modelPosition` names. A label as wide as its node (a group's header) is drawn against the side its `alignment`
704
+ * names, so a right-aligned header along the top is in the top-right corner.
705
+ * @param label - the label element
706
+ * @param position - its `modelPosition`
707
+ * @returns the position
708
+ */
709
+ function insidePosition(label, position) {
710
+ const inside = INTERNAL_POSITIONS.get((position ?? "c").trim().toLowerCase()) ?? "center";
711
+ const align = treeAttr(label, "alignment");
712
+ const across = treeAttr(label, "autoSizePolicy") === "node_width" && (align === "left" || align === "right");
713
+ return across && (inside === "inside-top" || inside === "inside-bottom") ? `${inside}-${align}` : inside;
714
+ }
715
+ /** yEd's internal label model positions, as the neutral position inside the node. */
716
+ const INTERNAL_POSITIONS = new Map([
717
+ ["c", "center"],
718
+ ["t", "inside-top"],
719
+ ["b", "inside-bottom"],
720
+ ["l", "inside-left"],
721
+ ["r", "inside-right"],
722
+ ["tl", "inside-top-left"],
723
+ ["tr", "inside-top-right"],
724
+ ["bl", "inside-bottom-left"],
725
+ ["br", "inside-bottom-right"],
726
+ ]);
727
+ /** A label's position by the side of the node it lies on: rows above, level, below; columns left, level, right. */
728
+ const BOX_POSITIONS = [
729
+ ["top-left", "top", "top-right"],
730
+ ["left", "center", "right"],
731
+ ["bottom-left", "bottom", "bottom-right"],
732
+ ];
349
733
  /**
350
734
  * The shape of a node realizer: its `y:Shape` where it has one, a GenericNode's configuration, or the realizer
351
735
  * type itself for one that draws an image (SVG, image, table, UML).
@@ -361,11 +745,15 @@ function realizerShape(real, at) {
361
745
  if (real.type === "ShapeNode" || real.type === "GroupNode" || real.type === "GenericGroupNode") {
362
746
  return null;
363
747
  }
748
+ if (real.type === "TableNode") {
749
+ // a yEd table or pool is a rectangle of bands
750
+ return canonEnum("shape", "rectangle", "yed", at("shape"));
751
+ }
364
752
  if (real.type === "GenericNode") {
365
753
  const conf = treeAttr(real.r, "configuration") ?? "";
366
- const flowchart = flowchartShape(conf);
367
- if (flowchart !== null) {
368
- return flowchart;
754
+ const known = configurationOutline(conf);
755
+ if (known !== null) {
756
+ return known.shape;
369
757
  }
370
758
  const lower = conf.slice(0, MAX_STYLE_VALUE_LENGTH).toLowerCase();
371
759
  for (const [word, value] of GENERIC_SHAPES) {
@@ -382,28 +770,161 @@ function realizerShape(real, at) {
382
770
  noteAt(at("shape"), STYLE_ISSUE.UNKNOWN_VALUE, real.type);
383
771
  return `other:${real.type}`;
384
772
  }
773
+ /** yEd's gradient: from the fill color at a node's top-left corner to `color2` at its bottom-right one. */
774
+ const YED_GRADIENT_ANGLE = 45;
385
775
  /**
386
- * Reads one node realizer.
776
+ * Reads a node realizer's fill: its color, and a gradient into `color2`. yEd paints no fill where the fill has no
777
+ * color or is transparent.
387
778
  * @param real - the realizer
388
779
  * @param put - receives the values
389
780
  * @param at - the sites
390
781
  */
391
- function readNode(real, put, at) {
392
- const { r } = real;
393
- const fill = treeChild(r, "Fill");
394
- if (fill !== undefined) {
395
- if (treeAttr(fill, "hasColor") === "false" || treeAttr(fill, "transparent") === "true") {
396
- noteAt(at("fill"), STYLE_ISSUE.NO_FILL, "transparent");
397
- put("fillOpacity", 0);
782
+ function readFill(real, put, at) {
783
+ const fill = treeChild(real.r, "Fill");
784
+ if (fill === undefined) {
785
+ return;
786
+ }
787
+ if (treeAttr(fill, "hasColor") === "false" || treeAttr(fill, "transparent") === "true") {
788
+ noteAt(at("fill"), STYLE_ISSUE.NO_FILL, "transparent");
789
+ put("fillOpacity", 0);
790
+ return;
791
+ }
792
+ readColor(treeAttr(fill, "color"), "fill", "fillOpacity", put, at);
793
+ const second = canonColor(treeAttr(fill, "color2"), "yed", at("fillGradient"));
794
+ if (second !== null) {
795
+ put("fillGradient", second.color);
796
+ put("fillGradientAngle", YED_GRADIENT_ANGLE);
797
+ }
798
+ }
799
+ /**
800
+ * A `y:TableNode`'s `yed.table.*` style property, as a color.
801
+ * @param real - the table realizer
802
+ * @param name - the property's name
803
+ * @param at - the sites
804
+ * @returns the `#rrggbb` color, or null when the table does not set it
805
+ */
806
+ function tableColor(real, name, at) {
807
+ const props = treeChildren(treeChild(real.r, "StyleProperties"), "Property");
808
+ const prop = props.find((p) => treeAttr(p, "name") === name);
809
+ return prop === undefined ? null : (canonColor(treeAttr(prop, "value"), "yed", at("stripeColors"))?.color ?? null);
810
+ }
811
+ /**
812
+ * Reads a `y:TableNode` (a yEd table or BPMN pool) as bands over the node: its header (the table's top inset, or
813
+ * its left one for columns side by side) in `yed.table.header.color.main`, then its rows top to bottom (or its
814
+ * columns left to right) in `yed.table.lane.color.main` and `.alternating` by turns, then the opposite inset. A
815
+ * color the table does not set is the node's fill. The lines between the lanes and the row and column headers
816
+ * (`yed.table.header.color.alternating`) are not drawn.
817
+ * @param real - the realizer
818
+ * @param put - receives the values
819
+ * @param at - the sites
820
+ */
821
+ function readTable(real, put, at) {
822
+ const table = treeChild(real.r, "Table");
823
+ const rows = treeChildren(treeChild(table, "Rows"), "Row");
824
+ const columns = treeChildren(treeChild(table, "Columns"), "Column");
825
+ const across = columns.length > 1 && rows.length <= 1;
826
+ const lanes = (across ? columns : rows).map((l) => Number(treeAttr(l, across ? "width" : "height")));
827
+ const insets = treeChild(table, "Insets");
828
+ const inset = (side) => Math.max(0, Number(treeAttr(insets, side) ?? 0) || 0);
829
+ const [head, tail] = across ? [inset("left"), inset("right")] : [inset("top"), inset("bottom")];
830
+ const sizes = [head, ...lanes, tail];
831
+ const total = sizes.reduce((a, b) => a + b, 0);
832
+ if (lanes.length === 0 || !sizes.every(Number.isFinite) || total <= 0) {
833
+ return;
834
+ }
835
+ const fill = canonColor(treeAttr(treeChild(real.r, "Fill"), "color"), "yed", at("stripeColors"))?.color ?? "#ffffff";
836
+ const main = tableColor(real, "yed.table.lane.color.main", at) ?? fill;
837
+ const alternating = tableColor(real, "yed.table.lane.color.alternating", at) ?? main;
838
+ const header = tableColor(real, "yed.table.header.color.main", at) ?? fill;
839
+ const bands = [[head, header], ...lanes.map((size, i) => [size, i % 2 === 0 ? main : alternating]), [tail, fill]].filter(([size]) => size > 0);
840
+ put("stripeColors", bands.map(([, color]) => color).join(" "));
841
+ put("stripeSizes", bands.map(([size]) => String(Number((size / total).toFixed(6)))).join(" "));
842
+ if (across) {
843
+ put("stripeDirection", "right");
844
+ }
845
+ }
846
+ /**
847
+ * yEd's shared pictures (`<y:Resources>` on the graph): each resource's id to the picture as a URL, an SVG's text as
848
+ * a `data:image/svg+xml` URL and a `java.awt.image.BufferedImage` (base64 PNG) as a `data:image/png` one.
849
+ * @param snapshot - the graph
850
+ * @returns the pictures by id
851
+ */
852
+ function yedResources(snapshot) {
853
+ const out = new Map();
854
+ for (const col of snapshot.graph) {
855
+ if (col.dtype !== "json" || col.meta.origin?.namespace !== "yfiles") {
856
+ continue;
398
857
  }
399
- else {
400
- readColor(treeAttr(fill, "color"), "fill", "fillOpacity", put, at);
401
- const second = treeAttr(fill, "color2");
402
- if (second !== undefined) {
403
- noteAt(at("fill"), STYLE_ISSUE.GRADIENT, second);
858
+ addYedResources(plainCell(snapshot.graph.value(col.meta.name, 0)), out);
859
+ }
860
+ return out;
861
+ }
862
+ /**
863
+ * Adds the pictures of one yFiles graph value's `<y:Resources>`; an id already there keeps its picture.
864
+ * @param root - the graph's yFiles value
865
+ * @param out - the pictures by id, added to
866
+ */
867
+ function addYedResources(root, out) {
868
+ for (const resources of treeChildren(root, "Resources")) {
869
+ for (const r of treeChildren(resources, "Resource")) {
870
+ const id = treeAttr(r, "id");
871
+ const url = id === undefined || out.has(id) ? null : yedResourceUrl(r);
872
+ if (id !== undefined && url !== null) {
873
+ out.set(id, url);
404
874
  }
405
875
  }
406
876
  }
877
+ }
878
+ /**
879
+ * One `<y:Resource>` as a picture URL: a `java.awt.image.BufferedImage` (base64 PNG) as a `data:image/png` URL and
880
+ * an SVG's text as a `data:image/svg+xml` one.
881
+ * @param r - the resource element
882
+ * @returns the URL, or null for an empty resource or one that is no picture
883
+ */
884
+ function yedResourceUrl(r) {
885
+ const text = treeText(r)?.trim() ?? "";
886
+ if (text === "") {
887
+ return null;
888
+ }
889
+ const type = treeAttr(r, "type") ?? "";
890
+ if (type.endsWith("BufferedImage")) {
891
+ return `data:image/png;base64,${text.replaceAll(/\s+/g, "")}`;
892
+ }
893
+ if (text.includes("<svg")) {
894
+ return `data:image/svg+xml;utf8,${encodeURIComponent(text)}`;
895
+ }
896
+ return null;
897
+ }
898
+ /**
899
+ * The picture an image or SVG node realizer draws (`y:Image refid`, `y:SVGModel/y:SVGContent refid`), stretched over
900
+ * the node's box, as yEd draws `y:ImageNode` and `y:SVGNode`. The realizer's own fill and border are kept beneath it:
901
+ * whether yEd paints them under the picture waits for a drawing by yEd itself (ISSUES.md).
902
+ * @param real - the realizer
903
+ * @param resources - the graph's shared pictures
904
+ * @param put - receives the values
905
+ */
906
+ function readPicture(real, resources, put) {
907
+ const ref = real.type === "ImageNode"
908
+ ? treeAttr(treeChild(real.r, "Image"), "refid")
909
+ : treeAttr(treeChild(treeChild(real.r, "SVGModel"), "SVGContent"), "refid");
910
+ const src = ref === undefined ? undefined : resources.get(ref);
911
+ if (src === undefined) {
912
+ return;
913
+ }
914
+ put("image", src);
915
+ put("imageFit", "fill");
916
+ put("imageClip", "none");
917
+ }
918
+ /**
919
+ * Reads one node realizer.
920
+ * @param real - the realizer
921
+ * @param put - receives the values
922
+ * @param at - the sites
923
+ * @param resources - the graph's shared pictures, for image and SVG nodes
924
+ */
925
+ function readNode(real, put, at, resources) {
926
+ const { r } = real;
927
+ readFill(real, put, at);
407
928
  const border = treeChild(r, "BorderStyle");
408
929
  if (border !== undefined) {
409
930
  if (treeAttr(border, "hasColor") === "false") {
@@ -419,7 +940,17 @@ function readNode(real, put, at) {
419
940
  put("width", canonNumber(treeAttr(geometry, "width"), at("width")));
420
941
  put("height", canonNumber(treeAttr(geometry, "height"), at("height")));
421
942
  put("shape", realizerShape(real, at));
422
- readLabels(treeChildren(r, "NodeLabel"), true, put, at);
943
+ const points = real.type === "GenericNode" ? configurationOutline(treeAttr(r, "configuration") ?? "")?.points : undefined;
944
+ if (points !== undefined) {
945
+ put("shapePoints", points);
946
+ }
947
+ if (real.type === "TableNode") {
948
+ readTable(real, put, at);
949
+ }
950
+ if (resources !== undefined && (real.type === "ImageNode" || real.type === "SVGNode")) {
951
+ readPicture(real, resources, put);
952
+ }
953
+ readLabels(treeChildren(r, "NodeLabel"), true, put, at, geometry);
423
954
  }
424
955
  /**
425
956
  * Reads one edge realizer.
@@ -441,11 +972,20 @@ function readEdge(real, put, at) {
441
972
  put("targetArrow", canonEnum("arrow", treeAttr(arrows, "target"), "yed", at("targetArrow")));
442
973
  }
443
974
  put("curved", edgeCurved(real));
975
+ if (real.type === "ArcEdge") {
976
+ // the bend yEd saves is the arc's apex, `y:Arc height` from the line between the ends (every yEd-saved arc
977
+ // in the corpus: scala-collection-mutable, Animatron__player__flow), so the arc is the circle through it
978
+ put("bendCurve", "arc");
979
+ }
444
980
  readLabels(treeChildren(r, "EdgeLabel"), false, put, at);
445
981
  }
446
982
  /**
447
- * Whether yEd draws an edge curved: an arc always; a Bezier, quad curve, spline or generic edge only through its
448
- * control points (with none it is a straight line); a polyline only when it smooths bends it has.
983
+ * Whether an edge is drawn curved through its bends: an arc always; a spline only through its control points (with
984
+ * none it is a straight line); a polyline, and a generic edge (a framed or styled polyline), only when it smooths
985
+ * bends it has. A quad curve edge never, nor a Bezier edge of whole cubic pieces (two control points, five, ...): its
986
+ * curve is flattened into points on it (`readEdgeRoute`), drawn straight from one to the next, as a Graphviz spline
987
+ * is; rounding their corners cut inside the curve (a quad curve of straightness 1, whose points are its control
988
+ * polygon, was drawn bowed).
449
989
  * @param real - the edge realizer
450
990
  * @returns true when curved, null when a polyline does not say whether it smooths
451
991
  */
@@ -453,30 +993,61 @@ function edgeCurved(real) {
453
993
  if (real.type === "ArcEdge") {
454
994
  return true;
455
995
  }
456
- const bent = treeChildren(treeChild(real.r, "Path"), "Point").length > 0;
457
- if (real.type !== "PolyLineEdge") {
996
+ const points = treeChildren(treeChild(real.r, "Path"), "Point").length;
997
+ if (real.type === "QuadCurveEdge") {
998
+ return false;
999
+ }
1000
+ if (real.type === "BezierEdge") {
1001
+ // a count of control points no run of cubic pieces takes is not flattened: its corners are rounded
1002
+ return points > 0 && (points + 1) % 3 !== 0;
1003
+ }
1004
+ const bent = points > 0;
1005
+ if (real.type !== "PolyLineEdge" && real.type !== "GenericEdge") {
458
1006
  return bent;
459
1007
  }
460
1008
  const smoothed = treeAttr(treeChild(real.r, "BendStyle"), "smoothed");
461
1009
  return smoothed === undefined ? null : smoothed === "true" && bent;
462
1010
  }
463
1011
  /**
464
- * An edge's bends: the points of its `y:Path`, relative to the centers of its two nodes. yEd draws a polyline through
465
- * them; a curve type (Bezier, quad curve, spline) passes near them as its control points.
1012
+ * An edge's route from its `y:Path`: the ports its ends attach at (`sx sy`, `tx ty`: offsets from the node centers),
1013
+ * relative to each node's size, and its bends, relative to the centers of its two nodes (a self-loop's to its node's
1014
+ * size). yEd draws a polyline, an arc or a spline through the points; a Bezier or quad curve edge takes them as
1015
+ * control points its curve does not pass through, so its curve is flattened into the points it does pass through.
466
1016
  * @param real - the edge realizer
467
- * @param centers - each node's center, x and y
1017
+ * @param nodes - each node's center x and y, width and height
468
1018
  * @param source - the source node's index
469
1019
  * @param target - the target node's index
470
- * @returns the `bends` value, or null without bends
1020
+ * @param put - receives the values
471
1021
  */
472
- function edgeBends(real, centers, source, target) {
473
- const points = treeChildren(treeChild(real.r, "Path"), "Point").map((p) => [
1022
+ function readEdgeRoute(real, nodes, source, target, put) {
1023
+ const path = treeChild(real.r, "Path");
1024
+ const at = (k) => [nodes[4 * k], nodes[4 * k + 1]];
1025
+ const size = (k) => [nodes[4 * k + 2], nodes[4 * k + 3]];
1026
+ const offset = (key) => Number(treeAttr(path, key) ?? 0) || 0;
1027
+ const ends = [
1028
+ [at(source)[0] + offset("sx"), at(source)[1] + offset("sy")],
1029
+ [at(target)[0] + offset("tx"), at(target)[1] + offset("ty")],
1030
+ ];
1031
+ const port = (k, end) => end[0] === at(k)[0] && end[1] === at(k)[1] ? null : canonNodeOffsets(at(k), size(k), [end], true);
1032
+ put("sourcePort", port(source, ends[0]));
1033
+ put("targetPort", port(target, ends[1]));
1034
+ let points = treeChildren(path, "Point").map((p) => [
474
1035
  Number(treeAttr(p, "x")),
475
1036
  Number(treeAttr(p, "y")),
476
1037
  ]);
477
- const at = (k) => [centers[2 * k], centers[2 * k + 1]];
478
- return canonBends(at(source), at(target), points, true);
1038
+ if (points.length > 0 && (real.type === "BezierEdge" || real.type === "QuadCurveEdge")) {
1039
+ const controls = [ends[0], ...points, ends[1]];
1040
+ const curve = real.type === "BezierEdge"
1041
+ ? flattenCubic(controls)
1042
+ : flattenQuadSpline(controls, Number(treeAttr(real.r, "straightness") ?? YED_STRAIGHTNESS));
1043
+ points = (curve ?? controls).slice(1, -1);
1044
+ }
1045
+ put("bends", source === target
1046
+ ? canonNodeOffsets(at(source), size(source), points, true)
1047
+ : canonBends(at(source), at(target), points, true));
479
1048
  }
1049
+ /** yEd's quad curve straightness when a file gives none. */
1050
+ const YED_STRAIGHTNESS = 0.1;
480
1051
  /**
481
1052
  * A collector of canonical values for one target.
482
1053
  * @param n - the element count
@@ -503,8 +1074,9 @@ export function valueColumns(n) {
503
1074
  */
504
1075
  export function readYedStyles(snapshot, notes, budget) {
505
1076
  let found = false;
506
- // each node's center, read with the node, for its edges' bends; NaN for a node without yEd graphics
507
- const centers = new Float64Array(2 * snapshot.nodeCount).fill(Number.NaN);
1077
+ const resources = yedResources(snapshot);
1078
+ // each node's center, width and height, read with the node, for its edges' routes; NaN without yEd graphics
1079
+ const boxes = new Float64Array(4 * snapshot.nodeCount).fill(Number.NaN);
508
1080
  const read = (target) => {
509
1081
  const table = target === "node" ? snapshot.nodes : snapshot.edges;
510
1082
  const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
@@ -529,14 +1101,14 @@ export function readYedStyles(snapshot, notes, budget) {
529
1101
  out.put(i, property, value);
530
1102
  };
531
1103
  if (target === "node") {
532
- readNode(real, put, at);
1104
+ readNode(real, put, at, resources);
533
1105
  const geometry = treeChild(real.r, "Geometry");
534
- centers[2 * i] = Number(treeAttr(geometry, "x")) + Number(treeAttr(geometry, "width")) / 2;
535
- centers[2 * i + 1] = Number(treeAttr(geometry, "y")) + Number(treeAttr(geometry, "height")) / 2;
1106
+ const [w, h] = [Number(treeAttr(geometry, "width")), Number(treeAttr(geometry, "height"))];
1107
+ boxes.set([Number(treeAttr(geometry, "x")) + w / 2, Number(treeAttr(geometry, "y")) + h / 2, w, h], 4 * i);
536
1108
  }
537
1109
  else {
538
1110
  readEdge(real, put, at);
539
- put("bends", edgeBends(real, centers, snapshot.edgeSource(i), snapshot.edgeTarget(i)));
1111
+ readEdgeRoute(real, boxes, snapshot.edgeSource(i), snapshot.edgeTarget(i), put);
540
1112
  }
541
1113
  }
542
1114
  return out.values;
@@ -552,9 +1124,12 @@ export function readYedStyles(snapshot, notes, budget) {
552
1124
  * @category Built-in formats
553
1125
  */
554
1126
  export const GRAPHML_STYLE_CAPABILITIES = Object.freeze({
1127
+ tool: "yed",
555
1128
  node: Object.freeze([
556
1129
  "fill",
557
1130
  "fillOpacity",
1131
+ "fillGradient",
1132
+ "fillGradientAngle",
558
1133
  "borderColor",
559
1134
  "borderWidth",
560
1135
  "borderStyle",
@@ -578,6 +1153,8 @@ export const GRAPHML_STYLE_CAPABILITIES = Object.freeze({
578
1153
  "targetArrow",
579
1154
  "curved",
580
1155
  "bends",
1156
+ "sourcePort",
1157
+ "targetPort",
581
1158
  "label",
582
1159
  "labelColor",
583
1160
  "labelSize",
@@ -621,17 +1198,18 @@ export const YED_ARROWS = new Map([
621
1198
  ["square", "skewed_dash"],
622
1199
  ["crow", "crows_foot_many"],
623
1200
  ]);
624
- /** yEd's label positions in the internal model, by neutral position. */
1201
+ /** yEd's internal label model positions by neutral position: the center, and against a side or in a corner inside. */
1202
+ const INTERNAL_MODEL_POSITIONS = new Map([...INTERNAL_POSITIONS].map(([model, position]) => [position, model]));
1203
+ /** yEd's eight-position label model positions by neutral position, all outside the node. */
625
1204
  const YED_MODEL_POSITIONS = new Map([
626
- ["center", "c"],
627
- ["top", "t"],
628
- ["bottom", "b"],
629
- ["left", "l"],
630
- ["right", "r"],
631
- ["top-left", "tl"],
632
- ["top-right", "tr"],
633
- ["bottom-left", "bl"],
634
- ["bottom-right", "br"],
1205
+ ["top", "n"],
1206
+ ["bottom", "s"],
1207
+ ["left", "w"],
1208
+ ["right", "e"],
1209
+ ["top-left", "nw"],
1210
+ ["top-right", "ne"],
1211
+ ["bottom-left", "sw"],
1212
+ ["bottom-right", "se"],
635
1213
  ]);
636
1214
  /**
637
1215
  * A value of a table, or the nearest value the table has.
@@ -681,22 +1259,30 @@ export function yedSpelled(table, value, nearest, property, approximate) {
681
1259
  }
682
1260
  return w.value;
683
1261
  }
1262
+ /** The Java logical font each family the reader gives one is written back as. */
1263
+ const JAVA_LOGICAL = {
1264
+ [JAVA_SANS]: "Dialog",
1265
+ [JAVA_SERIF]: "Serif",
1266
+ [JAVA_MONO]: "Monospaced",
1267
+ };
684
1268
  /**
685
- * The label attributes and text of one element.
1269
+ * A CSS family as the one font name yEd reads: a Java logical font's family as that font, else the list's first name.
1270
+ * @param family - the CSS family or family list
1271
+ * @returns the font name
1272
+ */
1273
+ export function yedFontName(family) {
1274
+ return Object.hasOwn(JAVA_LOGICAL, family) ? JAVA_LOGICAL[family] : family.split(",")[0].trim();
1275
+ }
1276
+ /**
1277
+ * A label's font attributes: family, size and style.
686
1278
  * @param get - the element's values
687
- * @param node - whether it is a node label (which has a position)
688
- * @param approximate - records approximations
689
- * @returns the label element, or null when the element has no label text
1279
+ * @returns the label element holding them
690
1280
  */
691
- function labelTree(get, node, approximate) {
692
- const text = get("label");
693
- if (typeof text !== "string" || text.trim().length === 0) {
694
- return null;
695
- }
1281
+ function labelFontTree(get) {
696
1282
  const label = {};
697
1283
  const font = get("labelFont");
698
1284
  if (typeof font === "string") {
699
- label["@_fontFamily"] = font;
1285
+ label["@_fontFamily"] = yedFontName(font);
700
1286
  }
701
1287
  const size = get("labelSize");
702
1288
  if (typeof size === "number") {
@@ -708,18 +1294,35 @@ function labelTree(get, node, approximate) {
708
1294
  const style = (weight === "bold" ? "bold" : "") + (italic === true ? "italic" : "");
709
1295
  label["@_fontStyle"] = style.length === 0 ? "plain" : style;
710
1296
  }
1297
+ return label;
1298
+ }
1299
+ /**
1300
+ * The label attributes and text of one element.
1301
+ * @param get - the element's values
1302
+ * @param node - whether it is a node label (which has a position)
1303
+ * @param approximate - records approximations
1304
+ * @returns the label element, or null when the element has no label text
1305
+ */
1306
+ function labelTree(get, node, approximate) {
1307
+ const text = get("label");
1308
+ if (typeof text !== "string" || text.trim().length === 0) {
1309
+ return null;
1310
+ }
1311
+ const label = labelFontTree(get);
711
1312
  const color = get("labelColor");
712
1313
  if (typeof color === "string") {
713
1314
  label["@_textColor"] = color.toUpperCase();
714
1315
  }
715
1316
  const position = node ? get("labelPosition") : null;
716
1317
  if (typeof position === "string") {
717
- const written = YED_MODEL_POSITIONS.get(position);
718
- if (written === undefined) {
1318
+ const inside = INTERNAL_MODEL_POSITIONS.get(position);
1319
+ const outside = YED_MODEL_POSITIONS.get(position);
1320
+ if (inside === undefined && outside === undefined) {
719
1321
  approximate("labelPosition", position);
720
1322
  }
721
- label["@_modelName"] = "internal";
722
- label["@_modelPosition"] = written ?? "c";
1323
+ // the center and the inside positions in yEd's internal model, the outside ones in its eight-position one
1324
+ label["@_modelName"] = outside === undefined ? "internal" : "eight_pos";
1325
+ label["@_modelPosition"] = outside ?? inside ?? "c";
723
1326
  }
724
1327
  label["#text"] = text;
725
1328
  return label;
@@ -738,6 +1341,14 @@ function shapeNodeTree(get, at, approximate) {
738
1341
  const fillOpacity = get("fillOpacity");
739
1342
  if (typeof fill === "string") {
740
1343
  node["y:Fill"] = { "@_color": yedColor(fill, fillOpacity), "@_transparent": "false" };
1344
+ const second = get("fillGradient");
1345
+ if (typeof second === "string") {
1346
+ node["y:Fill"]["@_color2"] = second.toUpperCase();
1347
+ const angle = get("fillGradientAngle");
1348
+ if (angle !== YED_GRADIENT_ANGLE) {
1349
+ approximate("fillGradientAngle", angle ?? 0);
1350
+ }
1351
+ }
741
1352
  }
742
1353
  else if (fillOpacity === 0) {
743
1354
  node["y:Fill"] = { "@_hasColor": "false", "@_transparent": "false" };
@@ -842,50 +1453,25 @@ function polyLineEdgeTree(get, path, approximate) {
842
1453
  }
843
1454
  return { "y:PolyLineEdge": edge };
844
1455
  }
845
- /**
846
- * Each element's values of the properties the writer writes, as a getter per element.
847
- * @param picture - each element's value of a property
848
- * @param target - nodes or edges
849
- * @returns the getter
850
- */
851
- function getter(picture, target) {
852
- const columns = new Map();
853
- for (const p of GRAPHML_STYLE_CAPABILITIES[target]) {
854
- columns.set(p, picture(target, p));
855
- }
856
- return (i) => (property) => columns.get(property)?.[i] ?? null;
857
- }
858
1456
  /**
859
1457
  * For a file graphty wrote: where a value read from the yEd graphics is what the writer writes for the block's own
860
1458
  * value (a pentagon written as a hexagon, an opacity rounded to yEd's 255 steps), the block's exact value is the
861
1459
  * truth, so a re-import gives back the same rules; a value another program changed since stays the truth.
1460
+ * @param snapshot - the graph
1461
+ * @param text - the block's text
862
1462
  * @param read - the values the reader read, changed in place
863
- * @param picture - each element's value of a property under the block's rules
864
- * @param counts - the node and edge counts
865
- * @param counts.node - the node count
866
- * @param counts.edge - the edge count
867
- * @param notes - a scratch note list for reading back what the writer writes
868
1463
  */
869
- export function exactFromBlock(read, picture, counts, notes) {
870
- for (const target of ["node", "edge"]) {
871
- const values = read[target];
872
- const get = getter(picture, target);
873
- for (let i = 0; i < counts[target]; i++) {
874
- const want = get(i);
1464
+ export function exactFromBlock(snapshot, text, read) {
1465
+ const notes = new StyleNotes();
1466
+ takeFromBlock(snapshot, text, "graphml", (target) => ({
1467
+ values: read[target],
1468
+ properties: GRAPHML_STYLE_CAPABILITIES[target],
1469
+ writes: GRAPHML_STYLE_CAPABILITIES[target],
1470
+ readBack: (_i, want) => {
875
1471
  const back = writtenAndReadBack(target, want, notes);
876
- if (back === null) {
877
- continue;
878
- }
879
- for (const property of GRAPHML_STYLE_CAPABILITIES[target]) {
880
- const native = values[property]?.[i] ?? null;
881
- const w = want(property);
882
- if (native !== w && native === (back.get(property) ?? null)) {
883
- values[property] ?? (values[property] = new Array(counts[target]).fill(null));
884
- values[property][i] = w;
885
- }
886
- }
887
- }
888
- }
1472
+ return back === null ? null : (property) => back.get(property) ?? null;
1473
+ },
1474
+ }));
889
1475
  }
890
1476
  /**
891
1477
  * An element's values written as the writer writes them and read back as the reader reads them.
@@ -984,24 +1570,39 @@ function keptPath(table, columns, e) {
984
1570
  return undefined;
985
1571
  }
986
1572
  /**
987
- * An edge's `y:Path` with its points placed from its `bends` value between the written node centers, so the bends
988
- * read back as written; the ports of the path it had are kept. Without a value, or without both centers, the path it
989
- * had.
1573
+ * An edge's `y:Path` with its points placed from its `bends` value between the written node centers (a self-loop's
1574
+ * around its node) and its ports from its `sourcePort` and `targetPort`, so they read back as written; a port with no
1575
+ * value keeps the one of the path it had. Without a bend or port value, or without both centers, the path it had.
990
1576
  * @param kept - the path from the graphics the edge had, or undefined
991
- * @param bends - the edge's `bends` value
992
- * @param ends - the written centers of its source and target
1577
+ * @param get - the edge's values
1578
+ * @param ends - the written boxes of its source and target
1579
+ * @param loop - whether the edge is a self-loop
993
1580
  * @returns the path, or undefined
994
1581
  */
995
- function pathWithBends(kept, bends, ends) {
996
- const points = typeof bends === "string" ? bendsToPoints(ends[0], ends[1], bends, true) : null;
997
- if (points === null) {
1582
+ function pathWithRoute(kept, get, ends, loop) {
1583
+ const bends = get("bends");
1584
+ const [[c0, size0], [c1]] = ends;
1585
+ let points = null;
1586
+ if (typeof bends === "string") {
1587
+ points = loop ? nodeOffsetsToPoints(c0, size0, bends, true) : bendsToPoints(c0, c1, bends, true);
1588
+ }
1589
+ const ports = ["sourcePort", "targetPort"].map((property, k) => {
1590
+ const value = get(property);
1591
+ const [center, size] = ends[k];
1592
+ const at = typeof value === "string" ? nodeOffsetsToPoints(center, size, value, true) : null;
1593
+ return at === null ? null : [at[0][0] - center[0], at[0][1] - center[1]];
1594
+ });
1595
+ if (points === null && ports.every((p) => p === null)) {
998
1596
  return kept;
999
1597
  }
1000
1598
  const path = {};
1001
- for (const port of ["sx", "sy", "tx", "ty"]) {
1002
- path[`@_${port}`] = treeAttr(kept, port) ?? "0.0";
1003
- }
1004
- path["y:Point"] = points.map(([x, y]) => ({ "@_x": String(x), "@_y": String(y) }));
1599
+ ["sx", "sy", "tx", "ty"].forEach((key, k) => {
1600
+ const port = ports[k >> 1];
1601
+ path[`@_${key}`] = port === null ? (treeAttr(kept, key) ?? "0.0") : String(port[k & 1]);
1602
+ });
1603
+ const written = points ??
1604
+ treeChildren(kept, "Point").map((q) => [Number(treeAttr(q, "x")), Number(treeAttr(q, "y"))]);
1605
+ path["y:Point"] = written.map(([x, y]) => ({ "@_x": String(x), "@_y": String(y) }));
1005
1606
  return path;
1006
1607
  }
1007
1608
  /**
@@ -1039,27 +1640,27 @@ export function graphmlStyledExport(snapshot, input) {
1039
1640
  const picture = (target, property) => input.picture(target, property);
1040
1641
  const nodeColumns = treeColumns(snapshot.nodes);
1041
1642
  const edgeColumns = treeColumns(snapshot.edges);
1042
- const getNode = getter(picture, "node");
1043
- const getEdge = getter(picture, "edge");
1643
+ const getNode = elementValues(picture, "node", GRAPHML_STYLE_CAPABILITIES.node);
1644
+ const getEdge = elementValues(picture, "edge", GRAPHML_STYLE_CAPABILITIES.edge);
1044
1645
  const nodeTrees = [];
1045
1646
  for (let i = 0; i < snapshot.nodeCount; i++) {
1046
1647
  const get = getNode(i);
1047
1648
  const at = keptPosition(snapshot.nodes, nodeColumns, i) ?? columnPosition(snapshot, i, get);
1048
1649
  nodeTrees.push(shapeNodeTree(get, at, approximateFor("node")));
1049
1650
  }
1050
- const centers = nodeTrees.map((tree) => {
1651
+ const boxes = nodeTrees.map((tree) => {
1051
1652
  const geometry = treeChild(treeChild(tree, "ShapeNode"), "Geometry");
1052
1653
  const at = (k) => Number(treeAttr(geometry, k) ?? Number.NaN);
1053
- return [at("x") + at("width") / 2, at("y") + at("height") / 2];
1654
+ return [
1655
+ [at("x") + at("width") / 2, at("y") + at("height") / 2],
1656
+ [at("width"), at("height")],
1657
+ ];
1054
1658
  });
1055
1659
  const edgeTrees = [];
1056
1660
  for (let e = 0; e < snapshot.edgeCount; e++) {
1057
1661
  const get = getEdge(e);
1058
- const ends = [
1059
- centers[snapshot.edgeSource(e)],
1060
- centers[snapshot.edgeTarget(e)],
1061
- ];
1062
- const path = pathWithBends(keptPath(snapshot.edges, edgeColumns, e), get("bends"), ends);
1662
+ const [source, target] = [snapshot.edgeSource(e), snapshot.edgeTarget(e)];
1663
+ const path = pathWithRoute(keptPath(snapshot.edges, edgeColumns, e), get, [boxes[source], boxes[target]], source === target);
1063
1664
  edgeTrees.push(polyLineEdgeTree(get, path, approximateFor("edge")));
1064
1665
  }
1065
1666
  const out = snapshot.withColumns();