@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.
- package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
- package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
- package/dist/chunks/block-JQiwViEt.js +2777 -0
- package/dist/chunks/block-JQiwViEt.js.map +1 -0
- package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
- package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
- package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
- package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
- package/dist/chunks/convert-BcQ8_jMo.js +59 -0
- package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
- package/dist/chunks/emit-DCwFLts5.js +3456 -0
- package/dist/chunks/emit-DCwFLts5.js.map +1 -0
- package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
- package/dist/chunks/escape-B1rMftd9.js.map +1 -0
- package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
- package/dist/chunks/export-D7IGzTG4.js.map +1 -0
- package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
- package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
- package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
- package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
- package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
- package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
- package/dist/chunks/{exporter-CpRyHZ3H.js → exporter-quPUCBiC.js} +1807 -288
- package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
- package/dist/chunks/format-GDmO6m6Q.js +676 -0
- package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
- package/dist/chunks/generic-BL06jrJf.js +1347 -0
- package/dist/chunks/generic-BL06jrJf.js.map +1 -0
- package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
- package/dist/chunks/importer-B7r2owVf.js.map +1 -0
- package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
- package/dist/chunks/importer-BFmOP96W.js.map +1 -0
- package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
- package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
- package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
- package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
- package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
- package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
- package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
- package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
- package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
- package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
- package/dist/chunks/index-B9fdNpTA.js +4310 -0
- package/dist/chunks/index-B9fdNpTA.js.map +1 -0
- package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
- package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
- package/dist/chunks/lexicon-B-knUi-l.js +508 -0
- package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
- package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
- package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
- package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
- package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
- package/dist/chunks/styles-Brt9JMfs.js +690 -0
- package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
- package/dist/chunks/styles-_N-C8S-U.js +2102 -0
- package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
- package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
- package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
- package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
- package/dist/chunks/units-XMZFIFe1.js +19 -0
- package/dist/chunks/units-XMZFIFe1.js.map +1 -0
- package/dist/csv.js +5 -4
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +5 -2
- package/dist/dot.js.map +1 -1
- package/dist/gexf.js +295 -414
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +8 -3031
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +354 -240
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +4 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +4 -3
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +4 -2
- package/dist/positions.d.ts +1 -0
- package/dist/positions.js +427 -0
- package/dist/positions.js.map +1 -0
- package/dist/src/common/codes.d.ts +6 -0
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +6 -0
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +4 -2
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +10 -0
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +123 -100
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +8 -1
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +12 -9
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +160 -37
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/notes.d.ts +42 -0
- package/dist/src/common/notes.d.ts.map +1 -0
- package/dist/src/common/notes.js +72 -0
- package/dist/src/common/notes.js.map +1 -0
- package/dist/src/common/report.d.ts +18 -0
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +36 -1
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/units.d.ts +24 -0
- package/dist/src/common/units.d.ts.map +1 -0
- package/dist/src/common/units.js +26 -0
- package/dist/src/common/units.js.map +1 -0
- package/dist/src/common/xml.d.ts +18 -0
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +42 -5
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +6 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx/exporter.js +71 -8
- package/dist/src/formats/cx/exporter.js.map +1 -1
- package/dist/src/formats/cx/importer.d.ts +5 -2
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +102 -72
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/styles.d.ts +102 -0
- package/dist/src/formats/cx/styles.d.ts.map +1 -0
- package/dist/src/formats/cx/styles.js +225 -0
- package/dist/src/formats/cx/styles.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +5 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +181 -71
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +4 -1
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +19 -1
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/styles.d.ts +18 -0
- package/dist/src/formats/cx2/styles.d.ts.map +1 -0
- package/dist/src/formats/cx2/styles.js +24 -0
- package/dist/src/formats/cx2/styles.js.map +1 -0
- package/dist/src/formats/cys/constants.d.ts +2 -0
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +2 -0
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +6 -2
- package/dist/src/formats/cys/exporter.d.ts.map +1 -1
- package/dist/src/formats/cys/exporter.js +215 -53
- package/dist/src/formats/cys/exporter.js.map +1 -1
- package/dist/src/formats/cys/importer.d.ts +2 -1
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +119 -6
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +2 -0
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +5 -0
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/styles.d.ts +38 -0
- package/dist/src/formats/cys/styles.d.ts.map +1 -0
- package/dist/src/formats/cys/styles.js +213 -0
- package/dist/src/formats/cys/styles.js.map +1 -0
- package/dist/src/formats/cys/tables.d.ts +8 -3
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +88 -34
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +2 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +195 -81
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +100 -20
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +1 -0
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +1 -0
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/positions.d.ts +14 -0
- package/dist/src/formats/dot/positions.d.ts.map +1 -0
- package/dist/src/formats/dot/positions.js +70 -0
- package/dist/src/formats/dot/positions.js.map +1 -0
- package/dist/src/formats/dot/styles.d.ts +82 -0
- package/dist/src/formats/dot/styles.d.ts.map +1 -0
- package/dist/src/formats/dot/styles.js +1484 -0
- package/dist/src/formats/dot/styles.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +23 -7
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +8 -1
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +251 -131
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +8 -0
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +10 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +5 -0
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +5 -0
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gexf/styles.d.ts +74 -0
- package/dist/src/formats/gexf/styles.d.ts.map +1 -0
- package/dist/src/formats/gexf/styles.js +604 -0
- package/dist/src/formats/gexf/styles.js.map +1 -0
- package/dist/src/formats/gml/exporter.d.ts +1 -5
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +19 -8
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +4 -0
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +2 -1
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +2 -1
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/positions.d.ts +14 -0
- package/dist/src/formats/gml/positions.d.ts.map +1 -0
- package/dist/src/formats/gml/positions.js +46 -0
- package/dist/src/formats/gml/positions.js.map +1 -0
- package/dist/src/formats/gml/styles.d.ts +59 -0
- package/dist/src/formats/gml/styles.d.ts.map +1 -0
- package/dist/src/formats/gml/styles.js +1056 -0
- package/dist/src/formats/gml/styles.js.map +1 -0
- package/dist/src/formats/gml/syntax.d.ts +11 -0
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +151 -62
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +4 -0
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +5 -1
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +133 -65
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +4 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +100 -44
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +1 -0
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +1 -0
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
- package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-plain.js +187 -0
- package/dist/src/formats/graphml/styles-plain.js.map +1 -0
- package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
- package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yed.js +1086 -0
- package/dist/src/formats/graphml/styles-yed.js.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
- package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +34 -19
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +16 -2
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +83 -12
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +5 -0
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +68 -25
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +22 -3
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +441 -265
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/positions.d.ts +16 -0
- package/dist/src/formats/json/positions.d.ts.map +1 -0
- package/dist/src/formats/json/positions.js +44 -0
- package/dist/src/formats/json/positions.js.map +1 -0
- package/dist/src/formats/json/styles.d.ts +102 -0
- package/dist/src/formats/json/styles.d.ts.map +1 -0
- package/dist/src/formats/json/styles.js +1753 -0
- package/dist/src/formats/json/styles.js.map +1 -0
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +2 -1
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +2 -0
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +142 -76
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +4 -0
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +60 -6
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -0
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -0
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts +50 -0
- package/dist/src/formats/pajek/styles.d.ts.map +1 -0
- package/dist/src/formats/pajek/styles.js +569 -0
- package/dist/src/formats/pajek/styles.js.map +1 -0
- package/dist/src/formats/pajek/syntax.d.ts +6 -0
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +6 -0
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +34 -9
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +2 -0
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +3 -1
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +12 -8
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +56 -13
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +12 -6
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +3 -1
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +22 -9
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +2 -1
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +31 -24
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/styles.d.ts +104 -0
- package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
- package/dist/src/formats/xgmml/styles.js +310 -0
- package/dist/src/formats/xgmml/styles.js.map +1 -0
- package/dist/src/index.d.ts +9 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/positions/codes.d.ts +31 -0
- package/dist/src/positions/codes.d.ts.map +1 -0
- package/dist/src/positions/codes.js +26 -0
- package/dist/src/positions/codes.js.map +1 -0
- package/dist/src/positions/convert.d.ts +58 -0
- package/dist/src/positions/convert.d.ts.map +1 -0
- package/dist/src/positions/convert.js +107 -0
- package/dist/src/positions/convert.js.map +1 -0
- package/dist/src/positions/extract.d.ts +27 -0
- package/dist/src/positions/extract.d.ts.map +1 -0
- package/dist/src/positions/extract.js +526 -0
- package/dist/src/positions/extract.js.map +1 -0
- package/dist/src/positions/index.d.ts +10 -0
- package/dist/src/positions/index.d.ts.map +1 -0
- package/dist/src/positions/index.js +9 -0
- package/dist/src/positions/index.js.map +1 -0
- package/dist/src/positions/types.d.ts +208 -0
- package/dist/src/positions/types.d.ts.map +1 -0
- package/dist/src/positions/types.js +10 -0
- package/dist/src/positions/types.js.map +1 -0
- package/dist/src/registry.d.ts +30 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +130 -9
- package/dist/src/registry.js.map +1 -1
- package/dist/src/styles/annotations.d.ts +132 -0
- package/dist/src/styles/annotations.d.ts.map +1 -0
- package/dist/src/styles/annotations.js +320 -0
- package/dist/src/styles/annotations.js.map +1 -0
- package/dist/src/styles/budget.d.ts +45 -0
- package/dist/src/styles/budget.d.ts.map +1 -0
- package/dist/src/styles/budget.js +58 -0
- package/dist/src/styles/budget.js.map +1 -0
- package/dist/src/styles/canon/bends.d.ts +32 -0
- package/dist/src/styles/canon/bends.d.ts.map +1 -0
- package/dist/src/styles/canon/bends.js +74 -0
- package/dist/src/styles/canon/bends.js.map +1 -0
- package/dist/src/styles/canon/color-tables.d.ts +22 -0
- package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
- package/dist/src/styles/canon/color-tables.js +369 -0
- package/dist/src/styles/canon/color-tables.js.map +1 -0
- package/dist/src/styles/canon/color.d.ts +66 -0
- package/dist/src/styles/canon/color.d.ts.map +1 -0
- package/dist/src/styles/canon/color.js +548 -0
- package/dist/src/styles/canon/color.js.map +1 -0
- package/dist/src/styles/canon/enums.d.ts +25 -0
- package/dist/src/styles/canon/enums.d.ts.map +1 -0
- package/dist/src/styles/canon/enums.js +187 -0
- package/dist/src/styles/canon/enums.js.map +1 -0
- package/dist/src/styles/canon/graphviz.d.ts +48 -0
- package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
- package/dist/src/styles/canon/graphviz.js +160 -0
- package/dist/src/styles/canon/graphviz.js.map +1 -0
- package/dist/src/styles/canon/index.d.ts +13 -0
- package/dist/src/styles/canon/index.d.ts.map +1 -0
- package/dist/src/styles/canon/index.js +13 -0
- package/dist/src/styles/canon/index.js.map +1 -0
- package/dist/src/styles/canon/number.d.ts +59 -0
- package/dist/src/styles/canon/number.d.ts.map +1 -0
- package/dist/src/styles/canon/number.js +142 -0
- package/dist/src/styles/canon/number.js.map +1 -0
- package/dist/src/styles/canon/site.d.ts +51 -0
- package/dist/src/styles/canon/site.d.ts.map +1 -0
- package/dist/src/styles/canon/site.js +63 -0
- package/dist/src/styles/canon/site.js.map +1 -0
- package/dist/src/styles/canon/text.d.ts +61 -0
- package/dist/src/styles/canon/text.d.ts.map +1 -0
- package/dist/src/styles/canon/text.js +199 -0
- package/dist/src/styles/canon/text.js.map +1 -0
- package/dist/src/styles/codes.d.ts +95 -0
- package/dist/src/styles/codes.d.ts.map +1 -0
- package/dist/src/styles/codes.js +97 -0
- package/dist/src/styles/codes.js.map +1 -0
- package/dist/src/styles/cyjs/cascade.d.ts +134 -0
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
- package/dist/src/styles/cyjs/cascade.js +2252 -0
- package/dist/src/styles/cyjs/cascade.js.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
- package/dist/src/styles/cyjs/defaults-table.js +76 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
- package/dist/src/styles/cyjs/emit.d.ts +82 -0
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
- package/dist/src/styles/cyjs/emit.js +790 -0
- package/dist/src/styles/cyjs/emit.js.map +1 -0
- package/dist/src/styles/cyjs/index.d.ts +13 -0
- package/dist/src/styles/cyjs/index.d.ts.map +1 -0
- package/dist/src/styles/cyjs/index.js +13 -0
- package/dist/src/styles/cyjs/index.js.map +1 -0
- package/dist/src/styles/cyjs/live.d.ts +46 -0
- package/dist/src/styles/cyjs/live.d.ts.map +1 -0
- package/dist/src/styles/cyjs/live.js +108 -0
- package/dist/src/styles/cyjs/live.js.map +1 -0
- package/dist/src/styles/cyjs/mappers.d.ts +147 -0
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
- package/dist/src/styles/cyjs/mappers.js +744 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -0
- package/dist/src/styles/cyjs/selector.d.ts +113 -0
- package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
- package/dist/src/styles/cyjs/selector.js +611 -0
- package/dist/src/styles/cyjs/selector.js.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
- package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
- package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
- package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
- package/dist/src/styles/cytoscape/emit.d.ts +125 -0
- package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/emit.js +1025 -0
- package/dist/src/styles/cytoscape/emit.js.map +1 -0
- package/dist/src/styles/cytoscape/index.d.ts +10 -0
- package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/index.js +10 -0
- package/dist/src/styles/cytoscape/index.js.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
- package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/lexicon.js +603 -0
- package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
- package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
- package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/mappings.js +460 -0
- package/dist/src/styles/cytoscape/mappings.js.map +1 -0
- package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
- package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/resolve.js +381 -0
- package/dist/src/styles/cytoscape/resolve.js.map +1 -0
- package/dist/src/styles/cytoscape/translate.d.ts +50 -0
- package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
- package/dist/src/styles/cytoscape/translate.js +156 -0
- package/dist/src/styles/cytoscape/translate.js.map +1 -0
- package/dist/src/styles/defaults.d.ts +90 -0
- package/dist/src/styles/defaults.d.ts.map +1 -0
- package/dist/src/styles/defaults.js +414 -0
- package/dist/src/styles/defaults.js.map +1 -0
- package/dist/src/styles/index.d.ts +15 -0
- package/dist/src/styles/index.d.ts.map +1 -0
- package/dist/src/styles/index.js +14 -0
- package/dist/src/styles/index.js.map +1 -0
- package/dist/src/styles/internal.d.ts +17 -0
- package/dist/src/styles/internal.d.ts.map +1 -0
- package/dist/src/styles/internal.js +16 -0
- package/dist/src/styles/internal.js.map +1 -0
- package/dist/src/styles/io/approximations.d.ts +24 -0
- package/dist/src/styles/io/approximations.d.ts.map +1 -0
- package/dist/src/styles/io/approximations.js +51 -0
- package/dist/src/styles/io/approximations.js.map +1 -0
- package/dist/src/styles/io/block.d.ts +166 -0
- package/dist/src/styles/io/block.d.ts.map +1 -0
- package/dist/src/styles/io/block.js +930 -0
- package/dist/src/styles/io/block.js.map +1 -0
- package/dist/src/styles/io/generic.d.ts +88 -0
- package/dist/src/styles/io/generic.d.ts.map +1 -0
- package/dist/src/styles/io/generic.js +516 -0
- package/dist/src/styles/io/generic.js.map +1 -0
- package/dist/src/styles/io/index.d.ts +8 -0
- package/dist/src/styles/io/index.d.ts.map +1 -0
- package/dist/src/styles/io/index.js +7 -0
- package/dist/src/styles/io/index.js.map +1 -0
- package/dist/src/styles/io/writer.d.ts +80 -0
- package/dist/src/styles/io/writer.d.ts.map +1 -0
- package/dist/src/styles/io/writer.js +596 -0
- package/dist/src/styles/io/writer.js.map +1 -0
- package/dist/src/styles/notes.d.ts +47 -0
- package/dist/src/styles/notes.d.ts.map +1 -0
- package/dist/src/styles/notes.js +140 -0
- package/dist/src/styles/notes.js.map +1 -0
- package/dist/src/styles/plan/classes.d.ts +31 -0
- package/dist/src/styles/plan/classes.d.ts.map +1 -0
- package/dist/src/styles/plan/classes.js +139 -0
- package/dist/src/styles/plan/classes.js.map +1 -0
- package/dist/src/styles/plan/continuous.d.ts +32 -0
- package/dist/src/styles/plan/continuous.d.ts.map +1 -0
- package/dist/src/styles/plan/continuous.js +165 -0
- package/dist/src/styles/plan/continuous.js.map +1 -0
- package/dist/src/styles/plan/discrete.d.ts +39 -0
- package/dist/src/styles/plan/discrete.d.ts.map +1 -0
- package/dist/src/styles/plan/discrete.js +127 -0
- package/dist/src/styles/plan/discrete.js.map +1 -0
- package/dist/src/styles/plan/families.d.ts +31 -0
- package/dist/src/styles/plan/families.d.ts.map +1 -0
- package/dist/src/styles/plan/families.js +95 -0
- package/dist/src/styles/plan/families.js.map +1 -0
- package/dist/src/styles/plan/features.d.ts +58 -0
- package/dist/src/styles/plan/features.d.ts.map +1 -0
- package/dist/src/styles/plan/features.js +185 -0
- package/dist/src/styles/plan/features.js.map +1 -0
- package/dist/src/styles/plan/index.d.ts +7 -0
- package/dist/src/styles/plan/index.d.ts.map +1 -0
- package/dist/src/styles/plan/index.js +7 -0
- package/dist/src/styles/plan/index.js.map +1 -0
- package/dist/src/styles/plan/plan.d.ts +71 -0
- package/dist/src/styles/plan/plan.d.ts.map +1 -0
- package/dist/src/styles/plan/plan.js +893 -0
- package/dist/src/styles/plan/plan.js.map +1 -0
- package/dist/src/styles/plan/resolve.d.ts +137 -0
- package/dist/src/styles/plan/resolve.d.ts.map +1 -0
- package/dist/src/styles/plan/resolve.js +587 -0
- package/dist/src/styles/plan/resolve.js.map +1 -0
- package/dist/src/styles/types.d.ts +702 -0
- package/dist/src/styles/types.d.ts.map +1 -0
- package/dist/src/styles/types.js +10 -0
- package/dist/src/styles/types.js.map +1 -0
- package/dist/src/styles/vocabulary.d.ts +41 -0
- package/dist/src/styles/vocabulary.d.ts.map +1 -0
- package/dist/src/styles/vocabulary.js +140 -0
- package/dist/src/styles/vocabulary.js.map +1 -0
- package/dist/src/types.d.ts +64 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/styles.d.ts +1 -0
- package/dist/styles.js +322 -0
- package/dist/styles.js.map +1 -0
- package/dist/xgmml.js +5 -4
- package/dist/xgmml.js.map +1 -1
- package/package.json +13 -2
- package/src/common/codes.ts +7 -0
- package/src/common/escape.ts +5 -2
- package/src/common/export.ts +179 -140
- package/src/common/input.ts +8 -4
- package/src/common/json-elements.ts +169 -38
- package/src/common/notes.ts +94 -0
- package/src/common/report.ts +41 -1
- package/src/common/units.ts +42 -0
- package/src/common/xml.ts +45 -5
- package/src/formats/cx/exporter.ts +95 -11
- package/src/formats/cx/importer.ts +126 -90
- package/src/formats/cx/styles.ts +304 -0
- package/src/formats/cx2/exporter.ts +234 -77
- package/src/formats/cx2/importer.ts +19 -1
- package/src/formats/cx2/styles.ts +29 -0
- package/src/formats/cys/constants.ts +3 -0
- package/src/formats/cys/exporter.ts +246 -60
- package/src/formats/cys/importer.ts +125 -9
- package/src/formats/cys/session.ts +6 -0
- package/src/formats/cys/styles.ts +254 -0
- package/src/formats/cys/tables.ts +117 -48
- package/src/formats/dot/exporter.ts +262 -126
- package/src/formats/dot/importer.ts +111 -20
- package/src/formats/dot/index.ts +1 -0
- package/src/formats/dot/positions.ts +77 -0
- package/src/formats/dot/styles.ts +1741 -0
- package/src/formats/gexf/exporter.ts +30 -13
- package/src/formats/gexf/importer.ts +308 -158
- package/src/formats/gexf/index.ts +10 -0
- package/src/formats/gexf/schema.ts +5 -0
- package/src/formats/gexf/styles.ts +719 -0
- package/src/formats/gml/exporter.ts +33 -14
- package/src/formats/gml/importer.ts +4 -0
- package/src/formats/gml/index.ts +2 -1
- package/src/formats/gml/positions.ts +52 -0
- package/src/formats/gml/styles.ts +1248 -0
- package/src/formats/gml/syntax.ts +173 -62
- package/src/formats/graphml/constants.ts +5 -0
- package/src/formats/graphml/exporter.ts +163 -71
- package/src/formats/graphml/importer.ts +119 -45
- package/src/formats/graphml/index.ts +1 -0
- package/src/formats/graphml/styles-plain.ts +236 -0
- package/src/formats/graphml/styles-yed.ts +1221 -0
- package/src/formats/graphml/styles-yfiles3.ts +573 -0
- package/src/formats/graphml/tree.ts +36 -20
- package/src/formats/graphml/yfiles.ts +89 -13
- package/src/formats/json/exporter.ts +76 -26
- package/src/formats/json/importer.ts +543 -323
- package/src/formats/json/positions.ts +50 -0
- package/src/formats/json/styles.ts +2082 -0
- package/src/formats/neo4j/exporter.ts +2 -1
- package/src/formats/pajek/exporter.ts +195 -106
- package/src/formats/pajek/importer.ts +78 -9
- package/src/formats/pajek/index.ts +2 -0
- package/src/formats/pajek/styles.ts +685 -0
- package/src/formats/pajek/syntax.ts +7 -0
- package/src/formats/xgmml/columns.ts +39 -9
- package/src/formats/xgmml/constants.ts +3 -0
- package/src/formats/xgmml/document.ts +54 -12
- package/src/formats/xgmml/emit.ts +11 -6
- package/src/formats/xgmml/exporter.ts +32 -13
- package/src/formats/xgmml/importer.ts +43 -29
- package/src/formats/xgmml/styles.ts +400 -0
- package/src/index.ts +16 -0
- package/src/positions/codes.ts +32 -0
- package/src/positions/convert.ts +123 -0
- package/src/positions/extract.ts +619 -0
- package/src/positions/index.ts +23 -0
- package/src/positions/types.ts +221 -0
- package/src/registry.ts +179 -8
- package/src/styles/annotations.ts +478 -0
- package/src/styles/budget.ts +60 -0
- package/src/styles/canon/bends.ts +84 -0
- package/src/styles/canon/color-tables.ts +386 -0
- package/src/styles/canon/color.ts +624 -0
- package/src/styles/canon/enums.ts +211 -0
- package/src/styles/canon/graphviz.ts +189 -0
- package/src/styles/canon/index.ts +13 -0
- package/src/styles/canon/number.ts +152 -0
- package/src/styles/canon/site.ts +87 -0
- package/src/styles/canon/text.ts +221 -0
- package/src/styles/codes.ts +104 -0
- package/src/styles/cyjs/cascade.ts +2670 -0
- package/src/styles/cyjs/defaults-table.ts +82 -0
- package/src/styles/cyjs/emit.ts +951 -0
- package/src/styles/cyjs/index.ts +37 -0
- package/src/styles/cyjs/live.ts +147 -0
- package/src/styles/cyjs/mappers.ts +879 -0
- package/src/styles/cyjs/selector.ts +778 -0
- package/src/styles/cyjs/stylesheet-text.ts +214 -0
- package/src/styles/cytoscape/emit.ts +1264 -0
- package/src/styles/cytoscape/index.ts +40 -0
- package/src/styles/cytoscape/lexicon.ts +656 -0
- package/src/styles/cytoscape/mappings.ts +603 -0
- package/src/styles/cytoscape/resolve.ts +521 -0
- package/src/styles/cytoscape/translate.ts +237 -0
- package/src/styles/defaults.ts +504 -0
- package/src/styles/index.ts +57 -0
- package/src/styles/internal.ts +17 -0
- package/src/styles/io/approximations.ts +47 -0
- package/src/styles/io/block.ts +1138 -0
- package/src/styles/io/generic.ts +687 -0
- package/src/styles/io/index.ts +18 -0
- package/src/styles/io/writer.ts +745 -0
- package/src/styles/notes.ts +165 -0
- package/src/styles/plan/classes.ts +166 -0
- package/src/styles/plan/continuous.ts +218 -0
- package/src/styles/plan/discrete.ts +165 -0
- package/src/styles/plan/families.ts +115 -0
- package/src/styles/plan/features.ts +234 -0
- package/src/styles/plan/index.ts +7 -0
- package/src/styles/plan/plan.ts +1129 -0
- package/src/styles/plan/resolve.ts +685 -0
- package/src/styles/types.ts +814 -0
- package/src/styles/vocabulary.ts +172 -0
- package/src/types.ts +76 -1
- package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
- package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
- package/dist/chunks/export-rKLeGQMo.js.map +0 -1
- package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
- package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
- package/dist/chunks/exporter-CpRyHZ3H.js.map +0 -1
- package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
- package/dist/chunks/importer-C98dpSH4.js.map +0 -1
- package/dist/chunks/importer-D794XUTe.js.map +0 -1
- package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
- package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
- package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
- package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
- 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 {
|
|
3
|
-
import {
|
|
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 {
|
|
6
|
-
import {
|
|
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
|
|
361
|
-
if (!
|
|
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(
|
|
371
|
+
root = JSON.parse(trimmed2);
|
|
367
372
|
} catch {
|
|
368
|
-
const skeleton = skeletonOf(
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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([
|
|
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
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
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
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
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 (
|
|
1809
|
-
nodeIdKey
|
|
3222
|
+
if (json2.nodeIdKey !== null) {
|
|
3223
|
+
return json2.nodeIdKey;
|
|
1810
3224
|
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
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
|
-
|
|
1820
|
-
|
|
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 (
|
|
1828
|
-
ctx
|
|
3253
|
+
if (isJsonObject(record)) {
|
|
3254
|
+
pushed = pushNodeLinkNode(ctx, record, i, nodeIdKey);
|
|
1829
3255
|
} else {
|
|
1830
|
-
|
|
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
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
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(
|
|
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
|
-
|
|
2362
|
-
pushGraphologyNode(ctx, nodes[i], `nodes[${i}]`);
|
|
2363
|
-
}
|
|
3780
|
+
importGraphologyNodes(ctx, nodes, gephi);
|
|
2364
3781
|
throwIfAborted(ctx.options.signal);
|
|
2365
|
-
const
|
|
2366
|
-
|
|
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
|
|
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
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
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
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
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
|
-
|
|
3843
|
+
return violations;
|
|
2412
3844
|
}
|
|
2413
|
-
function
|
|
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
|
|
2448
|
-
const {
|
|
2449
|
-
|
|
2450
|
-
|
|
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
|
-
|
|
2453
|
-
|
|
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
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
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(
|
|
3879
|
+
`${element}: attributes must be an object, found ${describe(rawAttributes)}`,
|
|
2464
3880
|
{ element }
|
|
2465
3881
|
);
|
|
2466
3882
|
}
|
|
2467
|
-
|
|
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,
|
|
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
|
|
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(
|
|
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(
|
|
3966
|
+
anyHas(nodeRecords2, "label")
|
|
2540
3967
|
);
|
|
2541
3968
|
if (isJsonObject(nodesRaw)) {
|
|
2542
|
-
for (const key of
|
|
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 <
|
|
2547
|
-
pushJgfListedNode(ctx,
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
4390
|
+
const object = root;
|
|
4391
|
+
ctx.writeGraphDict(object.data, "data");
|
|
2965
4392
|
const rest = {};
|
|
2966
|
-
for (const key of Object.keys(
|
|
2967
|
-
if (key !== "elements" && key !== "data") {
|
|
2968
|
-
rest[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:
|
|
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
|
|
4427
|
+
function importCytoscapeNode(ctx, record, data, raw, element, columns, parents) {
|
|
2974
4428
|
const { report } = ctx;
|
|
2975
|
-
|
|
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
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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.
|
|
3125
|
-
const v = ctx.
|
|
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
|
|
3248
|
-
if (!
|
|
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) =>
|
|
3252
|
-
return
|
|
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(
|
|
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(
|
|
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
|
|
5712
|
+
let numeric2 = 0;
|
|
4225
5713
|
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
4226
5714
|
const id = snapshot.ids.idOf(i);
|
|
4227
|
-
|
|
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 (
|
|
5731
|
+
if (numeric2 > 0) {
|
|
4244
5732
|
this.note(
|
|
4245
5733
|
LOSS.ID_TEXT_TYPE,
|
|
4246
|
-
`${
|
|
5734
|
+
`${numeric2} numeric node id${plural(numeric2)} ${agree(numeric2, "is", "are")} written as text and read back as strings`,
|
|
4247
5735
|
null,
|
|
4248
|
-
|
|
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
|
|
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
|
-
|
|
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 (
|
|
6967
|
+
if (numeric2 > 0) {
|
|
5473
6968
|
note(
|
|
5474
6969
|
JSON_LOSS.NUMERIC_IDS_STRINGIFIED,
|
|
5475
|
-
`${
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
7437
|
+
writeCytoscapeTopLevel(c, p);
|
|
7438
|
+
writeTopLevelBlock(c, p);
|
|
5931
7439
|
w.close("}");
|
|
5932
7440
|
yield w.take();
|
|
5933
7441
|
}
|
|
5934
|
-
function writeCytoscapePosition(c,
|
|
7442
|
+
function writeCytoscapePosition(c, p, i) {
|
|
5935
7443
|
const { w } = c;
|
|
5936
|
-
for (const item of
|
|
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
|
|
5949
|
-
|
|
5950
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
6005
|
-
const
|
|
6006
|
-
|
|
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,
|
|
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,
|
|
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-
|
|
7567
|
+
//# sourceMappingURL=exporter-quPUCBiC.js.map
|