@graphty/graph-io 0.3.40 → 0.3.42

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 (210) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/{children-CL3Cy0ez.js → children-CA4coBi0.js} +36 -27
  3. package/dist/chunks/children-CA4coBi0.js.map +1 -0
  4. package/dist/chunks/{choose-CS3fvGT1.js → choose-DvpbdRuz.js} +2 -2
  5. package/dist/chunks/{choose-CS3fvGT1.js.map → choose-DvpbdRuz.js.map} +1 -1
  6. package/dist/chunks/{constants-DqKZT6cH.js → constants-fT3E8JYY.js} +2 -2
  7. package/dist/chunks/{constants-DqKZT6cH.js.map → constants-fT3E8JYY.js.map} +1 -1
  8. package/dist/chunks/{escape-BJRLd3vJ.js → escape-B62ZGM_a.js} +2 -2
  9. package/dist/chunks/{escape-BJRLd3vJ.js.map → escape-B62ZGM_a.js.map} +1 -1
  10. package/dist/chunks/{export-B-aVCwyG.js → export-rKLeGQMo.js} +404 -243
  11. package/dist/chunks/export-rKLeGQMo.js.map +1 -0
  12. package/dist/chunks/{exporter-6ocL_9x_.js → exporter-8hLNemFk.js} +4 -4
  13. package/dist/chunks/{exporter-6ocL_9x_.js.map → exporter-8hLNemFk.js.map} +1 -1
  14. package/dist/chunks/{exporter-BVXnV9-9.js → exporter-BWwEuOPT.js} +29 -17
  15. package/dist/chunks/exporter-BWwEuOPT.js.map +1 -0
  16. package/dist/chunks/{exporter-Bcp-l4Bo.js → exporter-CpRyHZ3H.js} +574 -475
  17. package/dist/chunks/exporter-CpRyHZ3H.js.map +1 -0
  18. package/dist/chunks/{exporter-SFYkDzD0.js → exporter-yLxKBvLE.js} +23 -20
  19. package/dist/chunks/{exporter-SFYkDzD0.js.map → exporter-yLxKBvLE.js.map} +1 -1
  20. package/dist/chunks/{importer-DcKB97kW.js → importer-BbNb7eNg.js} +111 -71
  21. package/dist/chunks/importer-BbNb7eNg.js.map +1 -0
  22. package/dist/chunks/{importer-D_srHyj6.js → importer-C98dpSH4.js} +5 -5
  23. package/dist/chunks/{importer-D_srHyj6.js.map → importer-C98dpSH4.js.map} +1 -1
  24. package/dist/chunks/{importer-BJlGAOht.js → importer-D794XUTe.js} +3 -3
  25. package/dist/chunks/{importer-BJlGAOht.js.map → importer-D794XUTe.js.map} +1 -1
  26. package/dist/chunks/{importer-AjwOJrn2.js → importer-Dz7tI8Sa.js} +202 -181
  27. package/dist/chunks/importer-Dz7tI8Sa.js.map +1 -0
  28. package/dist/chunks/{importer-DEp_fYjf.js → importer-Ht7LNg8L.js} +92 -64
  29. package/dist/chunks/importer-Ht7LNg8L.js.map +1 -0
  30. package/dist/chunks/{importer-CPqnIY8m.js → importer-WrGRZb0N.js} +42 -29
  31. package/dist/chunks/importer-WrGRZb0N.js.map +1 -0
  32. package/dist/chunks/{importer-BpuS3J8C.js → importer-xZ-3suY1.js} +74 -61
  33. package/dist/chunks/importer-xZ-3suY1.js.map +1 -0
  34. package/dist/chunks/{json-elements-DpO6AXIc.js → json-elements-DKSqpNW1.js} +3 -3
  35. package/dist/chunks/{json-elements-DpO6AXIc.js.map → json-elements-DKSqpNW1.js.map} +1 -1
  36. package/dist/chunks/{ontology-export-50L9DOV4.js → ontology-export-CtRXjg_i.js} +2 -2
  37. package/dist/chunks/{ontology-export-50L9DOV4.js.map → ontology-export-CtRXjg_i.js.map} +1 -1
  38. package/dist/chunks/{records-r3SFHz11.js → records-Cu4bxYOm.js} +69 -36
  39. package/dist/chunks/records-Cu4bxYOm.js.map +1 -0
  40. package/dist/chunks/{text-Bjfa1xYL.js → text-DHOJXnED.js} +20 -11
  41. package/dist/chunks/text-DHOJXnED.js.map +1 -0
  42. package/dist/csv.js +323 -241
  43. package/dist/csv.js.map +1 -1
  44. package/dist/cx.js +1 -1
  45. package/dist/cx2.js +2 -2
  46. package/dist/cys.js +1 -1
  47. package/dist/dot.js +1 -1
  48. package/dist/gexf.js +195 -97
  49. package/dist/gexf.js.map +1 -1
  50. package/dist/gml.js +170 -149
  51. package/dist/gml.js.map +1 -1
  52. package/dist/graph-io.js +27 -27
  53. package/dist/graphml.js +2 -2
  54. package/dist/json.js +1 -1
  55. package/dist/neo4j.js +103 -65
  56. package/dist/neo4j.js.map +1 -1
  57. package/dist/obo.js +1 -1
  58. package/dist/pajek.js +1 -1
  59. package/dist/src/children.d.ts.map +1 -1
  60. package/dist/src/children.js +50 -27
  61. package/dist/src/children.js.map +1 -1
  62. package/dist/src/common/attributes.d.ts.map +1 -1
  63. package/dist/src/common/attributes.js +86 -42
  64. package/dist/src/common/attributes.js.map +1 -1
  65. package/dist/src/common/input.d.ts.map +1 -1
  66. package/dist/src/common/input.js +358 -184
  67. package/dist/src/common/input.js.map +1 -1
  68. package/dist/src/common/lists.js +30 -15
  69. package/dist/src/common/lists.js.map +1 -1
  70. package/dist/src/common/text.d.ts +7 -0
  71. package/dist/src/common/text.d.ts.map +1 -1
  72. package/dist/src/common/text.js +15 -7
  73. package/dist/src/common/text.js.map +1 -1
  74. package/dist/src/common/zip.d.ts.map +1 -1
  75. package/dist/src/common/zip.js +36 -19
  76. package/dist/src/common/zip.js.map +1 -1
  77. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  78. package/dist/src/formats/csv/exporter.js +288 -146
  79. package/dist/src/formats/csv/exporter.js.map +1 -1
  80. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  81. package/dist/src/formats/csv/importer.js +129 -80
  82. package/dist/src/formats/csv/importer.js.map +1 -1
  83. package/dist/src/formats/csv/records.d.ts.map +1 -1
  84. package/dist/src/formats/csv/records.js +78 -36
  85. package/dist/src/formats/csv/records.js.map +1 -1
  86. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  87. package/dist/src/formats/cys/tables.js +11 -8
  88. package/dist/src/formats/cys/tables.js.map +1 -1
  89. package/dist/src/formats/dot/tokenizer.d.ts +39 -0
  90. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  91. package/dist/src/formats/dot/tokenizer.js +112 -66
  92. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  93. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  94. package/dist/src/formats/gexf/exporter.js +65 -37
  95. package/dist/src/formats/gexf/exporter.js.map +1 -1
  96. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  97. package/dist/src/formats/gexf/importer.js +138 -50
  98. package/dist/src/formats/gexf/importer.js.map +1 -1
  99. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  100. package/dist/src/formats/gml/exporter.js +51 -35
  101. package/dist/src/formats/gml/exporter.js.map +1 -1
  102. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  103. package/dist/src/formats/gml/importer.js +103 -58
  104. package/dist/src/formats/gml/importer.js.map +1 -1
  105. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  106. package/dist/src/formats/gml/syntax.js +17 -8
  107. package/dist/src/formats/gml/syntax.js.map +1 -1
  108. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  109. package/dist/src/formats/graphml/exporter.js +34 -24
  110. package/dist/src/formats/graphml/exporter.js.map +1 -1
  111. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  112. package/dist/src/formats/graphml/importer.js +17 -13
  113. package/dist/src/formats/graphml/importer.js.map +1 -1
  114. package/dist/src/formats/graphml/tree.js +23 -14
  115. package/dist/src/formats/graphml/tree.js.map +1 -1
  116. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  117. package/dist/src/formats/graphml/yfiles.js +22 -10
  118. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  119. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  120. package/dist/src/formats/json/dialect.js +54 -20
  121. package/dist/src/formats/json/dialect.js.map +1 -1
  122. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  123. package/dist/src/formats/json/exporter.js +38 -21
  124. package/dist/src/formats/json/exporter.js.map +1 -1
  125. package/dist/src/formats/json/importer.d.ts.map +1 -1
  126. package/dist/src/formats/json/importer.js +536 -343
  127. package/dist/src/formats/json/importer.js.map +1 -1
  128. package/dist/src/formats/json/obographs.js +29 -17
  129. package/dist/src/formats/json/obographs.js.map +1 -1
  130. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  131. package/dist/src/formats/neo4j/exporter.js +73 -43
  132. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  133. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  134. package/dist/src/formats/neo4j/header.js +37 -16
  135. package/dist/src/formats/neo4j/header.js.map +1 -1
  136. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  137. package/dist/src/formats/neo4j/importer.js +21 -11
  138. package/dist/src/formats/neo4j/importer.js.map +1 -1
  139. package/dist/src/formats/obo/exporter.d.ts.map +1 -1
  140. package/dist/src/formats/obo/exporter.js +18 -7
  141. package/dist/src/formats/obo/exporter.js.map +1 -1
  142. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  143. package/dist/src/formats/pajek/exporter.js +142 -73
  144. package/dist/src/formats/pajek/exporter.js.map +1 -1
  145. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  146. package/dist/src/formats/pajek/importer.js +26 -15
  147. package/dist/src/formats/pajek/importer.js.map +1 -1
  148. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  149. package/dist/src/formats/pajek/syntax.js +85 -58
  150. package/dist/src/formats/pajek/syntax.js.map +1 -1
  151. package/dist/src/formats/xgmml/emit.d.ts +7 -0
  152. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  153. package/dist/src/formats/xgmml/emit.js +79 -40
  154. package/dist/src/formats/xgmml/emit.js.map +1 -1
  155. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  156. package/dist/src/formats/xgmml/exporter.js +38 -12
  157. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  158. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  159. package/dist/src/formats/xgmml/importer.js +38 -18
  160. package/dist/src/formats/xgmml/importer.js.map +1 -1
  161. package/dist/src/sniff.js +109 -57
  162. package/dist/src/sniff.js.map +1 -1
  163. package/dist/xgmml.js +2 -2
  164. package/package.json +2 -2
  165. package/src/children.ts +54 -27
  166. package/src/common/attributes.ts +118 -49
  167. package/src/common/input.ts +439 -197
  168. package/src/common/lists.ts +29 -15
  169. package/src/common/text.ts +24 -15
  170. package/src/common/zip.ts +47 -18
  171. package/src/formats/csv/exporter.ts +377 -175
  172. package/src/formats/csv/importer.ts +155 -84
  173. package/src/formats/csv/records.ts +90 -35
  174. package/src/formats/cys/tables.ts +11 -10
  175. package/src/formats/dot/tokenizer.ts +118 -68
  176. package/src/formats/gexf/exporter.ts +67 -36
  177. package/src/formats/gexf/importer.ts +173 -63
  178. package/src/formats/gml/exporter.ts +78 -82
  179. package/src/formats/gml/importer.ts +119 -68
  180. package/src/formats/gml/syntax.ts +18 -8
  181. package/src/formats/graphml/exporter.ts +44 -24
  182. package/src/formats/graphml/importer.ts +18 -11
  183. package/src/formats/graphml/tree.ts +22 -12
  184. package/src/formats/graphml/yfiles.ts +23 -10
  185. package/src/formats/json/dialect.ts +61 -22
  186. package/src/formats/json/exporter.ts +40 -21
  187. package/src/formats/json/importer.ts +701 -385
  188. package/src/formats/json/obographs.ts +35 -15
  189. package/src/formats/neo4j/exporter.ts +79 -41
  190. package/src/formats/neo4j/header.ts +50 -16
  191. package/src/formats/neo4j/importer.ts +21 -10
  192. package/src/formats/obo/exporter.ts +34 -17
  193. package/src/formats/pajek/exporter.ts +180 -117
  194. package/src/formats/pajek/importer.ts +27 -15
  195. package/src/formats/pajek/syntax.ts +99 -58
  196. package/src/formats/xgmml/emit.ts +88 -40
  197. package/src/formats/xgmml/exporter.ts +40 -12
  198. package/src/formats/xgmml/importer.ts +45 -23
  199. package/src/sniff.ts +115 -59
  200. package/dist/chunks/children-CL3Cy0ez.js.map +0 -1
  201. package/dist/chunks/export-B-aVCwyG.js.map +0 -1
  202. package/dist/chunks/exporter-BVXnV9-9.js.map +0 -1
  203. package/dist/chunks/exporter-Bcp-l4Bo.js.map +0 -1
  204. package/dist/chunks/importer-AjwOJrn2.js.map +0 -1
  205. package/dist/chunks/importer-BpuS3J8C.js.map +0 -1
  206. package/dist/chunks/importer-CPqnIY8m.js.map +0 -1
  207. package/dist/chunks/importer-DEp_fYjf.js.map +0 -1
  208. package/dist/chunks/importer-DcKB97kW.js.map +0 -1
  209. package/dist/chunks/records-r3SFHz11.js.map +0 -1
  210. package/dist/chunks/text-Bjfa1xYL.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
- import { L as LOSS, r as resolveExportOptions, aE as sanitizeIds, a as checkCapabilities, p as pairFolding, b as plural, $ as agree, c as capabilities, a9 as idText, e as explicitWeights, av as formatNumber, aF as formatDecimal, aa as formatF32, aG as formatInteger, aH as canonicalId, P as PRECISION_CODE, o as DUPLICATE_ATTRIBUTE_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, R as ROLE_TAKEN_CODE, ay as RENAMED_CODE, I as ID_MERGED_CODE, n as DUPLICATE_NODE_CODE, ak as SYNTAX_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, an as reportUnusedOptions, az as LineReader, am as throwIfAborted, ap as graphChosen, ao as reportSinkOptions, aq as DirectionResolver, ar as IdCoercer, a0 as uniqueColumnName, a1 as declareResolved, aI as coerceIdText, aJ as isWeightField, aK as parseWeightText } from "./export-B-aVCwyG.js";
3
- import { i as isPajekLabel, q as quotePajekLabel } from "./escape-BJRLd3vJ.js";
4
- import { i as inferTextDtype, W as WIDENING_UNSUPPORTED_CODE, a as isNumericText, T as TextCellWriter } from "./text-Bjfa1xYL.js";
2
+ import { L as LOSS, r as resolveExportOptions, aE as sanitizeIds, a as checkCapabilities, p as pairFolding, b as plural, $ as agree, c as capabilities, a9 as idText, e as explicitWeights, av as formatNumber, aF as formatDecimal, aa as formatF32, aG as formatInteger, aH as canonicalId, P as PRECISION_CODE, o as DUPLICATE_ATTRIBUTE_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, R as ROLE_TAKEN_CODE, ay as RENAMED_CODE, I as ID_MERGED_CODE, n as DUPLICATE_NODE_CODE, ak as SYNTAX_CODE, ae as AMBIGUOUS_GRAPH_NAME_CODE, af as GRAPH_NOT_FOUND_CODE, l as MULTIPLE_GRAPHS_CODE, w as UNKNOWN_ENCODING_CODE, x as ENCODING_FALLBACK_CODE, y as INVALID_ENCODING_CODE, z as INVALID_UTF8_CODE, F as ELEMENT_ISSUE, G as INPUT_ISSUE, al as resolveImportOptions, a8 as ImportReportBuilder, an as reportUnusedOptions, az as LineReader, am as throwIfAborted, ap as graphChosen, ao as reportSinkOptions, aq as DirectionResolver, ar as IdCoercer, a0 as uniqueColumnName, a1 as declareResolved, aI as coerceIdText, aJ as isWeightField, aK as parseWeightText } from "./export-rKLeGQMo.js";
3
+ import { i as isPajekLabel, q as quotePajekLabel } from "./escape-B62ZGM_a.js";
4
+ import { i as inferTextDtype, W as WIDENING_UNSUPPORTED_CODE, a as isNumericText, T as TextCellWriter } from "./text-DHOJXnED.js";
5
5
  import { j as joinText, e as encodeChunks } from "./writer-DxjgHwSe.js";
6
- import { i as importChosenGraph } from "./choose-CS3fvGT1.js";
6
+ import { i as importChosenGraph } from "./choose-DvpbdRuz.js";
7
7
  const LABEL_COLUMN = "label";
8
8
  const POSITION_COLUMN = "position";
9
9
  const SHAPE_COLUMN = "shape";
@@ -173,57 +173,60 @@ function parseSectionHeader(line) {
173
173
  }
174
174
  const keyword = tokens[0];
175
175
  const kind = SECTION_KINDS.get(keyword.toLowerCase()) ?? "unsupported";
176
- let count = null;
177
- let secondCount = null;
178
- let relation = null;
179
- let name = null;
180
- const extra = [];
181
- let i = 1;
176
+ let args;
182
177
  switch (kind) {
183
178
  case "vertices":
184
- if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {
185
- count = Number(tokens[i]);
186
- i++;
187
- if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {
188
- secondCount = Number(tokens[i]);
189
- i++;
190
- }
191
- }
179
+ args = verticesArgs(tokens);
192
180
  break;
193
181
  case "arcs":
194
182
  case "edges":
195
183
  case "arcslist":
196
184
  case "edgeslist":
197
185
  case "matrix":
198
- if (i < tokens.length && tokens[i].startsWith(":") && INTEGER_TEXT.test(tokens[i].slice(1))) {
199
- relation = Number(tokens[i].slice(1));
200
- i++;
201
- if (i < tokens.length) {
202
- name = tokens[i];
203
- i++;
204
- }
205
- }
186
+ args = relationArgs(tokens);
206
187
  break;
207
188
  case "network":
208
189
  case "partition":
209
190
  case "vector":
210
- if (i < tokens.length) {
211
- name = tokens.slice(i).join(" ");
212
- i = tokens.length;
213
- }
191
+ args = nameArgs(tokens);
214
192
  break;
215
193
  case "unsupported":
216
- i = tokens.length;
194
+ args = { ...NO_ARGS, next: tokens.length };
217
195
  break;
218
196
  default: {
219
197
  const unknown = kind;
220
198
  throw new Error(`unknown section kind ${unknown}`);
221
199
  }
222
200
  }
223
- for (; i < tokens.length; i++) {
224
- extra.push(tokens[i]);
201
+ const { count, secondCount, relation, name, next } = args;
202
+ return { kind, keyword, count, secondCount, relation, name, extra: tokens.slice(next) };
203
+ }
204
+ const NO_ARGS = { count: null, secondCount: null, relation: null, name: null, next: 1 };
205
+ function verticesArgs(tokens) {
206
+ if (tokens.length < 2 || !INTEGER_TEXT.test(tokens[1])) {
207
+ return NO_ARGS;
208
+ }
209
+ const count = Number(tokens[1]);
210
+ if (tokens.length < 3 || !INTEGER_TEXT.test(tokens[2])) {
211
+ return { ...NO_ARGS, count, next: 2 };
212
+ }
213
+ return { ...NO_ARGS, count, secondCount: Number(tokens[2]), next: 3 };
214
+ }
215
+ function relationArgs(tokens) {
216
+ if (tokens.length < 2 || !tokens[1].startsWith(":") || !INTEGER_TEXT.test(tokens[1].slice(1))) {
217
+ return NO_ARGS;
225
218
  }
226
- return { kind, keyword, count, secondCount, relation, name, extra };
219
+ const relation = Number(tokens[1].slice(1));
220
+ if (tokens.length < 3) {
221
+ return { ...NO_ARGS, relation, next: 2 };
222
+ }
223
+ return { ...NO_ARGS, relation, name: tokens[2], next: 3 };
224
+ }
225
+ function nameArgs(tokens) {
226
+ if (tokens.length < 2) {
227
+ return NO_ARGS;
228
+ }
229
+ return { ...NO_ARGS, name: tokens.slice(1).join(" "), next: tokens.length };
227
230
  }
228
231
  function isVertexNumber(token) {
229
232
  if (token.length === 0) {
@@ -247,33 +250,36 @@ function parseIntervals(token) {
247
250
  }
248
251
  const spells = [];
249
252
  for (const part of body.split(",")) {
250
- const match = TIME_POINT.exec(part.replaceAll(/\s+/g, ""));
251
- if (match === null) {
252
- throw new Error(`malformed time interval ${token}: "${part}" is not a-b, a-* or a`);
253
- }
254
- const [, startText, endText] = match;
255
- if (startText === "*" && endText === void 0) {
256
- throw new Error(`malformed time interval ${token}: "*" alone is not a time point`);
257
- }
258
- const start = startText === "*" ? -Infinity : Number(startText);
259
- let end;
260
- if (endText === void 0) {
261
- end = start;
262
- } else if (endText === "*") {
263
- end = Infinity;
264
- } else {
265
- end = Number(endText);
266
- }
267
- if (startText !== "*" && !Number.isFinite(start) || endText !== void 0 && endText !== "*" && !Number.isFinite(end)) {
268
- throw new Error(`malformed time interval ${token}: "${part}" is beyond the number range`);
269
- }
270
- if (start > end) {
271
- throw new Error(`malformed time interval ${token}: ${startText} is after ${endText ?? ""}`);
272
- }
273
- spells.push([start, end]);
253
+ spells.push(parseSpell(token, part));
274
254
  }
275
255
  return spells;
276
256
  }
257
+ function parseSpell(token, part) {
258
+ const match = TIME_POINT.exec(part.replaceAll(/\s+/g, ""));
259
+ if (match === null) {
260
+ throw new Error(`malformed time interval ${token}: "${part}" is not a-b, a-* or a`);
261
+ }
262
+ const [, startText, endText] = match;
263
+ if (startText === "*" && endText === void 0) {
264
+ throw new Error(`malformed time interval ${token}: "*" alone is not a time point`);
265
+ }
266
+ const start = startText === "*" ? -Infinity : Number(startText);
267
+ let end;
268
+ if (endText === void 0) {
269
+ end = start;
270
+ } else if (endText === "*") {
271
+ end = Infinity;
272
+ } else {
273
+ end = Number(endText);
274
+ }
275
+ if (startText !== "*" && !Number.isFinite(start) || endText !== void 0 && endText !== "*" && !Number.isFinite(end)) {
276
+ throw new Error(`malformed time interval ${token}: "${part}" is beyond the number range`);
277
+ }
278
+ if (start > end) {
279
+ throw new Error(`malformed time interval ${token}: ${startText} is after ${endText ?? ""}`);
280
+ }
281
+ return [start, end];
282
+ }
277
283
  const CHARACTER_REFERENCE = /&#(?:[xX]([\da-fA-F]+)|(\d+));/g;
278
284
  function decodeCharacterReferences(text, onUnknown) {
279
285
  if (!text.includes("&#")) {
@@ -399,121 +405,125 @@ const CAPABILITIES = capabilities({
399
405
  });
400
406
  function plan(table, domain, notes) {
401
407
  const planned = [];
402
- const rows = (column) => column.length - column.nullCount;
403
408
  for (const column of table) {
404
- const { meta } = column;
405
- const { role, name, dtype } = meta;
406
- if (role === "label" && domain === "node") {
407
- if (dtype !== "string" && dtype !== "dict" && notes !== null) {
408
- notes.push(
409
- note(
410
- PAJEK_LOSS.LABEL_AS_TEXT,
411
- `node column "${name}" (label) is ${dtype}; labels are text and re-import as string`,
412
- name,
413
- rows(column)
414
- )
415
- );
416
- }
417
- planned.push({ column, slot: "label" });
418
- continue;
419
- }
420
- if (role === "position") {
421
- if (domain === "node" && (meta.components === 2 || meta.components === 3)) {
422
- planned.push({ column, slot: "position" });
423
- } else if (notes !== null && domain === "node") {
424
- notes.push(
425
- note(
426
- PAJEK_LOSS.POSITION_STRIDE,
427
- `node column "${name}" (position) has ${meta.components} components; Pajek coordinates are x y [z]`,
428
- name,
429
- rows(column)
430
- )
431
- );
432
- } else if (notes !== null) {
433
- notes.push(
434
- note(LOSS.POSITIONS, `edge column "${name}" (position) cannot be written`, name, rows(column))
435
- );
436
- }
437
- continue;
438
- }
439
- if (role === "spells") {
440
- if (dtype === "list" && (meta.itemDtype === "f64" || meta.itemDtype === "i32" || meta.itemDtype === "f32")) {
441
- planned.push({ column, slot: "spells" });
442
- continue;
443
- }
444
- if (notes !== null) {
445
- notes.push(
446
- note(
447
- LOSS.SPELLS,
448
- `${domain} column "${name}" (spells) is not a list of number pairs; it cannot be written`,
449
- name,
450
- rows(column)
451
- )
452
- );
453
- }
454
- continue;
455
- }
456
- if (role !== null && DROPPED_TEMPORAL_ROLES.has(role)) {
457
- if (notes !== null) {
458
- notes.push(
459
- note(
460
- PAJEK_LOSS.TEMPORAL_DROPPED,
461
- `${domain} column "${name}" (${role}) cannot be written; Pajek intervals come from the spells role`,
462
- name,
463
- rows(column)
464
- )
465
- );
466
- }
467
- continue;
468
- }
469
- if (role !== null && (STRUCTURAL_ROLES.has(role) || CHECKED_ROLES.has(role))) {
470
- continue;
471
- }
472
- if (domain === "edge" && role === "id") {
473
- continue;
474
- }
475
- if (dtype === "list" || dtype === "json") {
476
- continue;
477
- }
478
- if (domain === "node" && name === SHAPE_COLUMN && (dtype === "dict" || dtype === "string")) {
479
- if (allShapeKeywords(column)) {
480
- planned.push({ column, slot: "shape" });
481
- continue;
482
- }
483
- if (notes !== null && dtype === "dict") {
484
- notes.push(
485
- note(
486
- PAJEK_LOSS.SHAPE_AS_PARAMETER,
487
- `node column "${name}" holds values outside the Pajek shape keywords; it is written as a parameter and reads back as string`,
488
- name,
489
- rows(column)
490
- )
491
- );
492
- }
493
- planned.push({ column, slot: "param" });
494
- continue;
495
- }
496
- if (domain === "edge" && name === RELATION_COLUMN && (dtype === "dict" || dtype === "string")) {
497
- planned.push({ column, slot: "relation" });
498
- continue;
499
- }
500
- if (!isParameterKey(name)) {
501
- if (notes !== null) {
502
- notes.push(
503
- note(
504
- PAJEK_LOSS.KEY_DROPPED,
505
- `${domain} column "${name}" cannot be a Pajek parameter key; it is not written`,
506
- name,
507
- rows(column)
508
- )
509
- );
510
- }
511
- continue;
409
+ const slot = columnSlot(column, domain, notes);
410
+ if (slot !== null) {
411
+ planned.push({ column, slot });
512
412
  }
513
- planned.push({ column, slot: "param" });
514
413
  }
515
414
  return planned;
516
415
  }
416
+ function columnNote(notes, code, message, column) {
417
+ notes?.push(note(code, message, column.meta.name, column.length - column.nullCount));
418
+ }
419
+ function columnSlot(column, domain, notes) {
420
+ const { role, name } = column.meta;
421
+ if (role === "label" && domain === "node") {
422
+ return labelSlot(column, notes);
423
+ }
424
+ if (role === "position") {
425
+ return positionSlot(column, domain, notes);
426
+ }
427
+ if (role === "spells") {
428
+ return spellsSlot(column, domain, notes);
429
+ }
430
+ if (role !== null && DROPPED_TEMPORAL_ROLES.has(role)) {
431
+ columnNote(
432
+ notes,
433
+ PAJEK_LOSS.TEMPORAL_DROPPED,
434
+ `${domain} column "${name}" (${role}) cannot be written; Pajek intervals come from the spells role`,
435
+ column
436
+ );
437
+ return null;
438
+ }
439
+ if (writtenElsewhere(column, domain)) {
440
+ return null;
441
+ }
442
+ return namedSlot(column, domain, notes);
443
+ }
444
+ function labelSlot(column, notes) {
445
+ const { name, dtype } = column.meta;
446
+ if (dtype !== "string" && dtype !== "dict") {
447
+ columnNote(
448
+ notes,
449
+ PAJEK_LOSS.LABEL_AS_TEXT,
450
+ `node column "${name}" (label) is ${dtype}; labels are text and re-import as string`,
451
+ column
452
+ );
453
+ }
454
+ return "label";
455
+ }
456
+ function positionSlot(column, domain, notes) {
457
+ const { name, components } = column.meta;
458
+ if (domain === "edge") {
459
+ columnNote(notes, LOSS.POSITIONS, `edge column "${name}" (position) cannot be written`, column);
460
+ return null;
461
+ }
462
+ if (components === 2 || components === 3) {
463
+ return "position";
464
+ }
465
+ columnNote(
466
+ notes,
467
+ PAJEK_LOSS.POSITION_STRIDE,
468
+ `node column "${name}" (position) has ${components} components; Pajek coordinates are x y [z]`,
469
+ column
470
+ );
471
+ return null;
472
+ }
473
+ function spellsSlot(column, domain, notes) {
474
+ const { name, dtype, itemDtype } = column.meta;
475
+ if (dtype === "list" && (itemDtype === "f64" || itemDtype === "i32" || itemDtype === "f32")) {
476
+ return "spells";
477
+ }
478
+ columnNote(
479
+ notes,
480
+ LOSS.SPELLS,
481
+ `${domain} column "${name}" (spells) is not a list of number pairs; it cannot be written`,
482
+ column
483
+ );
484
+ return null;
485
+ }
486
+ function writtenElsewhere(column, domain) {
487
+ const { role, dtype } = column.meta;
488
+ if (role !== null && (STRUCTURAL_ROLES.has(role) || CHECKED_ROLES.has(role))) {
489
+ return true;
490
+ }
491
+ return domain === "edge" && role === "id" || dtype === "list" || dtype === "json";
492
+ }
493
+ function namedSlot(column, domain, notes) {
494
+ const { name, dtype } = column.meta;
495
+ const text = dtype === "dict" || dtype === "string";
496
+ if (text && domain === "node" && name === SHAPE_COLUMN) {
497
+ return shapeSlot(column, notes);
498
+ }
499
+ if (text && domain === "edge" && name === RELATION_COLUMN) {
500
+ return "relation";
501
+ }
502
+ if (!isParameterKey(name)) {
503
+ columnNote(
504
+ notes,
505
+ PAJEK_LOSS.KEY_DROPPED,
506
+ `${domain} column "${name}" cannot be a Pajek parameter key; it is not written`,
507
+ column
508
+ );
509
+ return null;
510
+ }
511
+ return "param";
512
+ }
513
+ function shapeSlot(column, notes) {
514
+ if (allShapeKeywords(column)) {
515
+ return "shape";
516
+ }
517
+ if (column.meta.dtype === "dict") {
518
+ columnNote(
519
+ notes,
520
+ PAJEK_LOSS.SHAPE_AS_PARAMETER,
521
+ `node column "${column.meta.name}" holds values outside the Pajek shape keywords; it is written as a parameter and reads back as string`,
522
+ column
523
+ );
524
+ }
525
+ return "param";
526
+ }
517
527
  function labelNotes(snapshot, nodePlan, notes) {
518
528
  let labels = null;
519
529
  let carried = 0;
@@ -1527,18 +1537,7 @@ class PajekParser {
1527
1537
  this.section = "none";
1528
1538
  return;
1529
1539
  case "vertices":
1530
- if (afterObjectHeader) {
1531
- this.section = previous;
1532
- if (previous === "object") {
1533
- this.objects[this.objects.length - 1].count = h.count;
1534
- }
1535
- return;
1536
- }
1537
- if (this.vertexCount >= 0) {
1538
- this.ended = true;
1539
- return;
1540
- }
1541
- this.verticesHeader(h, line);
1540
+ this.verticesSectionLine(h, line, previous, afterObjectHeader);
1542
1541
  return;
1543
1542
  case "arcs":
1544
1543
  case "edges":
@@ -1575,6 +1574,28 @@ class PajekParser {
1575
1574
  }
1576
1575
  }
1577
1576
  }
1577
+ /**
1578
+ * A `*Vertices` line: a project object's own count, the start of the next network, or the
1579
+ * network's vertices header.
1580
+ * @param h - the header
1581
+ * @param line - the line number
1582
+ * @param previous - the section before this header
1583
+ * @param afterObjectHeader - the previous line was a `*Partition`, `*Vector` or skipped section header
1584
+ */
1585
+ verticesSectionLine(h, line, previous, afterObjectHeader) {
1586
+ if (afterObjectHeader) {
1587
+ this.section = previous;
1588
+ if (previous === "object") {
1589
+ this.objects[this.objects.length - 1].count = h.count;
1590
+ }
1591
+ return;
1592
+ }
1593
+ if (this.vertexCount >= 0) {
1594
+ this.ended = true;
1595
+ return;
1596
+ }
1597
+ this.verticesHeader(h, line);
1598
+ }
1578
1599
  /**
1579
1600
  * `*Vertices N [N1]`.
1580
1601
  * @param h - the header
@@ -2653,4 +2674,4 @@ export {
2653
2674
  pajekImporter as b,
2654
2675
  pajekExporter as p
2655
2676
  };
2656
- //# sourceMappingURL=importer-AjwOJrn2.js.map
2677
+ //# sourceMappingURL=importer-Dz7tI8Sa.js.map