@graphty/graph-io 0.3.42 → 0.3.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/dist/chunks/approximations-3Q4TsdTh.js +40 -0
  2. package/dist/chunks/approximations-3Q4TsdTh.js.map +1 -0
  3. package/dist/chunks/block-JQiwViEt.js +2777 -0
  4. package/dist/chunks/block-JQiwViEt.js.map +1 -0
  5. package/dist/chunks/{choose-DvpbdRuz.js → choose-BemygfH8.js} +3 -2
  6. package/dist/chunks/{choose-DvpbdRuz.js.map → choose-BemygfH8.js.map} +1 -1
  7. package/dist/chunks/{constants-fT3E8JYY.js → constants-BFUR_CtU.js} +6 -2
  8. package/dist/chunks/constants-BFUR_CtU.js.map +1 -0
  9. package/dist/chunks/convert-BcQ8_jMo.js +59 -0
  10. package/dist/chunks/convert-BcQ8_jMo.js.map +1 -0
  11. package/dist/chunks/emit-DCwFLts5.js +3456 -0
  12. package/dist/chunks/emit-DCwFLts5.js.map +1 -0
  13. package/dist/chunks/{escape-B62ZGM_a.js → escape-B1rMftd9.js} +43 -20
  14. package/dist/chunks/escape-B1rMftd9.js.map +1 -0
  15. package/dist/chunks/{export-rKLeGQMo.js → export-D7IGzTG4.js} +196 -792
  16. package/dist/chunks/export-D7IGzTG4.js.map +1 -0
  17. package/dist/chunks/{exporter-BWwEuOPT.js → exporter-BtnqYuuj.js} +22 -12
  18. package/dist/chunks/exporter-BtnqYuuj.js.map +1 -0
  19. package/dist/chunks/{exporter-yLxKBvLE.js → exporter-ChPyhBOv.js} +4 -3
  20. package/dist/chunks/{exporter-yLxKBvLE.js.map → exporter-ChPyhBOv.js.map} +1 -1
  21. package/dist/chunks/{exporter-8hLNemFk.js → exporter-KEPxYUXD.js} +133 -74
  22. package/dist/chunks/exporter-KEPxYUXD.js.map +1 -0
  23. package/dist/chunks/{exporter-CpRyHZ3H.js → exporter-quPUCBiC.js} +1807 -288
  24. package/dist/chunks/exporter-quPUCBiC.js.map +1 -0
  25. package/dist/chunks/format-GDmO6m6Q.js +676 -0
  26. package/dist/chunks/format-GDmO6m6Q.js.map +1 -0
  27. package/dist/chunks/generic-BL06jrJf.js +1347 -0
  28. package/dist/chunks/generic-BL06jrJf.js.map +1 -0
  29. package/dist/chunks/{importer-WrGRZb0N.js → importer-B7r2owVf.js} +449 -102
  30. package/dist/chunks/importer-B7r2owVf.js.map +1 -0
  31. package/dist/chunks/{importer-Ht7LNg8L.js → importer-BFmOP96W.js} +116 -296
  32. package/dist/chunks/importer-BFmOP96W.js.map +1 -0
  33. package/dist/chunks/{importer-BbNb7eNg.js → importer-C2nzGhdV.js} +1390 -129
  34. package/dist/chunks/importer-C2nzGhdV.js.map +1 -0
  35. package/dist/chunks/{importer-Dz7tI8Sa.js → importer-CbX2_rNF.js} +617 -115
  36. package/dist/chunks/importer-CbX2_rNF.js.map +1 -0
  37. package/dist/chunks/{importer-D794XUTe.js → importer-CdzeN6X4.js} +31 -8
  38. package/dist/chunks/importer-CdzeN6X4.js.map +1 -0
  39. package/dist/chunks/{importer-xZ-3suY1.js → importer-ChKNC_GN.js} +791 -135
  40. package/dist/chunks/importer-ChKNC_GN.js.map +1 -0
  41. package/dist/chunks/{importer-C98dpSH4.js → importer-dwoYpSqb.js} +141 -82
  42. package/dist/chunks/importer-dwoYpSqb.js.map +1 -0
  43. package/dist/chunks/index-B9fdNpTA.js +4310 -0
  44. package/dist/chunks/index-B9fdNpTA.js.map +1 -0
  45. package/dist/chunks/{json-elements-DKSqpNW1.js → json-elements-C4FwgnH5.js} +123 -32
  46. package/dist/chunks/json-elements-C4FwgnH5.js.map +1 -0
  47. package/dist/chunks/lexicon-B-knUi-l.js +508 -0
  48. package/dist/chunks/lexicon-B-knUi-l.js.map +1 -0
  49. package/dist/chunks/{ontology-export-CtRXjg_i.js → ontology-export-BSpbY5FL.js} +3 -2
  50. package/dist/chunks/{ontology-export-CtRXjg_i.js.map → ontology-export-BSpbY5FL.js.map} +1 -1
  51. package/dist/chunks/{records-Cu4bxYOm.js → records-Nwz_rbNt.js} +2 -2
  52. package/dist/chunks/{records-Cu4bxYOm.js.map → records-Nwz_rbNt.js.map} +1 -1
  53. package/dist/chunks/styles-Brt9JMfs.js +690 -0
  54. package/dist/chunks/styles-Brt9JMfs.js.map +1 -0
  55. package/dist/chunks/styles-_N-C8S-U.js +2102 -0
  56. package/dist/chunks/styles-_N-C8S-U.js.map +1 -0
  57. package/dist/chunks/styles-yed-DAfcIkf7.js +842 -0
  58. package/dist/chunks/styles-yed-DAfcIkf7.js.map +1 -0
  59. package/dist/chunks/{text-DHOJXnED.js → text-CgzMqHQb.js} +2 -2
  60. package/dist/chunks/{text-DHOJXnED.js.map → text-CgzMqHQb.js.map} +1 -1
  61. package/dist/chunks/units-XMZFIFe1.js +19 -0
  62. package/dist/chunks/units-XMZFIFe1.js.map +1 -0
  63. package/dist/csv.js +5 -4
  64. package/dist/csv.js.map +1 -1
  65. package/dist/cx.js +1 -1
  66. package/dist/cx2.js +2 -2
  67. package/dist/cys.js +1 -1
  68. package/dist/dot.js +5 -2
  69. package/dist/dot.js.map +1 -1
  70. package/dist/gexf.js +295 -414
  71. package/dist/gexf.js.map +1 -1
  72. package/dist/gml.js +8 -3031
  73. package/dist/gml.js.map +1 -1
  74. package/dist/graph-io.js +354 -240
  75. package/dist/graph-io.js.map +1 -1
  76. package/dist/graphml.js +4 -2
  77. package/dist/graphml.js.map +1 -1
  78. package/dist/json.js +1 -1
  79. package/dist/neo4j.js +4 -3
  80. package/dist/neo4j.js.map +1 -1
  81. package/dist/obo.js +1 -1
  82. package/dist/pajek.js +4 -2
  83. package/dist/positions.d.ts +1 -0
  84. package/dist/positions.js +427 -0
  85. package/dist/positions.js.map +1 -0
  86. package/dist/src/common/codes.d.ts +6 -0
  87. package/dist/src/common/codes.d.ts.map +1 -1
  88. package/dist/src/common/codes.js +6 -0
  89. package/dist/src/common/codes.js.map +1 -1
  90. package/dist/src/common/escape.d.ts.map +1 -1
  91. package/dist/src/common/escape.js +4 -2
  92. package/dist/src/common/escape.js.map +1 -1
  93. package/dist/src/common/export.d.ts +10 -0
  94. package/dist/src/common/export.d.ts.map +1 -1
  95. package/dist/src/common/export.js +123 -100
  96. package/dist/src/common/export.js.map +1 -1
  97. package/dist/src/common/input.d.ts.map +1 -1
  98. package/dist/src/common/input.js +8 -1
  99. package/dist/src/common/input.js.map +1 -1
  100. package/dist/src/common/json-elements.d.ts +12 -9
  101. package/dist/src/common/json-elements.d.ts.map +1 -1
  102. package/dist/src/common/json-elements.js +160 -37
  103. package/dist/src/common/json-elements.js.map +1 -1
  104. package/dist/src/common/notes.d.ts +42 -0
  105. package/dist/src/common/notes.d.ts.map +1 -0
  106. package/dist/src/common/notes.js +72 -0
  107. package/dist/src/common/notes.js.map +1 -0
  108. package/dist/src/common/report.d.ts +18 -0
  109. package/dist/src/common/report.d.ts.map +1 -1
  110. package/dist/src/common/report.js +36 -1
  111. package/dist/src/common/report.js.map +1 -1
  112. package/dist/src/common/units.d.ts +24 -0
  113. package/dist/src/common/units.d.ts.map +1 -0
  114. package/dist/src/common/units.js +26 -0
  115. package/dist/src/common/units.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +18 -0
  117. package/dist/src/common/xml.d.ts.map +1 -1
  118. package/dist/src/common/xml.js +42 -5
  119. package/dist/src/common/xml.js.map +1 -1
  120. package/dist/src/formats/cx/exporter.d.ts +6 -0
  121. package/dist/src/formats/cx/exporter.d.ts.map +1 -1
  122. package/dist/src/formats/cx/exporter.js +71 -8
  123. package/dist/src/formats/cx/exporter.js.map +1 -1
  124. package/dist/src/formats/cx/importer.d.ts +5 -2
  125. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  126. package/dist/src/formats/cx/importer.js +102 -72
  127. package/dist/src/formats/cx/importer.js.map +1 -1
  128. package/dist/src/formats/cx/styles.d.ts +102 -0
  129. package/dist/src/formats/cx/styles.d.ts.map +1 -0
  130. package/dist/src/formats/cx/styles.js +225 -0
  131. package/dist/src/formats/cx/styles.js.map +1 -0
  132. package/dist/src/formats/cx2/exporter.d.ts +5 -0
  133. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  134. package/dist/src/formats/cx2/exporter.js +181 -71
  135. package/dist/src/formats/cx2/exporter.js.map +1 -1
  136. package/dist/src/formats/cx2/importer.d.ts +4 -1
  137. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  138. package/dist/src/formats/cx2/importer.js +19 -1
  139. package/dist/src/formats/cx2/importer.js.map +1 -1
  140. package/dist/src/formats/cx2/styles.d.ts +18 -0
  141. package/dist/src/formats/cx2/styles.d.ts.map +1 -0
  142. package/dist/src/formats/cx2/styles.js +24 -0
  143. package/dist/src/formats/cx2/styles.js.map +1 -0
  144. package/dist/src/formats/cys/constants.d.ts +2 -0
  145. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  146. package/dist/src/formats/cys/constants.js +2 -0
  147. package/dist/src/formats/cys/constants.js.map +1 -1
  148. package/dist/src/formats/cys/exporter.d.ts +6 -2
  149. package/dist/src/formats/cys/exporter.d.ts.map +1 -1
  150. package/dist/src/formats/cys/exporter.js +215 -53
  151. package/dist/src/formats/cys/exporter.js.map +1 -1
  152. package/dist/src/formats/cys/importer.d.ts +2 -1
  153. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  154. package/dist/src/formats/cys/importer.js +119 -6
  155. package/dist/src/formats/cys/importer.js.map +1 -1
  156. package/dist/src/formats/cys/session.d.ts +2 -0
  157. package/dist/src/formats/cys/session.d.ts.map +1 -1
  158. package/dist/src/formats/cys/session.js +5 -0
  159. package/dist/src/formats/cys/session.js.map +1 -1
  160. package/dist/src/formats/cys/styles.d.ts +38 -0
  161. package/dist/src/formats/cys/styles.d.ts.map +1 -0
  162. package/dist/src/formats/cys/styles.js +213 -0
  163. package/dist/src/formats/cys/styles.js.map +1 -0
  164. package/dist/src/formats/cys/tables.d.ts +8 -3
  165. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  166. package/dist/src/formats/cys/tables.js +88 -34
  167. package/dist/src/formats/cys/tables.js.map +1 -1
  168. package/dist/src/formats/dot/exporter.d.ts +2 -0
  169. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  170. package/dist/src/formats/dot/exporter.js +195 -81
  171. package/dist/src/formats/dot/exporter.js.map +1 -1
  172. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  173. package/dist/src/formats/dot/importer.js +100 -20
  174. package/dist/src/formats/dot/importer.js.map +1 -1
  175. package/dist/src/formats/dot/index.d.ts +1 -0
  176. package/dist/src/formats/dot/index.d.ts.map +1 -1
  177. package/dist/src/formats/dot/index.js +1 -0
  178. package/dist/src/formats/dot/index.js.map +1 -1
  179. package/dist/src/formats/dot/positions.d.ts +14 -0
  180. package/dist/src/formats/dot/positions.d.ts.map +1 -0
  181. package/dist/src/formats/dot/positions.js +70 -0
  182. package/dist/src/formats/dot/positions.js.map +1 -0
  183. package/dist/src/formats/dot/styles.d.ts +82 -0
  184. package/dist/src/formats/dot/styles.d.ts.map +1 -0
  185. package/dist/src/formats/dot/styles.js +1484 -0
  186. package/dist/src/formats/dot/styles.js.map +1 -0
  187. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  188. package/dist/src/formats/gexf/exporter.js +23 -7
  189. package/dist/src/formats/gexf/exporter.js.map +1 -1
  190. package/dist/src/formats/gexf/importer.d.ts +8 -1
  191. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  192. package/dist/src/formats/gexf/importer.js +251 -131
  193. package/dist/src/formats/gexf/importer.js.map +1 -1
  194. package/dist/src/formats/gexf/index.d.ts +8 -0
  195. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  196. package/dist/src/formats/gexf/index.js +10 -2
  197. package/dist/src/formats/gexf/index.js.map +1 -1
  198. package/dist/src/formats/gexf/schema.d.ts +5 -0
  199. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  200. package/dist/src/formats/gexf/schema.js +5 -0
  201. package/dist/src/formats/gexf/schema.js.map +1 -1
  202. package/dist/src/formats/gexf/styles.d.ts +74 -0
  203. package/dist/src/formats/gexf/styles.d.ts.map +1 -0
  204. package/dist/src/formats/gexf/styles.js +604 -0
  205. package/dist/src/formats/gexf/styles.js.map +1 -0
  206. package/dist/src/formats/gml/exporter.d.ts +1 -5
  207. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  208. package/dist/src/formats/gml/exporter.js +19 -8
  209. package/dist/src/formats/gml/exporter.js.map +1 -1
  210. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  211. package/dist/src/formats/gml/importer.js +4 -0
  212. package/dist/src/formats/gml/importer.js.map +1 -1
  213. package/dist/src/formats/gml/index.d.ts +2 -1
  214. package/dist/src/formats/gml/index.d.ts.map +1 -1
  215. package/dist/src/formats/gml/index.js +2 -1
  216. package/dist/src/formats/gml/index.js.map +1 -1
  217. package/dist/src/formats/gml/positions.d.ts +14 -0
  218. package/dist/src/formats/gml/positions.d.ts.map +1 -0
  219. package/dist/src/formats/gml/positions.js +46 -0
  220. package/dist/src/formats/gml/positions.js.map +1 -0
  221. package/dist/src/formats/gml/styles.d.ts +59 -0
  222. package/dist/src/formats/gml/styles.d.ts.map +1 -0
  223. package/dist/src/formats/gml/styles.js +1056 -0
  224. package/dist/src/formats/gml/styles.js.map +1 -0
  225. package/dist/src/formats/gml/syntax.d.ts +11 -0
  226. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  227. package/dist/src/formats/gml/syntax.js +151 -62
  228. package/dist/src/formats/gml/syntax.js.map +1 -1
  229. package/dist/src/formats/graphml/constants.d.ts +4 -0
  230. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  231. package/dist/src/formats/graphml/constants.js +5 -1
  232. package/dist/src/formats/graphml/constants.js.map +1 -1
  233. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  234. package/dist/src/formats/graphml/exporter.js +133 -65
  235. package/dist/src/formats/graphml/exporter.js.map +1 -1
  236. package/dist/src/formats/graphml/importer.d.ts +4 -1
  237. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  238. package/dist/src/formats/graphml/importer.js +100 -44
  239. package/dist/src/formats/graphml/importer.js.map +1 -1
  240. package/dist/src/formats/graphml/index.d.ts +1 -0
  241. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  242. package/dist/src/formats/graphml/index.js +1 -0
  243. package/dist/src/formats/graphml/index.js.map +1 -1
  244. package/dist/src/formats/graphml/styles-plain.d.ts +19 -0
  245. package/dist/src/formats/graphml/styles-plain.d.ts.map +1 -0
  246. package/dist/src/formats/graphml/styles-plain.js +187 -0
  247. package/dist/src/formats/graphml/styles-plain.js.map +1 -0
  248. package/dist/src/formats/graphml/styles-yed.d.ts +179 -0
  249. package/dist/src/formats/graphml/styles-yed.d.ts.map +1 -0
  250. package/dist/src/formats/graphml/styles-yed.js +1086 -0
  251. package/dist/src/formats/graphml/styles-yed.js.map +1 -0
  252. package/dist/src/formats/graphml/styles-yfiles3.d.ts +19 -0
  253. package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -0
  254. package/dist/src/formats/graphml/styles-yfiles3.js +508 -0
  255. package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -0
  256. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  257. package/dist/src/formats/graphml/tree.js +34 -19
  258. package/dist/src/formats/graphml/tree.js.map +1 -1
  259. package/dist/src/formats/graphml/yfiles.d.ts +16 -2
  260. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  261. package/dist/src/formats/graphml/yfiles.js +83 -12
  262. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  263. package/dist/src/formats/json/exporter.d.ts +5 -0
  264. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  265. package/dist/src/formats/json/exporter.js +68 -25
  266. package/dist/src/formats/json/exporter.js.map +1 -1
  267. package/dist/src/formats/json/importer.d.ts +22 -3
  268. package/dist/src/formats/json/importer.d.ts.map +1 -1
  269. package/dist/src/formats/json/importer.js +441 -265
  270. package/dist/src/formats/json/importer.js.map +1 -1
  271. package/dist/src/formats/json/positions.d.ts +16 -0
  272. package/dist/src/formats/json/positions.d.ts.map +1 -0
  273. package/dist/src/formats/json/positions.js +44 -0
  274. package/dist/src/formats/json/positions.js.map +1 -0
  275. package/dist/src/formats/json/styles.d.ts +102 -0
  276. package/dist/src/formats/json/styles.d.ts.map +1 -0
  277. package/dist/src/formats/json/styles.js +1753 -0
  278. package/dist/src/formats/json/styles.js.map +1 -0
  279. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  280. package/dist/src/formats/neo4j/exporter.js +2 -1
  281. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  282. package/dist/src/formats/pajek/exporter.d.ts +2 -0
  283. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/pajek/exporter.js +142 -76
  285. package/dist/src/formats/pajek/exporter.js.map +1 -1
  286. package/dist/src/formats/pajek/importer.d.ts +4 -0
  287. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  288. package/dist/src/formats/pajek/importer.js +60 -6
  289. package/dist/src/formats/pajek/importer.js.map +1 -1
  290. package/dist/src/formats/pajek/index.d.ts +2 -0
  291. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  292. package/dist/src/formats/pajek/index.js +2 -0
  293. package/dist/src/formats/pajek/index.js.map +1 -1
  294. package/dist/src/formats/pajek/styles.d.ts +50 -0
  295. package/dist/src/formats/pajek/styles.d.ts.map +1 -0
  296. package/dist/src/formats/pajek/styles.js +569 -0
  297. package/dist/src/formats/pajek/styles.js.map +1 -0
  298. package/dist/src/formats/pajek/syntax.d.ts +6 -0
  299. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  300. package/dist/src/formats/pajek/syntax.js +6 -0
  301. package/dist/src/formats/pajek/syntax.js.map +1 -1
  302. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  303. package/dist/src/formats/xgmml/columns.js +34 -9
  304. package/dist/src/formats/xgmml/columns.js.map +1 -1
  305. package/dist/src/formats/xgmml/constants.d.ts +2 -0
  306. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  307. package/dist/src/formats/xgmml/constants.js +3 -1
  308. package/dist/src/formats/xgmml/constants.js.map +1 -1
  309. package/dist/src/formats/xgmml/document.d.ts +12 -8
  310. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  311. package/dist/src/formats/xgmml/document.js +56 -13
  312. package/dist/src/formats/xgmml/document.js.map +1 -1
  313. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  314. package/dist/src/formats/xgmml/emit.js +12 -6
  315. package/dist/src/formats/xgmml/emit.js.map +1 -1
  316. package/dist/src/formats/xgmml/exporter.d.ts +3 -1
  317. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  318. package/dist/src/formats/xgmml/exporter.js +22 -9
  319. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  320. package/dist/src/formats/xgmml/importer.d.ts +2 -1
  321. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  322. package/dist/src/formats/xgmml/importer.js +31 -24
  323. package/dist/src/formats/xgmml/importer.js.map +1 -1
  324. package/dist/src/formats/xgmml/styles.d.ts +104 -0
  325. package/dist/src/formats/xgmml/styles.d.ts.map +1 -0
  326. package/dist/src/formats/xgmml/styles.js +310 -0
  327. package/dist/src/formats/xgmml/styles.js.map +1 -0
  328. package/dist/src/index.d.ts +9 -7
  329. package/dist/src/index.d.ts.map +1 -1
  330. package/dist/src/index.js +7 -7
  331. package/dist/src/index.js.map +1 -1
  332. package/dist/src/positions/codes.d.ts +31 -0
  333. package/dist/src/positions/codes.d.ts.map +1 -0
  334. package/dist/src/positions/codes.js +26 -0
  335. package/dist/src/positions/codes.js.map +1 -0
  336. package/dist/src/positions/convert.d.ts +58 -0
  337. package/dist/src/positions/convert.d.ts.map +1 -0
  338. package/dist/src/positions/convert.js +107 -0
  339. package/dist/src/positions/convert.js.map +1 -0
  340. package/dist/src/positions/extract.d.ts +27 -0
  341. package/dist/src/positions/extract.d.ts.map +1 -0
  342. package/dist/src/positions/extract.js +526 -0
  343. package/dist/src/positions/extract.js.map +1 -0
  344. package/dist/src/positions/index.d.ts +10 -0
  345. package/dist/src/positions/index.d.ts.map +1 -0
  346. package/dist/src/positions/index.js +9 -0
  347. package/dist/src/positions/index.js.map +1 -0
  348. package/dist/src/positions/types.d.ts +208 -0
  349. package/dist/src/positions/types.d.ts.map +1 -0
  350. package/dist/src/positions/types.js +10 -0
  351. package/dist/src/positions/types.js.map +1 -0
  352. package/dist/src/registry.d.ts +30 -0
  353. package/dist/src/registry.d.ts.map +1 -1
  354. package/dist/src/registry.js +130 -9
  355. package/dist/src/registry.js.map +1 -1
  356. package/dist/src/styles/annotations.d.ts +132 -0
  357. package/dist/src/styles/annotations.d.ts.map +1 -0
  358. package/dist/src/styles/annotations.js +320 -0
  359. package/dist/src/styles/annotations.js.map +1 -0
  360. package/dist/src/styles/budget.d.ts +45 -0
  361. package/dist/src/styles/budget.d.ts.map +1 -0
  362. package/dist/src/styles/budget.js +58 -0
  363. package/dist/src/styles/budget.js.map +1 -0
  364. package/dist/src/styles/canon/bends.d.ts +32 -0
  365. package/dist/src/styles/canon/bends.d.ts.map +1 -0
  366. package/dist/src/styles/canon/bends.js +74 -0
  367. package/dist/src/styles/canon/bends.js.map +1 -0
  368. package/dist/src/styles/canon/color-tables.d.ts +22 -0
  369. package/dist/src/styles/canon/color-tables.d.ts.map +1 -0
  370. package/dist/src/styles/canon/color-tables.js +369 -0
  371. package/dist/src/styles/canon/color-tables.js.map +1 -0
  372. package/dist/src/styles/canon/color.d.ts +66 -0
  373. package/dist/src/styles/canon/color.d.ts.map +1 -0
  374. package/dist/src/styles/canon/color.js +548 -0
  375. package/dist/src/styles/canon/color.js.map +1 -0
  376. package/dist/src/styles/canon/enums.d.ts +25 -0
  377. package/dist/src/styles/canon/enums.d.ts.map +1 -0
  378. package/dist/src/styles/canon/enums.js +187 -0
  379. package/dist/src/styles/canon/enums.js.map +1 -0
  380. package/dist/src/styles/canon/graphviz.d.ts +48 -0
  381. package/dist/src/styles/canon/graphviz.d.ts.map +1 -0
  382. package/dist/src/styles/canon/graphviz.js +160 -0
  383. package/dist/src/styles/canon/graphviz.js.map +1 -0
  384. package/dist/src/styles/canon/index.d.ts +13 -0
  385. package/dist/src/styles/canon/index.d.ts.map +1 -0
  386. package/dist/src/styles/canon/index.js +13 -0
  387. package/dist/src/styles/canon/index.js.map +1 -0
  388. package/dist/src/styles/canon/number.d.ts +59 -0
  389. package/dist/src/styles/canon/number.d.ts.map +1 -0
  390. package/dist/src/styles/canon/number.js +142 -0
  391. package/dist/src/styles/canon/number.js.map +1 -0
  392. package/dist/src/styles/canon/site.d.ts +51 -0
  393. package/dist/src/styles/canon/site.d.ts.map +1 -0
  394. package/dist/src/styles/canon/site.js +63 -0
  395. package/dist/src/styles/canon/site.js.map +1 -0
  396. package/dist/src/styles/canon/text.d.ts +61 -0
  397. package/dist/src/styles/canon/text.d.ts.map +1 -0
  398. package/dist/src/styles/canon/text.js +199 -0
  399. package/dist/src/styles/canon/text.js.map +1 -0
  400. package/dist/src/styles/codes.d.ts +95 -0
  401. package/dist/src/styles/codes.d.ts.map +1 -0
  402. package/dist/src/styles/codes.js +97 -0
  403. package/dist/src/styles/codes.js.map +1 -0
  404. package/dist/src/styles/cyjs/cascade.d.ts +134 -0
  405. package/dist/src/styles/cyjs/cascade.d.ts.map +1 -0
  406. package/dist/src/styles/cyjs/cascade.js +2252 -0
  407. package/dist/src/styles/cyjs/cascade.js.map +1 -0
  408. package/dist/src/styles/cyjs/defaults-table.d.ts +25 -0
  409. package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -0
  410. package/dist/src/styles/cyjs/defaults-table.js +76 -0
  411. package/dist/src/styles/cyjs/defaults-table.js.map +1 -0
  412. package/dist/src/styles/cyjs/emit.d.ts +82 -0
  413. package/dist/src/styles/cyjs/emit.d.ts.map +1 -0
  414. package/dist/src/styles/cyjs/emit.js +790 -0
  415. package/dist/src/styles/cyjs/emit.js.map +1 -0
  416. package/dist/src/styles/cyjs/index.d.ts +13 -0
  417. package/dist/src/styles/cyjs/index.d.ts.map +1 -0
  418. package/dist/src/styles/cyjs/index.js +13 -0
  419. package/dist/src/styles/cyjs/index.js.map +1 -0
  420. package/dist/src/styles/cyjs/live.d.ts +46 -0
  421. package/dist/src/styles/cyjs/live.d.ts.map +1 -0
  422. package/dist/src/styles/cyjs/live.js +108 -0
  423. package/dist/src/styles/cyjs/live.js.map +1 -0
  424. package/dist/src/styles/cyjs/mappers.d.ts +147 -0
  425. package/dist/src/styles/cyjs/mappers.d.ts.map +1 -0
  426. package/dist/src/styles/cyjs/mappers.js +744 -0
  427. package/dist/src/styles/cyjs/mappers.js.map +1 -0
  428. package/dist/src/styles/cyjs/selector.d.ts +113 -0
  429. package/dist/src/styles/cyjs/selector.d.ts.map +1 -0
  430. package/dist/src/styles/cyjs/selector.js +611 -0
  431. package/dist/src/styles/cyjs/selector.js.map +1 -0
  432. package/dist/src/styles/cyjs/stylesheet-text.d.ts +37 -0
  433. package/dist/src/styles/cyjs/stylesheet-text.d.ts.map +1 -0
  434. package/dist/src/styles/cyjs/stylesheet-text.js +181 -0
  435. package/dist/src/styles/cyjs/stylesheet-text.js.map +1 -0
  436. package/dist/src/styles/cytoscape/emit.d.ts +125 -0
  437. package/dist/src/styles/cytoscape/emit.d.ts.map +1 -0
  438. package/dist/src/styles/cytoscape/emit.js +1025 -0
  439. package/dist/src/styles/cytoscape/emit.js.map +1 -0
  440. package/dist/src/styles/cytoscape/index.d.ts +10 -0
  441. package/dist/src/styles/cytoscape/index.d.ts.map +1 -0
  442. package/dist/src/styles/cytoscape/index.js +10 -0
  443. package/dist/src/styles/cytoscape/index.js.map +1 -0
  444. package/dist/src/styles/cytoscape/lexicon.d.ts +49 -0
  445. package/dist/src/styles/cytoscape/lexicon.d.ts.map +1 -0
  446. package/dist/src/styles/cytoscape/lexicon.js +603 -0
  447. package/dist/src/styles/cytoscape/lexicon.js.map +1 -0
  448. package/dist/src/styles/cytoscape/mappings.d.ts +171 -0
  449. package/dist/src/styles/cytoscape/mappings.d.ts.map +1 -0
  450. package/dist/src/styles/cytoscape/mappings.js +460 -0
  451. package/dist/src/styles/cytoscape/mappings.js.map +1 -0
  452. package/dist/src/styles/cytoscape/resolve.d.ts +137 -0
  453. package/dist/src/styles/cytoscape/resolve.d.ts.map +1 -0
  454. package/dist/src/styles/cytoscape/resolve.js +381 -0
  455. package/dist/src/styles/cytoscape/resolve.js.map +1 -0
  456. package/dist/src/styles/cytoscape/translate.d.ts +50 -0
  457. package/dist/src/styles/cytoscape/translate.d.ts.map +1 -0
  458. package/dist/src/styles/cytoscape/translate.js +156 -0
  459. package/dist/src/styles/cytoscape/translate.js.map +1 -0
  460. package/dist/src/styles/defaults.d.ts +90 -0
  461. package/dist/src/styles/defaults.d.ts.map +1 -0
  462. package/dist/src/styles/defaults.js +414 -0
  463. package/dist/src/styles/defaults.js.map +1 -0
  464. package/dist/src/styles/index.d.ts +15 -0
  465. package/dist/src/styles/index.d.ts.map +1 -0
  466. package/dist/src/styles/index.js +14 -0
  467. package/dist/src/styles/index.js.map +1 -0
  468. package/dist/src/styles/internal.d.ts +17 -0
  469. package/dist/src/styles/internal.d.ts.map +1 -0
  470. package/dist/src/styles/internal.js +16 -0
  471. package/dist/src/styles/internal.js.map +1 -0
  472. package/dist/src/styles/io/approximations.d.ts +24 -0
  473. package/dist/src/styles/io/approximations.d.ts.map +1 -0
  474. package/dist/src/styles/io/approximations.js +51 -0
  475. package/dist/src/styles/io/approximations.js.map +1 -0
  476. package/dist/src/styles/io/block.d.ts +166 -0
  477. package/dist/src/styles/io/block.d.ts.map +1 -0
  478. package/dist/src/styles/io/block.js +930 -0
  479. package/dist/src/styles/io/block.js.map +1 -0
  480. package/dist/src/styles/io/generic.d.ts +88 -0
  481. package/dist/src/styles/io/generic.d.ts.map +1 -0
  482. package/dist/src/styles/io/generic.js +516 -0
  483. package/dist/src/styles/io/generic.js.map +1 -0
  484. package/dist/src/styles/io/index.d.ts +8 -0
  485. package/dist/src/styles/io/index.d.ts.map +1 -0
  486. package/dist/src/styles/io/index.js +7 -0
  487. package/dist/src/styles/io/index.js.map +1 -0
  488. package/dist/src/styles/io/writer.d.ts +80 -0
  489. package/dist/src/styles/io/writer.d.ts.map +1 -0
  490. package/dist/src/styles/io/writer.js +596 -0
  491. package/dist/src/styles/io/writer.js.map +1 -0
  492. package/dist/src/styles/notes.d.ts +47 -0
  493. package/dist/src/styles/notes.d.ts.map +1 -0
  494. package/dist/src/styles/notes.js +140 -0
  495. package/dist/src/styles/notes.js.map +1 -0
  496. package/dist/src/styles/plan/classes.d.ts +31 -0
  497. package/dist/src/styles/plan/classes.d.ts.map +1 -0
  498. package/dist/src/styles/plan/classes.js +139 -0
  499. package/dist/src/styles/plan/classes.js.map +1 -0
  500. package/dist/src/styles/plan/continuous.d.ts +32 -0
  501. package/dist/src/styles/plan/continuous.d.ts.map +1 -0
  502. package/dist/src/styles/plan/continuous.js +165 -0
  503. package/dist/src/styles/plan/continuous.js.map +1 -0
  504. package/dist/src/styles/plan/discrete.d.ts +39 -0
  505. package/dist/src/styles/plan/discrete.d.ts.map +1 -0
  506. package/dist/src/styles/plan/discrete.js +127 -0
  507. package/dist/src/styles/plan/discrete.js.map +1 -0
  508. package/dist/src/styles/plan/families.d.ts +31 -0
  509. package/dist/src/styles/plan/families.d.ts.map +1 -0
  510. package/dist/src/styles/plan/families.js +95 -0
  511. package/dist/src/styles/plan/families.js.map +1 -0
  512. package/dist/src/styles/plan/features.d.ts +58 -0
  513. package/dist/src/styles/plan/features.d.ts.map +1 -0
  514. package/dist/src/styles/plan/features.js +185 -0
  515. package/dist/src/styles/plan/features.js.map +1 -0
  516. package/dist/src/styles/plan/index.d.ts +7 -0
  517. package/dist/src/styles/plan/index.d.ts.map +1 -0
  518. package/dist/src/styles/plan/index.js +7 -0
  519. package/dist/src/styles/plan/index.js.map +1 -0
  520. package/dist/src/styles/plan/plan.d.ts +71 -0
  521. package/dist/src/styles/plan/plan.d.ts.map +1 -0
  522. package/dist/src/styles/plan/plan.js +893 -0
  523. package/dist/src/styles/plan/plan.js.map +1 -0
  524. package/dist/src/styles/plan/resolve.d.ts +137 -0
  525. package/dist/src/styles/plan/resolve.d.ts.map +1 -0
  526. package/dist/src/styles/plan/resolve.js +587 -0
  527. package/dist/src/styles/plan/resolve.js.map +1 -0
  528. package/dist/src/styles/types.d.ts +702 -0
  529. package/dist/src/styles/types.d.ts.map +1 -0
  530. package/dist/src/styles/types.js +10 -0
  531. package/dist/src/styles/types.js.map +1 -0
  532. package/dist/src/styles/vocabulary.d.ts +41 -0
  533. package/dist/src/styles/vocabulary.d.ts.map +1 -0
  534. package/dist/src/styles/vocabulary.js +140 -0
  535. package/dist/src/styles/vocabulary.js.map +1 -0
  536. package/dist/src/types.d.ts +64 -1
  537. package/dist/src/types.d.ts.map +1 -1
  538. package/dist/src/types.js.map +1 -1
  539. package/dist/styles.d.ts +1 -0
  540. package/dist/styles.js +322 -0
  541. package/dist/styles.js.map +1 -0
  542. package/dist/xgmml.js +5 -4
  543. package/dist/xgmml.js.map +1 -1
  544. package/package.json +13 -2
  545. package/src/common/codes.ts +7 -0
  546. package/src/common/escape.ts +5 -2
  547. package/src/common/export.ts +179 -140
  548. package/src/common/input.ts +8 -4
  549. package/src/common/json-elements.ts +169 -38
  550. package/src/common/notes.ts +94 -0
  551. package/src/common/report.ts +41 -1
  552. package/src/common/units.ts +42 -0
  553. package/src/common/xml.ts +45 -5
  554. package/src/formats/cx/exporter.ts +95 -11
  555. package/src/formats/cx/importer.ts +126 -90
  556. package/src/formats/cx/styles.ts +304 -0
  557. package/src/formats/cx2/exporter.ts +234 -77
  558. package/src/formats/cx2/importer.ts +19 -1
  559. package/src/formats/cx2/styles.ts +29 -0
  560. package/src/formats/cys/constants.ts +3 -0
  561. package/src/formats/cys/exporter.ts +246 -60
  562. package/src/formats/cys/importer.ts +125 -9
  563. package/src/formats/cys/session.ts +6 -0
  564. package/src/formats/cys/styles.ts +254 -0
  565. package/src/formats/cys/tables.ts +117 -48
  566. package/src/formats/dot/exporter.ts +262 -126
  567. package/src/formats/dot/importer.ts +111 -20
  568. package/src/formats/dot/index.ts +1 -0
  569. package/src/formats/dot/positions.ts +77 -0
  570. package/src/formats/dot/styles.ts +1741 -0
  571. package/src/formats/gexf/exporter.ts +30 -13
  572. package/src/formats/gexf/importer.ts +308 -158
  573. package/src/formats/gexf/index.ts +10 -0
  574. package/src/formats/gexf/schema.ts +5 -0
  575. package/src/formats/gexf/styles.ts +719 -0
  576. package/src/formats/gml/exporter.ts +33 -14
  577. package/src/formats/gml/importer.ts +4 -0
  578. package/src/formats/gml/index.ts +2 -1
  579. package/src/formats/gml/positions.ts +52 -0
  580. package/src/formats/gml/styles.ts +1248 -0
  581. package/src/formats/gml/syntax.ts +173 -62
  582. package/src/formats/graphml/constants.ts +5 -0
  583. package/src/formats/graphml/exporter.ts +163 -71
  584. package/src/formats/graphml/importer.ts +119 -45
  585. package/src/formats/graphml/index.ts +1 -0
  586. package/src/formats/graphml/styles-plain.ts +236 -0
  587. package/src/formats/graphml/styles-yed.ts +1221 -0
  588. package/src/formats/graphml/styles-yfiles3.ts +573 -0
  589. package/src/formats/graphml/tree.ts +36 -20
  590. package/src/formats/graphml/yfiles.ts +89 -13
  591. package/src/formats/json/exporter.ts +76 -26
  592. package/src/formats/json/importer.ts +543 -323
  593. package/src/formats/json/positions.ts +50 -0
  594. package/src/formats/json/styles.ts +2082 -0
  595. package/src/formats/neo4j/exporter.ts +2 -1
  596. package/src/formats/pajek/exporter.ts +195 -106
  597. package/src/formats/pajek/importer.ts +78 -9
  598. package/src/formats/pajek/index.ts +2 -0
  599. package/src/formats/pajek/styles.ts +685 -0
  600. package/src/formats/pajek/syntax.ts +7 -0
  601. package/src/formats/xgmml/columns.ts +39 -9
  602. package/src/formats/xgmml/constants.ts +3 -0
  603. package/src/formats/xgmml/document.ts +54 -12
  604. package/src/formats/xgmml/emit.ts +11 -6
  605. package/src/formats/xgmml/exporter.ts +32 -13
  606. package/src/formats/xgmml/importer.ts +43 -29
  607. package/src/formats/xgmml/styles.ts +400 -0
  608. package/src/index.ts +16 -0
  609. package/src/positions/codes.ts +32 -0
  610. package/src/positions/convert.ts +123 -0
  611. package/src/positions/extract.ts +619 -0
  612. package/src/positions/index.ts +23 -0
  613. package/src/positions/types.ts +221 -0
  614. package/src/registry.ts +179 -8
  615. package/src/styles/annotations.ts +478 -0
  616. package/src/styles/budget.ts +60 -0
  617. package/src/styles/canon/bends.ts +84 -0
  618. package/src/styles/canon/color-tables.ts +386 -0
  619. package/src/styles/canon/color.ts +624 -0
  620. package/src/styles/canon/enums.ts +211 -0
  621. package/src/styles/canon/graphviz.ts +189 -0
  622. package/src/styles/canon/index.ts +13 -0
  623. package/src/styles/canon/number.ts +152 -0
  624. package/src/styles/canon/site.ts +87 -0
  625. package/src/styles/canon/text.ts +221 -0
  626. package/src/styles/codes.ts +104 -0
  627. package/src/styles/cyjs/cascade.ts +2670 -0
  628. package/src/styles/cyjs/defaults-table.ts +82 -0
  629. package/src/styles/cyjs/emit.ts +951 -0
  630. package/src/styles/cyjs/index.ts +37 -0
  631. package/src/styles/cyjs/live.ts +147 -0
  632. package/src/styles/cyjs/mappers.ts +879 -0
  633. package/src/styles/cyjs/selector.ts +778 -0
  634. package/src/styles/cyjs/stylesheet-text.ts +214 -0
  635. package/src/styles/cytoscape/emit.ts +1264 -0
  636. package/src/styles/cytoscape/index.ts +40 -0
  637. package/src/styles/cytoscape/lexicon.ts +656 -0
  638. package/src/styles/cytoscape/mappings.ts +603 -0
  639. package/src/styles/cytoscape/resolve.ts +521 -0
  640. package/src/styles/cytoscape/translate.ts +237 -0
  641. package/src/styles/defaults.ts +504 -0
  642. package/src/styles/index.ts +57 -0
  643. package/src/styles/internal.ts +17 -0
  644. package/src/styles/io/approximations.ts +47 -0
  645. package/src/styles/io/block.ts +1138 -0
  646. package/src/styles/io/generic.ts +687 -0
  647. package/src/styles/io/index.ts +18 -0
  648. package/src/styles/io/writer.ts +745 -0
  649. package/src/styles/notes.ts +165 -0
  650. package/src/styles/plan/classes.ts +166 -0
  651. package/src/styles/plan/continuous.ts +218 -0
  652. package/src/styles/plan/discrete.ts +165 -0
  653. package/src/styles/plan/families.ts +115 -0
  654. package/src/styles/plan/features.ts +234 -0
  655. package/src/styles/plan/index.ts +7 -0
  656. package/src/styles/plan/plan.ts +1129 -0
  657. package/src/styles/plan/resolve.ts +685 -0
  658. package/src/styles/types.ts +814 -0
  659. package/src/styles/vocabulary.ts +172 -0
  660. package/src/types.ts +76 -1
  661. package/dist/chunks/constants-fT3E8JYY.js.map +0 -1
  662. package/dist/chunks/escape-B62ZGM_a.js.map +0 -1
  663. package/dist/chunks/export-rKLeGQMo.js.map +0 -1
  664. package/dist/chunks/exporter-8hLNemFk.js.map +0 -1
  665. package/dist/chunks/exporter-BWwEuOPT.js.map +0 -1
  666. package/dist/chunks/exporter-CpRyHZ3H.js.map +0 -1
  667. package/dist/chunks/importer-BbNb7eNg.js.map +0 -1
  668. package/dist/chunks/importer-C98dpSH4.js.map +0 -1
  669. package/dist/chunks/importer-D794XUTe.js.map +0 -1
  670. package/dist/chunks/importer-Dz7tI8Sa.js.map +0 -1
  671. package/dist/chunks/importer-Ht7LNg8L.js.map +0 -1
  672. package/dist/chunks/importer-WrGRZb0N.js.map +0 -1
  673. package/dist/chunks/importer-xZ-3suY1.js.map +0 -1
  674. package/dist/chunks/json-elements-DKSqpNW1.js.map +0 -1
@@ -0,0 +1,573 @@
1
+ /**
2
+ * yFiles 3 styles (yFiles for HTML, yEd Live): the per-element style objects of the `NodeStyle`, `EdgeStyle`,
3
+ * `NodeLabels`, `EdgeLabels` and `NodeGeometry` keys, inline or by reference to the graph's `SharedData`, read into
4
+ * the neutral style vocabulary. References are resolved by value with a depth limit; a reference that is circular
5
+ * or deeper than the limit is one `W_STYLE_REFERENCE_CYCLE` note, never a hang.
6
+ */
7
+
8
+ import type { GraphSnapshot } from "@graphty/graph-format";
9
+
10
+ import { canonColor, colorOpacity } from "../../styles/canon/color.js";
11
+ import { canonEnum } from "../../styles/canon/enums.js";
12
+ import { canonNumber } from "../../styles/canon/number.js";
13
+ import { MAX_STYLE_VALUE_LENGTH, noteAt } from "../../styles/canon/site.js";
14
+ import { canonText } from "../../styles/canon/text.js";
15
+ import { STYLE_ISSUE } from "../../styles/codes.js";
16
+ import type { StyleNotes } from "../../styles/notes.js";
17
+ import { plainCell } from "../../styles/plan/resolve.js";
18
+ import type { StyleDialect, StyleTarget, StyleWorkBudget } from "../../styles/types.js";
19
+ import {
20
+ isTree,
21
+ localOf,
22
+ type PutValue,
23
+ type SiteOf,
24
+ treeAttr,
25
+ treeChild,
26
+ treeChildren,
27
+ treeText,
28
+ valueColumns,
29
+ type YedRead,
30
+ } from "./styles-yed.js";
31
+
32
+ /** How deep a chain of shared references is followed. */
33
+ const MAX_REFERENCE_DEPTH = 16;
34
+
35
+ /** A style object: its element's local name and the element. */
36
+ interface StyleObject {
37
+ readonly tag: string;
38
+ readonly e: unknown;
39
+ }
40
+
41
+ /** `{x:Null}`: a property explicitly set to nothing. */
42
+ const NULL = Symbol("x:Null");
43
+
44
+ /** A property value resolved through references. */
45
+ type Resolved = StyleObject | string | typeof NULL | null;
46
+
47
+ /** A paint: a color in a dialect, `{x:Null}`, or nothing. */
48
+ type Paint = { readonly raw: string; readonly dialect: StyleDialect } | typeof NULL | null;
49
+
50
+ /** A `{y:GraphMLReference key}` markup extension, whatever the prefix. */
51
+ const REFERENCE = /^\{\s*[\w.-]*:?GraphMLReference\s+([^\s}]+)\s*\}$/;
52
+
53
+ /** A `{x:Null}` markup extension. */
54
+ const NULL_MARKUP = /^\{\s*[\w.-]*:?Null\s*\}$/;
55
+
56
+ /** The yFiles key types the reader reads, by the last segment of their `attr.uri`. */
57
+ type KeyKind = "NodeStyle" | "EdgeStyle" | "NodeLabels" | "EdgeLabels" | "NodeGeometry" | "SharedData";
58
+ const KINDS: ReadonlySet<string> = new Set(["NodeStyle", "EdgeStyle", "NodeLabels", "EdgeLabels", "NodeGeometry"]);
59
+
60
+ /**
61
+ * The kind of a yFiles 3 column, from the `attr.uri` the importer keeps as its origin type.
62
+ * @param type - the origin type
63
+ * @returns the kind, or null
64
+ */
65
+ function keyKind(type: string | null | undefined): KeyKind | null {
66
+ if (typeof type !== "string" || !type.includes("://")) {
67
+ return null;
68
+ }
69
+ const last = type.slice(type.lastIndexOf("/") + 1);
70
+ return KINDS.has(last) || last === "SharedData" ? (last as KeyKind) : null;
71
+ }
72
+
73
+ /**
74
+ * The columns of a table by kind.
75
+ * @param table - the table
76
+ * @returns kind to column name
77
+ */
78
+ function columnsByKind(table: GraphSnapshot["nodes"]): Map<KeyKind, string> {
79
+ const out = new Map<KeyKind, string>();
80
+ for (const col of table) {
81
+ const kind =
82
+ col.dtype === "json" && col.meta.origin?.namespace === "yfiles" ? keyKind(col.meta.origin.type) : null;
83
+ if (kind !== null && !out.has(kind)) {
84
+ out.set(kind, col.meta.name);
85
+ }
86
+ }
87
+ return out;
88
+ }
89
+
90
+ /** Resolves references against the graph's shared data, counting the ones it gives up on. */
91
+ class References {
92
+ private readonly shared = new Map<string, StyleObject>();
93
+
94
+ /** The references given up on: circular or deeper than the limit. */
95
+ cycles = 0;
96
+
97
+ /**
98
+ * Collects the shared objects of the graph's `SharedData` value.
99
+ * @param data - the `<data>` content of the SharedData key
100
+ */
101
+ constructor(data: unknown) {
102
+ for (const sd of treeChildren(data, "SharedData")) {
103
+ if (isTree(sd)) {
104
+ this.collect(sd);
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Collects the shared objects of one SharedData element: the first of each key wins.
111
+ * @param sd - the element
112
+ */
113
+ private collect(sd: Record<string, unknown>): void {
114
+ for (const key of Object.keys(sd).filter((k) => !k.startsWith("@_") && k !== "#text")) {
115
+ for (const e of treeChildren(sd, localOf(key))) {
116
+ const name = sharedKey(e);
117
+ if (name !== null && !this.shared.has(name)) {
118
+ this.shared.set(name, { tag: localOf(key), e });
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Whether a walk has gone too deep; counts it once when it has.
126
+ * @param depth - the walk's depth
127
+ * @returns true past the limit
128
+ */
129
+ tooDeep(depth: number): boolean {
130
+ if (depth > MAX_REFERENCE_DEPTH) {
131
+ this.cycles++;
132
+ return true;
133
+ }
134
+ return false;
135
+ }
136
+
137
+ /**
138
+ * A style object, following a `<y:GraphMLReference ResourceKey>` element to what it names.
139
+ * @param tag - the element's local name
140
+ * @param e - the element
141
+ * @returns the object, or null when the reference names nothing
142
+ */
143
+ object(tag: string, e: unknown): StyleObject | null {
144
+ if (tag === "GraphMLReference") {
145
+ return this.shared.get(treeAttr(e, "ResourceKey") ?? "") ?? null;
146
+ }
147
+ return { tag, e };
148
+ }
149
+
150
+ /**
151
+ * The first child element of a property element, as a style object.
152
+ * @param d - the property element (or a `<data>` content)
153
+ * @returns the object, or null
154
+ */
155
+ first(d: unknown): StyleObject | null {
156
+ if (!isTree(d)) {
157
+ return null;
158
+ }
159
+ for (const key of Object.keys(d)) {
160
+ if (!key.startsWith("@_") && key !== "#text") {
161
+ return this.object(localOf(key), treeChildren(d, localOf(key))[0]);
162
+ }
163
+ }
164
+ return null;
165
+ }
166
+
167
+ /**
168
+ * A property value resolved through references: a style object, text, `{x:Null}` or nothing.
169
+ * @param v - an attribute's text or a property element
170
+ * @param depth - the walk's depth
171
+ * @returns the resolved value
172
+ */
173
+ deref(v: unknown, depth = 0): Resolved {
174
+ if (v === undefined || v === null || this.tooDeep(depth)) {
175
+ return null;
176
+ }
177
+ if (typeof v === "object") {
178
+ return this.first(v);
179
+ }
180
+ if (typeof v !== "string") {
181
+ return null;
182
+ }
183
+ const t = v.trim();
184
+ if (t.length > MAX_STYLE_VALUE_LENGTH) {
185
+ return t;
186
+ }
187
+ if (NULL_MARKUP.test(t)) {
188
+ return NULL;
189
+ }
190
+ const m = REFERENCE.exec(t);
191
+ if (m !== null) {
192
+ return this.shared.get(m[1]) ?? null;
193
+ }
194
+ return t;
195
+ }
196
+ }
197
+
198
+ /**
199
+ * The `x:Key` of a shared object.
200
+ * @param e - the element
201
+ * @returns the key, or null
202
+ */
203
+ function sharedKey(e: unknown): string | null {
204
+ if (!isTree(e)) {
205
+ return null;
206
+ }
207
+ for (const key of Object.keys(e)) {
208
+ if (key.startsWith("@_") && localOf(key.slice(2)) === "Key") {
209
+ const value = e[key];
210
+ return typeof value === "string" ? value : null;
211
+ }
212
+ }
213
+ return null;
214
+ }
215
+
216
+ /**
217
+ * A property of a style object: its attribute, or its `<Tag.property>` child element.
218
+ * @param st - the style object
219
+ * @param name - the property name
220
+ * @returns the attribute text, the property element, or undefined
221
+ */
222
+ function prop(st: StyleObject, name: string): unknown {
223
+ const attr = treeAttr(st.e, name);
224
+ if (attr !== undefined) {
225
+ return attr;
226
+ }
227
+ return treeChild(st.e, `${st.tag}.${name}`);
228
+ }
229
+
230
+ /**
231
+ * A paint: a color constant or `#AARRGGBB` in the yFiles 3 dialect, a CSS color, the first stop of a gradient
232
+ * (with a note), or `{x:Null}`.
233
+ * @param refs - the references
234
+ * @param v - the property value
235
+ * @param gradient - called when the paint is a gradient
236
+ * @param depth - the walk's depth
237
+ * @returns the paint
238
+ */
239
+ function paintOf(refs: References, v: unknown, gradient: (() => void) | null, depth = 0): Paint {
240
+ if (refs.tooDeep(depth)) {
241
+ return null;
242
+ }
243
+ const x = refs.deref(v, depth);
244
+ if (x === null || x === NULL) {
245
+ return x;
246
+ }
247
+ if (typeof x === "string") {
248
+ return { raw: x, dialect: "yfiles3" };
249
+ }
250
+ const { tag } = x;
251
+ if (tag === "SolidColorFill") {
252
+ return paintOf(refs, prop(x, "color"), gradient, depth + 1);
253
+ }
254
+ if (tag === "Color") {
255
+ return paintOf(refs, treeAttr(x.e, "value"), gradient, depth + 1);
256
+ }
257
+ if (tag === "CssFill") {
258
+ const css = treeAttr(x.e, "cssString");
259
+ return css === undefined ? null : { raw: css, dialect: "css" };
260
+ }
261
+ if (tag.endsWith("Gradient")) {
262
+ gradient?.();
263
+ const stop =
264
+ treeChildren(x.e, "GradientStop")[0] ??
265
+ treeChildren(treeChild(x.e, `${tag}.GradientStops`), "GradientStop")[0];
266
+ return stop === undefined ? null : paintOf(refs, treeAttr(stop, "color"), null, depth + 1);
267
+ }
268
+ if (tag === "Stroke") {
269
+ return paintOf(refs, prop(x, "fill"), gradient, depth + 1);
270
+ }
271
+ return null;
272
+ }
273
+
274
+ /** A stroke's color, width and line style. */
275
+ interface Stroke {
276
+ readonly color: Paint;
277
+ readonly width: unknown;
278
+ readonly line: string;
279
+ }
280
+
281
+ /** yFiles 3's dash style names. */
282
+ const DASHES: ReadonlyMap<string, string> = new Map([
283
+ ["solid", "solid"],
284
+ ["dash", "dashed"],
285
+ ["dot", "dotted"],
286
+ ["dashdot", "dash-dot"],
287
+ ["dashdotdot", "dash-dot"],
288
+ ]);
289
+
290
+ /**
291
+ * A stroke: a `Stroke` object, a color written as a stroke, or `{x:Null}`.
292
+ * @param refs - the references
293
+ * @param v - the property value
294
+ * @returns the stroke, `{x:Null}`, or null
295
+ */
296
+ function strokeOf(refs: References, v: unknown): Stroke | typeof NULL | null {
297
+ const x = refs.deref(v);
298
+ if (x === null || x === NULL) {
299
+ return x;
300
+ }
301
+ if (typeof x === "string" || x.tag !== "Stroke") {
302
+ return { color: paintOf(refs, v, null), width: 1, line: "solid" };
303
+ }
304
+ let line = "solid";
305
+ const d = refs.deref(prop(x, "dashStyle"), 1);
306
+ if (typeof d === "string") {
307
+ const lower = d.slice(0, MAX_STYLE_VALUE_LENGTH).toLowerCase().replaceAll("_", "");
308
+ line = DASHES.get(lower) ?? `other:${lower}`;
309
+ } else if (d !== null && d !== NULL) {
310
+ // a DashStyle object: two numbers dash or dot, four dash-dot
311
+ const dashes = (treeAttr(d.e, "dashes") ?? "")
312
+ .slice(0, MAX_STYLE_VALUE_LENGTH)
313
+ .trim()
314
+ .split(/[\s,]+/)
315
+ .map(Number)
316
+ .filter(Number.isFinite);
317
+ if (dashes.length === 2) {
318
+ line = dashes[0] <= 1 ? "dotted" : "dashed";
319
+ } else if (dashes.length === 4) {
320
+ line = "dash-dot";
321
+ } else if (dashes.length > 0) {
322
+ line = `other:dashes ${dashes.slice(0, 8).join(" ")}`;
323
+ }
324
+ }
325
+ const w = prop(x, "thickness");
326
+ return { color: paintOf(refs, prop(x, "fill"), null), width: typeof w === "string" ? w : 1, line };
327
+ }
328
+
329
+ /**
330
+ * Writes a paint into a color property, its alpha into the property's opacity where it has one.
331
+ * @param pt - the paint
332
+ * @param property - the color property
333
+ * @param opacity - its opacity property, or null
334
+ * @param put - receives the values
335
+ * @param at - the sites
336
+ */
337
+ function putPaint(pt: Paint, property: string, opacity: string | null, put: PutValue, at: SiteOf): void {
338
+ if (pt === null || pt === NULL) {
339
+ return;
340
+ }
341
+ const c = canonColor(pt.raw, pt.dialect, at(property));
342
+ if (c === null) {
343
+ return;
344
+ }
345
+ put(property, c.color);
346
+ const alpha = colorOpacity(c, null, at(property), opacity !== null);
347
+ if (opacity !== null) {
348
+ put(opacity, alpha);
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Reads a node style.
354
+ * @param refs - the references
355
+ * @param data - the `<data>` content of the NodeStyle key
356
+ * @param put - receives the values
357
+ * @param at - the sites
358
+ */
359
+ function readNodeStyle(refs: References, data: unknown, put: PutValue, at: SiteOf): void {
360
+ const st = unwrapped(refs, refs.first(data));
361
+ if (st === null || typeof st !== "object") {
362
+ if (data !== null && data !== undefined && data !== "") {
363
+ noteAt(at("fill"), STYLE_ISSUE.UNRESOLVED, "NodeStyle");
364
+ }
365
+ return;
366
+ }
367
+ const style = st;
368
+ putPaint(
369
+ paintOf(refs, prop(style, "fill"), () => {
370
+ noteAt(at("fill"), STYLE_ISSUE.GRADIENT, style.tag);
371
+ }),
372
+ "fill",
373
+ "fillOpacity",
374
+ put,
375
+ at,
376
+ );
377
+ const stroke = strokeOf(refs, prop(style, "stroke"));
378
+ if (stroke === NULL) {
379
+ put("borderWidth", 0);
380
+ } else if (stroke !== null) {
381
+ putPaint(stroke.color, "borderColor", null, put, at);
382
+ put("borderWidth", canonNumber(stroke.width, at("borderWidth")));
383
+ put("borderStyle", canonEnum("borderStyle", stroke.line, "yfiles3", at("borderStyle")));
384
+ }
385
+ put("shape", nodeShapeOf(style, at));
386
+ const cornerSize = style.tag === "RectangleNodeStyle" ? treeAttr(style.e, "cornerSize") : undefined;
387
+ if (cornerSize !== undefined) {
388
+ put("cornerRadius", canonNumber(cornerSize, at("cornerRadius")));
389
+ }
390
+ }
391
+
392
+ /**
393
+ * The style a collapsible group's decorators wrap; a decorator that wraps itself is a cycle.
394
+ * @param refs - the references
395
+ * @param first - the node's style
396
+ * @returns the style that draws the node, or null for a cycle
397
+ */
398
+ function unwrapped(refs: References, first: Resolved): Resolved {
399
+ let st = first;
400
+ const seen = new Set<unknown>();
401
+ while (st !== null && typeof st === "object" && st.tag === "CollapsibleNodeStyleDecorator") {
402
+ if (seen.has(st.e) || refs.tooDeep(seen.size)) {
403
+ refs.cycles++;
404
+ return null;
405
+ }
406
+ seen.add(st.e);
407
+ st = refs.deref(prop(st, "wrappedStyle"));
408
+ }
409
+ return st;
410
+ }
411
+
412
+ /**
413
+ * A node style's shape: its `shape`, else what its kind draws.
414
+ * @param style - the style
415
+ * @param at - the sites
416
+ * @returns the shape, or null when it does not parse
417
+ */
418
+ function nodeShapeOf(style: StyleObject, at: SiteOf): string | null {
419
+ const shape = treeAttr(style.e, "shape");
420
+ if (shape !== undefined) {
421
+ return canonEnum("shape", shape, "yfiles3", at("shape"));
422
+ }
423
+ if (style.tag === "RectangleNodeStyle") {
424
+ return treeAttr(style.e, "cornerSize") === undefined ? "rectangle" : "round-rectangle";
425
+ }
426
+ if (style.tag === "ShapeNodeStyle") {
427
+ return "rectangle";
428
+ }
429
+ noteAt(at("shape"), STYLE_ISSUE.UNKNOWN_VALUE, style.tag);
430
+ return `other:${style.tag}`;
431
+ }
432
+
433
+ /**
434
+ * Reads an edge style.
435
+ * @param refs - the references
436
+ * @param data - the `<data>` content of the EdgeStyle key
437
+ * @param put - receives the values
438
+ * @param at - the sites
439
+ */
440
+ function readEdgeStyle(refs: References, data: unknown, put: PutValue, at: SiteOf): void {
441
+ const st = refs.first(data);
442
+ if (st === null) {
443
+ return;
444
+ }
445
+ const stroke = strokeOf(refs, prop(st, "stroke"));
446
+ if (stroke === NULL) {
447
+ noteAt(at("color"), STYLE_ISSUE.NO_STROKE, "{x:Null}");
448
+ } else if (stroke !== null) {
449
+ putPaint(stroke.color, "color", "opacity", put, at);
450
+ put("width", canonNumber(stroke.width, at("width")));
451
+ put("lineStyle", canonEnum("lineStyle", stroke.line, "yfiles3", at("lineStyle")));
452
+ }
453
+ for (const end of ["source", "target"] as const) {
454
+ const a = refs.deref(prop(st, `${end}Arrow`));
455
+ const property = `${end}Arrow`;
456
+ let type: string | null = null;
457
+ if (a !== null && a !== NULL && typeof a === "object") {
458
+ type = treeAttr(a.e, "type") ?? "DEFAULT";
459
+ putPaint(paintOf(refs, prop(a, "fill"), null), `${end}ArrowColor`, null, put, at);
460
+ } else if (typeof a === "string") {
461
+ type = a;
462
+ }
463
+ if (type !== null) {
464
+ put(property, canonEnum("arrow", /^default$/i.test(type) ? "triangle" : type, "yfiles3", at(property)));
465
+ }
466
+ }
467
+ }
468
+
469
+ /**
470
+ * Reads an element's labels: the first one with text; further ones are noted for the element.
471
+ * @param refs - the references
472
+ * @param data - the `<data>` content of the NodeLabels or EdgeLabels key
473
+ * @param put - receives the values
474
+ * @param at - the sites
475
+ */
476
+ function readLabels(refs: References, data: unknown, put: PutValue, at: SiteOf): void {
477
+ let label: unknown = undefined;
478
+ let text = "";
479
+ let extra = 0;
480
+ for (const l of treeChildren(treeChild(data, "List"), "Label")) {
481
+ const raw = treeAttr(l, "Text") ?? treeText(treeChild(l, "Label.Text")) ?? "";
482
+ if (raw.trim().length === 0) {
483
+ continue;
484
+ }
485
+ if (label === undefined) {
486
+ label = l;
487
+ text = raw;
488
+ } else {
489
+ extra++;
490
+ }
491
+ }
492
+ if (label === undefined) {
493
+ return;
494
+ }
495
+ if (extra > 0) {
496
+ noteAt(at("label"), STYLE_ISSUE.EXTRA_LABELS, `${String(extra + 1)} labels`);
497
+ }
498
+ put("label", canonText(text, at("label")));
499
+ const ls = refs.deref(treeAttr(label, "Style") ?? treeChild(label, "Label.Style"));
500
+ if (ls === null || ls === NULL || typeof ls !== "object" || !ls.tag.endsWith("LabelStyle")) {
501
+ return;
502
+ }
503
+ putPaint(paintOf(refs, prop(ls, "textFill"), null), "labelColor", null, put, at);
504
+ const f = refs.deref(prop(ls, "font"));
505
+ if (f !== null && f !== NULL && typeof f === "object" && f.tag === "Font") {
506
+ put("labelSize", canonNumber(treeAttr(f.e, "fontSize"), at("labelSize")));
507
+ const family = treeAttr(f.e, "fontFamily");
508
+ if (family !== undefined) {
509
+ put("labelFont", canonText(family.replaceAll(/(^['"])|(['"]$)/g, ""), at("labelFont")));
510
+ }
511
+ const weight = treeAttr(f.e, "fontWeight");
512
+ if (weight !== undefined) {
513
+ put("labelWeight", canonEnum("weight", weight, "yfiles3", at("labelWeight")));
514
+ }
515
+ }
516
+ }
517
+
518
+ /**
519
+ * The yFiles 3 styles of a graph.
520
+ * @param snapshot - the graph
521
+ * @param notes - where problems are noted
522
+ * @param budget - the work budget
523
+ * @returns the values, or null when the graph has none of yFiles 3's style keys
524
+ */
525
+ export function readYfiles3Styles(snapshot: GraphSnapshot, notes: StyleNotes, budget: StyleWorkBudget): YedRead | null {
526
+ const nodeKinds = columnsByKind(snapshot.nodes);
527
+ const edgeKinds = columnsByKind(snapshot.edges);
528
+ const styled = [...nodeKinds.keys(), ...edgeKinds.keys()].some((k) => k !== "SharedData");
529
+ if (!styled) {
530
+ return null;
531
+ }
532
+ const graphKinds = columnsByKind(snapshot.graph);
533
+ const sharedName = graphKinds.get("SharedData");
534
+ const refs = new References(sharedName === undefined ? null : plainCell(snapshot.graph.value(sharedName, 0)));
535
+ const read = (target: StyleTarget, kinds: Map<KeyKind, string>): ReturnType<typeof valueColumns>["values"] => {
536
+ const table = target === "node" ? snapshot.nodes : snapshot.edges;
537
+ const n = target === "node" ? snapshot.nodeCount : snapshot.edgeCount;
538
+ const out = valueColumns(n);
539
+ const style = kinds.get(target === "node" ? "NodeStyle" : "EdgeStyle");
540
+ const labels = kinds.get(target === "node" ? "NodeLabels" : "EdgeLabels");
541
+ const geometry = target === "node" ? kinds.get("NodeGeometry") : undefined;
542
+ const readStyle = target === "node" ? readNodeStyle : readEdgeStyle;
543
+ const cell = (name: string | undefined, i: number): unknown =>
544
+ name === undefined ? undefined : plainCell(table.value(name, i));
545
+ for (let i = 0; i < n; i++) {
546
+ budget.spend(target, 1);
547
+ const at: SiteOf = (property) => ({ notes, target, property, element: i, budget });
548
+ const put: PutValue = (property, value) => {
549
+ out.put(i, property, value);
550
+ };
551
+ if (style !== undefined) {
552
+ readStyle(refs, cell(style, i), put, at);
553
+ }
554
+ if (labels !== undefined) {
555
+ readLabels(refs, cell(labels, i), put, at);
556
+ }
557
+ if (geometry !== undefined) {
558
+ const rect = treeChild(cell(geometry, i), "RectD");
559
+ put("width", canonNumber(treeAttr(rect, "Width"), at("width")));
560
+ put("height", canonNumber(treeAttr(rect, "Height"), at("height")));
561
+ }
562
+ }
563
+ return out.values;
564
+ };
565
+ const node = read("node", nodeKinds);
566
+ const edge = read("edge", edgeKinds);
567
+ if (refs.cycles > 0) {
568
+ notes.add(STYLE_ISSUE.REFERENCE_CYCLE, null, null, {
569
+ sample: `references deeper than ${String(MAX_REFERENCE_DEPTH)} or circular (${String(refs.cycles)})`,
570
+ });
571
+ }
572
+ return { node, edge };
573
+ }
@@ -141,9 +141,10 @@ function valueOf(frame: Frame): unknown {
141
141
  */
142
142
  function attachChild(parent: Frame, name: string, value: unknown): void {
143
143
  parent.hasChildren = true;
144
- const existing = parent.node[name];
144
+ // own keys only: an element named `__proto__` is a child like any other, never the object's prototype
145
+ const existing = Object.hasOwn(parent.node, name) ? parent.node[name] : undefined;
145
146
  if (existing === undefined) {
146
- parent.node[name] = value;
147
+ Object.defineProperty(parent.node, name, { value, writable: true, enumerable: true, configurable: true });
147
148
  } else if (Array.isArray(existing)) {
148
149
  existing.push(value);
149
150
  } else {
@@ -251,53 +252,68 @@ export function writeXmlTree(value: unknown, indent: string, out: string[]): voi
251
252
  }
252
253
 
253
254
  /**
254
- * Write one element (or, for an array, one element per item).
255
+ * Write one element (or, for an array, one element per item). An element holding text beside child elements (a yEd
256
+ * label: its text, then its label model) is written without any whitespace of its own inside it, so the text reads
257
+ * back exactly as it was.
255
258
  * @param name - the element name
256
259
  * @param value - the element value
257
- * @param indent - the indentation of this element
260
+ * @param indent - the indentation of this element, or null to write it with no line break or indentation
258
261
  * @param out - receives the text parts
259
262
  */
260
- function writeElements(name: string, value: unknown, indent: string, out: string[]): void {
263
+ function writeElements(name: string, value: unknown, indent: string | null, out: string[]): void {
261
264
  if (Array.isArray(value)) {
262
265
  for (const item of value) {
263
266
  writeElements(name, item, indent, out);
264
267
  }
265
268
  return;
266
269
  }
270
+ const brk = indent === null ? "" : `\n${indent}`;
267
271
  if (value === null || typeof value !== "object") {
268
272
  const text = scalarText(value);
269
- out.push(text.length === 0 ? `\n${indent}<${name}/>` : `\n${indent}<${name}>${escapeXmlText(text)}</${name}>`);
273
+ out.push(text.length === 0 ? `${brk}<${name}/>` : `${brk}<${name}>${escapeXmlText(text)}</${name}>`);
270
274
  return;
271
275
  }
272
- const object = value as XmlTreeObject;
273
- const { attrs, text, hasChildren } = scanElement(object);
276
+ writeObjectElement(name, value as XmlTreeObject, indent, out);
277
+ }
278
+
279
+ /**
280
+ * Write one element whose value is a tree object: its attributes, its text and its children.
281
+ * @param name - the element name
282
+ * @param object - the element value
283
+ * @param indent - the indentation of this element, or null to write it with no line break or indentation
284
+ * @param out - receives the text parts
285
+ */
286
+ function writeObjectElement(name: string, object: XmlTreeObject, indent: string | null, out: string[]): void {
287
+ const brk = indent === null ? "" : `\n${indent}`;
288
+ const { attrs, text, hasChildren } = elementParts(object);
274
289
  if (!hasChildren) {
275
290
  out.push(
276
291
  text === null || text.length === 0
277
- ? `\n${indent}<${name}${attrs}/>`
278
- : `\n${indent}<${name}${attrs}>${escapeXmlText(text)}</${name}>`,
292
+ ? `${brk}<${name}${attrs}/>`
293
+ : `${brk}<${name}${attrs}>${escapeXmlText(text)}</${name}>`,
279
294
  );
280
295
  return;
281
296
  }
282
- out.push(`\n${indent}<${name}${attrs}>`);
283
- const inner = `${indent} `;
297
+ // mixed content: the text first and the children with no whitespace, so none is added to the text
298
+ const inner = indent === null || text !== null ? null : `${indent} `;
299
+ out.push(`${brk}<${name}${attrs}>`);
300
+ if (text !== null) {
301
+ out.push(escapeXmlText(text));
302
+ }
284
303
  for (const [key, child] of Object.entries(object)) {
285
304
  if (key !== TEXT_KEY && !key.startsWith(ATTRIBUTE_PREFIX)) {
286
305
  writeElements(key, child, inner, out);
287
306
  }
288
307
  }
289
- if (text !== null) {
290
- out.push(escapeXmlText(text));
291
- }
292
- out.push(`\n${indent}</${name}>`);
308
+ out.push(inner === null ? `</${name}>` : `${brk}</${name}>`);
293
309
  }
294
310
 
295
311
  /**
296
- * Split an element object into its attribute text, its text content and whether it has children.
297
- * @param object - the element object
298
- * @returns the attribute text, the text content (null when absent) and the children flag
312
+ * What a tree object holds besides its children: its attributes as text and its text.
313
+ * @param object - the object
314
+ * @returns the attribute text, the text (null for none) and whether it has child elements
299
315
  */
300
- function scanElement(object: XmlTreeObject): { attrs: string; text: string | null; hasChildren: boolean } {
316
+ function elementParts(object: XmlTreeObject): { attrs: string; text: string | null; hasChildren: boolean } {
301
317
  let attrs = "";
302
318
  let text: string | null = null;
303
319
  let hasChildren = false;