@graphty/graph-io 0.3.47 → 0.3.48

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 (460) hide show
  1. package/dist/chunks/{approximations-wWjCRzKj.js → approximations-C2riR4NT.js} +2 -2
  2. package/dist/chunks/{approximations-wWjCRzKj.js.map → approximations-C2riR4NT.js.map} +1 -1
  3. package/dist/chunks/{block-DiGq58c3.js → block-Cu22ewuS.js} +92 -21
  4. package/dist/chunks/block-Cu22ewuS.js.map +1 -0
  5. package/dist/chunks/{choose--jM0yYCo.js → choose-Cdx6Enl2.js} +3 -3
  6. package/dist/chunks/{choose--jM0yYCo.js.map → choose-Cdx6Enl2.js.map} +1 -1
  7. package/dist/chunks/codes-CV_Bhcyi.js +153 -0
  8. package/dist/chunks/codes-CV_Bhcyi.js.map +1 -0
  9. package/dist/chunks/{constants-BKwqelYD.js → constants-D0LqcsLJ.js} +2 -2
  10. package/dist/chunks/{constants-BKwqelYD.js.map → constants-D0LqcsLJ.js.map} +1 -1
  11. package/dist/chunks/context-cgmmOxZ2.js +663 -0
  12. package/dist/chunks/context-cgmmOxZ2.js.map +1 -0
  13. package/dist/chunks/credentials-BiQsnMTb.js +347 -0
  14. package/dist/chunks/credentials-BiQsnMTb.js.map +1 -0
  15. package/dist/chunks/cx-export-BEeF6ymo.js +259 -0
  16. package/dist/chunks/cx-export-BEeF6ymo.js.map +1 -0
  17. package/dist/chunks/descriptor-BJ-W0Jd-.js +137 -0
  18. package/dist/chunks/descriptor-BJ-W0Jd-.js.map +1 -0
  19. package/dist/chunks/descriptor-C-YDhtsn.js +48 -0
  20. package/dist/chunks/descriptor-C-YDhtsn.js.map +1 -0
  21. package/dist/chunks/{emit-CwU8cUmG.js → emit-CD8xnY8s.js} +70 -10
  22. package/dist/chunks/emit-CD8xnY8s.js.map +1 -0
  23. package/dist/chunks/{escape-CgzxiYPg.js → escape-DH2Egt-l.js} +12 -12
  24. package/dist/chunks/{escape-CgzxiYPg.js.map → escape-DH2Egt-l.js.map} +1 -1
  25. package/dist/chunks/{export-BvqAXCKh.js → export-CZ7VRm4I.js} +53 -1443
  26. package/dist/chunks/export-CZ7VRm4I.js.map +1 -0
  27. package/dist/chunks/{exporter-DndFlGSa.js → exporter-BIdaoIgh.js} +7 -6
  28. package/dist/chunks/{exporter-DndFlGSa.js.map → exporter-BIdaoIgh.js.map} +1 -1
  29. package/dist/chunks/{exporter-CJgfhF-l.js → exporter-ChjL5fmP.js} +8 -7
  30. package/dist/chunks/{exporter-CJgfhF-l.js.map → exporter-ChjL5fmP.js.map} +1 -1
  31. package/dist/chunks/{exporter--Mk9gXCJ.js → exporter-Dcw7Ldtq.js} +6 -4
  32. package/dist/chunks/{exporter--Mk9gXCJ.js.map → exporter-Dcw7Ldtq.js.map} +1 -1
  33. package/dist/chunks/exporter-DtVU80Fa.js +1008 -0
  34. package/dist/chunks/exporter-DtVU80Fa.js.map +1 -0
  35. package/dist/chunks/{exporter-CrDWIyiq.js → exporter-bxxjOrDZ.js} +11 -9
  36. package/dist/chunks/{exporter-CrDWIyiq.js.map → exporter-bxxjOrDZ.js.map} +1 -1
  37. package/dist/chunks/format-BMS-1Nxb.js +64 -0
  38. package/dist/chunks/format-BMS-1Nxb.js.map +1 -0
  39. package/dist/chunks/{generic-Dq1ntt9q.js → generic-CP6YD34u.js} +4 -4
  40. package/dist/chunks/{generic-Dq1ntt9q.js.map → generic-CP6YD34u.js.map} +1 -1
  41. package/dist/chunks/{importer-DiZRmOQG.js → importer-B87_fmVx.js} +13 -17
  42. package/dist/chunks/importer-B87_fmVx.js.map +1 -0
  43. package/dist/chunks/{importer-BSvfrX_h.js → importer-Bji2MeWr.js} +18 -1014
  44. package/dist/chunks/importer-Bji2MeWr.js.map +1 -0
  45. package/dist/chunks/{importer-COTK9Tsl.js → importer-CB_zV5_L.js} +14 -11
  46. package/dist/chunks/importer-CB_zV5_L.js.map +1 -0
  47. package/dist/chunks/{importer-e6LGpqHB.js → importer-CVT-JyDE.js} +12 -9
  48. package/dist/chunks/importer-CVT-JyDE.js.map +1 -0
  49. package/dist/chunks/{importer-yh_aBCU6.js → importer-Cyy6UseH.js} +7 -6
  50. package/dist/chunks/{importer-yh_aBCU6.js.map → importer-Cyy6UseH.js.map} +1 -1
  51. package/dist/chunks/{importer-iFYPEKaJ.js → importer-DPZDN40-.js} +14 -10
  52. package/dist/chunks/{importer-iFYPEKaJ.js.map → importer-DPZDN40-.js.map} +1 -1
  53. package/dist/chunks/{importer-CMmeMWlC.js → importer-e3huMZbm.js} +8 -260
  54. package/dist/chunks/importer-e3huMZbm.js.map +1 -0
  55. package/dist/chunks/input-Ccg9I22A.js +1397 -0
  56. package/dist/chunks/input-Ccg9I22A.js.map +1 -0
  57. package/dist/chunks/{json-elements-DJZRZ6jd.js → json-elements-By172SVq.js} +4 -4
  58. package/dist/chunks/{json-elements-DJZRZ6jd.js.map → json-elements-By172SVq.js.map} +1 -1
  59. package/dist/chunks/{lexicon-CT69Kd87.js → lexicon-u2SI5xcx.js} +19 -5
  60. package/dist/chunks/lexicon-u2SI5xcx.js.map +1 -0
  61. package/dist/chunks/{ontology-export-G4MqRdux.js → ontology-export-BwgMyuF0.js} +4 -3
  62. package/dist/chunks/{ontology-export-G4MqRdux.js.map → ontology-export-BwgMyuF0.js.map} +1 -1
  63. package/dist/chunks/{records-CiaWZrFH.js → records-Cgvxz-Vx.js} +2 -2
  64. package/dist/chunks/{records-CiaWZrFH.js.map → records-Cgvxz-Vx.js.map} +1 -1
  65. package/dist/chunks/{format-BpQBx8MZ.js → report-CgdsL9Hb.js} +72 -129
  66. package/dist/chunks/report-CgdsL9Hb.js.map +1 -0
  67. package/dist/chunks/sigv4-LkAzsLAu.js +247 -0
  68. package/dist/chunks/sigv4-LkAzsLAu.js.map +1 -0
  69. package/dist/chunks/{styles-BQnsga7p.js → styles-CaABMoO1.js} +76 -43
  70. package/dist/chunks/styles-CaABMoO1.js.map +1 -0
  71. package/dist/chunks/{styles-D3fRphrO.js → styles-P_gmFAOi.js} +101 -21
  72. package/dist/chunks/styles-P_gmFAOi.js.map +1 -0
  73. package/dist/chunks/{styles-yed-BF5x3_Y5.js → styles-yed-Cs1nmrjn.js} +60 -20
  74. package/dist/chunks/styles-yed-Cs1nmrjn.js.map +1 -0
  75. package/dist/chunks/{text-CzJNFOS9.js → text-BuKQVMz2.js} +2 -2
  76. package/dist/chunks/{text-CzJNFOS9.js.map → text-BuKQVMz2.js.map} +1 -1
  77. package/dist/chunks/{writer-DMKvthQE.js → writer-DvHTl36J.js} +5 -4
  78. package/dist/chunks/writer-DvHTl36J.js.map +1 -0
  79. package/dist/csv.js +7 -5
  80. package/dist/csv.js.map +1 -1
  81. package/dist/cx.js +5 -4
  82. package/dist/cx.js.map +1 -1
  83. package/dist/cx2.js +2 -2
  84. package/dist/cys.js +1 -1
  85. package/dist/dot.js +2 -2
  86. package/dist/gexf.js +7 -5
  87. package/dist/gexf.js.map +1 -1
  88. package/dist/gml.js +16 -13
  89. package/dist/gml.js.map +1 -1
  90. package/dist/graph-io.js +1181 -224
  91. package/dist/graph-io.js.map +1 -1
  92. package/dist/graphml.js +3 -3
  93. package/dist/json.js +1 -1
  94. package/dist/neo4j.js +6 -4
  95. package/dist/neo4j.js.map +1 -1
  96. package/dist/obo.js +1 -1
  97. package/dist/pajek.js +1 -1
  98. package/dist/sources-cypher.d.ts +1 -0
  99. package/dist/sources-cypher.js +1236 -0
  100. package/dist/sources-cypher.js.map +1 -0
  101. package/dist/sources-ndex.d.ts +1 -0
  102. package/dist/sources-ndex.js +278 -0
  103. package/dist/sources-ndex.js.map +1 -0
  104. package/dist/sources-rest.d.ts +1 -0
  105. package/dist/sources-rest.js +1367 -0
  106. package/dist/sources-rest.js.map +1 -0
  107. package/dist/src/common/report.d.ts +6 -3
  108. package/dist/src/common/report.d.ts.map +1 -1
  109. package/dist/src/common/report.js +15 -9
  110. package/dist/src/common/report.js.map +1 -1
  111. package/dist/src/formats/cx/styles.d.ts.map +1 -1
  112. package/dist/src/formats/cx/styles.js +1 -0
  113. package/dist/src/formats/cx/styles.js.map +1 -1
  114. package/dist/src/formats/dot/styles.d.ts.map +1 -1
  115. package/dist/src/formats/dot/styles.js +3 -1
  116. package/dist/src/formats/dot/styles.js.map +1 -1
  117. package/dist/src/formats/gexf/styles.d.ts +29 -12
  118. package/dist/src/formats/gexf/styles.d.ts.map +1 -1
  119. package/dist/src/formats/gexf/styles.js +160 -31
  120. package/dist/src/formats/gexf/styles.js.map +1 -1
  121. package/dist/src/formats/gml/styles.d.ts.map +1 -1
  122. package/dist/src/formats/gml/styles.js +5 -4
  123. package/dist/src/formats/gml/styles.js.map +1 -1
  124. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -1
  125. package/dist/src/formats/graphml/styles-plain.js +3 -3
  126. package/dist/src/formats/graphml/styles-plain.js.map +1 -1
  127. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -1
  128. package/dist/src/formats/graphml/styles-yed.js +89 -19
  129. package/dist/src/formats/graphml/styles-yed.js.map +1 -1
  130. package/dist/src/formats/pajek/styles.d.ts.map +1 -1
  131. package/dist/src/formats/pajek/styles.js +1 -0
  132. package/dist/src/formats/pajek/styles.js.map +1 -1
  133. package/dist/src/formats/xgmml/styles.d.ts.map +1 -1
  134. package/dist/src/formats/xgmml/styles.js +1 -0
  135. package/dist/src/formats/xgmml/styles.js.map +1 -1
  136. package/dist/src/index.d.ts +8 -1
  137. package/dist/src/index.d.ts.map +1 -1
  138. package/dist/src/index.js +9 -1
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/registry.d.ts +173 -1
  141. package/dist/src/registry.d.ts.map +1 -1
  142. package/dist/src/registry.js +196 -1
  143. package/dist/src/registry.js.map +1 -1
  144. package/dist/src/sources/builtins.d.ts +11 -0
  145. package/dist/src/sources/builtins.d.ts.map +1 -0
  146. package/dist/src/sources/builtins.js +47 -0
  147. package/dist/src/sources/builtins.js.map +1 -0
  148. package/dist/src/sources/codes.d.ts +230 -0
  149. package/dist/src/sources/codes.d.ts.map +1 -0
  150. package/dist/src/sources/codes.js +58 -0
  151. package/dist/src/sources/codes.js.map +1 -0
  152. package/dist/src/sources/context.d.ts +112 -0
  153. package/dist/src/sources/context.d.ts.map +1 -0
  154. package/dist/src/sources/context.js +739 -0
  155. package/dist/src/sources/context.js.map +1 -0
  156. package/dist/src/sources/credentials.d.ts +179 -0
  157. package/dist/src/sources/credentials.d.ts.map +1 -0
  158. package/dist/src/sources/credentials.js +301 -0
  159. package/dist/src/sources/credentials.js.map +1 -0
  160. package/dist/src/sources/cypher/descriptor.d.ts +21 -0
  161. package/dist/src/sources/cypher/descriptor.d.ts.map +1 -0
  162. package/dist/src/sources/cypher/descriptor.js +119 -0
  163. package/dist/src/sources/cypher/descriptor.js.map +1 -0
  164. package/dist/src/sources/cypher/flatten.d.ts +72 -0
  165. package/dist/src/sources/cypher/flatten.d.ts.map +1 -0
  166. package/dist/src/sources/cypher/flatten.js +279 -0
  167. package/dist/src/sources/cypher/flatten.js.map +1 -0
  168. package/dist/src/sources/cypher/index.d.ts +33 -0
  169. package/dist/src/sources/cypher/index.d.ts.map +1 -0
  170. package/dist/src/sources/cypher/index.js +405 -0
  171. package/dist/src/sources/cypher/index.js.map +1 -0
  172. package/dist/src/sources/cypher/params.d.ts +40 -0
  173. package/dist/src/sources/cypher/params.d.ts.map +1 -0
  174. package/dist/src/sources/cypher/params.js +6 -0
  175. package/dist/src/sources/cypher/params.js.map +1 -0
  176. package/dist/src/sources/cypher/profiles.d.ts +44 -0
  177. package/dist/src/sources/cypher/profiles.d.ts.map +1 -0
  178. package/dist/src/sources/cypher/profiles.js +61 -0
  179. package/dist/src/sources/cypher/profiles.js.map +1 -0
  180. package/dist/src/sources/cypher/query-builder.d.ts +106 -0
  181. package/dist/src/sources/cypher/query-builder.d.ts.map +1 -0
  182. package/dist/src/sources/cypher/query-builder.js +236 -0
  183. package/dist/src/sources/cypher/query-builder.js.map +1 -0
  184. package/dist/src/sources/cypher/transports/bolt.d.ts +21 -0
  185. package/dist/src/sources/cypher/transports/bolt.d.ts.map +1 -0
  186. package/dist/src/sources/cypher/transports/bolt.js +185 -0
  187. package/dist/src/sources/cypher/transports/bolt.js.map +1 -0
  188. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts +15 -0
  189. package/dist/src/sources/cypher/transports/neptune-analytics.d.ts.map +1 -0
  190. package/dist/src/sources/cypher/transports/neptune-analytics.js +38 -0
  191. package/dist/src/sources/cypher/transports/neptune-analytics.js.map +1 -0
  192. package/dist/src/sources/cypher/transports/neptune-https.d.ts +31 -0
  193. package/dist/src/sources/cypher/transports/neptune-https.d.ts.map +1 -0
  194. package/dist/src/sources/cypher/transports/neptune-https.js +104 -0
  195. package/dist/src/sources/cypher/transports/neptune-https.js.map +1 -0
  196. package/dist/src/sources/cypher/transports/query-api.d.ts +14 -0
  197. package/dist/src/sources/cypher/transports/query-api.d.ts.map +1 -0
  198. package/dist/src/sources/cypher/transports/query-api.js +80 -0
  199. package/dist/src/sources/cypher/transports/query-api.js.map +1 -0
  200. package/dist/src/sources/cypher/transports/transport.d.ts +78 -0
  201. package/dist/src/sources/cypher/transports/transport.d.ts.map +1 -0
  202. package/dist/src/sources/cypher/transports/transport.js +77 -0
  203. package/dist/src/sources/cypher/transports/transport.js.map +1 -0
  204. package/dist/src/sources/cypher/types-map.d.ts +91 -0
  205. package/dist/src/sources/cypher/types-map.d.ts.map +1 -0
  206. package/dist/src/sources/cypher/types-map.js +306 -0
  207. package/dist/src/sources/cypher/types-map.js.map +1 -0
  208. package/dist/src/sources/define.d.ts +47 -0
  209. package/dist/src/sources/define.d.ts.map +1 -0
  210. package/dist/src/sources/define.js +173 -0
  211. package/dist/src/sources/define.js.map +1 -0
  212. package/dist/src/sources/fail.d.ts +33 -0
  213. package/dist/src/sources/fail.d.ts.map +1 -0
  214. package/dist/src/sources/fail.js +49 -0
  215. package/dist/src/sources/fail.js.map +1 -0
  216. package/dist/src/sources/ids.d.ts +64 -0
  217. package/dist/src/sources/ids.d.ts.map +1 -0
  218. package/dist/src/sources/ids.js +64 -0
  219. package/dist/src/sources/ids.js.map +1 -0
  220. package/dist/src/sources/ndex/client.d.ts +31 -0
  221. package/dist/src/sources/ndex/client.d.ts.map +1 -0
  222. package/dist/src/sources/ndex/client.js +90 -0
  223. package/dist/src/sources/ndex/client.js.map +1 -0
  224. package/dist/src/sources/ndex/descriptor.d.ts +10 -0
  225. package/dist/src/sources/ndex/descriptor.d.ts.map +1 -0
  226. package/dist/src/sources/ndex/descriptor.js +55 -0
  227. package/dist/src/sources/ndex/descriptor.js.map +1 -0
  228. package/dist/src/sources/ndex/expand.d.ts +20 -0
  229. package/dist/src/sources/ndex/expand.d.ts.map +1 -0
  230. package/dist/src/sources/ndex/expand.js +87 -0
  231. package/dist/src/sources/ndex/expand.js.map +1 -0
  232. package/dist/src/sources/ndex/index.d.ts +25 -0
  233. package/dist/src/sources/ndex/index.d.ts.map +1 -0
  234. package/dist/src/sources/ndex/index.js +191 -0
  235. package/dist/src/sources/ndex/index.js.map +1 -0
  236. package/dist/src/sources/ndex/params.d.ts +17 -0
  237. package/dist/src/sources/ndex/params.d.ts.map +1 -0
  238. package/dist/src/sources/ndex/params.js +6 -0
  239. package/dist/src/sources/ndex/params.js.map +1 -0
  240. package/dist/src/sources/ndex/share-url.d.ts +40 -0
  241. package/dist/src/sources/ndex/share-url.d.ts.map +1 -0
  242. package/dist/src/sources/ndex/share-url.js +64 -0
  243. package/dist/src/sources/ndex/share-url.js.map +1 -0
  244. package/dist/src/sources/params.d.ts +28 -0
  245. package/dist/src/sources/params.d.ts.map +1 -0
  246. package/dist/src/sources/params.js +6 -0
  247. package/dist/src/sources/params.js.map +1 -0
  248. package/dist/src/sources/registry.d.ts +118 -0
  249. package/dist/src/sources/registry.d.ts.map +1 -0
  250. package/dist/src/sources/registry.js +193 -0
  251. package/dist/src/sources/registry.js.map +1 -0
  252. package/dist/src/sources/rest/descriptor.d.ts +16 -0
  253. package/dist/src/sources/rest/descriptor.d.ts.map +1 -0
  254. package/dist/src/sources/rest/descriptor.js +71 -0
  255. package/dist/src/sources/rest/descriptor.js.map +1 -0
  256. package/dist/src/sources/rest/index.d.ts +14 -0
  257. package/dist/src/sources/rest/index.d.ts.map +1 -0
  258. package/dist/src/sources/rest/index.js +13 -0
  259. package/dist/src/sources/rest/index.js.map +1 -0
  260. package/dist/src/sources/rest/mapping.d.ts +30 -0
  261. package/dist/src/sources/rest/mapping.d.ts.map +1 -0
  262. package/dist/src/sources/rest/mapping.js +362 -0
  263. package/dist/src/sources/rest/mapping.js.map +1 -0
  264. package/dist/src/sources/rest/openalex.d.ts +27 -0
  265. package/dist/src/sources/rest/openalex.d.ts.map +1 -0
  266. package/dist/src/sources/rest/openalex.js +269 -0
  267. package/dist/src/sources/rest/openalex.js.map +1 -0
  268. package/dist/src/sources/rest/paging.d.ts +53 -0
  269. package/dist/src/sources/rest/paging.d.ts.map +1 -0
  270. package/dist/src/sources/rest/paging.js +138 -0
  271. package/dist/src/sources/rest/paging.js.map +1 -0
  272. package/dist/src/sources/rest/params.d.ts +216 -0
  273. package/dist/src/sources/rest/params.d.ts.map +1 -0
  274. package/dist/src/sources/rest/params.js +7 -0
  275. package/dist/src/sources/rest/params.js.map +1 -0
  276. package/dist/src/sources/rest/records.d.ts +41 -0
  277. package/dist/src/sources/rest/records.d.ts.map +1 -0
  278. package/dist/src/sources/rest/records.js +240 -0
  279. package/dist/src/sources/rest/records.js.map +1 -0
  280. package/dist/src/sources/rest/samples/deps-dev.d.ts +10 -0
  281. package/dist/src/sources/rest/samples/deps-dev.d.ts.map +1 -0
  282. package/dist/src/sources/rest/samples/deps-dev.js +47 -0
  283. package/dist/src/sources/rest/samples/deps-dev.js.map +1 -0
  284. package/dist/src/sources/rest/samples/string.d.ts +9 -0
  285. package/dist/src/sources/rest/samples/string.d.ts.map +1 -0
  286. package/dist/src/sources/rest/samples/string.js +42 -0
  287. package/dist/src/sources/rest/samples/string.js.map +1 -0
  288. package/dist/src/sources/rest/selectors.d.ts +41 -0
  289. package/dist/src/sources/rest/selectors.d.ts.map +1 -0
  290. package/dist/src/sources/rest/selectors.js +81 -0
  291. package/dist/src/sources/rest/selectors.js.map +1 -0
  292. package/dist/src/sources/rest/source.d.ts +67 -0
  293. package/dist/src/sources/rest/source.d.ts.map +1 -0
  294. package/dist/src/sources/rest/source.js +635 -0
  295. package/dist/src/sources/rest/source.js.map +1 -0
  296. package/dist/src/sources/rest/templates.d.ts +38 -0
  297. package/dist/src/sources/rest/templates.d.ts.map +1 -0
  298. package/dist/src/sources/rest/templates.js +125 -0
  299. package/dist/src/sources/rest/templates.js.map +1 -0
  300. package/dist/src/sources/run.d.ts +93 -0
  301. package/dist/src/sources/run.d.ts.map +1 -0
  302. package/dist/src/sources/run.js +673 -0
  303. package/dist/src/sources/run.js.map +1 -0
  304. package/dist/src/sources/sha256.d.ts +12 -0
  305. package/dist/src/sources/sha256.d.ts.map +1 -0
  306. package/dist/src/sources/sha256.js +95 -0
  307. package/dist/src/sources/sha256.js.map +1 -0
  308. package/dist/src/sources/sigv4.d.ts +24 -0
  309. package/dist/src/sources/sigv4.d.ts.map +1 -0
  310. package/dist/src/sources/sigv4.js +182 -0
  311. package/dist/src/sources/sigv4.js.map +1 -0
  312. package/dist/src/sources/testing.d.ts +96 -0
  313. package/dist/src/sources/testing.d.ts.map +1 -0
  314. package/dist/src/sources/testing.js +138 -0
  315. package/dist/src/sources/testing.js.map +1 -0
  316. package/dist/src/sources/types.d.ts +665 -0
  317. package/dist/src/sources/types.d.ts.map +1 -0
  318. package/dist/src/sources/types.js +10 -0
  319. package/dist/src/sources/types.js.map +1 -0
  320. package/dist/src/styles/canon/enums.d.ts.map +1 -1
  321. package/dist/src/styles/canon/enums.js +1 -0
  322. package/dist/src/styles/canon/enums.js.map +1 -1
  323. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
  324. package/dist/src/styles/cyjs/cascade.js +68 -2
  325. package/dist/src/styles/cyjs/cascade.js.map +1 -1
  326. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
  327. package/dist/src/styles/cyjs/defaults-table.js +2 -0
  328. package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
  329. package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
  330. package/dist/src/styles/cyjs/emit.js +18 -7
  331. package/dist/src/styles/cyjs/emit.js.map +1 -1
  332. package/dist/src/styles/cyjs/mappers.d.ts +4 -1
  333. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
  334. package/dist/src/styles/cyjs/mappers.js +2 -0
  335. package/dist/src/styles/cyjs/mappers.js.map +1 -1
  336. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -1
  337. package/dist/src/styles/cytoscape/emit.js +59 -7
  338. package/dist/src/styles/cytoscape/emit.js.map +1 -1
  339. package/dist/src/styles/cytoscape/lexicon.d.ts +6 -0
  340. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -1
  341. package/dist/src/styles/cytoscape/lexicon.js +26 -2
  342. package/dist/src/styles/cytoscape/lexicon.js.map +1 -1
  343. package/dist/src/styles/cytoscape/resolve.d.ts +4 -1
  344. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -1
  345. package/dist/src/styles/cytoscape/resolve.js +10 -6
  346. package/dist/src/styles/cytoscape/resolve.js.map +1 -1
  347. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -1
  348. package/dist/src/styles/cytoscape/translate.js +10 -10
  349. package/dist/src/styles/cytoscape/translate.js.map +1 -1
  350. package/dist/src/styles/defaults.d.ts +30 -0
  351. package/dist/src/styles/defaults.d.ts.map +1 -1
  352. package/dist/src/styles/defaults.js +45 -4
  353. package/dist/src/styles/defaults.js.map +1 -1
  354. package/dist/src/styles/io/block.d.ts.map +1 -1
  355. package/dist/src/styles/io/block.js +9 -0
  356. package/dist/src/styles/io/block.js.map +1 -1
  357. package/dist/src/styles/io/writer.d.ts.map +1 -1
  358. package/dist/src/styles/io/writer.js +7 -3
  359. package/dist/src/styles/io/writer.js.map +1 -1
  360. package/dist/src/styles/plan/resolve.d.ts +2 -1
  361. package/dist/src/styles/plan/resolve.d.ts.map +1 -1
  362. package/dist/src/styles/plan/resolve.js +13 -2
  363. package/dist/src/styles/plan/resolve.js.map +1 -1
  364. package/dist/src/styles/types.d.ts +19 -2
  365. package/dist/src/styles/types.d.ts.map +1 -1
  366. package/dist/src/styles/vocabulary.d.ts.map +1 -1
  367. package/dist/src/styles/vocabulary.js +15 -1
  368. package/dist/src/styles/vocabulary.js.map +1 -1
  369. package/dist/src/types.d.ts +19 -5
  370. package/dist/src/types.d.ts.map +1 -1
  371. package/dist/src/types.js.map +1 -1
  372. package/dist/styles.js +11 -11
  373. package/dist/xgmml.js +3 -3
  374. package/docs/samples/people.json +6 -0
  375. package/package.json +29 -4
  376. package/src/common/report.ts +27 -7
  377. package/src/formats/cx/styles.ts +1 -0
  378. package/src/formats/dot/styles.ts +3 -1
  379. package/src/formats/gexf/styles.ts +185 -37
  380. package/src/formats/gml/styles.ts +5 -4
  381. package/src/formats/graphml/styles-plain.ts +3 -9
  382. package/src/formats/graphml/styles-yed.ts +93 -20
  383. package/src/formats/pajek/styles.ts +1 -0
  384. package/src/formats/xgmml/styles.ts +1 -0
  385. package/src/index.ts +90 -0
  386. package/src/registry.ts +326 -1
  387. package/src/sources/builtins.ts +56 -0
  388. package/src/sources/codes.ts +235 -0
  389. package/src/sources/context.ts +893 -0
  390. package/src/sources/credentials.ts +409 -0
  391. package/src/sources/cypher/descriptor.ts +125 -0
  392. package/src/sources/cypher/flatten.ts +323 -0
  393. package/src/sources/cypher/index.ts +498 -0
  394. package/src/sources/cypher/params.ts +41 -0
  395. package/src/sources/cypher/profiles.ts +78 -0
  396. package/src/sources/cypher/query-builder.ts +294 -0
  397. package/src/sources/cypher/transports/bolt.ts +228 -0
  398. package/src/sources/cypher/transports/neptune-analytics.ts +41 -0
  399. package/src/sources/cypher/transports/neptune-https.ts +122 -0
  400. package/src/sources/cypher/transports/query-api.ts +100 -0
  401. package/src/sources/cypher/transports/transport.ts +139 -0
  402. package/src/sources/cypher/types-map.ts +418 -0
  403. package/src/sources/define.ts +195 -0
  404. package/src/sources/fail.ts +70 -0
  405. package/src/sources/ids.ts +74 -0
  406. package/src/sources/ndex/client.ts +102 -0
  407. package/src/sources/ndex/descriptor.ts +64 -0
  408. package/src/sources/ndex/expand.ts +100 -0
  409. package/src/sources/ndex/index.ts +235 -0
  410. package/src/sources/ndex/params.ts +17 -0
  411. package/src/sources/ndex/share-url.ts +84 -0
  412. package/src/sources/params.ts +29 -0
  413. package/src/sources/registry.ts +325 -0
  414. package/src/sources/rest/descriptor.ts +74 -0
  415. package/src/sources/rest/index.ts +22 -0
  416. package/src/sources/rest/mapping.ts +401 -0
  417. package/src/sources/rest/openalex.ts +288 -0
  418. package/src/sources/rest/paging.ts +180 -0
  419. package/src/sources/rest/params.ts +243 -0
  420. package/src/sources/rest/records.ts +289 -0
  421. package/src/sources/rest/samples/deps-dev.ts +49 -0
  422. package/src/sources/rest/samples/string.ts +44 -0
  423. package/src/sources/rest/selectors.ts +91 -0
  424. package/src/sources/rest/source.ts +760 -0
  425. package/src/sources/rest/templates.ts +151 -0
  426. package/src/sources/run.ts +793 -0
  427. package/src/sources/sha256.ts +99 -0
  428. package/src/sources/sigv4.ts +207 -0
  429. package/src/sources/testing.ts +210 -0
  430. package/src/sources/types.ts +741 -0
  431. package/src/styles/canon/enums.ts +1 -0
  432. package/src/styles/cyjs/cascade.ts +81 -2
  433. package/src/styles/cyjs/defaults-table.ts +2 -0
  434. package/src/styles/cyjs/emit.ts +18 -7
  435. package/src/styles/cyjs/mappers.ts +6 -1
  436. package/src/styles/cytoscape/emit.ts +61 -7
  437. package/src/styles/cytoscape/lexicon.ts +28 -2
  438. package/src/styles/cytoscape/resolve.ts +22 -6
  439. package/src/styles/cytoscape/translate.ts +11 -11
  440. package/src/styles/defaults.ts +93 -4
  441. package/src/styles/io/block.ts +10 -0
  442. package/src/styles/io/writer.ts +8 -3
  443. package/src/styles/plan/resolve.ts +14 -2
  444. package/src/styles/types.ts +28 -2
  445. package/src/styles/vocabulary.ts +15 -1
  446. package/src/types.ts +19 -5
  447. package/dist/chunks/block-DiGq58c3.js.map +0 -1
  448. package/dist/chunks/emit-CwU8cUmG.js.map +0 -1
  449. package/dist/chunks/export-BvqAXCKh.js.map +0 -1
  450. package/dist/chunks/format-BpQBx8MZ.js.map +0 -1
  451. package/dist/chunks/importer-BSvfrX_h.js.map +0 -1
  452. package/dist/chunks/importer-CMmeMWlC.js.map +0 -1
  453. package/dist/chunks/importer-COTK9Tsl.js.map +0 -1
  454. package/dist/chunks/importer-DiZRmOQG.js.map +0 -1
  455. package/dist/chunks/importer-e6LGpqHB.js.map +0 -1
  456. package/dist/chunks/lexicon-CT69Kd87.js.map +0 -1
  457. package/dist/chunks/styles-BQnsga7p.js.map +0 -1
  458. package/dist/chunks/styles-D3fRphrO.js.map +0 -1
  459. package/dist/chunks/styles-yed-BF5x3_Y5.js.map +0 -1
  460. package/dist/chunks/writer-DMKvthQE.js.map +0 -1
@@ -46,6 +46,7 @@ export const GRAPHTY_XML_NAMESPACE = "https://graphty.app/ns/gexf";
46
46
  * @category Built-in formats
47
47
  */
48
48
  export const GEXF_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({
49
+ tool: "gephi",
49
50
  node: Object.freeze(["label", "fill", "fillOpacity", "width", "height", "shape", "image"] as const),
50
51
  edge: Object.freeze(["color", "opacity", "width", "lineStyle"] as const),
51
52
  block: "native",
@@ -57,8 +58,13 @@ const GEPHI_NODE_FILL = "#000000";
57
58
  /** The style column marking directed edges, which Gephi draws with an arrow at the target. */
58
59
  const DIRECTED_KEY = "directed";
59
60
 
60
- /** The style column holding the source node's color of each edge without a color of its own. */
61
- const SOURCE_COLOR_KEY = "source-color";
61
+ /** The style column holding the mixed color of each edge without a color of its own. */
62
+ const MIXED_COLOR_KEY = "mixed-color";
63
+ /** The style columns of the border Gephi draws on each node without one of its own. */
64
+ const BORDER_COLOR_KEY = "border-color";
65
+ const BORDER_WIDTH_KEY = "border-width";
66
+ /** The style column of the label size Gephi draws on each node, scaled with the node. */
67
+ const LABEL_SIZE_KEY = "label-size";
62
68
  /** The style column of the width Gephi draws an edge with from its weight. */
63
69
  const WEIGHT_WIDTH_KEY = "weight-width";
64
70
 
@@ -299,23 +305,127 @@ function directedEdges(snapshot: GraphSnapshot): boolean[] {
299
305
  }
300
306
 
301
307
  /**
302
- * The rules Gephi's defaults make per element: an arrow at the target of every directed edge, the source node's
303
- * color on every edge without a color of its own, and the edge's weight as the thickness of every edge without a
304
- * thickness of its own (Gephi draws GEXF and its GraphML export the same way).
308
+ * The rules Gephi's defaults make per element, as Gephi's Preview draws them (`DefaultPreset.java`; sources in
309
+ * `styles/defaults.ts`): an arrow at the target of every directed edge; the mean of its two nodes' colors on every
310
+ * edge without a color of its own (Preview's "mixed" edge color); the edge's weight as the thickness of every edge
311
+ * without a thickness of its own; a border darker than its fill and scaled with its size on every node without a
312
+ * border of its own; and each node's label, in a size scaled with the node (12 for a size-10 node) on every node
313
+ * without a label size of its own (Gephi draws GEXF, its GraphML export and its GML the same way).
314
+ *
315
+ * Labels are a choice, not Gephi's default: Gephi hides them in both its drawings (`DefaultPreset.java` line 106,
316
+ * `VizConfig.java` line 113), while sigma.js and gexf-js, which most published GEXF files are viewed with, show
317
+ * them. graph-io shows them: a label is what the file states about a node, and hiding it is a view setting Gephi
318
+ * offers as a switch, like the application's own; an application that wants Gephi's look hides them itself.
319
+ *
320
+ * An edge's own color is kept, though Preview's "mixed" mode draws over it: the file states it, and Gephi's
321
+ * Overview, Preview's "original" mode, sigma.js and gexf-js all draw it.
305
322
  * @param snapshot - the graph
306
- * @param nodeFill - each node's fill, or undefined when no node has one
307
- * @param edgeColor - each edge's own color, or undefined when no edge has one
323
+ * @param node - the node values read from the file
324
+ * @param edge - the edge values read from the file
308
325
  * @param budget - the work budget
309
- * @param edgeWidth - each edge's own width, or undefined when no edge has one
310
- * @returns the edge rules and the style columns they read
326
+ * @returns the node and edge rules and the style columns they read
311
327
  */
312
328
  export function gephiRules(
313
329
  snapshot: GraphSnapshot,
314
- nodeFill: readonly (StyleValue | null)[] | undefined,
315
- edgeColor: readonly (StyleValue | null)[] | undefined,
330
+ node: Readonly<Record<string, readonly (StyleValue | null)[]>>,
331
+ edge: Readonly<Record<string, readonly (StyleValue | null)[]>>,
316
332
  budget: StyleReadContext["budget"],
317
- edgeWidth?: readonly (StyleValue | null)[],
318
- ): { readonly rules: StyleRule[]; readonly columns: Map<string, StyleColumn> } {
333
+ ): { readonly node: ToolRules; readonly edge: ToolRules } {
334
+ return { node: gephiNodeRules(snapshot, node, budget), edge: gephiEdgeRules(snapshot, node, edge, budget) };
335
+ }
336
+
337
+ /** Rules and the style columns they read. */
338
+ interface ToolRules {
339
+ readonly rules: StyleRule[];
340
+ readonly columns: Map<string, StyleColumn>;
341
+ }
342
+
343
+ /** Preview's "darker" border: each channel of the fill times this (`DependantColor.java` line 55). */
344
+ const GEPHI_BORDER_DARKEN = 0.498;
345
+ /** Preview's border width as a share of the node's drawn width (`SizeUtils.java` lines 11, 37). */
346
+ const GEPHI_BORDER_SHARE = 0.08;
347
+ /** Gephi's node size when a node has none (`AbstractProcessor.java` lines 195-198). */
348
+ const GEPHI_NODE_SIZE = 10;
349
+ /**
350
+ * Preview's label size per unit of node size: Arial 12 (`DefaultPreset.java` line 93) times the node drawn twice its
351
+ * size wide times 0.05 (`NodeLabelRenderer.java` lines 165-173, `NODE_LABEL_PROPORTIONAL_SIZE` true), so 12 for a
352
+ * size-10 node.
353
+ */
354
+ const GEPHI_LABEL_PER_SIZE = 1.2;
355
+
356
+ /**
357
+ * The node rules of Gephi's defaults: the border Preview draws, the label and its size scaled with the node.
358
+ * @param snapshot - the graph
359
+ * @param node - the node values read from the file
360
+ * @param budget - the work budget
361
+ * @returns the rules and their columns
362
+ */
363
+ function gephiNodeRules(
364
+ snapshot: GraphSnapshot,
365
+ node: Readonly<Record<string, readonly (StyleValue | null)[]>>,
366
+ budget: StyleReadContext["budget"],
367
+ ): ToolRules {
368
+ const rules: StyleRule[] = [];
369
+ const columns = new Map<string, StyleColumn>();
370
+ const n = snapshot.nodeCount;
371
+ budget.spend("node", n);
372
+ // Preview draws a ring of the fill, each channel times 0.498 (rounded), 0.08 of the node's width wide
373
+ const color = withoutOwn(node.borderColor, n, (i) => darker(node.fill?.[i] ?? GEPHI_NODE_FILL));
374
+ const size = (i: number): number => {
375
+ const w = node.width?.[i];
376
+ return typeof w === "number" ? w : GEPHI_NODE_SIZE;
377
+ };
378
+ const width = withoutOwn(node.borderWidth, n, (i) => round6(size(i) * GEPHI_BORDER_SHARE));
379
+ // Preview scales each label with its node (NODE_LABEL_PROPORTIONAL_SIZE)
380
+ const labelSize = withoutOwn(node.labelSize, n, (i) => round6(size(i) * GEPHI_LABEL_PER_SIZE));
381
+ for (const [property, key, values, reason] of [
382
+ ["borderColor", BORDER_COLOR_KEY, color, "FILL_BORDER"],
383
+ ["borderWidth", BORDER_WIDTH_KEY, width, "FILL_BORDER"],
384
+ ["labelSize", LABEL_SIZE_KEY, labelSize, "NODE_SIZE_LABEL"],
385
+ ] as const) {
386
+ const elements = values.filter((v) => v !== null).length;
387
+ if (elements > 0) {
388
+ columns.set(key, values);
389
+ rules.push({
390
+ id: `node.tool.${key}`,
391
+ target: "node",
392
+ role: "passthrough",
393
+ origin: "tool",
394
+ where: { has: { style: key } },
395
+ map: { [property]: { kind: "passthrough" as const, by: { style: key } } },
396
+ facts: { elements, reason },
397
+ });
398
+ }
399
+ }
400
+ const label = snapshot.nodes.names().find((name) => snapshot.nodes.get(name)?.meta.role === "label");
401
+ if (label !== undefined && node.label === undefined) {
402
+ rules.push({
403
+ id: "node.tool.label",
404
+ target: "node",
405
+ role: "passthrough",
406
+ origin: "tool",
407
+ where: { has: { data: label } },
408
+ map: { label: { kind: "passthrough", by: { data: label } } },
409
+ facts: { reason: "NODE_NAME" },
410
+ });
411
+ }
412
+ return { rules, columns };
413
+ }
414
+
415
+ /**
416
+ * The edge rules of Gephi's defaults: the target arrow of a directed edge, the mixed color and the weight's width.
417
+ * @param snapshot - the graph
418
+ * @param node - the node values read from the file
419
+ * @param edge - the edge values read from the file
420
+ * @param budget - the work budget
421
+ * @returns the rules and their columns
422
+ */
423
+ function gephiEdgeRules(
424
+ snapshot: GraphSnapshot,
425
+ node: Readonly<Record<string, readonly (StyleValue | null)[]>>,
426
+ edge: Readonly<Record<string, readonly (StyleValue | null)[]>>,
427
+ budget: StyleReadContext["budget"],
428
+ ): ToolRules {
319
429
  const rules: StyleRule[] = [];
320
430
  const columns = new Map<string, StyleColumn>();
321
431
  const directed = directedEdges(snapshot);
@@ -333,24 +443,22 @@ export function gephiRules(
333
443
  set: { targetArrow: "triangle" },
334
444
  });
335
445
  }
336
- // Gephi draws an edge without a color in its source node's color. graphty-element cannot bind an edge's color
337
- // to its source node's drawn color yet, so the color is frozen here; replace this column with that binding once
338
- // the element has it (tracking issue "graphty-element: bind an edge's color to its source node's drawn color").
339
- // An undirected edge in a directed graph is one edge in the file and two halves here: Gephi draws it once, in
340
- // the color of the source the file names, so the second half takes the first half's source.
341
- const first = firstHalf(snapshot);
342
- const sourceColor = withoutOwn(
343
- edgeColor,
344
- snapshot.edgeCount,
345
- (e) => nodeFill?.[snapshot.edgeSource(first(e))] ?? GEPHI_NODE_FILL,
446
+ // Preview draws an edge in the mean of its two nodes' colors. graphty-element cannot bind an edge's color to its
447
+ // nodes' drawn colors yet, so the color is frozen here; replace this column with that binding once the element
448
+ // has it (tracking issue "graphty-element: bind an edge's color to its source node's drawn color").
449
+ const fill = (i: number): StyleValue => node.fill?.[i] ?? GEPHI_NODE_FILL;
450
+ const mixed = withoutOwn(edge.color, snapshot.edgeCount, (e) =>
451
+ mix(fill(snapshot.edgeSource(e)), fill(snapshot.edgeTarget(e))),
346
452
  );
347
- const uncolored = sourceColor.filter((v) => v !== null).length;
453
+ const uncolored = mixed.filter((v) => v !== null).length;
348
454
  budget.spend("edge", snapshot.edgeCount);
349
455
  // Gephi draws an edge as thick as its weight (1 for an edge with none); a width of its own is the file's
350
456
  // The weights come from the snapshot's own weights (the role column exists only when some edge has none), read
351
457
  // as the shortest decimal of their dtype. A weight of 0 or below is drawn 1 wide, so the edge stays visible.
458
+ // An undirected edge in a directed graph is one edge in the file and two halves here: both take the first's.
459
+ const first = firstHalf(snapshot);
352
460
  const weights = explicitWeights(snapshot);
353
- const weightWidth = withoutOwn(edgeWidth, snapshot.edgeCount, (e) => {
461
+ const weightWidth = withoutOwn(edge.width, snapshot.edgeCount, (e) => {
354
462
  const w = Number(weights.text(first(e)) ?? 1);
355
463
  return Number.isFinite(w) && w > 0 ? w : 1;
356
464
  });
@@ -368,20 +476,54 @@ export function gephiRules(
368
476
  });
369
477
  }
370
478
  if (uncolored > 0) {
371
- columns.set(SOURCE_COLOR_KEY, sourceColor);
479
+ columns.set(MIXED_COLOR_KEY, mixed);
372
480
  rules.push({
373
- id: "edge.tool.source-color",
481
+ id: "edge.tool.mixed-color",
374
482
  target: "edge",
375
483
  role: "passthrough",
376
484
  origin: "tool",
377
- where: { has: { style: SOURCE_COLOR_KEY } },
378
- map: { color: { kind: "passthrough", by: { style: SOURCE_COLOR_KEY } } },
379
- facts: { elements: uncolored, reason: "SOURCE_NODE_COLOR" },
485
+ where: { has: { style: MIXED_COLOR_KEY } },
486
+ map: { color: { kind: "passthrough", by: { style: MIXED_COLOR_KEY } } },
487
+ facts: { elements: uncolored, reason: "END_NODES_COLOR" },
380
488
  });
381
489
  }
382
490
  return { rules, columns };
383
491
  }
384
492
 
493
+ /**
494
+ * Preview's "mixed" edge color: the mean of two colors, each channel rounded down (`EdgeColor.java` lines 89-93).
495
+ * @param a - one end's color, `#rrggbb`
496
+ * @param b - the other's
497
+ * @returns the mixed color
498
+ */
499
+ function gephiMix(a: string, b: string): string {
500
+ const x = Number.parseInt(a.slice(1), 16);
501
+ const y = Number.parseInt(b.slice(1), 16);
502
+ let out = 0;
503
+ for (const shift of [16, 8, 0]) {
504
+ out |= Math.floor((((x >> shift) & 255) + ((y >> shift) & 255)) / 2) << shift;
505
+ }
506
+ return `#${out.toString(16).padStart(6, "0")}`;
507
+ }
508
+
509
+ /**
510
+ * Preview's "darker" border color: each channel times 0.498, rounded (`ColorUtils.java` lines 22-34).
511
+ * @param c - the fill, `#rrggbb`
512
+ * @returns the border color
513
+ */
514
+ function gephiDarker(c: string): string {
515
+ const x = Number.parseInt(c.slice(1), 16);
516
+ let out = 0;
517
+ for (const shift of [16, 8, 0]) {
518
+ out |= Math.min(255, Math.round(((x >> shift) & 255) * GEPHI_BORDER_DARKEN)) << shift;
519
+ }
520
+ return `#${out.toString(16).padStart(6, "0")}`;
521
+ }
522
+
523
+ const mix = (a: StyleValue, b: StyleValue): StyleValue => gephiMix(String(a), String(b));
524
+ const darker = (c: StyleValue): StyleValue => gephiDarker(String(c));
525
+ const round6 = (x: number): number => Math.round(x * 1e6) / 1e6;
526
+
385
527
  /**
386
528
  * The edge whose source Gephi draws for each edge: an undirected edge in a directed graph is one edge in the file
387
529
  * and two halves here, and the second half takes the first half's.
@@ -415,9 +557,10 @@ function withoutOwn(
415
557
  }
416
558
 
417
559
  /**
418
- * The styles of a GEXF file: each node's label and each element's viz values as Gephi draws them, Gephi's defaults beneath
419
- * (black size-10 discs), an arrow at the target of every directed edge, and the source node's color on every edge
420
- * without a color of its own; plus a `graphty.styles` block the file holds in `<meta>`.
560
+ * The styles of a GEXF file: each element's viz values as Gephi draws them, with Gephi Preview's defaults beneath
561
+ * (black size-10 discs with a darker border, curved edges, an arrow at the target of every directed edge, the mixed
562
+ * color of its nodes on every edge without a color of its own) and each node's label (see gephiRules()); plus a
563
+ * `graphty.styles` block the file holds in `<meta>`.
421
564
  * @param snapshot - the graph the import built
422
565
  * @param context - the work budget and the block text the import kept
423
566
  * @returns the styles
@@ -430,14 +573,14 @@ export function gexfStyles(snapshot: GraphSnapshot, context: StyleReadContext):
430
573
  if (block !== null) {
431
574
  exactFromBlock(snapshot, block, node, edge);
432
575
  }
433
- const { rules, columns } = gephiRules(snapshot, node.fill, edge.color, context.budget, edge.width);
576
+ const gephi = gephiRules(snapshot, node, edge, context.budget);
434
577
  return {
435
578
  canonical: true,
436
579
  dialect: "gexf",
437
580
  tool: "gephi",
438
581
  units: "relative",
439
- node: { values: node },
440
- edge: { values: edge, rules, columns },
582
+ node: { values: node, ...gephi.node },
583
+ edge: { values: edge, ...gephi.edge },
441
584
  notes: notes.list(),
442
585
  opacityInColor: true,
443
586
  block,
@@ -581,8 +724,13 @@ export function gexfStyledExport(
581
724
  },
582
725
  edge(e, indent) {
583
726
  const w = thickness[e];
727
+ // an edge in the mixed color of its nodes is left without one: Gephi, and graph-io, draw it so anyway
728
+ const c = color[e];
729
+ const end = (i: number): string => String(fill[i] ?? GEPHI_NODE_FILL);
730
+ const mixed =
731
+ typeof c === "string" && c === gephiMix(end(snapshot.edgeSource(e)), end(snapshot.edgeTarget(e)));
584
732
  return (
585
- colorElement(color[e], opacity[e], indent) +
733
+ (mixed && (opacity[e] ?? 1) === 1 ? "" : colorElement(c, opacity[e], indent)) +
586
734
  (typeof w === "number" ? `${indent}<viz:thickness value="${String(w)}"/>\n` : "") +
587
735
  shapeElement(edgeShapes[e], null, indent)
588
736
  );
@@ -732,15 +732,15 @@ export function gmlStyles(snapshot: GraphSnapshot, context: StyleReadContext): I
732
732
  }
733
733
  const gephi =
734
734
  writer.tool === "gephi"
735
- ? gephiRules(snapshot, values.node.fill, values.edge.color, context.budget, values.edge.width)
736
- : { rules: [], columns: new Map<string, StyleColumn>() };
735
+ ? gephiRules(snapshot, values.node, values.edge, context.budget)
736
+ : { node: {}, edge: {} };
737
737
  return {
738
738
  canonical: true,
739
739
  dialect: writer.dialect,
740
740
  tool: writer.tool,
741
741
  units: writer.units,
742
- node: { values: values.node },
743
- edge: { values: values.edge, rules: gephi.rules, columns: gephi.columns },
742
+ node: { values: values.node, ...gephi.node },
743
+ edge: { values: values.edge, ...gephi.edge },
744
744
  notes: notes.list(),
745
745
  opacityInColor: true,
746
746
  block,
@@ -757,6 +757,7 @@ export function gmlStyles(snapshot: GraphSnapshot, context: StyleReadContext): I
757
757
  * @category Built-in formats
758
758
  */
759
759
  export const GML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({
760
+ tool: "yed",
760
761
  node: Object.freeze([
761
762
  "fill",
762
763
  "fillOpacity",
@@ -185,21 +185,15 @@ export function graphmlStyles(snapshot: GraphSnapshot, context: StyleReadContext
185
185
  }
186
186
  if (hasRgb(snapshot.nodes)) {
187
187
  const gephi = readGephi(snapshot, notes, context);
188
- const { rules, columns } = gephiRules(
189
- snapshot,
190
- gephi.node.fill,
191
- gephi.edge.color,
192
- context.budget,
193
- gephi.edge.width,
194
- );
188
+ const rules = gephiRules(snapshot, gephi.node, gephi.edge, context.budget);
195
189
  const used = (table: GraphSnapshot["nodes"]): string[] => GEPHI_COLUMNS.filter((c) => table.has(c));
196
190
  return {
197
191
  canonical: true,
198
192
  dialect: "gephi",
199
193
  tool: "gephi",
200
194
  units: "relative",
201
- node: { values: gephi.node },
202
- edge: { values: gephi.edge, rules, columns },
195
+ node: { values: gephi.node, ...rules.node },
196
+ edge: { values: gephi.edge, ...rules.edge },
203
197
  notes: notes.list(),
204
198
  readFrom: { node: used(snapshot.nodes), edge: used(snapshot.edges) },
205
199
  };
@@ -278,7 +278,11 @@ const GENERIC_SHAPES: readonly (readonly [string, string])[] = [
278
278
  ["box", "rectangle"],
279
279
  ];
280
280
 
281
- /** yEd's label positions (`modelPosition` of the internal, sides and eight-position models). */
281
+ /**
282
+ * yEd's label positions (`modelPosition` of the internal, sides, sandwich, corners and eight-position models). The
283
+ * internal model's `t` (inside the top of the box: a group's title) is `inside-top`; its other inside positions have
284
+ * no neutral value and read as the nearest side or corner.
285
+ */
282
286
  const YED_POSITIONS: ReadonlyMap<string, string> = new Map([
283
287
  ["c", "center"],
284
288
  ["t", "top"],
@@ -382,14 +386,78 @@ function readLabelLook(label: unknown, node: boolean, put: PutValue, at: SiteOf)
382
386
  put("labelItalic", known[1]);
383
387
  }
384
388
  }
385
- const position = node ? treeAttr(label, "modelPosition") : undefined;
386
- if (position !== undefined) {
387
- const known = YED_POSITIONS.get(position.trim().toLowerCase());
388
- if (known === undefined) {
389
- noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, position.slice(0, MAX_STYLE_VALUE_LENGTH));
389
+ if (node) {
390
+ readLabelPosition(label, put, at);
391
+ }
392
+ }
393
+
394
+ /**
395
+ * Reads a node label's position: a `custom` label from its `y:SmartNodeLabelModelParameter`, any other from its
396
+ * `modelPosition` (yEd's default model is `internal`).
397
+ * @param label - the label element
398
+ * @param put - receives the values
399
+ * @param at - the sites
400
+ */
401
+ function readLabelPosition(label: unknown, put: PutValue, at: SiteOf): void {
402
+ const model = treeAttr(label, "modelName")?.trim().toLowerCase() ?? "internal";
403
+ if (model === "custom") {
404
+ const smart = treeChild(treeChild(label, "ModelParameter"), "SmartNodeLabelModelParameter");
405
+ if (smart === undefined) {
406
+ noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, "custom");
407
+ return;
390
408
  }
391
- put("labelPosition", known ?? null);
409
+ put("labelPosition", smartPosition(smart));
410
+ return;
411
+ }
412
+ const position = treeAttr(label, "modelPosition");
413
+ if (position === undefined) {
414
+ return;
415
+ }
416
+ const key = position.trim().toLowerCase();
417
+ const known = model === "internal" && key === "t" ? "inside-top" : YED_POSITIONS.get(key);
418
+ if (known === undefined) {
419
+ noteAt(at("labelPosition"), STYLE_ISSUE.UNKNOWN_VALUE, position.slice(0, MAX_STYLE_VALUE_LENGTH));
392
420
  }
421
+ put("labelPosition", known ?? null);
422
+ }
423
+
424
+ /**
425
+ * The nearest neutral position of a SmartNodeLabelModel placement. yEd puts the point `labelRatio` of the label
426
+ * (-0.5..0.5 of its size from its center) on the point `nodeRatio` of the node; the offsets are ignored. On each axis
427
+ * a node ratio below or above zero is that side, zero is the middle. A label on the node's top edge that hangs down
428
+ * into it (labelRatioY at or below zero) is `inside-top`; every other edge or corner placement is the outside side
429
+ * or corner, the nearest neutral value (an inside bottom or side has none).
430
+ * @param smart - the `y:SmartNodeLabelModelParameter` element
431
+ * @returns the position
432
+ */
433
+ function smartPosition(smart: unknown): string {
434
+ const ratio = (name: string): number => {
435
+ const n = Number(treeAttr(smart, name));
436
+ return Number.isFinite(n) ? n : 0;
437
+ };
438
+ const h = sideOf(ratio("nodeRatioX"), "left", "right");
439
+ const v = sideOf(ratio("nodeRatioY"), "top", "bottom");
440
+ if (v === "top" && h === "" && ratio("labelRatioY") <= 0) {
441
+ return "inside-top";
442
+ }
443
+ if (v === "" || h === "") {
444
+ return v + h || "center";
445
+ }
446
+ return `${v}-${h}`;
447
+ }
448
+
449
+ /**
450
+ * One axis of a SmartNodeLabelModel node ratio.
451
+ * @param ratio - the ratio, -0.5..0.5
452
+ * @param low - the side below zero
453
+ * @param high - the side above zero
454
+ * @returns the side, or "" for the middle
455
+ */
456
+ function sideOf(ratio: number, low: string, high: string): string {
457
+ if (ratio < 0) {
458
+ return low;
459
+ }
460
+ return ratio > 0 ? high : "";
393
461
  }
394
462
 
395
463
  /**
@@ -617,6 +685,7 @@ export function readYedStyles(snapshot: GraphSnapshot, notes: StyleNotes, budget
617
685
  * @category Built-in formats
618
686
  */
619
687
  export const GRAPHML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({
688
+ tool: "yed",
620
689
  node: Object.freeze([
621
690
  "fill",
622
691
  "fillOpacity",
@@ -696,17 +765,21 @@ export const YED_ARROWS: ReadonlyMap<string, string> = new Map([
696
765
  ["crow", "crows_foot_many"],
697
766
  ]);
698
767
 
699
- /** yEd's label positions in the internal model, by neutral position. */
700
- const YED_MODEL_POSITIONS: ReadonlyMap<string, string> = new Map([
701
- ["center", "c"],
702
- ["top", "t"],
703
- ["bottom", "b"],
704
- ["left", "l"],
705
- ["right", "r"],
706
- ["top-left", "tl"],
707
- ["top-right", "tr"],
708
- ["bottom-left", "bl"],
709
- ["bottom-right", "br"],
768
+ /**
769
+ * yEd's label model and position by neutral position: the inside ones in the internal model, the outside sides and
770
+ * corners in the eight-position model.
771
+ */
772
+ const YED_MODEL_POSITIONS: ReadonlyMap<string, readonly [string, string]> = new Map([
773
+ ["center", ["internal", "c"]],
774
+ ["inside-top", ["internal", "t"]],
775
+ ["top", ["eight_pos", "n"]],
776
+ ["bottom", ["eight_pos", "s"]],
777
+ ["left", ["eight_pos", "w"]],
778
+ ["right", ["eight_pos", "e"]],
779
+ ["top-left", ["eight_pos", "nw"]],
780
+ ["top-right", ["eight_pos", "ne"]],
781
+ ["bottom-left", ["eight_pos", "sw"]],
782
+ ["bottom-right", ["eight_pos", "se"]],
710
783
  ]);
711
784
 
712
785
  /**
@@ -811,8 +884,8 @@ function labelTree(get: GetValue, node: boolean, approximate: Approximate): Tree
811
884
  if (written === undefined) {
812
885
  approximate("labelPosition", position);
813
886
  }
814
- label["@_modelName"] = "internal";
815
- label["@_modelPosition"] = written ?? "c";
887
+ label["@_modelName"] = written?.[0] ?? "internal";
888
+ label["@_modelPosition"] = written?.[1] ?? "c";
816
889
  }
817
890
  label["#text"] = text;
818
891
  return label;
@@ -44,6 +44,7 @@ import { LABEL_COLUMN, PAJEK_STYLE_COMMENT, SHAPE_COLUMN } from "./syntax.js";
44
44
  * @category Built-in formats
45
45
  */
46
46
  export const PAJEK_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({
47
+ tool: "pajek",
47
48
  node: Object.freeze([
48
49
  "label",
49
50
  "fill",
@@ -293,6 +293,7 @@ function graphStyleOf(snapshot: GraphSnapshot, notes: StyleNotes): GraphStyle {
293
293
  * background. The block and the tagged values go into graph and element `<att>`s.
294
294
  */
295
295
  export const XGMML_STYLE_CAPABILITIES: StyleWriteCapabilities = Object.freeze({
296
+ tool: "cytoscape",
296
297
  node: Object.freeze(cytoscapeWritableProperties("node", "desktop") as NodeStyleProperty[]),
297
298
  edge: Object.freeze(cytoscapeWritableProperties("edge", "desktop") as EdgeStyleProperty[]),
298
299
  graph: Object.freeze(["background"] as const),
package/src/index.ts CHANGED
@@ -62,6 +62,7 @@ export {
62
62
  createRegistry,
63
63
  downloadGraph,
64
64
  type DownloadGraphOptions,
65
+ expandFromSource,
65
66
  exportGraph,
66
67
  type ExportGraphOptions,
67
68
  exportGraphToBlob,
@@ -70,18 +71,25 @@ export {
70
71
  type FormatInfo,
71
72
  FormatRegistry,
72
73
  importAllGraphs,
74
+ importFromSource,
73
75
  importGraph,
74
76
  type ImportGraphOptions,
75
77
  type ImportGraphResult,
76
78
  listFormats,
79
+ listFromSource,
77
80
  listGraphs,
81
+ listSources,
78
82
  loadFromFile,
83
+ loadFromSource,
79
84
  loadFromUrl,
80
85
  type LoadFromUrlOptions,
86
+ probeSource,
87
+ registerSource,
81
88
  registry,
82
89
  sniff,
83
90
  SNIFF_FAILED_CODE,
84
91
  UNKNOWN_FORMAT_CODE,
92
+ validateSource,
85
93
  } from "./registry.js";
86
94
  export {
87
95
  extensionOf,
@@ -98,6 +106,88 @@ export {
98
106
  type SniffResult,
99
107
  } from "./sniff.js";
100
108
 
109
+ // ============================================================ network sources (experimental)
110
+ // The contract, the load functions and credentials; each built-in source's code is its own subpath
111
+ // (@graphty/graph-io/sources/ndex, /cypher, /rest), loaded on first use.
112
+ export {
113
+ SOURCE_ISSUE,
114
+ type SourceBlockedCause,
115
+ type SourceIssueCode,
116
+ type SourceIssueParams,
117
+ } from "./sources/codes.js";
118
+ export {
119
+ type AwsSigV4Options,
120
+ type CredentialBind,
121
+ credentials,
122
+ fromStorableCredential,
123
+ type StorableCredential,
124
+ storableCredential,
125
+ } from "./sources/credentials.js";
126
+ export { defineSource } from "./sources/define.js";
127
+ export {
128
+ CYPHER_SOURCE_ID,
129
+ NDEX_SOURCE_ID,
130
+ NEO4J_SOURCE_ID,
131
+ NEPTUNE_SOURCE_ID,
132
+ OPENALEX_SOURCE_ID,
133
+ REST_SOURCE_ID,
134
+ SOURCE_ATTR_PREFIX,
135
+ SOURCE_DEGREE_ATTR,
136
+ SOURCE_ENTITY_ATTR,
137
+ SOURCE_FORMAT_PREFIX,
138
+ SOURCE_STUB_ATTR,
139
+ } from "./sources/ids.js";
140
+ export { type SourceParamsMap } from "./sources/params.js";
141
+ export {
142
+ type Recording,
143
+ recordingFrom,
144
+ type ReplayCall,
145
+ type ReplayFetch,
146
+ replayFetch,
147
+ type ReplayOptions,
148
+ } from "./sources/testing.js";
149
+ export {
150
+ type AwsCredentials,
151
+ type Credential,
152
+ type CredentialKind,
153
+ type EdgeRecord,
154
+ type ExpandRequest,
155
+ type FileFn,
156
+ type GraphSource,
157
+ type ImportFn,
158
+ type LazySource,
159
+ type LoadFromSourceOptions,
160
+ type NodeRecord,
161
+ type QueryLanguage,
162
+ type RecordBatch,
163
+ type RecordsFn,
164
+ type RetryOptions,
165
+ type SourceBase,
166
+ type SourceContext,
167
+ type SourceCursor,
168
+ type SourceDescriptor,
169
+ type SourceFeature,
170
+ type SourceFile,
171
+ type SourceFinish,
172
+ type SourceFreshness,
173
+ type SourceInfo,
174
+ type SourceKind,
175
+ type SourceLimitOptions,
176
+ type SourceLimits,
177
+ type SourceListing,
178
+ type SourceListItem,
179
+ type SourceListQuery,
180
+ type SourceParamDescriptor,
181
+ type SourceParamType,
182
+ type SourceProbe,
183
+ type SourceReportInfo,
184
+ type SourceRequestInit,
185
+ type SourceRuntime,
186
+ type SourceRuntimeReason,
187
+ type SourceSample,
188
+ type SourceValidators,
189
+ } from "./sources/types.js";
190
+
101
191
  // ============================================================ formats (8.4, 8.5)
102
192
  export {
103
193
  CSV_CAPABILITIES,