@graphty/graph-io 0.3.42 → 0.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
  2. package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
  3. package/dist/chunks/block-JQiwViEt.js +2777 -0
  4. package/dist/chunks/block-JQiwViEt.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
  8. package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DCwFLts5.js +3456 -0
  12. package/dist/chunks/emit-DCwFLts5.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
  14. package/dist/chunks/escape-B1rMftd9.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
  16. package/dist/chunks/export-D7IGzTG4.js.map +1 -0
  17. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
  18. package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
  19. package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
  20. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
  22. package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
  23. package/dist/chunks/{exporter-CpRyHZ3H.js → exporter-quPUCBiC.js} +1807 -288
  24. package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
  25. package/dist/chunks/format-GDmO6m6Q.js +676 -0
  26. package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
  27. package/dist/chunks/generic-BL06jrJf.js +1347 -0
  28. package/dist/chunks/generic-BL06jrJf.js.map +1 -0
  29. package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
  30. package/dist/chunks/importer-B7r2owVf.js.map +1 -0
  31. package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
  32. package/dist/chunks/importer-BFmOP96W.js.map +1 -0
  33. package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
  34. package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
  35. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
  36. package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
  37. package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
  38. package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
  39. package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
  40. package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
  41. package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
  42. package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
  43. package/dist/chunks/index-B9fdNpTA.js +4310 -0
  44. package/dist/chunks/index-B9fdNpTA.js.map +1 -0
  45. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
  46. package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
  47. package/dist/chunks/lexicon-B-knUi-l.js +508 -0
  48. package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
  49. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
  50. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
  51. package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
  52. package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
  53. package/dist/chunks/styles-Brt9JMfs.js +690 -0
  54. package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
  55. package/dist/chunks/styles-_N-C8S-U.js +2102 -0
  56. package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
  57. package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
  58. package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
  59. package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
  60. package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
  61. package/dist/chunks/units-XMZFIFe1.js +19 -0
  62. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +295 -414
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +8 -3031
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +354 -240
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1484 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +23 -7
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +441 -265
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +790 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +603 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +80 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +596 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1741 -0
  571. package/src/formats/gexf/exporter.ts +30 -13
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +543 -323
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +951 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +656 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +745 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-CpRyHZ3H.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -1,9 +1,14 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { c as capabilities, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, o as DUPLICATE_ATTRIBUTE_CODE, g as UNKNOWN_ELEMENT_CODE, b5 as EMPTY_COLUMN_DROPPED_CODE, ai as PARENT_CYCLE_CODE, P as PRECISION_CODE, w as UNKNOWN_ENCODING_CODE, a2 as JSON_NONSTANDARD_NUMBER_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ad as TOO_LARGE_CODE, i as DANGLING_REFERENCE_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, m as DUPLICATE_EDGE_ID_CODE, n as DUPLICATE_NODE_CODE, q as UNKNOWN_PARENT_CODE, a3 as BAD_VALUE_CODE, s as MISSING_ENDPOINT_CODE, t as MISSING_ID_CODE, ak as SYNTAX_CODE, E as EMPTY_INPUT_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, bB as readText, b as plural, ao as reportSinkOptions, an as reportUnusedOptions, am as throwIfAborted, ar as IdCoercer, aq as DirectionResolver, $ as agree, as as weightFromValue, a0 as uniqueColumnName, a7 as chooseGraph, ap as graphChosen, a1 as declareResolved, aB as GRAPH_COLUMN_AS_METADATA_CODE, aC as TYPEDEF_NODES_CODE, aD as RELATION_ASSUMED_CODE, at as COLUMN_AS_PROPERTY_VALUE_CODE, p as pairFolding, e as explicitWeights, bd as NONFINITE_AS_NULL_CODE, L as LOSS, b3 as DIRECTION_DROPPED_CODE, aA as NODE_ORDER_CODE, r as resolveExportOptions, b_ as otherFormatDialect, a as checkCapabilities, bD as countMixedEdges, aa as formatF32, ab as formatF64 } from "./export-rKLeGQMo.js";
3
- import { M as MAYBE_UNSAFE_INTEGER, j as MAYBE_INEXACT_EXPONENT, l as rewriteNumbers, m as findDuplicateKeys, f as flipY } from "./json-elements-DKSqpNW1.js";
2
+ import { R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, k as DUPLICATE_ATTRIBUTE_CODE, c as UNKNOWN_ELEMENT_CODE, ax as EMPTY_COLUMN_DROPPED_CODE, a6 as PARENT_CYCLE_CODE, P as PRECISION_CODE, r as UNKNOWN_ENCODING_CODE, W as JSON_NONSTANDARD_NUMBER_CODE, s as ENCODING_FALLBACK_CODE, t as INVALID_ENCODING_CODE, u as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, H as HYPEREDGE_CODE, a1 as TOO_LARGE_CODE, e as DANGLING_REFERENCE_CODE, a2 as AMBIGUOUS_GRAPH_NAME_CODE, a3 as GRAPH_NOT_FOUND_CODE, h as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, i as DUPLICATE_EDGE_ID_CODE, j as DUPLICATE_NODE_CODE, l as UNKNOWN_PARENT_CODE, Y as BAD_VALUE_CODE, m as MISSING_ENDPOINT_CODE, n as MISSING_ID_CODE, a8 as SYNTAX_CODE, E as EMPTY_INPUT_CODE, x as ELEMENT_ISSUE, y as INPUT_ISSUE, Z as ImportReportBuilder, p as plural, V as agree, ag as GRAPH_COLUMN_AS_METADATA_CODE, ah as TYPEDEF_NODES_CODE, ai as RELATION_ASSUMED_CODE, a9 as COLUMN_AS_PROPERTY_VALUE_CODE, aE as NONFINITE_AS_NULL_CODE, av as DIRECTION_DROPPED_CODE, af as NODE_ORDER_CODE, $ as formatF32, a0 as formatF64 } from "./format-GDmO6m6Q.js";
3
+ import { c as capabilities, g as resolveImportOptions, ab as readText, j as reportSinkOptions, i as reportUnusedOptions, h as throwIfAborted, I as IdCoercer, l as DirectionResolver, w as weightFromValue, u as uniqueColumnName, f as chooseGraph, k as graphChosen, d as declareResolved, p as pairFolding, e as explicitWeights, L as LOSS, a as checkCapabilities, r as resolveExportOptions, ah as otherFormatDialect, ai as countMixedEdges } from "./export-D7IGzTG4.js";
4
4
  import { j as joinText, e as encodeChunks, i as indentUnit } from "./writer-DxjgHwSe.js";
5
- import { t as trimTrailingZeros } from "./text-DHOJXnED.js";
6
- import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-CtRXjg_i.js";
5
+ import { S as STYLE_BLOCK_NAME, w as toolDefaults, j as StyleNotes, p as parseStyleBlock, k as styleFingerprint, a as STYLE_ISSUE, m as plainCell, g as canonBoolean, h as canonText, b as canonNumber, l as blockStyles, c as canonColor, f as canonEnum, e as canonOpacity, r as resolveStyles } from "./block-JQiwViEt.js";
6
+ import { t as trimTrailingZeros } from "./text-CgzMqHQb.js";
7
+ import { d as OBOGRAPHS_PREDICATE_TAGS, g as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, h as synonymScopeOf, O as OBO_NODE_COLUMNS, c as capabilityNotes, s as slotColumn, e as emptyColumnNotes, j as OBO_PURL, f as framelessNodes, m as movedNodes, U as UNWRITTEN_ROLES, n as notePropertyColumn, a as cellOf, v as valuesOf$1, k as OBO_IN_OWL, b as fitsVocabulary, t as textOf, S as SYNONYM_SCOPES } from "./ontology-export-BSpbY5FL.js";
8
+ import { M as MAYBE_UNSAFE_INTEGER, g as MAYBE_INEXACT_EXPONENT, j as rewriteNumbers, l as findDuplicateKeys, m as keysInTextOrder } from "./json-elements-C4FwgnH5.js";
9
+ import { c as cytoscapeJsStyles, C as CYTOSCAPE_IMPORT_KEY, t as toCytoscapeStylesheet, a as cyjsHoldsExactly, b as CYJS_EDGE_PROPERTIES, d as CYJS_NODE_PROPERTIES } from "./emit-DCwFLts5.js";
10
+ import { S as StyleApproximations } from "./approximations-3Q4TsdTh.js";
11
+ import { f as flipY } from "./convert-BcQ8_jMo.js";
7
12
  const JSON_DIALECTS = Object.freeze([
8
13
  "node-link",
9
14
  "d3",
@@ -357,15 +362,15 @@ function sniffFormat(hints, importers) {
357
362
  function sniffJsonDialectHead(head) {
358
363
  const text = typeof head === "string" ? head : new TextDecoder("utf-8", { fatal: false }).decode(head);
359
364
  const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
360
- const trimmed = body.trimStart();
361
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
365
+ const trimmed2 = body.trimStart();
366
+ if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
362
367
  return null;
363
368
  }
364
369
  let root;
365
370
  try {
366
- root = JSON.parse(trimmed);
371
+ root = JSON.parse(trimmed2);
367
372
  } catch {
368
- const skeleton = skeletonOf(trimmed);
373
+ const skeleton = skeletonOf(trimmed2);
369
374
  root = skeleton;
370
375
  if (typeof skeleton === "object" && skeleton !== null && !Array.isArray(skeleton) && !["edges", "links", "directed", "multigraph", "graph"].some((key) => key in skeleton)) {
371
376
  const guess = sniffJsonDialect(skeleton);
@@ -565,6 +570,1367 @@ function clamp(value) {
565
570
  }
566
571
  return Math.min(value, 1);
567
572
  }
573
+ const Y_DOWN_MARKERS = ["vx", "vy", "fx", "fy", "index", "physics"];
574
+ function jsonPositions(snapshot) {
575
+ if (snapshot.nodes.byRole("position") !== null) {
576
+ return null;
577
+ }
578
+ const x = numeric(snapshot.nodes.get("x"));
579
+ const y = numeric(snapshot.nodes.get("y"));
580
+ if (x === null || y === null) {
581
+ return null;
582
+ }
583
+ const z = numeric(snapshot.nodes.get("z"));
584
+ const down = z === null && Y_DOWN_MARKERS.some((name) => snapshot.nodes.get(name) !== null);
585
+ return {
586
+ x: x.meta.name,
587
+ y: y.meta.name,
588
+ ...z === null ? {} : { z: z.meta.name },
589
+ yAxis: down ? "down" : "up",
590
+ units: down ? "px" : "file"
591
+ };
592
+ }
593
+ function numeric(column) {
594
+ const numericDtypes = ["f64", "f32", "i32", "u32", "u8"];
595
+ return column !== null && column.meta.components === 1 && numericDtypes.includes(column.dtype) ? column : null;
596
+ }
597
+ const TARGETS = ["node", "edge"];
598
+ function jsonStyles(snapshot, context) {
599
+ const src = context.kept;
600
+ if (!isJsonObject(src)) {
601
+ return null;
602
+ }
603
+ switch (src.dialect) {
604
+ case "cytoscape":
605
+ return cytoscapeStyles(snapshot, src, context);
606
+ case "graphology":
607
+ return graphologyStyles(snapshot, src, context);
608
+ case "vis":
609
+ return visStyles(snapshot, src, context);
610
+ case "node-link":
611
+ if (src.networkx === true) {
612
+ return networkxStyles(snapshot);
613
+ }
614
+ return src.block === null ? null : { canonical: true, block: src.block };
615
+ default:
616
+ return src.block === null ? null : { canonical: true, block: src.block };
617
+ }
618
+ }
619
+ function cytoscapeStyles(snapshot, src, context) {
620
+ const sheetless = (src.style === void 0 || src.style === null) && src.generatedBy?.startsWith("cytoscape-") === true;
621
+ const graphty = src.block !== null && parseStyleBlock(src.block, styleFingerprint(snapshot)).ok;
622
+ const read = cytoscapeJsStyles({
623
+ elements: withGeneratedIds(src.elements, src.generatedIds),
624
+ style: sheetless ? [] : src.style ?? [],
625
+ snapshot,
626
+ toolDefaults: !graphty && !sheetless,
627
+ budget: context.budget,
628
+ signal: context.signal
629
+ });
630
+ if (!("canonical" in read)) {
631
+ return read;
632
+ }
633
+ let tool = "cytoscape-js";
634
+ if (graphty) {
635
+ tool = null;
636
+ exactFromBlock(
637
+ snapshot,
638
+ src.block,
639
+ { node: read.node?.values ?? {}, edge: read.edge?.values ?? {} },
640
+ CYJS_WRITTEN,
641
+ cyjsHoldsExactly
642
+ );
643
+ } else if (sheetless) {
644
+ tool = "cytoscape";
645
+ }
646
+ return { ...read, tool, block: src.block };
647
+ }
648
+ const trimmed = (property) => (want) => {
649
+ const v = want(property);
650
+ return typeof v === "string" ? v.trim() : null;
651
+ };
652
+ const CYJS_TEXT = {
653
+ node: ["label"],
654
+ edge: ["label", "sourceLabel", "targetLabel"]
655
+ };
656
+ const CYJS_WRITTEN = {
657
+ node: Object.fromEntries(CYJS_TEXT.node.map((p) => [p, trimmed(p)])),
658
+ edge: {
659
+ ...Object.fromEntries(CYJS_TEXT.edge.map((p) => [p, trimmed(p)])),
660
+ // Cytoscape.js draws a loop curved whatever its curve style says
661
+ curved: (want, e, snapshot) => snapshot.edgeSource(e) === snapshot.edgeTarget(e) && want("curved") !== null ? true : want("curved")
662
+ }
663
+ };
664
+ function withGeneratedIds(elements, ids) {
665
+ if (ids === void 0 || ids.size === 0) {
666
+ return elements;
667
+ }
668
+ const patch = (e) => {
669
+ const id = isJsonObject(e) ? ids.get(e) : void 0;
670
+ return id === void 0 || !isJsonObject(e) ? e : { ...e, data: { ...e.data, id } };
671
+ };
672
+ if (Array.isArray(elements)) {
673
+ return elements.map(patch);
674
+ }
675
+ if (isJsonObject(elements) && Array.isArray(elements.nodes)) {
676
+ return { ...elements, nodes: elements.nodes.map(patch) };
677
+ }
678
+ return elements;
679
+ }
680
+ function networkxStyles(snapshot) {
681
+ return {
682
+ canonical: true,
683
+ dialect: null,
684
+ tool: "networkx",
685
+ units: "px",
686
+ node: { values: {} },
687
+ edge: directedArrows(snapshot)
688
+ };
689
+ }
690
+ function directedArrows(snapshot) {
691
+ if (!snapshot.directed || snapshot.edgeCount === 0) {
692
+ return { values: {}, rules: [], columns: /* @__PURE__ */ new Map() };
693
+ }
694
+ const col = snapshot.edges.byRole("directed");
695
+ const flags = Array.from(
696
+ { length: snapshot.edgeCount },
697
+ (_v, e) => col === null || plainCell(col.value(e)) !== false ? true : null
698
+ );
699
+ return {
700
+ values: {},
701
+ rules: [
702
+ {
703
+ id: "edge.tool.arrow",
704
+ target: "edge",
705
+ role: "group",
706
+ origin: "tool",
707
+ where: { has: { style: "directed" } },
708
+ set: { targetArrow: "triangle" }
709
+ }
710
+ ],
711
+ columns: /* @__PURE__ */ new Map([["directed", flags]])
712
+ };
713
+ }
714
+ function cells(snapshot, target, name) {
715
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
716
+ return table.has(name) ? (i) => plainCell(table.value(name, i)) : null;
717
+ }
718
+ function valuesOf(n) {
719
+ const values = {};
720
+ return {
721
+ values,
722
+ put: (p, i, v) => {
723
+ if (v !== null) {
724
+ setValue(values, p, n, i, v);
725
+ }
726
+ }
727
+ };
728
+ }
729
+ function setValue(values, property, n, i, v) {
730
+ values[property] ??= new Array(n).fill(null);
731
+ values[property][i] = v;
732
+ }
733
+ function graphologyStyles(snapshot, src, context) {
734
+ const notes = new StyleNotes();
735
+ const out = { node: {}, edge: {} };
736
+ const readFrom = { node: [], edge: [] };
737
+ for (const target of TARGETS) {
738
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
739
+ const { values, put } = valuesOf(n);
740
+ const keys = {
741
+ color: cells(snapshot, target, "color"),
742
+ size: cells(snapshot, target, "size"),
743
+ label: cells(snapshot, target, "label"),
744
+ hidden: cells(snapshot, target, "hidden")
745
+ };
746
+ readFrom[target].push(...Object.entries(keys).flatMap(([name, c]) => c === null ? [] : [name]));
747
+ for (let i = 0; i < n; i++) {
748
+ const site = (property) => ({
749
+ notes,
750
+ target,
751
+ property,
752
+ element: i,
753
+ budget: context.budget
754
+ });
755
+ readSigmaRow(keys, target, i, put, site);
756
+ }
757
+ out[target] = values;
758
+ }
759
+ exactFromBlock(snapshot, blockText(snapshot, src), out, GRAPHOLOGY_WRITTEN);
760
+ return {
761
+ canonical: true,
762
+ dialect: "graphology",
763
+ tool: "sigma",
764
+ opacityInColor: true,
765
+ units: "relative",
766
+ node: { values: out.node },
767
+ edge: { values: out.edge },
768
+ notes: notes.list(),
769
+ readFrom
770
+ };
771
+ }
772
+ function readSigmaRow(keys, target, i, put, site) {
773
+ const { color, size, label, hidden } = keys;
774
+ if (color !== null) {
775
+ const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
776
+ putColor(put, fill, opacity, i, color(i), site(fill));
777
+ }
778
+ if (size !== null) {
779
+ const v = canonNumber(size(i), site("width"));
780
+ put("width", i, v);
781
+ if (target === "node") {
782
+ put("height", i, v);
783
+ }
784
+ }
785
+ if (label !== null) {
786
+ put("label", i, canonText(label(i), site("label")));
787
+ }
788
+ if (hidden !== null && canonBoolean(hidden(i), site("visible")) === true) {
789
+ put("visible", i, false);
790
+ }
791
+ }
792
+ function putColor(put, property, opacity, i, raw, site) {
793
+ if (raw === null || raw === void 0 || raw === "") {
794
+ return;
795
+ }
796
+ const c = canonColor(raw, "css", site);
797
+ if (c === null) {
798
+ return;
799
+ }
800
+ put(property, i, c.color);
801
+ if (c.alpha < 1) {
802
+ if (opacity === null) {
803
+ site.notes.add(STYLE_ISSUE.ALPHA_DROPPED, site.target, property, { sample: raw, element: i });
804
+ } else {
805
+ put(opacity, i, c.alpha);
806
+ }
807
+ }
808
+ }
809
+ function blockText(snapshot, src) {
810
+ if (src.block !== null) {
811
+ return src.block;
812
+ }
813
+ if (!snapshot.graph.has(STYLE_BLOCK_NAME)) {
814
+ return null;
815
+ }
816
+ const v = plainCell(snapshot.graph.value(STYLE_BLOCK_NAME, 0));
817
+ return typeof v === "string" ? v : null;
818
+ }
819
+ function exactFromBlock(snapshot, text, values, written, holdsExactly) {
820
+ if (text === null) {
821
+ return;
822
+ }
823
+ const parsed = parseStyleBlock(text, styleFingerprint(snapshot));
824
+ const ex = parsed.ok ? blockStyles(parsed.block, snapshot, "json") : null;
825
+ if (ex === null) {
826
+ return;
827
+ }
828
+ for (const target of TARGETS) {
829
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
830
+ const cache = /* @__PURE__ */ new Map();
831
+ const resolved = (p) => {
832
+ let r = cache.get(p);
833
+ if (r === void 0) {
834
+ r = resolveStyles(ex, target, p, snapshot);
835
+ cache.set(p, r);
836
+ }
837
+ return r;
838
+ };
839
+ if (holdsExactly !== void 0) {
840
+ const properties = new Set(
841
+ ex.styles.rules.filter((r) => r.target === target).flatMap((r) => [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})])
842
+ );
843
+ for (const property of properties) {
844
+ const held = (w) => holdsExactly(target, property, w);
845
+ takeUnheld(values[target], property, resolved(property), n, held);
846
+ }
847
+ }
848
+ for (const [property, write2] of Object.entries(written[target] ?? {})) {
849
+ takeWritten(values[target], property, n, resolved, write2, snapshot);
850
+ }
851
+ }
852
+ }
853
+ function takeWritten(column, property, n, resolved, write2, snapshot) {
854
+ const want = resolved(property);
855
+ for (let i = 0; i < n; i++) {
856
+ const w = want[i];
857
+ const native = column[property]?.[i] ?? null;
858
+ if (native !== w && native !== null && native === write2((p) => resolved(p)[i], i, snapshot)) {
859
+ setValue(column, property, n, i, w);
860
+ }
861
+ }
862
+ }
863
+ function takeUnheld(values, property, want, n, held) {
864
+ for (let i = 0; i < n; i++) {
865
+ const w = want[i];
866
+ if (w !== null && !held(w)) {
867
+ setValue(values, property, n, i, w);
868
+ }
869
+ }
870
+ }
871
+ const oneSize = (want) => {
872
+ const w = want("width");
873
+ const h = want("height");
874
+ return typeof w === "number" && typeof h === "number" ? Math.max(w, h) : w ?? h;
875
+ };
876
+ const GRAPHOLOGY_WRITTEN = { node: { width: oneSize, height: oneSize } };
877
+ const VIS_SIZED = /* @__PURE__ */ new Set([
878
+ "image",
879
+ "circularImage",
880
+ "diamond",
881
+ "dot",
882
+ "star",
883
+ "triangle",
884
+ "triangleDown",
885
+ "hexagon",
886
+ "square",
887
+ "icon"
888
+ ]);
889
+ const VIS_GROUP_PALETTE = [
890
+ ["#2B7CE9", "#97C2FC"],
891
+ ["#FFA500", "#FFFF00"],
892
+ ["#FA0A10", "#FB7E81"],
893
+ ["#41A906", "#7BE141"],
894
+ ["#E129F0", "#EB7DF4"],
895
+ ["#7C29F0", "#AD85E4"],
896
+ ["#C37F00", "#FFA807"],
897
+ ["#4220FB", "#6E6EFD"],
898
+ ["#FD5A77", "#FFC0CB"],
899
+ ["#4AD63A", "#C2FABC"],
900
+ ["#990000", "#EE0000"],
901
+ ["#FF6000", "#FF6000"],
902
+ ["#97C2FC", "#2B7CE9"],
903
+ ["#399605", "#255C03"],
904
+ ["#B70054", "#FF007E"],
905
+ ["#AD85E4", "#7C29F0"],
906
+ ["#4557FA", "#000EA1"],
907
+ ["#FFC0CB", "#FD5A77"],
908
+ ["#C2FABC", "#74D66A"],
909
+ ["#EE0000", "#990000"]
910
+ ];
911
+ const VIS_EDGE_COLOR = "#848484";
912
+ function visParseColor(text) {
913
+ let hex = text;
914
+ const rgb = /^rgb\( *(\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *\)$/i.exec(text);
915
+ if (rgb?.slice(1).every((c) => Number(c) <= 255)) {
916
+ hex = `#${((1 << 24) + (Number(rgb[1]) << 16) + (Number(rgb[2]) << 8) + Number(rgb[3])).toString(16).slice(1)}`;
917
+ }
918
+ if (!/^#([0-9a-f]{6}|[0-9a-f]{3})$/i.test(hex)) {
919
+ return { background: text, border: text };
920
+ }
921
+ const full = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
922
+ return { background: full, border: visBorder(full) };
923
+ }
924
+ function visBorder(full) {
925
+ const n = Number.parseInt(full.slice(1), 16);
926
+ const [r, g, b] = [n >> 16 & 255, n >> 8 & 255, n & 255].map((c) => c / 255);
927
+ const max = Math.max(r, g, b);
928
+ const min = Math.min(r, g, b);
929
+ let h = 0;
930
+ let s = 0;
931
+ if (max !== min) {
932
+ let d = b - r;
933
+ let k = 5;
934
+ if (r === min) {
935
+ d = g - b;
936
+ k = 3;
937
+ } else if (b === min) {
938
+ d = r - g;
939
+ k = 1;
940
+ }
941
+ h = 60 * (k - d / (max - min)) / 360;
942
+ s = (max - min) / max;
943
+ }
944
+ const sv = Math.min(1, s * 1.25);
945
+ const vv = max * 0.8;
946
+ const i = Math.floor(h * 6);
947
+ const f = h * 6 - i;
948
+ const p = vv * (1 - sv);
949
+ const q = vv * (1 - f * sv);
950
+ const t = vv * (1 - (1 - f) * sv);
951
+ const rgbOut = [
952
+ [vv, t, p],
953
+ [q, vv, p],
954
+ [p, vv, t],
955
+ [p, q, vv],
956
+ [t, p, vv],
957
+ [vv, p, q]
958
+ ][i % 6].map((c) => Math.floor(c * 255));
959
+ return `#${((1 << 24) + (rgbOut[0] << 16) + (rgbOut[1] << 8) + rgbOut[2]).toString(16).slice(1)}`;
960
+ }
961
+ function visLayer(o, target) {
962
+ if (!isJsonObject(o)) {
963
+ return {};
964
+ }
965
+ const layer = {};
966
+ const set = (k, v) => {
967
+ if (v !== void 0 && v !== null) {
968
+ layer[k] = v;
969
+ }
970
+ };
971
+ if (target === "node") {
972
+ visNodeLayer(o, set);
973
+ } else {
974
+ visEdgeLayer(o, set);
975
+ }
976
+ set("hidden", o.hidden);
977
+ set("label", o.label);
978
+ set("title", o.title);
979
+ visFontLayer(o.font, set);
980
+ return layer;
981
+ }
982
+ function visNodeLayer(o, set) {
983
+ const { color } = o;
984
+ if (typeof color === "string") {
985
+ const parsed = visParseColor(color.trim());
986
+ set("fill", parsed.background);
987
+ set("border", parsed.border);
988
+ } else if (isJsonObject(color)) {
989
+ set("fill", color.background);
990
+ set("border", color.border);
991
+ }
992
+ set("shape", o.shape);
993
+ set("size", o.size);
994
+ set("borderWidth", o.borderWidth);
995
+ set("opacity", o.opacity);
996
+ }
997
+ function visEdgeLayer(o, set) {
998
+ const { color } = o;
999
+ if (typeof color === "string") {
1000
+ set("edgeColor", color);
1001
+ set("inherit", false);
1002
+ } else if (isJsonObject(color)) {
1003
+ set("edgeColor", color.color);
1004
+ set("edgeOpacity", color.opacity);
1005
+ const own = color.color !== void 0 || color.highlight !== void 0 || color.hover !== void 0;
1006
+ set("inherit", own ? false : color.inherit);
1007
+ }
1008
+ set("width", o.width);
1009
+ set("dashes", o.dashes);
1010
+ set("arrows", o.arrows);
1011
+ }
1012
+ function visFontLayer(font, set) {
1013
+ if (isJsonObject(font)) {
1014
+ set("fontColor", font.color);
1015
+ set("fontSize", font.size);
1016
+ set("fontFace", font.face);
1017
+ } else if (typeof font === "string") {
1018
+ const m = /^\s*(\d+(?:\.\d+)?)(?:px)?\s+(\S+)(?:\s+(\S+))?/.exec(font.slice(0, 256));
1019
+ if (m !== null) {
1020
+ set("fontSize", Number(m[1]));
1021
+ set("fontFace", m[2]);
1022
+ set("fontColor", m[3]);
1023
+ }
1024
+ }
1025
+ }
1026
+ function visValues(layer, target, site, sized) {
1027
+ const out = {};
1028
+ const put = (p, v) => {
1029
+ if (v !== null) {
1030
+ out[p] = v;
1031
+ }
1032
+ };
1033
+ const color = (p, opacity, raw) => {
1034
+ if (raw === void 0 || raw === null || raw === "") {
1035
+ return;
1036
+ }
1037
+ const c = canonColor(raw, "vis", site(p));
1038
+ if (c !== null) {
1039
+ put(p, c.color);
1040
+ if (c.alpha < 1 && opacity !== null) {
1041
+ put(opacity, c.alpha);
1042
+ }
1043
+ }
1044
+ };
1045
+ if (target === "node") {
1046
+ color("fill", "fillOpacity", layer.fill);
1047
+ color("borderColor", null, layer.border);
1048
+ visNodeValues(layer, sized, put, site);
1049
+ } else {
1050
+ color("color", "opacity", layer.edgeColor);
1051
+ visEdgeValues(layer, put, site);
1052
+ }
1053
+ if (layer.hidden !== void 0 && canonBoolean(layer.hidden, site("visible")) === true) {
1054
+ put("visible", false);
1055
+ }
1056
+ if (layer.label !== void 0) {
1057
+ put("label", canonText(layer.label, site("label")));
1058
+ }
1059
+ if (layer.title !== void 0) {
1060
+ put("tooltip", canonText(layer.title, site("tooltip")));
1061
+ }
1062
+ color("labelColor", null, layer.fontColor);
1063
+ if (layer.fontSize !== void 0) {
1064
+ put("labelSize", canonNumber(layer.fontSize, site("labelSize")));
1065
+ }
1066
+ if (layer.fontFace !== void 0) {
1067
+ put("labelFont", canonText(layer.fontFace, site("labelFont")));
1068
+ }
1069
+ return out;
1070
+ }
1071
+ function visNodeValues(layer, sized, put, site) {
1072
+ if (layer.shape !== void 0) {
1073
+ put("shape", canonEnum("shape", layer.shape, "vis", site("shape")));
1074
+ }
1075
+ if (sized && layer.size !== void 0) {
1076
+ const v = canonNumber(layer.size, site("width"));
1077
+ put("width", v);
1078
+ put("height", v);
1079
+ }
1080
+ if (layer.borderWidth !== void 0) {
1081
+ put("borderWidth", canonNumber(layer.borderWidth, site("borderWidth")));
1082
+ }
1083
+ if (layer.opacity !== void 0) {
1084
+ put("opacity", canonOpacity(layer.opacity, "vis", site("opacity")));
1085
+ }
1086
+ }
1087
+ function visEdgeValues(layer, put, site) {
1088
+ if (layer.edgeOpacity !== void 0) {
1089
+ put("opacity", canonOpacity(layer.edgeOpacity, "vis", site("opacity")));
1090
+ }
1091
+ if (layer.width !== void 0) {
1092
+ put("width", canonNumber(layer.width, site("width")));
1093
+ }
1094
+ if (layer.dashes !== void 0) {
1095
+ put("lineStyle", layer.dashes === false || layer.dashes === "false" ? "solid" : "dashed");
1096
+ }
1097
+ if (layer.arrows !== void 0) {
1098
+ const [to, from] = visArrows(layer.arrows, site);
1099
+ put("targetArrow", to);
1100
+ put("sourceArrow", from);
1101
+ }
1102
+ }
1103
+ function visArrows(arrows, site) {
1104
+ const end = (name, property) => {
1105
+ if (typeof arrows === "string") {
1106
+ return new RegExp(String.raw`\b${name}\b`).test(arrows.slice(0, 256)) ? "triangle" : "none";
1107
+ }
1108
+ if (!isJsonObject(arrows)) {
1109
+ return null;
1110
+ }
1111
+ const a = arrows[name];
1112
+ if (a === true) {
1113
+ return "triangle";
1114
+ }
1115
+ if (!isJsonObject(a) || a.enabled === false) {
1116
+ return "none";
1117
+ }
1118
+ return canonEnum("arrow", a.type ?? "arrow", "vis", site(property));
1119
+ };
1120
+ return [end("to", "targetArrow"), end("from", "sourceArrow")];
1121
+ }
1122
+ function visStyles(snapshot, src, context) {
1123
+ const notes = new StyleNotes();
1124
+ const options = isJsonObject(src.options) ? src.options : {};
1125
+ const n = snapshot.nodeCount;
1126
+ const ruleSite = (target) => (property) => ({ notes, target, property });
1127
+ const nodeRules = [];
1128
+ const nodeColumns = /* @__PURE__ */ new Map();
1129
+ const nodeDefaults = visLayer(options.nodes, "node");
1130
+ const groupCol = cells(snapshot, "node", "group");
1131
+ const groupOf = (i) => {
1132
+ const g = groupCol?.(i);
1133
+ return typeof g === "string" || typeof g === "number" ? String(g) : null;
1134
+ };
1135
+ const { groupLayers, paletteRows } = visGroupLayers(n, groupOf, visGroupDefs(src, options));
1136
+ context.budget.spend("node", n);
1137
+ const node = valuesOf(n);
1138
+ const records = nodeRecords(snapshot);
1139
+ const rawShape = (layer) => typeof layer.shape === "string" ? layer.shape : null;
1140
+ for (let i = 0; i < n; i++) {
1141
+ const g = groupOf(i);
1142
+ const own = records(i);
1143
+ const group = g === null ? {} : groupLayers.get(g) ?? {};
1144
+ const shape = rawShape(own) ?? rawShape(group) ?? rawShape(nodeDefaults) ?? "ellipse";
1145
+ const site = (property) => ({
1146
+ notes,
1147
+ target: "node",
1148
+ property,
1149
+ element: i,
1150
+ budget: context.budget
1151
+ });
1152
+ const merged = { ...nodeDefaults, ...group, ...own };
1153
+ for (const [p, v] of Object.entries(visValues(merged, "node", site, VIS_SIZED.has(shape)))) {
1154
+ node.put(p, i, v);
1155
+ }
1156
+ }
1157
+ const declaredNode = visValues(nodeDefaults, "node", ruleSite("node"), true);
1158
+ if (Object.keys(declaredNode).length > 0) {
1159
+ nodeRules.push(rule("node.vis.defaults", "node", "defaults", "declared", { all: true }, declaredNode));
1160
+ }
1161
+ let k = 0;
1162
+ for (const [g, layer] of groupLayers) {
1163
+ const set = paletteRows.get(g) ?? visValues(layer, "node", ruleSite("node"), true);
1164
+ if (Object.keys(set).length === 0) {
1165
+ continue;
1166
+ }
1167
+ const key = `group.${String(k)}`;
1168
+ nodeColumns.set(
1169
+ key,
1170
+ Array.from({ length: n }, (_v, i) => groupOf(i) === g ? true : null)
1171
+ );
1172
+ const origin = paletteRows.has(g) ? "tool" : "declared";
1173
+ const r = rule(`node.vis.group.${String(k++)}`, "node", "group", origin, { has: { style: key } }, set);
1174
+ nodeRules.push({ ...r, facts: { names: [[key, g]] } });
1175
+ }
1176
+ const toolNode = toolDefaults("vis-network")?.node;
1177
+ const borderOf = (i) => node.values.borderColor?.[i] ?? toolNode?.borderColor?.value ?? "#2b7ce9";
1178
+ const edge = visEdges(snapshot, visLayer(options.edges, "edge"), borderOf, notes, context);
1179
+ const values = { node: node.values, edge: edge.values };
1180
+ exactFromBlock(snapshot, src.block, values, VIS_WRITTEN);
1181
+ return {
1182
+ canonical: true,
1183
+ dialect: "vis",
1184
+ tool: "vis-network",
1185
+ opacityInColor: true,
1186
+ units: "px",
1187
+ node: { values: values.node, rules: nodeRules, columns: nodeColumns },
1188
+ edge: { values: values.edge, rules: edge.rules, columns: edge.columns },
1189
+ notes: notes.list(),
1190
+ block: src.block,
1191
+ readFrom: {
1192
+ node: VIS_KEYS.node.filter((x) => snapshot.nodes.has(x)),
1193
+ edge: VIS_KEYS.edge.filter((x) => snapshot.edges.has(x))
1194
+ }
1195
+ };
1196
+ }
1197
+ function visGroupDefs(src, options) {
1198
+ if (isJsonObject(options.groups)) {
1199
+ return options.groups;
1200
+ }
1201
+ return isJsonObject(src.groups) ? src.groups : {};
1202
+ }
1203
+ function visGroupLayers(n, groupOf, groupDefs) {
1204
+ const groupLayers = /* @__PURE__ */ new Map();
1205
+ const paletteRows = /* @__PURE__ */ new Map();
1206
+ let palette = 0;
1207
+ for (let i = 0; i < n; i++) {
1208
+ const g = groupOf(i);
1209
+ if (g === null || groupLayers.has(g)) {
1210
+ continue;
1211
+ }
1212
+ if (Object.hasOwn(groupDefs, g)) {
1213
+ groupLayers.set(g, visLayer(groupDefs[g], "node"));
1214
+ } else {
1215
+ const [border, background] = VIS_GROUP_PALETTE[palette++ % VIS_GROUP_PALETTE.length];
1216
+ groupLayers.set(g, { fill: background, border });
1217
+ paletteRows.set(g, { fill: background.toLowerCase(), borderColor: border.toLowerCase() });
1218
+ }
1219
+ }
1220
+ return { groupLayers, paletteRows };
1221
+ }
1222
+ function visEdges(snapshot, edgeDefaults, borderOf, notes, context) {
1223
+ const m = snapshot.edgeCount;
1224
+ const edge = valuesOf(m);
1225
+ const edgeRecords = elementRecords(snapshot, "edge");
1226
+ const inherited = new Array(m).fill(null);
1227
+ let inheriting = 0;
1228
+ for (let e = 0; e < m; e++) {
1229
+ const own = edgeRecords(e);
1230
+ const merged = { ...edgeDefaults, ...own };
1231
+ const site = (property) => ({
1232
+ notes,
1233
+ target: "edge",
1234
+ property,
1235
+ element: e,
1236
+ budget: context.budget
1237
+ });
1238
+ const vals = visValues(merged, "edge", site, true);
1239
+ for (const [p, v] of Object.entries(vals)) {
1240
+ edge.put(p, e, v);
1241
+ }
1242
+ const inherit = own.inherit ?? edgeDefaults.inherit ?? "from";
1243
+ if (inherit === false || inherit === "false") {
1244
+ if (vals.color === void 0) {
1245
+ edge.put("color", e, VIS_EDGE_COLOR);
1246
+ }
1247
+ continue;
1248
+ }
1249
+ if (inherit === "both") {
1250
+ notes.add(STYLE_ISSUE.GRADIENT, "edge", "color", { sample: "inherit both", element: e });
1251
+ }
1252
+ inherited[e] = borderOf(inherit === "to" ? snapshot.edgeTarget(e) : snapshot.edgeSource(e));
1253
+ inheriting++;
1254
+ }
1255
+ context.budget.spend("edge", m);
1256
+ const edgeRules = [];
1257
+ const edgeColumns = /* @__PURE__ */ new Map();
1258
+ const declaredEdge = visValues(edgeDefaults, "edge", (property) => ({ notes, target: "edge", property }), true);
1259
+ if (Object.keys(declaredEdge).length > 0) {
1260
+ edgeRules.push(rule("edge.vis.defaults", "edge", "defaults", "declared", { all: true }, declaredEdge));
1261
+ }
1262
+ if (inheriting > 0) {
1263
+ edgeColumns.set("source-color", inherited);
1264
+ edgeRules.push({
1265
+ id: "edge.tool.source-color",
1266
+ target: "edge",
1267
+ role: "passthrough",
1268
+ origin: "tool",
1269
+ where: { has: { style: "source-color" } },
1270
+ map: { color: { kind: "passthrough", by: { style: "source-color" } } },
1271
+ facts: { elements: inheriting, reason: "SOURCE_NODE_COLOR" }
1272
+ });
1273
+ }
1274
+ return { values: edge.values, rules: edgeRules, columns: edgeColumns };
1275
+ }
1276
+ const VIS_KEYS = {
1277
+ node: ["color", "shape", "size", "borderWidth", "opacity", "hidden", "label", "title", "font"],
1278
+ edge: ["color", "width", "dashes", "arrows", "hidden", "label", "title", "font"]
1279
+ };
1280
+ function nodeRecords(snapshot) {
1281
+ return elementRecords(snapshot, "node");
1282
+ }
1283
+ function elementRecords(snapshot, target) {
1284
+ const readers = VIS_KEYS[target].map((name) => [name, cells(snapshot, target, name)]).filter((x) => x[1] !== null);
1285
+ return (i) => {
1286
+ const record = {};
1287
+ for (const [name, read] of readers) {
1288
+ const v = read(i);
1289
+ if (v !== null) {
1290
+ record[name] = v;
1291
+ }
1292
+ }
1293
+ return visLayer(record, target);
1294
+ };
1295
+ }
1296
+ function rule(id, target, role, origin, where, set) {
1297
+ const values = {};
1298
+ for (const [p, v] of Object.entries(set)) {
1299
+ if (v !== null) {
1300
+ values[p] = v;
1301
+ }
1302
+ }
1303
+ return { id, target, role, origin, where, set: values };
1304
+ }
1305
+ const VIS_SHAPES = /* @__PURE__ */ new Map([
1306
+ ["ellipse", ["dot", true]],
1307
+ ["rectangle", ["square", true]],
1308
+ ["round-rectangle", ["box", true]],
1309
+ ["triangle", ["triangle", true]],
1310
+ ["diamond", ["diamond", true]],
1311
+ ["star", ["star", true]],
1312
+ ["hexagon", ["hexagon", true]],
1313
+ ["none", ["text", true]],
1314
+ ["pentagon", ["hexagon", false]],
1315
+ ["octagon", ["hexagon", false]],
1316
+ ["parallelogram", ["box", false]],
1317
+ ["trapezoid", ["box", false]],
1318
+ ["vee", ["triangle", false]]
1319
+ ]);
1320
+ const VIS_ARROW_TYPES = /* @__PURE__ */ new Map([
1321
+ ["triangle", ["arrow", true]],
1322
+ ["tee", ["bar", true]],
1323
+ ["circle", ["circle", true]],
1324
+ ["square", ["box", true]],
1325
+ ["crow", ["crow", true]],
1326
+ ["diamond", ["diamond", true]],
1327
+ ["vee", ["vee", true]],
1328
+ ["inverted", ["inv_triangle", true]],
1329
+ ["triangle-open", ["arrow", false]],
1330
+ ["diamond-open", ["diamond", false]],
1331
+ ["circle-open", ["circle", false]],
1332
+ ["half", ["arrow", false]]
1333
+ ]);
1334
+ function visShape(shape) {
1335
+ const known = VIS_SHAPES.get(shape);
1336
+ if (known !== void 0) {
1337
+ return known;
1338
+ }
1339
+ return shape.startsWith("other:") ? [shape.slice(6), true] : ["dot", false];
1340
+ }
1341
+ function visArrowType(arrow) {
1342
+ if (arrow === "none") {
1343
+ return [null, true];
1344
+ }
1345
+ const known = VIS_ARROW_TYPES.get(arrow);
1346
+ if (known !== void 0) {
1347
+ return known;
1348
+ }
1349
+ return arrow.startsWith("other:") ? [arrow.slice(6), true] : ["arrow", false];
1350
+ }
1351
+ const visSize = (want) => {
1352
+ const s = want("shape");
1353
+ const shape = typeof s === "string" ? visShape(s)[0] : "ellipse";
1354
+ return VIS_SIZED.has(shape) ? oneSize(want) : null;
1355
+ };
1356
+ const VIS_WRITTEN = {
1357
+ node: {
1358
+ width: visSize,
1359
+ height: visSize,
1360
+ shape: (want) => {
1361
+ const s = want("shape");
1362
+ if (typeof s !== "string") {
1363
+ return null;
1364
+ }
1365
+ const site = { notes: new StyleNotes(), target: "node", property: "shape" };
1366
+ return canonEnum("shape", visShape(s)[0], "vis", site);
1367
+ }
1368
+ },
1369
+ edge: {
1370
+ lineStyle: (want) => {
1371
+ const s = want("lineStyle");
1372
+ if (s === null) {
1373
+ return null;
1374
+ }
1375
+ return s === "solid" ? "solid" : "dashed";
1376
+ },
1377
+ targetArrow: (want) => arrowBack(want("targetArrow")),
1378
+ sourceArrow: (want) => arrowBack(want("sourceArrow"))
1379
+ }
1380
+ };
1381
+ function arrowBack(a) {
1382
+ if (typeof a !== "string") {
1383
+ return null;
1384
+ }
1385
+ const [type] = visArrowType(a);
1386
+ const site = { notes: new StyleNotes(), target: "edge", property: "targetArrow" };
1387
+ return type === null ? "none" : canonEnum("arrow", type, "vis", site);
1388
+ }
1389
+ function cyjsProperties(map, extra) {
1390
+ const out = /* @__PURE__ */ new Set();
1391
+ for (const spec of map.values()) {
1392
+ if (!spec.property.startsWith("_")) {
1393
+ out.add(spec.property);
1394
+ }
1395
+ }
1396
+ for (const p of extra) {
1397
+ out.add(p);
1398
+ }
1399
+ return [...out];
1400
+ }
1401
+ const NATIVE = {
1402
+ cytoscape: {
1403
+ node: cyjsProperties(CYJS_NODE_PROPERTIES, ["labelPosition", "labelItalic", "visible"]),
1404
+ edge: cyjsProperties(CYJS_EDGE_PROPERTIES, ["curved", "labelItalic", "visible"])
1405
+ },
1406
+ graphology: {
1407
+ node: ["fill", "fillOpacity", "width", "height", "label", "visible"],
1408
+ edge: ["color", "opacity", "width", "label", "visible"]
1409
+ },
1410
+ vis: {
1411
+ node: [
1412
+ "fill",
1413
+ "fillOpacity",
1414
+ "borderColor",
1415
+ "borderWidth",
1416
+ "shape",
1417
+ "width",
1418
+ "height",
1419
+ "opacity",
1420
+ "label",
1421
+ "tooltip",
1422
+ "labelColor",
1423
+ "labelSize",
1424
+ "labelFont",
1425
+ "visible"
1426
+ ],
1427
+ edge: [
1428
+ "color",
1429
+ "opacity",
1430
+ "width",
1431
+ "lineStyle",
1432
+ "targetArrow",
1433
+ "sourceArrow",
1434
+ "label",
1435
+ "tooltip",
1436
+ "labelColor",
1437
+ "labelSize",
1438
+ "labelFont",
1439
+ "visible"
1440
+ ]
1441
+ }
1442
+ };
1443
+ const JSON_STYLE_CAPABILITIES = Object.freeze({
1444
+ node: Object.freeze([
1445
+ .../* @__PURE__ */ new Set([...NATIVE.cytoscape.node, ...NATIVE.vis.node, ...NATIVE.graphology.node])
1446
+ ]),
1447
+ edge: Object.freeze([
1448
+ .../* @__PURE__ */ new Set([...NATIVE.cytoscape.edge, ...NATIVE.vis.edge, ...NATIVE.graphology.edge])
1449
+ ]),
1450
+ block: "native"
1451
+ });
1452
+ const BLOCK_AS_ATTRIBUTE = /* @__PURE__ */ new Set(["node-link", "jgf", "graphology"]);
1453
+ function jsonStyledExport(snapshot, dialect, input) {
1454
+ if (input === void 0) {
1455
+ return null;
1456
+ }
1457
+ const native = dialect === "cytoscape" || dialect === "graphology" || dialect === "vis" ? NATIVE[dialect] : null;
1458
+ const notes = [...notWritten(input, dialect, native), ...rulesNotKept(snapshot, dialect, input)];
1459
+ if (dialect === "obographs") {
1460
+ return { snapshot, topLevelBlock: null, stylesheet: null, groups: null, notes };
1461
+ }
1462
+ const out = snapshot.withColumns();
1463
+ const read = dataColumnsRead(input.rules.styles.rules);
1464
+ for (const [table, target] of [
1465
+ [out.nodes, "node"],
1466
+ [out.edges, "edge"]
1467
+ ]) {
1468
+ removeEarlierStyleKeys(table, dialect, read[target]);
1469
+ for (const [name, col] of input.tags[target]) {
1470
+ setColumn(table, name, col);
1471
+ }
1472
+ }
1473
+ if (out.graph.has(STYLE_BLOCK_NAME)) {
1474
+ out.graph.remove(STYLE_BLOCK_NAME);
1475
+ }
1476
+ if (BLOCK_AS_ATTRIBUTE.has(dialect)) {
1477
+ out.graph.set(STYLE_BLOCK_NAME, [input.block], { dtype: "string" });
1478
+ }
1479
+ let stylesheet = null;
1480
+ const approximated = new StyleApproximations();
1481
+ const replaced = new Replaced(out.nodes);
1482
+ if (dialect === "cytoscape") {
1483
+ const emitted = writeCytoscapeStyles(out, input);
1484
+ ({ stylesheet } = emitted);
1485
+ notes.push(...emitted.notes.map(lossOf));
1486
+ addUntrimmedText(input, approximated);
1487
+ } else if (dialect === "graphology") {
1488
+ writeGraphology$1(out, input, approximated, replaced);
1489
+ } else if (dialect === "vis") {
1490
+ writeVis$1(out, input, approximated, replaced);
1491
+ }
1492
+ notes.push(...approximated.notes(`the ${dialect} dialect of JSON`), ...replaced.notes(dialect));
1493
+ return {
1494
+ snapshot: out,
1495
+ topLevelBlock: BLOCK_AS_ATTRIBUTE.has(dialect) ? null : input.block,
1496
+ stylesheet,
1497
+ groups: dialect === "vis" ? visGroups(out) : null,
1498
+ notes
1499
+ };
1500
+ }
1501
+ function rulesNotKept(snapshot, dialect, input) {
1502
+ let message = null;
1503
+ if (dialect === "jgf" && !jgfKeepsNodes(snapshot)) {
1504
+ message = "the style rules are not kept: JGF changes the node ids' type or order (number ids become text, integer-like ids are read first), so the graphty.styles block no longer matches the graph read back";
1505
+ } else if (dialect === "obographs") {
1506
+ message = "the style rules are not kept: OBO Graphs has no place for them";
1507
+ }
1508
+ if (message === null) {
1509
+ return [];
1510
+ }
1511
+ return [
1512
+ Object.freeze({
1513
+ code: STYLE_ISSUE.RULES_NOT_KEPT,
1514
+ message,
1515
+ column: null,
1516
+ count: input.rules.styles.rules.length
1517
+ })
1518
+ ];
1519
+ }
1520
+ function removeEarlierStyleKeys(table, dialect, read) {
1521
+ for (const name of table.names()) {
1522
+ const styleKey = name.startsWith("graphty.style.") || name.startsWith("graphty_style_") || name === CYTOSCAPE_IMPORT_KEY;
1523
+ if (styleKey && !read.has(name)) {
1524
+ table.remove(name);
1525
+ }
1526
+ }
1527
+ if (dialect === "cytoscape") {
1528
+ for (const name of ["style#element", "css#element"].filter((c) => table.has(c))) {
1529
+ table.remove(name);
1530
+ }
1531
+ }
1532
+ }
1533
+ function writeCytoscapeStyles(out, input) {
1534
+ const features = {
1535
+ node: input.rules.features.node.filter((f) => !("data" in f.ref) || out.nodes.has(f.ref.data)),
1536
+ edge: input.rules.features.edge.filter((f) => !("data" in f.ref) || out.edges.has(f.ref.data))
1537
+ };
1538
+ const emitted = toCytoscapeStylesheet({ ...input.rules, features });
1539
+ for (const [table, target] of [
1540
+ [out.nodes, "node"],
1541
+ [out.edges, "edge"]
1542
+ ]) {
1543
+ const rows = emitted.elementData[target];
1544
+ const keys = new Set(rows.flatMap((row) => Object.keys(row ?? {})));
1545
+ for (const key of keys) {
1546
+ setColumn(
1547
+ table,
1548
+ key,
1549
+ rows.map((row) => row?.[key] ?? null)
1550
+ );
1551
+ }
1552
+ const bypass = emitted.bypass[target].map((b) => b === null || Object.keys(b).length === 0 ? null : b);
1553
+ if (bypass.some((b) => b !== null)) {
1554
+ setColumn(table, "style#element", bypass);
1555
+ }
1556
+ }
1557
+ return emitted;
1558
+ }
1559
+ function addUntrimmedText(input, approximated) {
1560
+ for (const target of TARGETS) {
1561
+ for (const property of CYJS_TEXT[target]) {
1562
+ for (const v of input.picture(target, property)) {
1563
+ if (typeof v === "string" && v.trim() !== v) {
1564
+ approximated.add(target, property, JSON.stringify(v));
1565
+ }
1566
+ }
1567
+ }
1568
+ }
1569
+ }
1570
+ function visGroups(snapshot) {
1571
+ const column = snapshot.nodes.get("group");
1572
+ if (column === null || column === void 0) {
1573
+ return null;
1574
+ }
1575
+ const groups = /* @__PURE__ */ new Map();
1576
+ for (let i = 0; i < snapshot.nodeCount; i++) {
1577
+ const value = column.isSet(i) ? column.value(i) : null;
1578
+ if (typeof value === "string" || typeof value === "number") {
1579
+ groups.set(String(value), {});
1580
+ }
1581
+ }
1582
+ return groups.size === 0 ? null : Object.fromEntries(groups);
1583
+ }
1584
+ function dataColumnsRead(rules) {
1585
+ const out = { node: /* @__PURE__ */ new Set(), edge: /* @__PURE__ */ new Set() };
1586
+ for (const rule2 of rules) {
1587
+ const refs = [
1588
+ ...predicateRefs(rule2.where),
1589
+ ...Object.values(rule2.map ?? {}).flatMap((m) => m === void 0 ? [] : [m.by])
1590
+ ];
1591
+ for (const ref of refs) {
1592
+ if ("data" in ref) {
1593
+ out[rule2.target].add(ref.data);
1594
+ }
1595
+ }
1596
+ }
1597
+ return out;
1598
+ }
1599
+ function predicateRefs(where) {
1600
+ const refs = [];
1601
+ const stack = [where];
1602
+ while (stack.length > 0) {
1603
+ const p = stack.pop();
1604
+ if ("has" in p) {
1605
+ refs.push(p.has);
1606
+ } else if ("eq" in p) {
1607
+ refs.push(p.eq[0]);
1608
+ } else if ("in" in p) {
1609
+ refs.push(p.in[0]);
1610
+ } else if ("and" in p) {
1611
+ stack.push(...p.and);
1612
+ } else if ("or" in p) {
1613
+ stack.push(...p.or);
1614
+ } else if ("not" in p) {
1615
+ stack.push(p.not);
1616
+ }
1617
+ }
1618
+ return refs;
1619
+ }
1620
+ function jgfKeepsNodes(snapshot) {
1621
+ let last = -1;
1622
+ let other = false;
1623
+ for (let i = 0; i < snapshot.nodeCount; i++) {
1624
+ const id = snapshot.ids.idOf(i);
1625
+ if (typeof id === "number") {
1626
+ return false;
1627
+ }
1628
+ if (/^(0|[1-9]\d*)$/.test(id) && Number(id) < 4294967295) {
1629
+ if (other || Number(id) <= last) {
1630
+ return false;
1631
+ }
1632
+ last = Number(id);
1633
+ } else {
1634
+ other = true;
1635
+ }
1636
+ }
1637
+ return true;
1638
+ }
1639
+ function notWritten(input, dialect, native) {
1640
+ const out = [];
1641
+ for (const target of TARGETS) {
1642
+ const all = new Set(JSON_STYLE_CAPABILITIES[target]);
1643
+ const held = new Set(native?.[target] ?? []);
1644
+ const used = /* @__PURE__ */ new Set();
1645
+ for (const r of input.rules.styles.rules) {
1646
+ if (r.target === target) {
1647
+ for (const p of [...Object.keys(r.set ?? {}), ...Object.keys(r.map ?? {})]) {
1648
+ used.add(p);
1649
+ }
1650
+ }
1651
+ }
1652
+ for (const property of used) {
1653
+ if (!all.has(property) || held.has(property)) {
1654
+ continue;
1655
+ }
1656
+ const count = input.picture(target, property).filter((v) => v !== null).length;
1657
+ out.push(
1658
+ Object.freeze({
1659
+ code: STYLE_ISSUE.NOT_WRITTEN,
1660
+ message: `${target} ${property} is not written: the ${dialect} dialect of JSON has no place for it`,
1661
+ column: null,
1662
+ count,
1663
+ style: Object.freeze({ target, property })
1664
+ })
1665
+ );
1666
+ }
1667
+ }
1668
+ return out;
1669
+ }
1670
+ function lossOf(n) {
1671
+ return Object.freeze({
1672
+ code: n.code,
1673
+ message: n.message,
1674
+ column: null,
1675
+ count: n.params.count,
1676
+ style: n.params.target === null || n.params.property === null ? void 0 : Object.freeze({ target: n.params.target, property: n.params.property })
1677
+ });
1678
+ }
1679
+ function setColumn(table, name, values) {
1680
+ const kinds = new Set(values.filter((v) => v !== null && v !== void 0).map((v) => typeof v));
1681
+ let dtype = "json";
1682
+ if (kinds.size === 1) {
1683
+ if (kinds.has("number")) {
1684
+ dtype = "f64";
1685
+ } else if (kinds.has("boolean")) {
1686
+ dtype = "bool";
1687
+ } else if (kinds.has("string")) {
1688
+ dtype = "string";
1689
+ }
1690
+ }
1691
+ table.set(
1692
+ name,
1693
+ values.map((v) => v === null ? void 0 : v),
1694
+ { dtype }
1695
+ );
1696
+ }
1697
+ function writeKey(table, name, values, replaced) {
1698
+ const old = table.get(name);
1699
+ let changed = 0;
1700
+ if (old !== null) {
1701
+ for (let i = 0; i < values.length; i++) {
1702
+ const before = plainCell(old.value(i));
1703
+ const after = values[i] ?? null;
1704
+ if (before !== null && JSON.stringify(before) !== JSON.stringify(after)) {
1705
+ changed++;
1706
+ }
1707
+ }
1708
+ }
1709
+ if (changed > 0) {
1710
+ replaced.add(table === replaced.nodes ? "node" : "edge", name, changed);
1711
+ }
1712
+ if (values.every((v) => v === null || v === void 0)) {
1713
+ if (old !== null) {
1714
+ table.remove(name);
1715
+ }
1716
+ return;
1717
+ }
1718
+ setColumn(table, name, values);
1719
+ }
1720
+ const STYLE_KEY_REPLACED_CODE = "W_JSON_STYLE_KEY_REPLACED";
1721
+ class Replaced {
1722
+ /**
1723
+ * Counts the replaced values of one export.
1724
+ * @param nodes - the node table being written, which tells node columns from edge columns
1725
+ */
1726
+ constructor(nodes) {
1727
+ this.nodes = nodes;
1728
+ }
1729
+ #counts = /* @__PURE__ */ new Map();
1730
+ /**
1731
+ * Counts replaced values.
1732
+ * @param target - nodes or edges
1733
+ * @param key - the key
1734
+ * @param count - how many
1735
+ */
1736
+ add(target, key, count) {
1737
+ this.#counts.set(`${target}\0${key}`, (this.#counts.get(`${target}\0${key}`) ?? 0) + count);
1738
+ }
1739
+ /**
1740
+ * The notes, one per key.
1741
+ * @param dialect - the dialect, for the message
1742
+ * @returns the notes
1743
+ */
1744
+ notes(dialect) {
1745
+ return Array.from(this.#counts, ([key, count]) => {
1746
+ const [target, name] = key.split("\0");
1747
+ return Object.freeze({
1748
+ code: STYLE_KEY_REPLACED_CODE,
1749
+ message: `${target} column "${name}" is the ${dialect} dialect's style key: ${String(count)} ${target}${count === 1 ? "" : "s"} get what graphty draws instead of the value the column held`,
1750
+ column: name,
1751
+ count
1752
+ });
1753
+ });
1754
+ }
1755
+ }
1756
+ function cssColor(color, alpha) {
1757
+ if (typeof color !== "string") {
1758
+ return null;
1759
+ }
1760
+ if (typeof alpha !== "number" || alpha >= 1) {
1761
+ return color;
1762
+ }
1763
+ const n = Number.parseInt(color.slice(1), 16);
1764
+ return `rgba(${String(n >> 16 & 255)},${String(n >> 8 & 255)},${String(n & 255)},${String(alpha)})`;
1765
+ }
1766
+ function nodeSizes(width, height, approximated) {
1767
+ return width.map((_v, i) => {
1768
+ const w = width[i];
1769
+ const h = height[i];
1770
+ if (typeof w === "number" && typeof h === "number" && w !== h) {
1771
+ approximated.add("node", w > h ? "height" : "width", `${String(w)} x ${String(h)}`);
1772
+ return Math.max(w, h);
1773
+ }
1774
+ if (typeof w === "number") {
1775
+ return w;
1776
+ }
1777
+ return typeof h === "number" ? h : null;
1778
+ });
1779
+ }
1780
+ function writeGraphology$1(out, input, approximated, replaced) {
1781
+ const p = (target, property) => input.picture(target, property);
1782
+ for (const [table, target] of [
1783
+ [out.nodes, "node"],
1784
+ [out.edges, "edge"]
1785
+ ]) {
1786
+ const [fill, opacity] = target === "node" ? ["fill", "fillOpacity"] : ["color", "opacity"];
1787
+ const colors = p(target, fill);
1788
+ const alphas = p(target, opacity);
1789
+ writeKey(
1790
+ table,
1791
+ "color",
1792
+ colors.map((c, i) => cssColor(c, alphas[i])),
1793
+ replaced
1794
+ );
1795
+ writeKey(
1796
+ table,
1797
+ "size",
1798
+ target === "node" ? nodeSizes(p("node", "width"), p("node", "height"), approximated) : p("edge", "width"),
1799
+ replaced
1800
+ );
1801
+ writeKey(table, "label", p(target, "label"), replaced);
1802
+ writeKey(
1803
+ table,
1804
+ "hidden",
1805
+ p(target, "visible").map((v) => v === false ? true : null),
1806
+ replaced
1807
+ );
1808
+ }
1809
+ }
1810
+ function writeVis$1(out, input, approximated, replaced) {
1811
+ const p = (target, property) => input.picture(target, property);
1812
+ const font = (target) => {
1813
+ const color2 = p(target, "labelColor");
1814
+ const size = p(target, "labelSize");
1815
+ const face = p(target, "labelFont");
1816
+ return color2.map((_v, i) => {
1817
+ const f = {};
1818
+ if (color2[i] !== null) {
1819
+ f.color = color2[i];
1820
+ }
1821
+ if (size[i] !== null) {
1822
+ f.size = size[i];
1823
+ }
1824
+ if (face[i] !== null) {
1825
+ f.face = face[i];
1826
+ }
1827
+ return Object.keys(f).length === 0 ? null : f;
1828
+ });
1829
+ };
1830
+ const label = (table, target) => {
1831
+ writeKey(table, "label", p(target, "label"), replaced);
1832
+ writeKey(table, "title", p(target, "tooltip"), replaced);
1833
+ writeKey(table, "font", font(target), replaced);
1834
+ writeKey(
1835
+ table,
1836
+ "hidden",
1837
+ p(target, "visible").map((v) => v === false ? true : null),
1838
+ replaced
1839
+ );
1840
+ };
1841
+ const fill = p("node", "fill");
1842
+ const fillOpacity = p("node", "fillOpacity");
1843
+ const border = p("node", "borderColor");
1844
+ writeKey(
1845
+ out.nodes,
1846
+ "color",
1847
+ fill.map((_v, i) => {
1848
+ const c = {};
1849
+ const bg = cssColor(fill[i], fillOpacity[i]);
1850
+ if (bg !== null) {
1851
+ c.background = bg;
1852
+ }
1853
+ if (typeof border[i] === "string") {
1854
+ c.border = border[i];
1855
+ }
1856
+ return Object.keys(c).length === 0 ? null : c;
1857
+ }),
1858
+ replaced
1859
+ );
1860
+ const sizes = nodeSizes(p("node", "width"), p("node", "height"), approximated);
1861
+ const shapes = p("node", "shape").map((s, i) => {
1862
+ const [shape, exact] = typeof s === "string" ? visShape(s) : [null, true];
1863
+ if (!exact) {
1864
+ approximated.add("node", "shape", s);
1865
+ }
1866
+ if (sizes[i] !== null && !VIS_SIZED.has(shape ?? "ellipse")) {
1867
+ approximated.add("node", "width", `${String(s ?? "ellipse")} sized by its label`);
1868
+ }
1869
+ return shape;
1870
+ });
1871
+ writeKey(out.nodes, "shape", shapes, replaced);
1872
+ writeKey(out.nodes, "size", sizes, replaced);
1873
+ writeKey(out.nodes, "borderWidth", p("node", "borderWidth"), replaced);
1874
+ writeKey(out.nodes, "opacity", p("node", "opacity"), replaced);
1875
+ label(out.nodes, "node");
1876
+ const color = p("edge", "color");
1877
+ const opacity = p("edge", "opacity");
1878
+ writeKey(
1879
+ out.edges,
1880
+ "color",
1881
+ color.map((_v, e) => {
1882
+ const c = {};
1883
+ if (typeof color[e] === "string") {
1884
+ c.color = color[e];
1885
+ }
1886
+ if (typeof opacity[e] === "number") {
1887
+ c.opacity = opacity[e];
1888
+ }
1889
+ return Object.keys(c).length === 0 ? null : c;
1890
+ }),
1891
+ replaced
1892
+ );
1893
+ writeKey(out.edges, "width", p("edge", "width"), replaced);
1894
+ writeKey(
1895
+ out.edges,
1896
+ "dashes",
1897
+ p("edge", "lineStyle").map((s) => {
1898
+ if (typeof s !== "string") {
1899
+ return null;
1900
+ }
1901
+ if (s !== "solid" && s !== "dashed") {
1902
+ approximated.add("edge", "lineStyle", s);
1903
+ }
1904
+ return s !== "solid";
1905
+ }),
1906
+ replaced
1907
+ );
1908
+ const to = p("edge", "targetArrow");
1909
+ const from = p("edge", "sourceArrow");
1910
+ writeKey(
1911
+ out.edges,
1912
+ "arrows",
1913
+ to.map((_v, e) => {
1914
+ const a = {};
1915
+ for (const [end, value, property] of [
1916
+ ["to", to[e], "targetArrow"],
1917
+ ["from", from[e], "sourceArrow"]
1918
+ ]) {
1919
+ if (typeof value !== "string") {
1920
+ continue;
1921
+ }
1922
+ const [type, exact] = visArrowType(value);
1923
+ if (!exact) {
1924
+ approximated.add("edge", property, value);
1925
+ }
1926
+ a[end] = type === null ? { enabled: false } : { enabled: true, type };
1927
+ }
1928
+ return Object.keys(a).length === 0 ? null : a;
1929
+ }),
1930
+ replaced
1931
+ );
1932
+ label(out.edges, "edge");
1933
+ }
568
1934
  const JSON_ISSUE = Object.freeze({
569
1935
  ...INPUT_ISSUE,
570
1936
  ...ELEMENT_ISSUE,
@@ -726,9 +2092,12 @@ const JGF_EDGE_KEYS = /* @__PURE__ */ new Set([
726
2092
  "metadata"
727
2093
  ]);
728
2094
  const JGF_HYPEREDGE_KEYS = /* @__PURE__ */ new Set([...JGF_EDGE_KEYS, "nodes"]);
2095
+ const ARRAY_INDEX = /^(?:0|[1-9]\d{0,9})$/;
729
2096
  const JGF_NODE_KEYS = /* @__PURE__ */ new Set(["label", "metadata"]);
730
2097
  const GRAPHOLOGY_NODE_KEYS = /* @__PURE__ */ new Set(["key", "attributes"]);
731
2098
  const GRAPHOLOGY_EDGE_KEYS = /* @__PURE__ */ new Set(["key", "source", "target", "attributes", "undirected"]);
2099
+ const GEPHI_NODE_KEYS = /* @__PURE__ */ new Set(["id", "attributes"]);
2100
+ const GEPHI_EDGE_KEYS = /* @__PURE__ */ new Set([...GRAPHOLOGY_EDGE_KEYS, "id"]);
732
2101
  const VIS_SOURCE_KEYS = Object.freeze(["from"]);
733
2102
  const VIS_TARGET_KEYS = Object.freeze(["to"]);
734
2103
  const PATH_DIALECTS = /* @__PURE__ */ new Set([
@@ -1050,11 +2419,13 @@ class ImportContext {
1050
2419
  * @param explicitDefaultDirected - whether the caller passed defaultDirected
1051
2420
  */
1052
2421
  constructor(sink, report, options, json2, explicitDefaultDirected) {
2422
+ this.text = "";
1053
2423
  this.elementsSinceCheck = 0;
1054
2424
  this.fileDirected = false;
1055
2425
  this.danglingIds = [];
1056
2426
  this.danglingCount = 0;
1057
2427
  this.nodesFromEdges = false;
2428
+ this.styleSource = null;
1058
2429
  this.nearMatches = [];
1059
2430
  this.sink = sink;
1060
2431
  this.report = report;
@@ -1213,10 +2584,34 @@ class ImportContext {
1213
2584
  if (missingSource) {
1214
2585
  this.dangling(source);
1215
2586
  }
1216
- if (missingTarget) {
1217
- this.dangling(target);
2587
+ if (missingTarget) {
2588
+ this.dangling(target);
2589
+ }
2590
+ return edge;
2591
+ }
2592
+ /**
2593
+ * A Cytoscape.js endpoint or parent id: Cytoscape.js holds every id as text, so an endpoint `0` names the node
2594
+ * `"0"` and an endpoint `"0"` the node `0` when the file has no node of the endpoint's own type.
2595
+ * @param raw - the JSON value
2596
+ * @param element - the element name for issues
2597
+ * @returns the id, or null when the value was reported
2598
+ */
2599
+ textualId(raw, element) {
2600
+ const id = this.coerceId(raw, element);
2601
+ if (id === null || this.sink.indexOf(id) !== INVALID_INDEX) {
2602
+ return id;
2603
+ }
2604
+ let other = null;
2605
+ if (typeof raw === "number" && Number.isFinite(raw)) {
2606
+ other = String(raw);
2607
+ } else if (typeof raw === "string" && /^-?\d+(?:\.\d+)?$/.test(raw)) {
2608
+ other = Number(raw);
1218
2609
  }
1219
- return edge;
2610
+ if (other === null) {
2611
+ return id;
2612
+ }
2613
+ const alt = this.ids.value(other);
2614
+ return this.sink.indexOf(alt) === INVALID_INDEX ? id : alt;
1220
2615
  }
1221
2616
  /**
1222
2617
  * Count a placeholder node an edge endpoint created.
@@ -1379,10 +2774,14 @@ class ImportContext {
1379
2774
  * @param record - the element record
1380
2775
  * @param dict - the nested attribute dict
1381
2776
  * @param structural - the element keys that are not attributes
1382
- * @param weightFrom - the weight key to skip in the dict, or null
1383
2777
  * @param element - the element name for issues
2778
+ * @param how - `weightFrom`: the weight key to skip in the dict; `plain`: write the element-level keys under their
2779
+ * own names, not with the `#element` suffix
2780
+ * @param how.weightFrom - the weight key to skip in the dict, or null (the default)
2781
+ * @param how.plain - write the element-level keys under their own names (default false)
1384
2782
  */
1385
- writeNested(writer, row, record, dict, structural, weightFrom, element) {
2783
+ writeNested(writer, row, record, dict, structural, element, how = {}) {
2784
+ const { weightFrom = null, plain = false } = how;
1386
2785
  for (const key of Object.keys(dict)) {
1387
2786
  if (key !== weightFrom) {
1388
2787
  writer.write(row, key, dict[key], SUFFIX.data, element);
@@ -1390,7 +2789,7 @@ class ImportContext {
1390
2789
  }
1391
2790
  for (const key of Object.keys(record)) {
1392
2791
  if (!structural.has(key)) {
1393
- writer.write(row, `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
2792
+ writer.write(row, plain ? key : `${key}${SUFFIX.element}`, record[key], SUFFIX.data, element);
1394
2793
  }
1395
2794
  }
1396
2795
  }
@@ -1680,7 +3079,8 @@ function arraySection(value, what, report) {
1680
3079
  if (!Array.isArray(value)) {
1681
3080
  return report.fail(JSON_ISSUE.SHAPE, `${what} must be an array, found ${describe(value)}`, { element: what });
1682
3081
  }
1683
- return value;
3082
+ const items = value;
3083
+ return items;
1684
3084
  }
1685
3085
  function flagOf(value, what, fallback, report) {
1686
3086
  if (value === void 0 || value === null) {
@@ -1727,8 +3127,14 @@ function reportUnreadKeys(ctx, record, known, prefix) {
1727
3127
  );
1728
3128
  }
1729
3129
  }
1730
- const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges"]);
1731
- const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges", "options", "attributes"]);
3130
+ const VIS_DOCUMENT_KEYS = /* @__PURE__ */ new Set(["nodes", "edges", STYLE_BLOCK_NAME]);
3131
+ const GRAPHOLOGY_DOCUMENT_KEYS = /* @__PURE__ */ new Set([
3132
+ "nodes",
3133
+ "edges",
3134
+ "options",
3135
+ "attributes",
3136
+ STYLE_BLOCK_NAME
3137
+ ]);
1732
3138
  const JGF_GRAPH_KEYS = /* @__PURE__ */ new Set([
1733
3139
  "id",
1734
3140
  "type",
@@ -1747,10 +3153,46 @@ function isIndexBelow(value, bound) {
1747
3153
  }
1748
3154
  function importNodeLink(ctx, root, dialect) {
1749
3155
  const { report, json: json2 } = ctx;
1750
- let { edgesKey } = json2;
1751
- if (edgesKey === null) {
1752
- edgesKey = hasKey(root, "edges") || !hasKey(root, "links") ? "edges" : "links";
3156
+ const edgesKey = json2.edgesKey ?? (hasKey(root, "edges") || !hasKey(root, "links") ? "edges" : "links");
3157
+ const { nodeList, edgeList } = nodeLinkSections(ctx, root, edgesKey);
3158
+ const directed = flagOf(root.directed, "directed", ctx.defaultDirected(dialect), report);
3159
+ const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
3160
+ ctx.setHeader(directed);
3161
+ ctx.writeGraphDict(root.graph, "graph");
3162
+ reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set(["nodes", edgesKey, "directed", "multigraph", "graph", STYLE_BLOCK_NAME]), "");
3163
+ const networkx = hasKey(root, "directed") && hasKey(root, "multigraph") && hasKey(root, "graph");
3164
+ ctx.styleSource = { dialect, block: blockOf(root), networkx };
3165
+ ctx.sink.reserve(nodeList.length, edgeList.length);
3166
+ const nodeIdKey = nodeLinkIdKey(ctx, nodeList);
3167
+ const positional = nodeIdKey === null;
3168
+ let indexLinks;
3169
+ if (positional) {
3170
+ indexLinks = true;
3171
+ } else if (json2.indexLinks === "auto") {
3172
+ indexLinks = looksIndexLinked(nodeList, edgeList, nodeIdKey, json2);
3173
+ } else {
3174
+ ({ indexLinks } = json2);
1753
3175
  }
3176
+ if (indexLinks && !positional && json2.indexLinks === "auto") {
3177
+ reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
3178
+ }
3179
+ const positionIds = importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks);
3180
+ throwIfAborted(ctx.options.signal);
3181
+ const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);
3182
+ ctx.setMeta(
3183
+ {
3184
+ dialect,
3185
+ edgesKey,
3186
+ nodeIdKey,
3187
+ indexLinks,
3188
+ sourceKey: endpointKeys.source ?? void 0,
3189
+ targetKey: endpointKeys.target ?? void 0
3190
+ },
3191
+ { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() }
3192
+ );
3193
+ }
3194
+ function nodeLinkSections(ctx, root, edgesKey) {
3195
+ const { report } = ctx;
1754
3196
  const nodes = arraySection(root.nodes, "nodes", report);
1755
3197
  const edges = arraySection(root[edgesKey], edgesKey, report);
1756
3198
  if (nodes === null) {
@@ -1770,94 +3212,67 @@ function importNodeLink(ctx, root, dialect) {
1770
3212
  { element: edgesKey }
1771
3213
  );
1772
3214
  }
1773
- const directed = flagOf(root.directed, "directed", ctx.defaultDirected(dialect), report);
1774
- const multigraph = hasKey(root, "multigraph") ? flagOf(root.multigraph, "multigraph", false, report) : null;
1775
- ctx.setHeader(directed);
1776
- ctx.writeGraphDict(root.graph, "graph");
1777
- reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set(["nodes", edgesKey, "directed", "multigraph", "graph"]), "");
1778
- const nodeList = nodes ?? [];
1779
- const edgeList = edges ?? [];
1780
- ctx.sink.reserve(nodeList.length, edgeList.length);
1781
- let { nodeIdKey } = json2;
1782
- let positional = ctx.options.nodeIdFrom === "index";
1783
- if (!positional && nodeIdKey === null) {
1784
- const candidates = ctx.options.nodeIdFrom === "label" ? ["label", "name", "id"] : ["id", "name"];
1785
- nodeIdKey = candidates.find((key) => anyHas(nodeList, key)) ?? null;
1786
- if (ctx.options.nodeIdFrom === "label" && (nodeIdKey === "id" || nodeIdKey === "name")) {
1787
- report.warning(
1788
- "unsupported",
1789
- JSON_ISSUE.OPTION_IGNORED,
1790
- nodeIdKey === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
1791
- { element: "nodeIdFrom" }
1792
- );
1793
- }
1794
- if (nodeIdKey === null) {
1795
- if (nodeList.length > 0) {
1796
- positional = true;
1797
- report.warning(
1798
- "missing-value",
1799
- JSON_ISSUE.POSITIONAL_NODES,
1800
- "no node has an id or name key; array positions are the node ids",
1801
- { element: "nodes" }
1802
- );
1803
- } else {
1804
- nodeIdKey = "id";
1805
- }
1806
- }
3215
+ return { nodeList: nodes ?? [], edgeList: edges ?? [] };
3216
+ }
3217
+ function nodeLinkIdKey(ctx, nodeList) {
3218
+ const { report, json: json2 } = ctx;
3219
+ if (ctx.options.nodeIdFrom === "index") {
3220
+ return null;
1807
3221
  }
1808
- if (positional) {
1809
- nodeIdKey = null;
3222
+ if (json2.nodeIdKey !== null) {
3223
+ return json2.nodeIdKey;
1810
3224
  }
1811
- let indexLinks;
1812
- if (positional) {
1813
- indexLinks = true;
1814
- } else if (json2.indexLinks === "auto") {
1815
- indexLinks = nodeIdKey !== null && looksIndexLinked(nodeList, edgeList, nodeIdKey, json2);
1816
- } else {
1817
- ({ indexLinks } = json2);
3225
+ const byLabel = ctx.options.nodeIdFrom === "label";
3226
+ const candidates = byLabel ? ["label", "name", "id"] : ["id", "name"];
3227
+ const found = candidates.find((key) => anyHas(nodeList, key)) ?? null;
3228
+ if (byLabel && (found === "id" || found === "name")) {
3229
+ report.warning(
3230
+ "unsupported",
3231
+ JSON_ISSUE.OPTION_IGNORED,
3232
+ found === "id" ? 'nodeIdFrom "label": no node has a label or name key; ids are read from "id"' : 'nodeIdFrom "label": no node has a "label" key; ids are read from "name"',
3233
+ { element: "nodeIdFrom" }
3234
+ );
1818
3235
  }
1819
- const positionIds = indexLinks ? [] : null;
1820
- if (indexLinks && !positional && json2.indexLinks === "auto" && nodeIdKey !== null) {
1821
- reportAmbiguousIndexLinks(ctx, nodeList, edgeList, nodeIdKey);
3236
+ if (found !== null || nodeList.length === 0) {
3237
+ return found ?? "id";
1822
3238
  }
3239
+ report.warning(
3240
+ "missing-value",
3241
+ JSON_ISSUE.POSITIONAL_NODES,
3242
+ "no node has an id or name key; array positions are the node ids",
3243
+ { element: "nodes" }
3244
+ );
3245
+ return null;
3246
+ }
3247
+ function importNodeLinkNodes(ctx, nodeList, nodeIdKey, indexLinks) {
3248
+ const positionIds = indexLinks ? [] : null;
1823
3249
  for (let i = 0; i < nodeList.length; i++) {
1824
3250
  const element = `nodes[${i}]`;
1825
3251
  const record = nodeList[i];
1826
3252
  let pushed = null;
1827
- if (!isJsonObject(record)) {
1828
- ctx.badElement("node", element);
3253
+ if (isJsonObject(record)) {
3254
+ pushed = pushNodeLinkNode(ctx, record, i, nodeIdKey);
1829
3255
  } else {
1830
- let id;
1831
- if (nodeIdKey === null) {
1832
- id = i;
1833
- } else {
1834
- id = ctx.coerceId(hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0, element);
1835
- }
1836
- if (id === null) {
1837
- ctx.countSkipped("node");
1838
- } else {
1839
- const index = ctx.pushNode(id, element);
1840
- if (index >= 0) {
1841
- pushed = id;
1842
- writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
1843
- }
1844
- }
3256
+ ctx.badElement("node", element);
1845
3257
  }
1846
3258
  positionIds?.push(pushed);
1847
3259
  }
1848
- throwIfAborted(ctx.options.signal);
1849
- const endpointKeys = importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph);
1850
- ctx.setMeta(
1851
- {
1852
- dialect,
1853
- edgesKey,
1854
- nodeIdKey,
1855
- indexLinks,
1856
- sourceKey: endpointKeys.source ?? void 0,
1857
- targetKey: endpointKeys.target ?? void 0
1858
- },
1859
- { declaredMultigraph: multigraph, ...ctx.weightOriginPatch() }
1860
- );
3260
+ return positionIds;
3261
+ }
3262
+ function pushNodeLinkNode(ctx, record, i, nodeIdKey) {
3263
+ const element = `nodes[${i}]`;
3264
+ const raw = nodeIdKey !== null && hasKey(record, nodeIdKey) ? record[nodeIdKey] : void 0;
3265
+ const id = nodeIdKey === null ? i : ctx.coerceId(raw, element);
3266
+ if (id === null) {
3267
+ ctx.countSkipped("node");
3268
+ return null;
3269
+ }
3270
+ const index = ctx.pushNode(id, element);
3271
+ if (index < 0) {
3272
+ return null;
3273
+ }
3274
+ writeFlat(ctx.nodes, index, record, id, (key) => key !== nodeIdKey);
3275
+ return id;
1861
3276
  }
1862
3277
  function importNodeLinkEdges(ctx, edgeList, edgesKey, positionIds, multigraph) {
1863
3278
  const { json: json2 } = ctx;
@@ -2087,6 +3502,7 @@ function importVis(ctx, root) {
2087
3502
  { element: "arrows" }
2088
3503
  );
2089
3504
  }
3505
+ ctx.styleSource = { dialect: "vis", block: blockOf(root), options: root.options, groups: root.groups };
2090
3506
  ctx.setMeta(
2091
3507
  { dialect: "vis", nodeIdKey, sourceKey: sourceKey ?? void 0, targetKey: targetKey ?? void 0 },
2092
3508
  ctx.weightOriginPatch()
@@ -2352,28 +3768,19 @@ function importGraphology(ctx, root) {
2352
3768
  });
2353
3769
  }
2354
3770
  const type = graphologyType(ctx, options);
2355
- ctx.setHeader(graphologyDirected(ctx, type, edges));
3771
+ ctx.setHeader(type === "mixed" ? mostlyDirected(ctx, edges) : type === "directed");
2356
3772
  const multi = hasKey(options, "multi") ? flagOf(options.multi, "options.multi", false, report) : null;
2357
3773
  const allowSelfLoops = hasKey(options, "allowSelfLoops") ? flagOf(options.allowSelfLoops, "options.allowSelfLoops", true, report) : void 0;
2358
3774
  ctx.writeGraphDict(root.attributes, "attributes");
3775
+ const firstNode = nodes.find((n) => isJsonObject(n));
3776
+ const gephi = isJsonObject(firstNode) && !hasKey(firstNode, "key") && hasKey(firstNode, "id");
3777
+ ctx.styleSource = { dialect: "graphology", block: blockOf(root), gephi };
2359
3778
  ctx.reportNodeIdFrom("graphology", "the node key");
2360
3779
  ctx.sink.reserve(nodes.length, edges.length);
2361
- for (let i = 0; i < nodes.length; i++) {
2362
- pushGraphologyNode(ctx, nodes[i], `nodes[${i}]`);
2363
- }
3780
+ importGraphologyNodes(ctx, nodes, gephi);
2364
3781
  throwIfAborted(ctx.options.signal);
2365
- const reading = {
2366
- ids: ctx.declareEdgeIds(edges, (edge) => edge.key, "key", true),
2367
- type,
2368
- allowSelfLoops,
2369
- // what the edges do against the declared options: graphology itself refuses such a document
2370
- violations: { selfLoops: 0, parallels: 0, flags: 0 },
2371
- pairs: multi === false ? /* @__PURE__ */ new Set() : null
2372
- };
2373
- for (let i = 0; i < edges.length; i++) {
2374
- readGraphologyEdge(ctx, reading, edges[i], `edges[${i}]`);
2375
- }
2376
- reportGraphologyViolations(ctx, reading.violations, type);
3782
+ const violations = importGraphologyEdges(ctx, edges, { type, gephi, multi, allowSelfLoops });
3783
+ reportGraphologyViolations(ctx, violations, type);
2377
3784
  ctx.setMeta({ dialect: "graphology", allowSelfLoops }, { declaredMultigraph: multi, ...ctx.weightOriginPatch() });
2378
3785
  }
2379
3786
  function graphologyType(ctx, options) {
@@ -2390,81 +3797,101 @@ function graphologyType(ctx, options) {
2390
3797
  }
2391
3798
  return "mixed";
2392
3799
  }
2393
- function graphologyDirected(ctx, type, edges) {
2394
- if (type !== "mixed") {
2395
- return type === "directed";
2396
- }
3800
+ function mostlyDirected(ctx, edges) {
2397
3801
  const objects = edges.filter((edge) => isJsonObject(edge));
2398
3802
  const undirectedEdges = objects.filter((edge) => edge.undirected === true).length;
2399
3803
  return objects.length === 0 ? ctx.defaultDirected("graphology") : undirectedEdges < objects.length;
2400
3804
  }
2401
- function pushGraphologyNode(ctx, record, element) {
2402
- if (!isJsonObject(record)) {
2403
- ctx.badElement("node", element);
2404
- return;
3805
+ function importGraphologyNodes(ctx, nodes, gephi) {
3806
+ const nodeKey = gephi ? "id" : "key";
3807
+ for (let i = 0; i < nodes.length; i++) {
3808
+ const element = `nodes[${i}]`;
3809
+ const record = nodes[i];
3810
+ if (!isJsonObject(record)) {
3811
+ ctx.badElement("node", element);
3812
+ continue;
3813
+ }
3814
+ const id = ctx.coerceId(hasKey(record, nodeKey) ? record[nodeKey] : void 0, element);
3815
+ if (id === null) {
3816
+ ctx.countSkipped("node");
3817
+ continue;
3818
+ }
3819
+ pushNestedNode(ctx, id, record, "attributes", gephi ? GEPHI_NODE_KEYS : GRAPHOLOGY_NODE_KEYS, element, gephi);
2405
3820
  }
2406
- const id = ctx.coerceId(hasKey(record, "key") ? record.key : void 0, element);
2407
- if (id === null) {
2408
- ctx.countSkipped("node");
2409
- return;
3821
+ }
3822
+ function importGraphologyEdges(ctx, edges, declared) {
3823
+ const { gephi } = declared;
3824
+ const ids = ctx.declareEdgeIds(edges, (edge) => gephi && !hasKey(edge, "key") ? edge.id : edge.key, "key", true);
3825
+ const violations = { selfLoops: 0, parallels: 0, flags: 0 };
3826
+ const pairs = declared.multi === false ? /* @__PURE__ */ new Set() : null;
3827
+ for (let i = 0; i < edges.length; i++) {
3828
+ const element = `edges[${i}]`;
3829
+ const record = graphologyEdgeRecord(ctx, edges[i], element);
3830
+ if (record === null) {
3831
+ continue;
3832
+ }
3833
+ try {
3834
+ const pushed = pushGraphologyEdge(ctx, record, element, ids, declared, violations);
3835
+ if (pushed !== null && pairs !== null) {
3836
+ violations.parallels += pairs.has(pushed) ? 1 : 0;
3837
+ pairs.add(pushed);
3838
+ }
3839
+ } catch (err) {
3840
+ ctx.skip(err, "edge", element);
3841
+ }
2410
3842
  }
2411
- pushNestedNode(ctx, id, record, "attributes", GRAPHOLOGY_NODE_KEYS, element);
3843
+ return violations;
2412
3844
  }
2413
- function readGraphologyEdge(ctx, reading, record, element) {
3845
+ function graphologyEdgeRecord(ctx, record, element) {
2414
3846
  if (!isJsonObject(record)) {
2415
3847
  ctx.badElement("edge", element);
2416
- return;
3848
+ return null;
2417
3849
  }
2418
3850
  if (!present(record, "source") || !present(record, "target")) {
2419
3851
  ctx.missingEndpoint(element, present(record, "source") ? "target" : "source");
2420
- return;
2421
- }
2422
- try {
2423
- const u = ctx.coerceId(record.source, `${element}.source`);
2424
- const v = ctx.coerceId(record.target, `${element}.target`);
2425
- if (u === null || v === null) {
2426
- ctx.countSkipped("edge");
2427
- return;
2428
- }
2429
- const kind = graphologyEdgeKind(ctx, reading, record, element);
2430
- const attributes = graphologyEdgeAttributes(ctx, record, element);
2431
- const idValue = ctx.edgeIdValue(reading.ids, record.key);
2432
- const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
2433
- ctx.setEdgeId(reading.ids, edge, idValue);
2434
- ctx.writeNested(ctx.edges, edge, record, attributes, GRAPHOLOGY_EDGE_KEYS, ctx.options.weightFrom, element);
2435
- if (reading.allowSelfLoops === false && u === v) {
2436
- reading.violations.selfLoops++;
2437
- }
2438
- if (reading.pairs !== null) {
2439
- const pair = `${kind} ${pairKey(u, v, kind === "directed")}`;
2440
- reading.violations.parallels += reading.pairs.has(pair) ? 1 : 0;
2441
- reading.pairs.add(pair);
2442
- }
2443
- } catch (err) {
2444
- ctx.skip(err, "edge", element);
3852
+ return null;
2445
3853
  }
3854
+ return record;
2446
3855
  }
2447
- function graphologyEdgeKind(ctx, reading, record, element) {
2448
- const { type } = reading;
2449
- if (type === "mixed") {
2450
- return flagOf(record.undirected, `${element}.undirected`, false, ctx.report) ? "undirected" : "directed";
3856
+ function pushGraphologyEdge(ctx, record, element, ids, declared, violations) {
3857
+ const { report } = ctx;
3858
+ const { type, gephi } = declared;
3859
+ const u = ctx.coerceId(record.source, `${element}.source`);
3860
+ const v = ctx.coerceId(record.target, `${element}.target`);
3861
+ if (u === null || v === null) {
3862
+ ctx.countSkipped("edge");
3863
+ return null;
2451
3864
  }
2452
- if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
2453
- reading.violations.flags++;
3865
+ let kind;
3866
+ if (type === "mixed") {
3867
+ kind = flagOf(record.undirected, `${element}.undirected`, false, report) ? "undirected" : "directed";
3868
+ } else {
3869
+ kind = type;
3870
+ if (typeof record.undirected === "boolean" && record.undirected !== (type === "undirected")) {
3871
+ violations.flags++;
3872
+ }
2454
3873
  }
2455
- return type;
2456
- }
2457
- function graphologyEdgeAttributes(ctx, record, element) {
2458
- const { attributes } = record;
2459
- if (attributes !== void 0 && attributes !== null && !isJsonObject(attributes)) {
2460
- ctx.report.error(
3874
+ const { attributes: rawAttributes } = record;
3875
+ if (rawAttributes !== void 0 && rawAttributes !== null && !isJsonObject(rawAttributes)) {
3876
+ report.error(
2461
3877
  "validation-error",
2462
3878
  JSON_ISSUE.BAD_VALUE,
2463
- `${element}: attributes must be an object, found ${describe(attributes)}`,
3879
+ `${element}: attributes must be an object, found ${describe(rawAttributes)}`,
2464
3880
  { element }
2465
3881
  );
2466
3882
  }
2467
- return isJsonObject(attributes) ? attributes : {};
3883
+ const attributes = isJsonObject(rawAttributes) ? rawAttributes : {};
3884
+ const idValue = ctx.edgeIdValue(ids, record.key);
3885
+ const edge = ctx.pushEdge(u, v, kind, ctx.weightOf(attributes), element);
3886
+ ctx.setEdgeId(ids, edge, idValue);
3887
+ ctx.writeNested(ctx.edges, edge, record, attributes, gephi ? GEPHI_EDGE_KEYS : GRAPHOLOGY_EDGE_KEYS, element, {
3888
+ weightFrom: ctx.options.weightFrom,
3889
+ plain: gephi
3890
+ });
3891
+ if (declared.allowSelfLoops === false && u === v) {
3892
+ violations.selfLoops++;
3893
+ }
3894
+ return `${kind} ${pairKey(u, v, kind === "directed")}`;
2468
3895
  }
2469
3896
  function reportGraphologyViolations(ctx, violations, type) {
2470
3897
  const notes = [];
@@ -2489,7 +3916,7 @@ function reportGraphologyViolations(ctx, violations, type) {
2489
3916
  });
2490
3917
  }
2491
3918
  }
2492
- function pushNestedNode(ctx, id, record, dictKey, structural, element) {
3919
+ function pushNestedNode(ctx, id, record, dictKey, structural, element, plain = false) {
2493
3920
  const index = ctx.pushNode(id, element);
2494
3921
  if (index < 0) {
2495
3922
  return index;
@@ -2504,7 +3931,7 @@ function pushNestedNode(ctx, id, record, dictKey, structural, element) {
2504
3931
  { element }
2505
3932
  );
2506
3933
  }
2507
- ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, null, element);
3934
+ ctx.writeNested(ctx.nodes, index, record, isJsonObject(dict) ? dict : {}, structural, element, { plain });
2508
3935
  } catch (err) {
2509
3936
  ctx.report.recordError(err, { element: String(id) });
2510
3937
  }
@@ -2522,7 +3949,7 @@ function importJgf(ctx, root) {
2522
3949
  `graph.nodes must be an object keyed by id or an array, found ${describe(nodesRaw)}`
2523
3950
  );
2524
3951
  }
2525
- const nodeRecords = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
3952
+ const nodeRecords2 = Array.isArray(nodesRaw) ? nodesRaw : Object.values(nodesRaw ?? {});
2526
3953
  const directed = jgfDirected(ctx, graph, edges);
2527
3954
  ctx.setHeader(directed);
2528
3955
  ctx.writeGraphDict(graph.metadata, "graph.metadata");
@@ -2533,18 +3960,18 @@ function importJgf(ctx, root) {
2533
3960
  };
2534
3961
  const label = typeof graph.label === "string" ? graph.label : null;
2535
3962
  ctx.reportNodeIdFrom("jgf", "the node keys");
2536
- ctx.sink.reserve(nodeRecords.length, edges.length);
3963
+ ctx.sink.reserve(nodeRecords2.length, edges.length);
2537
3964
  const labelColumn = ctx.nodes.declareIf(
2538
3965
  { name: "label", dtype: "string", role: "label", nullable: true },
2539
- anyHas(nodeRecords, "label")
3966
+ anyHas(nodeRecords2, "label")
2540
3967
  );
2541
3968
  if (isJsonObject(nodesRaw)) {
2542
- for (const key of Object.keys(nodesRaw)) {
3969
+ for (const key of jgfNodeKeys(ctx, root, graph, nodesRaw)) {
2543
3970
  pushJgfKeyedNode(ctx, key, nodesRaw[key], labelColumn);
2544
3971
  }
2545
3972
  } else {
2546
- for (let i = 0; i < nodeRecords.length; i++) {
2547
- pushJgfListedNode(ctx, nodeRecords[i], labelColumn, `nodes[${i}]`);
3973
+ for (let i = 0; i < nodeRecords2.length; i++) {
3974
+ pushJgfListedNode(ctx, nodeRecords2[i], labelColumn, `nodes[${i}]`);
2548
3975
  }
2549
3976
  }
2550
3977
  throwIfAborted(ctx.options.signal);
@@ -2629,7 +4056,7 @@ function jgfEdgeWriter(ctx, edges, hyperedges) {
2629
4056
  element
2630
4057
  });
2631
4058
  }
2632
- ctx.writeNested(ctx.edges, edge, record, dict, structural, ctx.options.weightFrom, element);
4059
+ ctx.writeNested(ctx.edges, edge, record, dict, structural, element, { weightFrom: ctx.options.weightFrom });
2633
4060
  };
2634
4061
  }
2635
4062
  function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
@@ -2654,6 +4081,14 @@ function readJgfEdge(ctx, record, element, directed, writeJgfEdge) {
2654
4081
  ctx.skip(err, "edge", element);
2655
4082
  }
2656
4083
  }
4084
+ function jgfNodeKeys(ctx, root, graph, nodes) {
4085
+ const keys = Object.keys(nodes);
4086
+ if (!keys.some((k) => ARRAY_INDEX.test(k))) {
4087
+ return keys;
4088
+ }
4089
+ const path = isJsonObject(root.graph) ? ["graph", "nodes"] : ["graphs", root.graphs.indexOf(graph), "nodes"];
4090
+ return keysInTextOrder(ctx.text, path) ?? keys;
4091
+ }
2657
4092
  function jgfGraphOf(ctx, root) {
2658
4093
  const single = isJsonObject(root.graph);
2659
4094
  reportUnreadKeys(ctx, root, /* @__PURE__ */ new Set([single ? "graph" : "graphs"]), "");
@@ -2760,7 +4195,7 @@ function pushJgfNode(ctx, id, record, labelColumn, element) {
2760
4195
  element
2761
4196
  });
2762
4197
  }
2763
- ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, null, element);
4198
+ ctx.writeNested(ctx.nodes, index, record, isJsonObject(metadata) ? metadata : {}, JGF_NODE_KEYS, element);
2764
4199
  } catch (err) {
2765
4200
  ctx.report.recordError(err, { element: String(id) });
2766
4201
  }
@@ -2909,44 +4344,35 @@ function distinctMembers(ctx, members, element) {
2909
4344
  function importCytoscape(ctx, root) {
2910
4345
  const { elements, extra } = cytoscapeRoot(ctx, root);
2911
4346
  const { nodes, edges } = cytoscapeSections(ctx, elements);
4347
+ const generatedIds = cytoscapeGeneratedIds(nodes);
4348
+ ctx.styleSource = {
4349
+ dialect: "cytoscape",
4350
+ block: blockOf(root),
4351
+ elements: elements ?? [],
4352
+ style: isJsonObject(root) ? root.style : void 0,
4353
+ generatedBy: isJsonObject(root) && typeof root.generated_by === "string" ? root.generated_by : null,
4354
+ generatedIds
4355
+ };
2912
4356
  ctx.setHeader(ctx.defaultDirected("cytoscape"));
2913
4357
  ctx.reportNodeIdFrom("cytoscape", "data.id");
2914
4358
  ctx.sink.reserve(nodes.length, edges.length);
2915
- const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
2916
- const reading = {
2917
- positionColumn: ctx.nodes.declareIf(
2918
- {
2919
- name: POSITION_COLUMN,
2920
- dtype: "f64",
2921
- components: 3,
2922
- role: "position",
2923
- mutable: true,
2924
- nullable: true,
2925
- // 3D layouts written by Cytoscape-compatible tools carry a z
2926
- extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
2927
- origin: { format: "json", namespace: "cytoscape" }
2928
- },
2929
- anyHas(nodes, "position")
2930
- ),
2931
- classesColumn: ctx.nodes.declareIf(
2932
- { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
2933
- anyHas(nodes, "classes")
2934
- ),
2935
- parents: [],
2936
- point: [0, 0, 0]
2937
- };
2938
- const parentColumn = ctx.nodes.declareIf(
2939
- { name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
2940
- dataHas(nodes, "parent")
2941
- );
4359
+ const columns = cytoscapeNodeColumns(ctx, nodes);
2942
4360
  const edgeClassesColumn = ctx.edges.declareIf(
2943
4361
  { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
2944
4362
  anyHas(edges, "classes")
2945
4363
  );
4364
+ const parents = [];
2946
4365
  for (let i = 0; i < nodes.length; i++) {
2947
- readCytoscapeNode(ctx, reading, nodes[i], `nodes[${i}]`);
4366
+ const element = `nodes[${i}]`;
4367
+ const record = nodes[i];
4368
+ if (isJsonObject(record) && isJsonObject(record.data)) {
4369
+ const raw = record.data.id === void 0 ? generatedIds.get(record) : record.data.id;
4370
+ importCytoscapeNode(ctx, record, record.data, raw, element, columns, parents);
4371
+ } else {
4372
+ ctx.badElement("node", element, "an element with a data object");
4373
+ }
2948
4374
  }
2949
- resolveCytoscapeParents(ctx, reading.parents, parentColumn);
4375
+ resolveCytoscapeParents(ctx, parents, columns.parent);
2950
4376
  throwIfAborted(ctx.options.signal);
2951
4377
  importCytoscapeEdges(ctx, edges, edgeClassesColumn);
2952
4378
  ctx.setMeta({ dialect: "cytoscape", cytoscape: extra }, ctx.weightOriginPatch());
@@ -2961,23 +4387,46 @@ function cytoscapeRoot(ctx, root) {
2961
4387
  `a Cytoscape document must be an object or an array, found ${describe(root)}`
2962
4388
  );
2963
4389
  }
2964
- ctx.writeGraphDict(root.data, "data");
4390
+ const object = root;
4391
+ ctx.writeGraphDict(object.data, "data");
2965
4392
  const rest = {};
2966
- for (const key of Object.keys(root)) {
2967
- if (key !== "elements" && key !== "data") {
2968
- rest[key] = root[key];
4393
+ for (const key of Object.keys(object)) {
4394
+ if (key !== "elements" && key !== "data" && key !== STYLE_BLOCK_NAME) {
4395
+ rest[key] = object[key];
2969
4396
  }
2970
4397
  }
2971
- return Object.keys(rest).length > 0 ? { elements: root.elements, extra: rest } : { elements: root.elements };
4398
+ return Object.keys(rest).length > 0 ? { elements: object.elements, extra: rest } : { elements: object.elements };
4399
+ }
4400
+ function cytoscapeNodeColumns(ctx, nodes) {
4401
+ const dataHas = (items, key) => items.some((item) => isJsonObject(item) && isJsonObject(item.data) && item.data[key] !== void 0);
4402
+ return {
4403
+ position: ctx.nodes.declareIf(
4404
+ {
4405
+ name: POSITION_COLUMN,
4406
+ dtype: "f64",
4407
+ components: 3,
4408
+ role: "position",
4409
+ mutable: true,
4410
+ nullable: true,
4411
+ // 3D layouts written by Cytoscape-compatible tools carry a z
4412
+ extra: { sourceDims: nodes.some(hasPositionZ) ? 3 : 2, units: "file" },
4413
+ origin: { format: "json", namespace: "cytoscape" }
4414
+ },
4415
+ anyHas(nodes, "position")
4416
+ ),
4417
+ classes: ctx.nodes.declareIf(
4418
+ { name: CLASSES_COLUMN, dtype: "list", itemDtype: "string", role: "classes", nullable: true },
4419
+ anyHas(nodes, "classes")
4420
+ ),
4421
+ parent: ctx.nodes.declareIf(
4422
+ { name: PARENT_COLUMN, dtype: "u32", role: "parent", refersTo: "node", nullable: true },
4423
+ dataHas(nodes, "parent")
4424
+ )
4425
+ };
2972
4426
  }
2973
- function readCytoscapeNode(ctx, reading, record, element) {
4427
+ function importCytoscapeNode(ctx, record, data, raw, element, columns, parents) {
2974
4428
  const { report } = ctx;
2975
- if (!isJsonObject(record) || !isJsonObject(record.data)) {
2976
- ctx.badElement("node", element, "an element with a data object");
2977
- return;
2978
- }
2979
- const { data } = record;
2980
- const id = ctx.coerceId(hasKey(data, "id") ? data.id : void 0, element);
4429
+ const id = ctx.coerceId(raw, element);
2981
4430
  if (id === null) {
2982
4431
  ctx.countSkipped("node");
2983
4432
  return;
@@ -2995,44 +4444,30 @@ function readCytoscapeNode(ctx, reading, record, element) {
2995
4444
  );
2996
4445
  }
2997
4446
  try {
2998
- writeCytoscapeData(ctx, reading, index, data, element);
2999
- writeCytoscapePosition$1(ctx, reading, index, record.position, element);
3000
- writeClasses(ctx, ctx.nodes, reading.classesColumn, index, record.classes, element);
4447
+ for (const key of Object.keys(data).filter((k) => k !== "id")) {
4448
+ if (key !== "parent") {
4449
+ ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
4450
+ continue;
4451
+ }
4452
+ const parent = data.parent === null ? null : ctx.coerceId(data.parent, `${element}.data.parent`);
4453
+ if (parent !== null) {
4454
+ parents.push({ index, parent, element });
4455
+ }
4456
+ }
4457
+ writeCytoscapePosition$1(ctx, columns.position, index, record.position, element);
4458
+ writeClasses(ctx, ctx.nodes, columns.classes, index, record.classes, element);
3001
4459
  writeElementKeys(ctx.nodes, index, record, element);
3002
4460
  } catch (err) {
3003
4461
  report.recordError(err, { element: String(id) });
3004
4462
  }
3005
4463
  }
3006
- function writeCytoscapeData(ctx, reading, index, data, element) {
3007
- for (const key of Object.keys(data)) {
3008
- if (key === "id") {
3009
- continue;
3010
- }
3011
- if (key !== "parent") {
3012
- ctx.nodes.write(index, key, data[key], SUFFIX.data, element);
3013
- continue;
3014
- }
3015
- const raw = data.parent;
3016
- if (raw === void 0 || raw === null) {
3017
- continue;
3018
- }
3019
- const parent = ctx.coerceId(raw, `${element}.data.parent`);
3020
- if (parent !== null) {
3021
- reading.parents.push({ index, parent, element });
3022
- }
3023
- }
3024
- }
3025
- function writeCytoscapePosition$1(ctx, reading, index, position, element) {
4464
+ function writeCytoscapePosition$1(ctx, column, index, position, element) {
3026
4465
  if (position === void 0 || position === null) {
3027
4466
  return;
3028
4467
  }
3029
4468
  const z = isJsonObject(position) ? position.z ?? 0 : 0;
3030
4469
  if (isJsonObject(position) && isCoordinate(position.x) && isCoordinate(position.y) && isCoordinate(z)) {
3031
- const { point } = reading;
3032
- point[0] = position.x;
3033
- point[1] = flipY(position.y);
3034
- point[2] = z;
3035
- ctx.nodes.set(reading.positionColumn, index, point);
4470
+ ctx.nodes.set(column, index, [position.x, flipY(position.y), z]);
3036
4471
  } else {
3037
4472
  ctx.report.error(
3038
4473
  "validation-error",
@@ -3046,7 +4481,11 @@ function resolveCytoscapeParents(ctx, parents, parentColumn) {
3046
4481
  const { report } = ctx;
3047
4482
  const linkOf = /* @__PURE__ */ new Map();
3048
4483
  for (let order = 0; order < parents.length; order++) {
3049
- const { index, parent, element } = parents[order];
4484
+ const { index, element } = parents[order];
4485
+ let { parent } = parents[order];
4486
+ if (ctx.sink.indexOf(parent) === INVALID_INDEX) {
4487
+ parent = ctx.textualId(parent, element) ?? parent;
4488
+ }
3050
4489
  const parentIndex = ctx.sink.indexOf(parent);
3051
4490
  if (parentIndex === INVALID_INDEX) {
3052
4491
  report.error(
@@ -3121,8 +4560,8 @@ function importCytoscapeEdges(ctx, edges, edgeClassesColumn) {
3121
4560
  function importCytoscapeEdge(ctx, shared, record, data, element) {
3122
4561
  const { ids, kind, edgeClassesColumn } = shared;
3123
4562
  try {
3124
- const u = ctx.coerceId(data.source, `${element}.data.source`);
3125
- const v = ctx.coerceId(data.target, `${element}.data.target`);
4563
+ const u = ctx.textualId(data.source, `${element}.data.source`);
4564
+ const v = ctx.textualId(data.target, `${element}.data.target`);
3126
4565
  if (u === null || v === null) {
3127
4566
  ctx.countSkipped("edge");
3128
4567
  return;
@@ -3174,6 +4613,36 @@ function cytoscapeSections(ctx, elements) {
3174
4613
  }
3175
4614
  return report.fail(JSON_ISSUE.SHAPE, `elements must be an object or an array, found ${describe(elements)}`);
3176
4615
  }
4616
+ function cytoscapeGeneratedIds(nodes) {
4617
+ const out = /* @__PURE__ */ new Map();
4618
+ const missing = nodes.filter(
4619
+ (n) => isJsonObject(n) && isJsonObject(n.data) && n.data.id === void 0
4620
+ );
4621
+ if (missing.length === 0) {
4622
+ return out;
4623
+ }
4624
+ const taken = /* @__PURE__ */ new Set();
4625
+ for (const n of nodes) {
4626
+ const id = isJsonObject(n) && isJsonObject(n.data) ? n.data.id : void 0;
4627
+ if (typeof id === "string" || typeof id === "number") {
4628
+ taken.add(String(id));
4629
+ }
4630
+ }
4631
+ for (let k = 0; k < missing.length; k++) {
4632
+ let id = `n${String(k)}`;
4633
+ let j = 2;
4634
+ while (taken.has(id)) {
4635
+ id = `n${String(k)}_${String(j)}`;
4636
+ j++;
4637
+ }
4638
+ taken.add(id);
4639
+ out.set(missing[k], id);
4640
+ }
4641
+ return out;
4642
+ }
4643
+ function blockOf(root) {
4644
+ return isJsonObject(root) && typeof root[STYLE_BLOCK_NAME] === "string" ? root[STYLE_BLOCK_NAME] : null;
4645
+ }
3177
4646
  function hasPositionZ(element) {
3178
4647
  return isJsonObject(element) && isJsonObject(element.position) && typeof element.position.z === "number";
3179
4648
  }
@@ -3234,6 +4703,7 @@ const jsonImporter = Object.freeze({
3234
4703
  "typedefs"
3235
4704
  ]),
3236
4705
  extensions: Object.freeze([".json"]),
4706
+ positions: jsonPositions,
3237
4707
  mimeTypes: Object.freeze(["application/json"]),
3238
4708
  /**
3239
4709
  * Confidence that the head is a JSON graph document: 0 unless it starts with `{` or `[`, 0.5
@@ -3244,12 +4714,12 @@ const jsonImporter = Object.freeze({
3244
4714
  */
3245
4715
  sniff(head) {
3246
4716
  const text = new TextDecoder("utf-8").decode(headBytes(head).subarray(0, SNIFF_BYTES));
3247
- const trimmed = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();
3248
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
4717
+ const trimmed2 = (text.startsWith(BOM) ? text.slice(1) : text).trimStart();
4718
+ if (!trimmed2.startsWith("{") && !trimmed2.startsWith("[")) {
3249
4719
  return 0;
3250
4720
  }
3251
- const score = SNIFF_KEYS.some((key) => trimmed.includes(key)) ? 0.9 : 0.5;
3252
- return trimmed.startsWith("[") && sniffJsonDialectHead(trimmed) !== "cytoscape" ? Math.min(score, 0.3) : score;
4721
+ const score = SNIFF_KEYS.some((key) => trimmed2.includes(key)) ? 0.9 : 0.5;
4722
+ return trimmed2.startsWith("[") && sniffJsonDialectHead(trimmed2) !== "cytoscape" ? Math.min(score, 0.3) : score;
3253
4723
  },
3254
4724
  /**
3255
4725
  * Read a JSON graph document into the sink.
@@ -3264,7 +4734,7 @@ const jsonImporter = Object.freeze({
3264
4734
  const report = new ImportReportBuilder("json", resolved.errorLimit);
3265
4735
  const text = await readText(input, report, { ...resolved, bomlessUtf16: true });
3266
4736
  const { root, dialect } = documentOf(parseDocument(text, report), json2, report);
3267
- readGraph(root, dialect, sink, report, resolved, json2, options);
4737
+ readGraph({ root, dialect, text }, sink, report, resolved, json2, options);
3268
4738
  return report.finish();
3269
4739
  },
3270
4740
  /**
@@ -3301,17 +4771,35 @@ const jsonImporter = Object.freeze({
3301
4771
  const reports = [];
3302
4772
  for (let i = 0; i < Math.max(graphs, 1); i++) {
3303
4773
  const report = i === 0 ? first : new ImportReportBuilder("json", resolved.errorLimit);
3304
- readGraph(root, dialect, sinkFor(i), report, resolved, { ...json2, graphIndex: i, all: true }, options);
4774
+ readGraph(
4775
+ { root, dialect, text },
4776
+ sinkFor(i),
4777
+ report,
4778
+ resolved,
4779
+ { ...json2, graphIndex: i, all: true },
4780
+ options
4781
+ );
3305
4782
  reports.push(report.finish());
3306
4783
  }
3307
4784
  return reports;
3308
- }
4785
+ },
4786
+ /**
4787
+ * The document's styles, read by its dialect's reader (Cytoscape.js stylesheets, graphology and vis.js keys,
4788
+ * NetworkX's defaults); a `graphty.styles` block gives back the rules graphty wrote.
4789
+ * @param snapshot - the graph the import built
4790
+ * @param context - the work budget and what the import kept
4791
+ * @returns the styles, or null when the dialect has none
4792
+ */
4793
+ styles: jsonStyles
3309
4794
  });
3310
- function readGraph(root, dialect, sink, report, resolved, json2, options) {
4795
+ function readGraph(doc, sink, report, resolved, json2, options) {
4796
+ const { root, dialect, text } = doc;
3311
4797
  const ctx = new ImportContext(sink, report, resolved, json2, options?.defaultDirected !== void 0);
4798
+ ctx.text = text;
3312
4799
  reportSinkOptions(sink, options, report, dialect === "obographs");
3313
4800
  reportUnusedOptions(options, report, USED_OPTIONS);
3314
4801
  readDialect(ctx, root, dialect);
4802
+ report.keepForStyles(ctx.styleSource ?? { dialect, block: blockOf(root) });
3315
4803
  ctx.reportDangling();
3316
4804
  ctx.nodes.reportNullOnly();
3317
4805
  ctx.edges.reportNullOnly();
@@ -4042,7 +5530,7 @@ function graphPropertyValues(snapshot) {
4042
5530
  const values = [];
4043
5531
  for (const column of snapshot.graph) {
4044
5532
  const dtype = column.dtype === "list" ? column.child.dtype : column.dtype;
4045
- for (const item of valuesOf(cellOf(column, 0))) {
5533
+ for (const item of valuesOf$1(cellOf(column, 0))) {
4046
5534
  values.push({ pred: column.meta.name, val: typeof item === "string" ? item : textOf(item, dtype) });
4047
5535
  }
4048
5536
  }
@@ -4221,10 +5709,10 @@ ${settings.indent}` : "";
4221
5709
  planIds() {
4222
5710
  const { snapshot } = this;
4223
5711
  const typeColumn = snapshot.nodes.get("type");
4224
- let numeric = 0;
5712
+ let numeric2 = 0;
4225
5713
  for (let i = 0; i < snapshot.nodeCount; i++) {
4226
5714
  const id = snapshot.ids.idOf(i);
4227
- numeric += typeof id === "number" ? 1 : 0;
5715
+ numeric2 += typeof id === "number" ? 1 : 0;
4228
5716
  const text = String(id);
4229
5717
  let { iri, exact } = this.iriOf(text);
4230
5718
  const typedef = typeColumn !== null && typeColumn.isSet(i) && typeColumn.value(i) === "Typedef";
@@ -4240,12 +5728,12 @@ ${settings.indent}` : "";
4240
5728
  this.changedRows.add(i);
4241
5729
  }
4242
5730
  }
4243
- if (numeric > 0) {
5731
+ if (numeric2 > 0) {
4244
5732
  this.note(
4245
5733
  LOSS.ID_TEXT_TYPE,
4246
- `${numeric} numeric node id${plural(numeric)} ${agree(numeric, "is", "are")} written as text and read back as strings`,
5734
+ `${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "is", "are")} written as text and read back as strings`,
4247
5735
  null,
4248
- numeric
5736
+ numeric2
4249
5737
  );
4250
5738
  }
4251
5739
  }
@@ -4593,7 +6081,7 @@ ${settings.indent}` : "";
4593
6081
  for (const tag of PROPERTY_TAGS) {
4594
6082
  const v = this.at(tag, i);
4595
6083
  const pred = TAG_PREDICATES.get(tag) ?? tag;
4596
- for (const item of valuesOf(v)) {
6084
+ for (const item of valuesOf$1(v)) {
4597
6085
  const text = String(item);
4598
6086
  values.push({ pred, val: tag === "replaced_by" || tag === "consider" ? this.iriOf(text).iri : text });
4599
6087
  }
@@ -4872,7 +6360,12 @@ const JSON_LOSS = Object.freeze({
4872
6360
  * OBO Graphs: an OBO attribute stored as text where graph-io uses a dictionary (or the other way round); it reads
4873
6361
  * back with graph-io's usual type. The values are the same.
4874
6362
  */
4875
- DTYPE_UNSUPPORTED: LOSS.DTYPE
6363
+ DTYPE_UNSUPPORTED: LOSS.DTYPE,
6364
+ /**
6365
+ * Saving with styles: a column named like one of the dialect's style keys (graphology's `color`, `size`, `label`,
6366
+ * vis.js's `color`, `shape`, `font`, ...) is written with what graphty draws, so the values it held differ.
6367
+ */
6368
+ STYLE_KEY_REPLACED: STYLE_KEY_REPLACED_CODE
4876
6369
  });
4877
6370
  const SLOT_ROLES = Object.freeze({
4878
6371
  "node-link": /* @__PURE__ */ new Set(),
@@ -5131,7 +6624,9 @@ function plan(snapshot, resolved) {
5131
6624
  const caps = dialectCapabilities(dialect);
5132
6625
  const notes = checkCapabilities(snapshot, caps, resolved.common, {
5133
6626
  roles: SLOT_ROLES[dialect],
5134
- positionDtype: "f64"
6627
+ positionDtype: "f64",
6628
+ // Deprecated (next major): role columns are written as plain attributes; styles go through the style writer.
6629
+ vizAsAttributes: true
5135
6630
  }).filter((n) => n.code !== LOSS.POSITIONS && n.code !== LOSS.EDGE_IDS_DROPPED);
5136
6631
  const note = (code, message, column = null, count = null) => {
5137
6632
  notes.push(Object.freeze({ code, message, column, count }));
@@ -5201,7 +6696,7 @@ function reservedKeys(snapshot, resolved) {
5201
6696
  break;
5202
6697
  case "vis":
5203
6698
  node.add(resolved.nodeIdKey ?? "id");
5204
- edge.add(resolved.sourceKey).add(resolved.targetKey);
6699
+ edge.add(resolved.sourceKey).add(resolved.targetKey).add("source").add("target");
5205
6700
  break;
5206
6701
  case "cytoscape":
5207
6702
  node.add("id").add("parent");
@@ -5442,7 +6937,7 @@ function countNonZeroZ(column) {
5442
6937
  function jgfIdNotes(snapshot, note) {
5443
6938
  const { ids } = snapshot;
5444
6939
  const seen = /* @__PURE__ */ new Set();
5445
- let numeric = 0;
6940
+ let numeric2 = 0;
5446
6941
  let collisions = 0;
5447
6942
  let indexLike = 0;
5448
6943
  let lastIndex = -1;
@@ -5452,7 +6947,7 @@ function jgfIdNotes(snapshot, note) {
5452
6947
  const id = ids.idOf(i);
5453
6948
  const text = String(id);
5454
6949
  if (typeof id === "number") {
5455
- numeric++;
6950
+ numeric2++;
5456
6951
  }
5457
6952
  if (seen.has(text)) {
5458
6953
  collisions++;
@@ -5469,12 +6964,12 @@ function jgfIdNotes(snapshot, note) {
5469
6964
  sawOther = true;
5470
6965
  }
5471
6966
  }
5472
- if (numeric > 0) {
6967
+ if (numeric2 > 0) {
5473
6968
  note(
5474
6969
  JSON_LOSS.NUMERIC_IDS_STRINGIFIED,
5475
- `${numeric} numeric node id${plural(numeric)} ${agree(numeric, "becomes", "become")} JGF object keys (strings); pass ids: "canonical" on re-import`,
6970
+ `${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "becomes", "become")} JGF object keys (strings); pass ids: "canonical" on re-import`,
5476
6971
  null,
5477
- numeric
6972
+ numeric2
5478
6973
  );
5479
6974
  }
5480
6975
  if (collisions > 0) {
@@ -5663,9 +7158,20 @@ function* writeNodeLink(snapshot, p) {
5663
7158
  yield w.take();
5664
7159
  }
5665
7160
  w.close("]");
7161
+ writeTopLevelBlock(c, p);
5666
7162
  w.close("}");
5667
7163
  yield w.take();
5668
7164
  }
7165
+ function writeTopLevelBlock(c, p) {
7166
+ const groups = p.resolved.styled?.groups ?? null;
7167
+ if (groups !== null) {
7168
+ c.w.member("groups", JSON.stringify(groups));
7169
+ }
7170
+ const block = p.resolved.styled?.topLevelBlock ?? null;
7171
+ if (block !== null) {
7172
+ c.w.member(STYLE_BLOCK_NAME, JSON.stringify(block));
7173
+ }
7174
+ }
5669
7175
  function* writeVis(snapshot, p) {
5670
7176
  const { resolved } = p;
5671
7177
  const c = { w: new JsonWriter(resolved.indent), ids: snapshot.ids, nonfinite: { count: 0 } };
@@ -5708,6 +7214,7 @@ function* writeVis(snapshot, p) {
5708
7214
  yield w.take();
5709
7215
  }
5710
7216
  w.close("]");
7217
+ writeTopLevelBlock(c, p);
5711
7218
  w.close("}");
5712
7219
  yield w.take();
5713
7220
  }
@@ -5890,7 +7397,7 @@ function* writeCytoscape(snapshot, p) {
5890
7397
  writeSlots(c, p.nodes, i, parentSlots);
5891
7398
  writeSlots(c, p.nodes, i, ATTRIBUTE_SLOTS);
5892
7399
  w.close("}");
5893
- writeCytoscapePosition(c, p.nodes, i);
7400
+ writeCytoscapePosition(c, p, i);
5894
7401
  writeSlots(c, p.nodes, i, ELEMENT_SLOTS);
5895
7402
  w.close("}");
5896
7403
  yield w.take();
@@ -5927,13 +7434,14 @@ function* writeCytoscape(snapshot, p) {
5927
7434
  w.key("data");
5928
7435
  writeGraphObject(c, p);
5929
7436
  }
5930
- writeCytoscapeExtra(c, resolved.shape.cytoscape);
7437
+ writeCytoscapeTopLevel(c, p);
7438
+ writeTopLevelBlock(c, p);
5931
7439
  w.close("}");
5932
7440
  yield w.take();
5933
7441
  }
5934
- function writeCytoscapePosition(c, items, i) {
7442
+ function writeCytoscapePosition(c, p, i) {
5935
7443
  const { w } = c;
5936
- for (const item of items) {
7444
+ for (const item of p.nodes) {
5937
7445
  if (item.slot === "cytoscapePosition" && item.column.isSet(i)) {
5938
7446
  const value = item.column.value(i);
5939
7447
  const f32 = item.column.dtype === "f32";
@@ -5945,15 +7453,18 @@ function writeCytoscapePosition(c, items, i) {
5945
7453
  }
5946
7454
  }
5947
7455
  }
5948
- function writeCytoscapeExtra(c, extra) {
5949
- if (extra === void 0) {
5950
- return;
5951
- }
7456
+ function writeCytoscapeTopLevel(c, p) {
7457
+ const { w } = c;
7458
+ const extra = p.resolved.shape.cytoscape ?? {};
7459
+ const stylesheet = p.resolved.styled?.stylesheet ?? null;
5952
7460
  for (const key of Object.keys(extra)) {
5953
- if (key !== "elements" && key !== "data") {
5954
- c.w.member(key, valueText(extra[key], false, c.nonfinite));
7461
+ if (key !== "elements" && key !== "data" && !(key === "style" && stylesheet !== null)) {
7462
+ w.member(key, valueText(extra[key], false, c.nonfinite));
5955
7463
  }
5956
7464
  }
7465
+ if (stylesheet !== null) {
7466
+ w.member("style", valueText(stylesheet, false, c.nonfinite));
7467
+ }
5957
7468
  }
5958
7469
  function edgeIdGenerator(snapshot, p) {
5959
7470
  const used = /* @__PURE__ */ new Set();
@@ -5978,7 +7489,13 @@ function edgeIdGenerator(snapshot, p) {
5978
7489
  };
5979
7490
  }
5980
7491
  function parts(snapshot, resolved) {
5981
- return resolved.dialect === "obographs" ? planObographs(snapshot, resolved).write() : write(snapshot, plan(snapshot, resolved));
7492
+ const s = resolved.styled?.snapshot ?? snapshot;
7493
+ return resolved.dialect === "obographs" ? planObographs(s, resolved).write() : write(s, plan(s, resolved));
7494
+ }
7495
+ function resolveStyled(snapshot, options) {
7496
+ const resolved = resolve(snapshot, options);
7497
+ const styled = jsonStyledExport(snapshot, resolved.dialect, options?.styles);
7498
+ return styled === null ? resolved : { ...resolved, styled };
5982
7499
  }
5983
7500
  const jsonExporter = Object.freeze({
5984
7501
  format: "json",
@@ -5994,6 +7511,7 @@ const jsonExporter = Object.freeze({
5994
7511
  "weightKey"
5995
7512
  ]),
5996
7513
  capabilities: dialectCapabilities("node-link"),
7514
+ styles: Object.freeze({ capabilities: JSON_STYLE_CAPABILITIES }),
5997
7515
  /**
5998
7516
  * Pre-flight: every loss of the selected dialect, without writing anything.
5999
7517
  * @param snapshot - the snapshot
@@ -6001,9 +7519,10 @@ const jsonExporter = Object.freeze({
6001
7519
  * @returns the notes, empty when the export is exact
6002
7520
  */
6003
7521
  check(snapshot, options) {
6004
- const resolved = resolve(snapshot, options);
6005
- const notes = resolved.dialect === "obographs" ? planObographs(snapshot, resolved).notes : plan(snapshot, resolved).notes;
6006
- return Object.freeze([...notes]);
7522
+ const resolved = resolveStyled(snapshot, options);
7523
+ const s = resolved.styled?.snapshot ?? snapshot;
7524
+ const notes = resolved.dialect === "obographs" ? planObographs(s, resolved).notes : plan(s, resolved).notes;
7525
+ return Object.freeze([...notes, ...resolved.styled?.notes ?? []]);
6007
7526
  },
6008
7527
  /**
6009
7528
  * Write the document as UTF-8 chunks.
@@ -6012,7 +7531,7 @@ const jsonExporter = Object.freeze({
6012
7531
  * @returns the chunks
6013
7532
  */
6014
7533
  export(snapshot, options) {
6015
- return encodeChunks(parts(snapshot, resolve(snapshot, options)));
7534
+ return encodeChunks(parts(snapshot, resolveStyled(snapshot, options)));
6016
7535
  },
6017
7536
  /**
6018
7537
  * Write the document as one string.
@@ -6021,7 +7540,7 @@ const jsonExporter = Object.freeze({
6021
7540
  * @returns the document
6022
7541
  */
6023
7542
  exportToString(snapshot, options) {
6024
- return joinText(parts(snapshot, resolve(snapshot, options)));
7543
+ return joinText(parts(snapshot, resolveStyled(snapshot, options)));
6025
7544
  }
6026
7545
  });
6027
7546
  function jsonCapabilities(dialect) {
@@ -6045,4 +7564,4 @@ export {
6045
7564
  rankFormats as r,
6046
7565
  sniffFormat as s
6047
7566
  };
6048
- //# sourceMappingURL=exporter-CpRyHZ3H.js.map
7567
+ //# sourceMappingURL=exporter-quPUCBiC.js.map