@graphty/graph-io 0.3.19 → 0.3.21

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 (201) hide show
  1. package/README.md +49 -4
  2. package/dist/chunks/{escape-CWExcecC.js → escape-B-tkk_Cl.js} +74 -16
  3. package/dist/chunks/escape-B-tkk_Cl.js.map +1 -0
  4. package/dist/chunks/{writer-DQiKgQJc.js → export-Bh60Dv-n.js} +5 -79
  5. package/dist/chunks/export-Bh60Dv-n.js.map +1 -0
  6. package/dist/chunks/{exporter-CbMZyVt-.js → exporter-BGrsWamJ.js} +7 -6
  7. package/dist/chunks/{exporter-CbMZyVt-.js.map → exporter-BGrsWamJ.js.map} +1 -1
  8. package/dist/chunks/exporter-DIeGJXAZ.js +834 -0
  9. package/dist/chunks/exporter-DIeGJXAZ.js.map +1 -0
  10. package/dist/chunks/{importer-BNFuV1-K.js → importer-BWY2FFc5.js} +28 -7
  11. package/dist/chunks/importer-BWY2FFc5.js.map +1 -0
  12. package/dist/chunks/importer-DD-xv9_Y.js +1471 -0
  13. package/dist/chunks/importer-DD-xv9_Y.js.map +1 -0
  14. package/dist/chunks/{importer-BAP4PrxR.js → importer-DET1tg6s.js} +30 -20
  15. package/dist/chunks/importer-DET1tg6s.js.map +1 -0
  16. package/dist/chunks/{importer-ByPGO-09.js → importer-DEcKhsmQ.js} +2 -2
  17. package/dist/chunks/{importer-ByPGO-09.js.map → importer-DEcKhsmQ.js.map} +1 -1
  18. package/dist/chunks/{importer-BW-Ft2ps.js → importer-DIrbbnAf.js} +6 -5
  19. package/dist/chunks/{importer-BW-Ft2ps.js.map → importer-DIrbbnAf.js.map} +1 -1
  20. package/dist/chunks/importer-D_e7e7LX.js +3055 -0
  21. package/dist/chunks/importer-D_e7e7LX.js.map +1 -0
  22. package/dist/chunks/{importer-Bm1_5vPS.js → importer-eUREhBGj.js} +11 -8
  23. package/dist/chunks/importer-eUREhBGj.js.map +1 -0
  24. package/dist/chunks/{importer-DOepkgnG.js → importer-vi3bSdtw.js} +4 -4
  25. package/dist/chunks/{importer-DOepkgnG.js.map → importer-vi3bSdtw.js.map} +1 -1
  26. package/dist/chunks/{importer-BVGtU1NA.js → importer-zGLo8Dg_.js} +6 -5
  27. package/dist/chunks/{importer-BVGtU1NA.js.map → importer-zGLo8Dg_.js.map} +1 -1
  28. package/dist/chunks/{json-elements-CZY1wiZh.js → json-elements-DDS8N2Dd.js} +2 -2
  29. package/dist/chunks/{json-elements-CZY1wiZh.js.map → json-elements-DDS8N2Dd.js.map} +1 -1
  30. package/dist/chunks/{records-BzNicMsf.js → records-dbRkxwaq.js} +2 -2
  31. package/dist/chunks/{records-BzNicMsf.js.map → records-dbRkxwaq.js.map} +1 -1
  32. package/dist/chunks/{report-BcWboivV.js → report-B1z4WT9e.js} +143 -111
  33. package/dist/chunks/{report-BcWboivV.js.map → report-B1z4WT9e.js.map} +1 -1
  34. package/dist/chunks/{weights-CwISIpCP.js → weights-Dzba96G3.js} +5 -5
  35. package/dist/chunks/{weights-CwISIpCP.js.map → weights-Dzba96G3.js.map} +1 -1
  36. package/dist/chunks/writer-C7flM-Ih.js +77 -0
  37. package/dist/chunks/writer-C7flM-Ih.js.map +1 -0
  38. package/dist/csv.js +6 -5
  39. package/dist/csv.js.map +1 -1
  40. package/dist/cx.js +1 -1
  41. package/dist/cx2.js +2 -2
  42. package/dist/cys.d.ts +1 -0
  43. package/dist/cys.js +6 -0
  44. package/dist/cys.js.map +1 -0
  45. package/dist/dot.js +1 -1
  46. package/dist/gexf.js +5 -4
  47. package/dist/gexf.js.map +1 -1
  48. package/dist/gml.js +12 -14
  49. package/dist/gml.js.map +1 -1
  50. package/dist/graph-io.js +288 -141
  51. package/dist/graph-io.js.map +1 -1
  52. package/dist/graphml.js +1 -1
  53. package/dist/json.js +1 -1
  54. package/dist/neo4j.js +6 -5
  55. package/dist/neo4j.js.map +1 -1
  56. package/dist/obo.js +1 -1
  57. package/dist/pajek.js +1 -1
  58. package/dist/src/common/cell-budget.d.ts +84 -0
  59. package/dist/src/common/cell-budget.d.ts.map +1 -0
  60. package/dist/src/common/cell-budget.js +138 -0
  61. package/dist/src/common/cell-budget.js.map +1 -0
  62. package/dist/src/common/input.d.ts +10 -0
  63. package/dist/src/common/input.d.ts.map +1 -1
  64. package/dist/src/common/input.js +39 -0
  65. package/dist/src/common/input.js.map +1 -1
  66. package/dist/src/common/options.d.ts +6 -0
  67. package/dist/src/common/options.d.ts.map +1 -1
  68. package/dist/src/common/options.js +1 -1
  69. package/dist/src/common/options.js.map +1 -1
  70. package/dist/src/common/xml.d.ts +37 -3
  71. package/dist/src/common/xml.d.ts.map +1 -1
  72. package/dist/src/common/xml.js +86 -6
  73. package/dist/src/common/xml.js.map +1 -1
  74. package/dist/src/common/zip.d.ts +92 -0
  75. package/dist/src/common/zip.d.ts.map +1 -0
  76. package/dist/src/common/zip.js +399 -0
  77. package/dist/src/common/zip.js.map +1 -0
  78. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  79. package/dist/src/formats/cx/importer.js +26 -17
  80. package/dist/src/formats/cx/importer.js.map +1 -1
  81. package/dist/src/formats/cys/constants.d.ts +68 -0
  82. package/dist/src/formats/cys/constants.d.ts.map +1 -0
  83. package/dist/src/formats/cys/constants.js +76 -0
  84. package/dist/src/formats/cys/constants.js.map +1 -0
  85. package/dist/src/formats/cys/importer.d.ts +38 -0
  86. package/dist/src/formats/cys/importer.d.ts.map +1 -0
  87. package/dist/src/formats/cys/importer.js +830 -0
  88. package/dist/src/formats/cys/importer.js.map +1 -0
  89. package/dist/src/formats/cys/index.d.ts +7 -0
  90. package/dist/src/formats/cys/index.d.ts.map +1 -0
  91. package/dist/src/formats/cys/index.js +7 -0
  92. package/dist/src/formats/cys/index.js.map +1 -0
  93. package/dist/src/formats/cys/session.d.ts +132 -0
  94. package/dist/src/formats/cys/session.d.ts.map +1 -0
  95. package/dist/src/formats/cys/session.js +315 -0
  96. package/dist/src/formats/cys/session.js.map +1 -0
  97. package/dist/src/formats/cys/tables.d.ts +90 -0
  98. package/dist/src/formats/cys/tables.d.ts.map +1 -0
  99. package/dist/src/formats/cys/tables.js +293 -0
  100. package/dist/src/formats/cys/tables.js.map +1 -0
  101. package/dist/src/formats/dot/exporter.d.ts +2 -0
  102. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  103. package/dist/src/formats/dot/exporter.js +12 -0
  104. package/dist/src/formats/dot/exporter.js.map +1 -1
  105. package/dist/src/formats/dot/importer.js +6 -2
  106. package/dist/src/formats/dot/importer.js.map +1 -1
  107. package/dist/src/formats/gexf/importer.d.ts +2 -2
  108. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  109. package/dist/src/formats/gexf/importer.js +1 -1
  110. package/dist/src/formats/gexf/importer.js.map +1 -1
  111. package/dist/src/formats/gml/exporter.d.ts +0 -8
  112. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  113. package/dist/src/formats/gml/exporter.js +7 -17
  114. package/dist/src/formats/gml/exporter.js.map +1 -1
  115. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  116. package/dist/src/formats/json/exporter.js +3 -1
  117. package/dist/src/formats/json/exporter.js.map +1 -1
  118. package/dist/src/formats/json/importer.d.ts.map +1 -1
  119. package/dist/src/formats/json/importer.js +3 -2
  120. package/dist/src/formats/json/importer.js.map +1 -1
  121. package/dist/src/formats/xgmml/columns.d.ts +152 -0
  122. package/dist/src/formats/xgmml/columns.d.ts.map +1 -0
  123. package/dist/src/formats/xgmml/columns.js +593 -0
  124. package/dist/src/formats/xgmml/columns.js.map +1 -0
  125. package/dist/src/formats/xgmml/constants.d.ts +196 -0
  126. package/dist/src/formats/xgmml/constants.d.ts.map +1 -0
  127. package/dist/src/formats/xgmml/constants.js +197 -0
  128. package/dist/src/formats/xgmml/constants.js.map +1 -0
  129. package/dist/src/formats/xgmml/document.d.ts +361 -0
  130. package/dist/src/formats/xgmml/document.d.ts.map +1 -0
  131. package/dist/src/formats/xgmml/document.js +695 -0
  132. package/dist/src/formats/xgmml/document.js.map +1 -0
  133. package/dist/src/formats/xgmml/emit.d.ts +341 -0
  134. package/dist/src/formats/xgmml/emit.d.ts.map +1 -0
  135. package/dist/src/formats/xgmml/emit.js +1275 -0
  136. package/dist/src/formats/xgmml/emit.js.map +1 -0
  137. package/dist/src/formats/xgmml/exporter.d.ts +24 -0
  138. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -0
  139. package/dist/src/formats/xgmml/exporter.js +999 -0
  140. package/dist/src/formats/xgmml/exporter.js.map +1 -0
  141. package/dist/src/formats/xgmml/importer.d.ts +58 -0
  142. package/dist/src/formats/xgmml/importer.d.ts.map +1 -0
  143. package/dist/src/formats/xgmml/importer.js +360 -0
  144. package/dist/src/formats/xgmml/importer.js.map +1 -0
  145. package/dist/src/formats/xgmml/index.d.ts +8 -0
  146. package/dist/src/formats/xgmml/index.d.ts.map +1 -0
  147. package/dist/src/formats/xgmml/index.js +8 -0
  148. package/dist/src/formats/xgmml/index.js.map +1 -0
  149. package/dist/src/formats/xgmml/values.d.ts +60 -0
  150. package/dist/src/formats/xgmml/values.d.ts.map +1 -0
  151. package/dist/src/formats/xgmml/values.js +148 -0
  152. package/dist/src/formats/xgmml/values.js.map +1 -0
  153. package/dist/src/index.d.ts +2 -0
  154. package/dist/src/index.d.ts.map +1 -1
  155. package/dist/src/index.js +2 -0
  156. package/dist/src/index.js.map +1 -1
  157. package/dist/src/registry.d.ts +7 -0
  158. package/dist/src/registry.d.ts.map +1 -1
  159. package/dist/src/registry.js +25 -10
  160. package/dist/src/registry.js.map +1 -1
  161. package/dist/src/sniff.d.ts +1 -1
  162. package/dist/src/sniff.d.ts.map +1 -1
  163. package/dist/src/sniff.js +2 -0
  164. package/dist/src/sniff.js.map +1 -1
  165. package/dist/xgmml.d.ts +1 -0
  166. package/dist/xgmml.js +9 -0
  167. package/dist/xgmml.js.map +1 -0
  168. package/package.json +15 -2
  169. package/src/common/cell-budget.ts +170 -0
  170. package/src/common/input.ts +40 -0
  171. package/src/common/options.ts +1 -1
  172. package/src/common/xml.ts +127 -6
  173. package/src/common/zip.ts +472 -0
  174. package/src/formats/cx/importer.ts +27 -19
  175. package/src/formats/cys/constants.ts +99 -0
  176. package/src/formats/cys/importer.ts +1100 -0
  177. package/src/formats/cys/index.ts +7 -0
  178. package/src/formats/cys/session.ts +428 -0
  179. package/src/formats/cys/tables.ts +400 -0
  180. package/src/formats/dot/exporter.ts +17 -0
  181. package/src/formats/dot/importer.ts +6 -2
  182. package/src/formats/gexf/importer.ts +0 -1
  183. package/src/formats/gml/exporter.ts +7 -18
  184. package/src/formats/json/exporter.ts +3 -1
  185. package/src/formats/json/importer.ts +3 -2
  186. package/src/formats/xgmml/columns.ts +747 -0
  187. package/src/formats/xgmml/constants.ts +265 -0
  188. package/src/formats/xgmml/document.ts +975 -0
  189. package/src/formats/xgmml/emit.ts +1563 -0
  190. package/src/formats/xgmml/exporter.ts +1215 -0
  191. package/src/formats/xgmml/importer.ts +491 -0
  192. package/src/formats/xgmml/index.ts +8 -0
  193. package/src/formats/xgmml/values.ts +183 -0
  194. package/src/index.ts +9 -0
  195. package/src/registry.ts +41 -15
  196. package/src/sniff.ts +5 -1
  197. package/dist/chunks/escape-CWExcecC.js.map +0 -1
  198. package/dist/chunks/importer-BAP4PrxR.js.map +0 -1
  199. package/dist/chunks/importer-BNFuV1-K.js.map +0 -1
  200. package/dist/chunks/importer-Bm1_5vPS.js.map +0 -1
  201. package/dist/chunks/writer-DQiKgQJc.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"importer-BVGtU1NA.js","sources":["../../src/formats/pajek/syntax.ts","../../src/formats/pajek/exporter.ts","../../src/formats/pajek/importer.ts"],"sourcesContent":["/**\n * The lexical layer of the Pajek NET format shared by the importer and the exporter (research\n * note 07 section 2.5): the line tokenizer (whitespace-separated tokens, double quotes group\n * spaces and are removed, no escape mechanism), the section headers (`*Vertices N [N1]`,\n * `*Arcs [:k [\"name\"]]`, `*Edges`, `*Arcslist`, `*Edgeslist`, `*Matrix`, `*Network name`,\n * `*Partition name`, `*Vector name` and the project-file sections the importer does not read), the\n * vertex shape keywords, the time interval tokens `[1-5,7-*]` that map to the spells role, the\n * `&#dddd;` character references of labels, and the column names both sides agree on.\n */\n\n/** The node column holding the vertex label (role label). */\nexport const LABEL_COLUMN = \"label\";\n\n/** The node column holding the vertex coordinates (role position, f32 x 3, units \"file\"). */\nexport const POSITION_COLUMN = \"position\";\n\n/** The node column holding the vertex shape keyword (dict, no role: Pajek has its own keyword set). */\nexport const SHAPE_COLUMN = \"shape\";\n\n/** The edge column holding the relation name of a `*Arcs :k \"name\"` section (dict). */\nexport const RELATION_COLUMN = \"relation\";\n\n/** The node or edge column holding Pajek time intervals (list of f64 pairs, role spells). */\nexport const SPELLS_COLUMN = \"spells\";\n\n/** The edge column holding the line value when `weightFrom` names another field or null. */\nexport const VALUE_COLUMN = \"value\";\n\n/** The `weightFrom` default: Pajek's third column is the line value (design section 8.4). */\nexport const VALUE_FIELD = \"value\";\n\n/** The node column holding the values of a `*Partition` object (i32). */\nexport const PARTITION_COLUMN = \"partition\";\n\n/** The node column holding the values of a `*Vector` object (f64). */\nexport const VECTOR_COLUMN = \"vector\";\n\n/**\n * The vertex shape keywords of the Pajek manual, lower-cased; a file may write them in any case\n * (use isShapeKeyword()).\n */\nexport const SHAPES: ReadonlySet<string> = new Set([\n \"ellipse\",\n \"box\",\n \"diamond\",\n \"triangle\",\n \"cross\",\n \"empty\",\n \"house\",\n \"man\",\n \"woman\",\n]);\n\n/**\n * Whether a token is a vertex shape keyword, in any case (`Ellipse`, `BOX`).\n * @param token - the token\n * @returns true for a shape keyword\n */\nexport function isShapeKeyword(token: string): boolean {\n return SHAPES.has(token.toLowerCase());\n}\n\n/** The section keywords the importer reads, lower-cased. */\ntype SectionKind =\n | \"network\"\n | \"vertices\"\n | \"arcs\"\n | \"edges\"\n | \"arcslist\"\n | \"edgeslist\"\n | \"matrix\"\n | \"partition\"\n | \"vector\"\n | \"unsupported\";\n\n/**\n * The parameter key the exporter writes a node's original id under when `sanitizeIds: \"mangle\"`\n * renumbers it (design section 8.5: the exporter names the attribute, `restoreMangledIds` reads\n * it back); a user column of that name is reserved under \"mangle\".\n */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/** A parsed section header line. */\nexport interface SectionHeader {\n /** The section kind. */\n readonly kind: SectionKind;\n /** The keyword as written, without the asterisk. */\n readonly keyword: string;\n /** The first count (`*Vertices N`), or null. */\n readonly count: number | null;\n /** The second count of a two-mode network (`*Vertices N N1`), or null. */\n readonly secondCount: number | null;\n /** The relation number of `*Arcs :k`, or null. */\n readonly relation: number | null;\n /** The relation or network name, or null. */\n readonly name: string | null;\n /** Tokens the grammar does not account for, for the importer to report. */\n readonly extra: readonly string[];\n}\n\nconst SECTION_KINDS: ReadonlyMap<string, SectionKind> = new Map([\n [\"network\", \"network\"],\n [\"vertices\", \"vertices\"],\n [\"arcs\", \"arcs\"],\n [\"edges\", \"edges\"],\n [\"arcslist\", \"arcslist\"],\n [\"edgeslist\", \"edgeslist\"],\n [\"matrix\", \"matrix\"],\n [\"partition\", \"partition\"],\n [\"vector\", \"vector\"],\n]);\n\nconst INTEGER_TEXT = /^[+-]?[0-9]+$/;\nconst TIME_POINT =\n /^(\\*|[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)(?:-(\\*|[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?))?$/;\n\n/**\n * Split one line into tokens: runs of non-whitespace, with double quotes grouping whitespace\n * into one token and removed from it (the shlex rule NetworkX applies; Pajek has no escapes, so a\n * quote never appears inside a token). An empty quoted string `\"\"` is one empty token. A token\n * that starts with `[` runs to the next `]` whatever whitespace it holds (when no other `[` comes\n * first), so a time set written `[ 1, 3 ]` is one token.\n * @param line - the line without its terminator\n * @returns the tokens, or null when a quote is not closed before the end of the line\n */\nexport function tokenize(line: string): string[] | null {\n const tokens: string[] = [];\n let current = \"\";\n let started = false;\n let quoted = false;\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 34) {\n quoted = !quoted;\n started = true;\n continue;\n }\n if (!quoted && !started && c === 91) {\n const close = line.indexOf(\"]\", i);\n if (close > i && line.lastIndexOf(\"[\", close) === i) {\n current += line.slice(i, close + 1);\n started = true;\n i = close;\n continue;\n }\n }\n if (!quoted && (c === 32 || c === 9 || c === 13 || c === 12 || c === 11)) {\n if (started) {\n tokens.push(current);\n current = \"\";\n started = false;\n }\n continue;\n }\n current += line[i];\n started = true;\n }\n if (quoted) {\n return null;\n }\n if (started) {\n tokens.push(current);\n }\n return tokens;\n}\n\n/**\n * Whether a line is a Pajek comment (`%` first) or blank.\n * @param line - the line\n * @returns true when the importer skips it\n */\nexport function isCommentOrBlank(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 32 || c === 9 || c === 13 || c === 12 || c === 11) {\n continue;\n }\n return c === 37;\n }\n return true;\n}\n\n/**\n * Whether a line starts a section (`*` first, after optional whitespace).\n * @param line - the line\n * @returns true for a header line\n */\nexport function isSectionLine(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 32 || c === 9 || c === 13 || c === 12 || c === 11) {\n continue;\n }\n return c === 42;\n }\n return false;\n}\n\n/**\n * Parse a section header line: the keyword (case-insensitive), then `N [N1]` for `*Vertices`,\n * `[:k] [\"name\"]` for the line sections, the name for `*Network`. Anything else after the keyword\n * lands in `extra` so the importer can report it instead of dropping it.\n * @param line - a line isSectionLine() accepted\n * @returns the header, or null when the line has no keyword or a quote is unbalanced\n */\nexport function parseSectionHeader(line: string): SectionHeader | null {\n const tokens = tokenize(line.trimStart().slice(1));\n if (tokens === null || tokens.length === 0 || tokens[0].length === 0) {\n return null;\n }\n const keyword = tokens[0];\n const kind = SECTION_KINDS.get(keyword.toLowerCase()) ?? \"unsupported\";\n let count: number | null = null;\n let secondCount: number | null = null;\n let relation: number | null = null;\n let name: string | null = null;\n const extra: string[] = [];\n let i = 1;\n switch (kind) {\n case \"vertices\":\n if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {\n count = Number(tokens[i]);\n i++;\n if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {\n secondCount = Number(tokens[i]);\n i++;\n }\n }\n break;\n case \"arcs\":\n case \"edges\":\n case \"arcslist\":\n case \"edgeslist\":\n case \"matrix\":\n if (i < tokens.length && tokens[i].startsWith(\":\") && INTEGER_TEXT.test(tokens[i].slice(1))) {\n relation = Number(tokens[i].slice(1));\n i++;\n if (i < tokens.length) {\n name = tokens[i];\n i++;\n }\n }\n break;\n case \"network\":\n case \"partition\":\n case \"vector\":\n if (i < tokens.length) {\n name = tokens.slice(i).join(\" \");\n i = tokens.length;\n }\n break;\n case \"unsupported\":\n i = tokens.length;\n break;\n default: {\n const unknown: string = kind;\n throw new Error(`unknown section kind ${unknown}`);\n }\n }\n for (; i < tokens.length; i++) {\n extra.push(tokens[i]);\n }\n return { kind, keyword, count, secondCount, relation, name, extra };\n}\n\n/**\n * Whether a token is a Pajek integer (a vertex number, a count), without sign.\n * @param token - the token\n * @returns true for one or more ASCII digits\n */\nexport function isVertexNumber(token: string): boolean {\n if (token.length === 0) {\n return false;\n }\n for (let i = 0; i < token.length; i++) {\n const c = token.charCodeAt(i);\n if (c < 48 || c > 57) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Whether a token is a time interval list `[...]`.\n * @param token - the token\n * @returns true when it starts with `[` and ends with `]`\n */\nexport function isIntervalToken(token: string): boolean {\n return token.length >= 2 && token.startsWith(\"[\") && token.endsWith(\"]\");\n}\n\n/**\n * Parse a Pajek time interval token into spells: `[1-5,7-*]` is `[[1, 5], [7, Infinity]]`, a\n * single time point `[3]` is `[[3, 3]]`, `*` at either end is the corresponding infinity, blanks\n * around the parts are ignored and an empty `[]` is no spell at all.\n * @param token - a token isIntervalToken() accepted\n * @returns the spells as [start, end] pairs (empty for `[]`)\n */\nexport function parseIntervals(token: string): [number, number][] {\n const body = token.slice(1, -1);\n if (body.trim().length === 0) {\n return [];\n }\n const spells: [number, number][] = [];\n for (const part of body.split(\",\")) {\n const match = TIME_POINT.exec(part.replace(/\\s+/g, \"\"));\n if (match === null) {\n throw new Error(`malformed time interval ${token}: \"${part}\" is not a-b, a-* or a`);\n }\n const start = match[1] === \"*\" ? -Infinity : Number(match[1]);\n const endText = match[2];\n let end: number;\n if (endText === undefined) {\n end = start;\n } else if (endText === \"*\") {\n end = Infinity;\n } else {\n end = Number(endText);\n }\n if (start > end) {\n throw new Error(`malformed time interval ${token}: ${match[1]} is after ${endText ?? \"\"}`);\n }\n spells.push([start, end]);\n }\n return spells;\n}\n\nconst CHARACTER_REFERENCE = /&#(?:[xX]([0-9a-fA-F]{1,6})|([0-9]{1,7}));/g;\n\n/**\n * Decode the `&#dddd;` and `&#xhhhh;` character references of a label, as Pajek does; a reference\n * outside the Unicode range is left as written.\n * @param text - the label as written\n * @returns the decoded label\n */\nexport function decodeCharacterReferences(text: string): string {\n if (!text.includes(\"&#\")) {\n return text;\n }\n return text.replace(CHARACTER_REFERENCE, (whole, hex: string | undefined, dec: string | undefined) => {\n const code = hex === undefined ? Number(dec) : Number.parseInt(hex, 16);\n return code <= 0x10ffff ? String.fromCodePoint(code) : whole;\n });\n}\n\n/**\n * Protect a label whose text would read back as a character reference: the `&` of every\n * `&#...;` run is written as `&#38;`, the inverse of decodeCharacterReferences().\n * @param text - the label text\n * @returns the text to write\n */\nexport function encodeCharacterReferences(text: string): string {\n if (!text.includes(\"&#\")) {\n return text;\n }\n return text.replace(CHARACTER_REFERENCE, (whole) => `&#38;${whole.slice(1)}`);\n}\n\n/**\n * Write spells as a Pajek time interval token, the inverse of parseIntervals().\n * @param spells - [start, end] pairs\n * @returns the token, e.g. `[1-5,7-*]`\n */\nexport function formatIntervals(spells: readonly (readonly [number, number])[]): string {\n const parts: string[] = [];\n for (const [start, end] of spells) {\n const s = start === -Infinity ? \"*\" : String(start);\n if (start === end) {\n parts.push(s);\n } else {\n parts.push(`${s}-${end === Infinity ? \"*\" : String(end)}`);\n }\n }\n return `[${parts.join(\",\")}]`;\n}\n\n/**\n * Whether a text can be written as a bare parameter key on a vertex or line row: non-empty, no\n * whitespace or quote, not an interval token, not a number (a number after the label is a\n * coordinate, at the third position of a line row the value) and not a shape keyword.\n * @param text - the candidate key (a column name)\n * @returns true when the importer reads it back as a key\n */\nexport function isParameterKey(text: string): boolean {\n if (text.length === 0 || /[\\s\"]/.test(text) || text.startsWith(\"[\") || text.startsWith(\"*\")) {\n return false;\n }\n if (isShapeKeyword(text)) {\n return false;\n }\n return !/^[+-]?(\\.[0-9]|[0-9])/.test(text);\n}\n","/**\n * The Pajek NET exporter (design section 8.5; research note 07 sections 2.5 and 9): vertices are\n * numbered 1..N in index order (the `dense-1-based` id charset: an id that is not its 1-based\n * index survives as the label only, which check() reports as W_ID_RENUMBERED; under\n * `sanitizeIds: \"mangle\"` it is also written as a `graphty_originalId` parameter the importer\n * restores under `restoreMangledIds`), the label role\n * column is the label, the position role column the coordinates, a `shape` column the shape\n * keyword, every other writable column a `key value` parameter and the spells role a time\n * interval token. Logical edges are written in index order in runs of `*Arcs` (directed) and\n * `*Edges` (undirected) sections, folding expanded pairs back through the pair role and reading\n * attributes from the primary half, so a mixed file round-trips in its original edge order. The\n * weight is written for edges whose weight was explicit (the role-weight column's validity).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, type NodeId } from \"@graphty/graph-format\";\n\nimport { pairFolding } from \"../../common/direction.js\";\nimport { isPajekLabel, quotePajekLabel } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS, type SanitizedIds, sanitizeIds } from \"../../common/export.js\";\nimport { formatDecimal, formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { canonicalId } from \"../../common/ids.js\";\nimport { resolveExportOptions } from \"../../common/options.js\";\nimport { inferTextDtype } from \"../../common/text.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n encodeCharacterReferences,\n formatIntervals,\n isParameterKey,\n LABEL_COLUMN,\n ORIGINAL_ID_KEY,\n POSITION_COLUMN,\n RELATION_COLUMN,\n SHAPE_COLUMN,\n SHAPES,\n} from \"./syntax.js\";\n\n/** The format-specific options of the Pajek exporter. */\nexport interface PajekExportOptions {\n /**\n * Write a `*Network <name>` header line (the .paj project-file convention) when the snapshot's\n * meta.name is set; default false, since plain .net readers do not expect it.\n */\n networkHeader?: boolean | undefined;\n}\n\n/**\n * The LossNote codes of the Pajek exporter's check(): the Pajek-specific ones and, aliased, the\n * shared ones it records itself (`LOSS` holds the rest of the generic pre-flight's codes). A key\n * is the code without its severity and format prefixes.\n */\nexport const PAJEK_LOSS = Object.freeze({\n /** A label or text value holds a double quote or a line break; export() will throw E_UNSUPPORTED. */\n TEXT: \"E_PAJEK_TEXT\",\n /** A column whose name cannot be a parameter key (whitespace, a quote, numeric, a shape keyword); skipped. */\n KEY_DROPPED: \"W_PAJEK_KEY_DROPPED\",\n /** A label role column that is not text; its values are written as text and re-import as string. */\n LABEL_AS_TEXT: \"W_PAJEK_LABEL_AS_TEXT\",\n /** A non-finite f64 value; written as Infinity / NaN text, which re-imports as string. */\n NONFINITE_AS_TEXT: \"W_PAJEK_NONFINITE_AS_TEXT\",\n /** A mutual pair; written as one undirected edge, the mark lost. */\n MUTUAL_AS_UNDIRECTED: LOSS.MUTUAL_AS_UNDIRECTED,\n /** A start / end / timestamp role column; Pajek intervals are written from the spells role only. */\n TEMPORAL_DROPPED: LOSS.TEMPORAL,\n /** A position column with a stride other than 2 or 3. */\n POSITION_STRIDE: \"W_PAJEK_POSITION_STRIDE\",\n /** meta.extra.pajek.firstMode is not a count within 0..N; the two-mode header is not written. */\n FIRST_MODE_DROPPED: \"W_PAJEK_FIRST_MODE_DROPPED\",\n /** A role column Pajek has no slot for (kind, ...) written as a plain parameter; the role is lost. */\n ROLE_DROPPED: LOSS.ROLE,\n /** A `shape` column with a value outside the shape keywords is written as a parameter (a string on re-import). */\n SHAPE_AS_PARAMETER: \"W_PAJEK_SHAPE_AS_PARAMETER\",\n /** A vertex line with coordinates, a shape or parameters needs a label: the id text is written and reads back as a label. */\n LABEL_GAINED: \"W_PAJEK_LABEL_GAINED\",\n /** A role-less node column named `label` reads back with the label role (its values become the vertex labels). */\n ROLE_ASSUMED: LOSS.ROLE_ASSUMED,\n /** Under sanitizeIds \"mangle\": an original id whose text reads back as the other type under ids \"canonical\". */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /** Parameter text that looks like a number or a boolean reads back as one (parameters are untyped, design 5.1). */\n TEXT_INFERRED: LOSS.TEXT_INFERRED,\n});\n\n/** The roles Pajek has a slot for beyond the structural, position and temporal ones. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\"]);\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({ label: \"label\", position: POSITION_COLUMN });\n\n/** The roles the exporter handles structurally rather than as parameters. */\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n]);\n\n/** The roles the generic checker reports for a format without viz, hierarchy or open-interval support. */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Roles the generic checker lets through under temporal \"spells\" that Pajek cannot write. */\nconst DROPPED_TEMPORAL_ROLES: ReadonlySet<string> = new Set([\"start\", \"end\", \"timestamp\", \"timestamps\"]);\n\nconst CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"dense-1-based\",\n dtypes: [\"f64\", \"i32\", \"bool\", \"string\"],\n temporal: \"spells\",\n positions: true,\n});\n\n/** Where a column's values go on a row. */\ntype Slot = \"label\" | \"position\" | \"shape\" | \"spells\" | \"relation\" | \"param\" | \"skip\";\n\n/** A column with its resolved slot, for the write loops. */\ninterface PlannedColumn {\n readonly column: Column;\n readonly slot: Slot;\n}\n\n/**\n * Decide the slot of every column of a table.\n * @param table - the node or edge table\n * @param domain - node or edge\n * @param notes - the note list check() fills; null when writing\n * @returns the plan, in declaration order\n */\nfunction plan(table: Iterable<Column>, domain: \"node\" | \"edge\", notes: LossNote[] | null): PlannedColumn[] {\n const planned: PlannedColumn[] = [];\n const rows = (column: Column): number => column.length - column.nullCount;\n for (const column of table) {\n const { meta } = column;\n const { role, name, dtype } = meta;\n if (role === \"label\" && domain === \"node\") {\n if (dtype !== \"string\" && dtype !== \"dict\" && notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.LABEL_AS_TEXT,\n `node column \"${name}\" (label) is ${dtype}; labels are text and re-import as string`,\n name,\n rows(column),\n ),\n );\n }\n planned.push({ column, slot: \"label\" });\n continue;\n }\n if (role === \"position\") {\n if (domain === \"node\" && (meta.components === 2 || meta.components === 3)) {\n planned.push({ column, slot: \"position\" });\n } else if (notes !== null && domain === \"node\") {\n notes.push(\n note(\n PAJEK_LOSS.POSITION_STRIDE,\n `node column \"${name}\" (position) has ${meta.components} components; Pajek coordinates are x y [z]`,\n name,\n rows(column),\n ),\n );\n } else if (notes !== null) {\n notes.push(\n note(LOSS.POSITIONS, `edge column \"${name}\" (position) cannot be written`, name, rows(column)),\n );\n }\n continue;\n }\n if (role === \"spells\") {\n if (\n dtype === \"list\" &&\n (meta.itemDtype === \"f64\" || meta.itemDtype === \"i32\" || meta.itemDtype === \"f32\")\n ) {\n planned.push({ column, slot: \"spells\" });\n continue;\n }\n if (notes !== null) {\n notes.push(\n note(\n LOSS.SPELLS,\n `${domain} column \"${name}\" (spells) is not a list of number pairs; it cannot be written`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n if (role !== null && DROPPED_TEMPORAL_ROLES.has(role)) {\n if (notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.TEMPORAL_DROPPED,\n `${domain} column \"${name}\" (${role}) cannot be written; Pajek intervals come from the spells role`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n if (role !== null && (STRUCTURAL_ROLES.has(role) || CHECKED_ROLES.has(role))) {\n // structural columns are folded into the topology; viz and hierarchy roles are reported by the generic checker\n continue;\n }\n if (domain === \"edge\" && role === \"id\") {\n continue;\n }\n if (dtype === \"list\" || dtype === \"json\") {\n // reported by the generic checker (lists: false, json: false)\n continue;\n }\n if (domain === \"node\" && name === SHAPE_COLUMN && (dtype === \"dict\" || dtype === \"string\")) {\n if (allShapeKeywords(column)) {\n planned.push({ column, slot: \"shape\" });\n continue;\n }\n // a value outside the keywords: the whole column is a `shape \"<text>\"` parameter, which the\n // importer reads back as one string column (a change for a dict column only)\n if (notes !== null && dtype === \"dict\") {\n notes.push(\n note(\n PAJEK_LOSS.SHAPE_AS_PARAMETER,\n `node column \"${name}\" holds values outside the Pajek shape keywords; it is written as a parameter and reads back as string`,\n name,\n rows(column),\n ),\n );\n }\n planned.push({ column, slot: \"param\" });\n continue;\n }\n if (domain === \"edge\" && name === RELATION_COLUMN && (dtype === \"dict\" || dtype === \"string\")) {\n planned.push({ column, slot: \"relation\" });\n continue;\n }\n if (!isParameterKey(name)) {\n if (notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.KEY_DROPPED,\n `${domain} column \"${name}\" cannot be a Pajek parameter key; it is not written`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n planned.push({ column, slot: \"param\" });\n }\n return planned;\n}\n\n/**\n * The notes about vertex labels: Pajek's grammar puts the label second, so a vertex line that\n * carries coordinates, a shape, parameters or an interval needs one, and a node without a label\n * value gets its id text written there (it reads back as a label); a role-less column named\n * `label` reads back with the label role.\n * @param snapshot - the snapshot\n * @param nodePlan - the node column plan\n * @param notes - where to record\n */\nfunction labelNotes(snapshot: GraphSnapshot, nodePlan: readonly PlannedColumn[], notes: LossNote[]): void {\n let labels: Column | null = null;\n let carried = 0;\n for (const { column, slot } of nodePlan) {\n if (slot === \"label\") {\n labels = column;\n } else if (slot !== \"skip\" && slot !== \"relation\") {\n carried++;\n }\n }\n const plain = [...snapshot.nodes].find((c) => c.meta.role === null && c.meta.name === LABEL_COLUMN);\n if (plain !== undefined) {\n notes.push(\n note(\n PAJEK_LOSS.ROLE_ASSUMED,\n `node column \"${LABEL_COLUMN}\" has no role; written as a parameter, it reads back as the vertex label (role label)`,\n LABEL_COLUMN,\n plain.length - plain.nullCount,\n ),\n );\n }\n if (carried === 0) {\n return;\n }\n let gained = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n if (labels === null || !labels.isSet(i)) {\n gained++;\n }\n }\n if (gained > 0) {\n notes.push(\n note(\n PAJEK_LOSS.LABEL_GAINED,\n `${gained} vertex line(s) carry coordinates, a shape or parameters and need a label; the id text is written there and reads back as a label`,\n labels === null ? LABEL_COLUMN : labels.meta.name,\n gained,\n ),\n );\n }\n}\n\n/**\n * Whether every set value of a shape column is a Pajek shape keyword.\n * @param column - the shape column (string or dict)\n * @returns true when the shape slot can hold the column\n */\nfunction allShapeKeywords(column: Column): boolean {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !SHAPES.has(column.value(r) as string)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Build a frozen LossNote.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n * @returns the note\n */\nfunction note(code: string, message: string, column: string | null = null, count: number | null = null): LossNote {\n return Object.freeze({ code, message, column, count });\n}\n\n/**\n * The text of one numeric cell: integers as digits, f64 with a decimal point guaranteed so the\n * importer's inference keeps the dtype, f32 as the shortest fround-round-trip decimal.\n * @param value - the value\n * @param dtype - the column dtype\n * @returns the text\n */\nfunction numberText(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\"): string {\n switch (dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return formatF32(value);\n case \"f64\":\n return formatDecimal(value, \"f64\");\n default: {\n const name: string = dtype;\n throw new Error(`unknown numeric dtype ${name}`);\n }\n }\n}\n\n/**\n * The text of a set cell as a parameter value or label, before quoting.\n * @param column - the column\n * @param row - the row\n * @returns the text\n */\nfunction cellText(column: Column, row: number): string {\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const value = column.value(row);\n if (typeof value === \"number\") {\n return numberText(value, column.dtype);\n }\n const parts: string[] = [];\n const vector = value as ArrayLike<number>;\n for (let k = 0; k < vector.length; k++) {\n parts.push(numberText(vector[k], column.dtype));\n }\n return parts.join(\" \");\n }\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n case \"dict\":\n case \"string\":\n return column.value(row) as string;\n case \"list\":\n case \"json\":\n return JSON.stringify(column.value(row));\n default: {\n const name: string = (column as Column).dtype;\n throw new Error(`unknown dtype ${name}`);\n }\n }\n}\n\n/**\n * Count the cells of a plan that cannot be written (text with a quote or line break, non-finite\n * f64) or read back typed (parameter text that looks like a number or a boolean) and add the notes.\n * @param planned - the plan\n * @param domain - node or edge\n * @param notes - the note list\n */\nfunction checkCells(planned: readonly PlannedColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, slot } of planned) {\n if (slot === \"position\" || slot === \"spells\") {\n continue;\n }\n const { name } = column.meta;\n let badText = 0;\n let nonFinite = 0;\n let typed = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n if (column.dtype === \"f64\" || column.dtype === \"f32\") {\n const value = column.value(r);\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n nonFinite++;\n }\n } else if (value !== undefined && !Array.from(value).every((v) => Number.isFinite(v))) {\n nonFinite++;\n }\n } else if (column.dtype === \"string\" || column.dtype === \"dict\") {\n const text = column.value(r) as string;\n if (!isPajekLabel(text)) {\n badText++;\n } else if (slot === \"param\" && inferTextDtype(text) !== \"string\") {\n typed++;\n }\n }\n }\n if (badText > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT,\n `${badText} value(s) of ${domain} column \"${name}\" hold a double quote or a line break; Pajek cannot write them`,\n name,\n badText,\n ),\n );\n }\n if (typed > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT_INFERRED,\n `${typed} value(s) of ${domain} column \"${name}\" look like numbers or booleans; Pajek parameters are untyped and they read back as such`,\n name,\n typed,\n ),\n );\n }\n if (nonFinite > 0) {\n notes.push(\n note(\n PAJEK_LOSS.NONFINITE_AS_TEXT,\n `${nonFinite} non-finite value(s) of ${domain} column \"${name}\" are written as text`,\n name,\n nonFinite,\n ),\n );\n }\n }\n}\n\n/**\n * The first-mode count to write in `*Vertices N N1`, from meta.extra.pajek.firstMode.\n * @param snapshot - the snapshot\n * @returns the count, or null when absent or invalid\n */\nfunction firstModeOf(snapshot: GraphSnapshot): number | null {\n const { pajek } = snapshot.meta.extra;\n if (typeof pajek !== \"object\" || pajek === null) {\n return null;\n }\n const value = (pajek as { firstMode?: unknown }).firstMode;\n if (value === undefined) {\n return null;\n }\n if (typeof value === \"number\" && Number.isInteger(value) && value >= 0 && value <= snapshot.nodeCount) {\n return value;\n }\n return NaN;\n}\n\n/**\n * The label of a vertex: the label column's value when set, the id's text when the id is not\n * the vertex number, otherwise null (no label needed). A label is forced when something follows\n * it on the line, because Pajek's grammar puts the label second.\n * @param labels - the label column, or null\n * @param ids - the sanitised ids\n * @param i - the node index\n * @param needed - whether the line has more after the label\n * @returns the label text, or null\n */\nfunction labelOf(labels: Column | null, ids: SanitizedIds, i: number, needed: boolean): string | null {\n if (labels !== null && labels.isSet(i)) {\n return cellText(labels, i);\n }\n if (needed || ids.isChanged(i)) {\n return idText(ids.originalAt(i));\n }\n return null;\n}\n\n/**\n * The text of an id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n return typeof id === \"number\" ? formatF64(id) : id;\n}\n\n/**\n * The spells text of a row, or null when unset or empty.\n * @param column - the spells list column\n * @param row - the row\n * @returns the interval token or null\n */\nfunction spellsText(column: Column, row: number): string | null {\n if (column.dtype !== \"list\" || !column.isSet(row)) {\n return null;\n }\n const items = column.sliceOf(row);\n if (items.length === 0) {\n return null;\n }\n const pairs: [number, number][] = [];\n for (const item of items) {\n const pair = item as ArrayLike<number>;\n pairs.push([pair[0], pair[1]]);\n }\n return formatIntervals(pairs);\n}\n\n/**\n * The coordinates text of a vertex, or null when unset.\n * @param column - the position column (2 or 3 components)\n * @param i - the node index\n * @param writeZ - whether z is written for a 3-component column\n * @returns \"x y\" or \"x y z\", or null\n */\nfunction coordinatesText(column: Column, i: number, writeZ: boolean): string | null {\n if (!column.isSet(i)) {\n return null;\n }\n const dtype = column.dtype as \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\";\n const vector = column.value(i) as ArrayLike<number>;\n const x = numberText(vector[0], dtype);\n const y = numberText(vector[1], dtype);\n if (column.meta.components === 3 && writeZ) {\n return `${x} ${y} ${numberText(vector[2], dtype)}`;\n }\n return `${x} ${y}`;\n}\n\n/**\n * Whether a 3-component position column needs its z written: the importer recorded sourceDims 3,\n * or any set row has a non-zero z (never drop data because of a 2-D hint).\n * @param column - the position column\n * @returns true when z is written\n */\nfunction needsZ(column: Column): boolean {\n if (column.meta.components !== 3) {\n return false;\n }\n if (column.meta.extra.sourceDims !== 2) {\n return true;\n }\n for (let i = 0; i < column.length; i++) {\n if (column.isSet(i)) {\n const vector = column.value(i) as ArrayLike<number>;\n if (vector[2] !== 0) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * The text parts of a Pajek document, one per line.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param options.networkHeader - whether the `*Network` line is written\n * @param options.mangle - whether the original ids are written as `graphty_originalId` parameters\n * @yields lines with their terminator\n * @returns nothing\n */\nfunction* writeParts(\n snapshot: GraphSnapshot,\n options: { networkHeader: boolean; mangle: boolean },\n): Generator<string, void, undefined> {\n const ids = sanitizeIds(snapshot, CAPABILITIES.idCharset, options.mangle ? \"mangle\" : \"error\");\n const nodePlan = withoutReservedKey(plan(snapshot.nodes, \"node\", null), options.mangle);\n const edgePlan = plan(snapshot.edges, \"edge\", null);\n // fail before writing anything when a text cannot be written (the check() E_ note)\n const preflight: LossNote[] = [];\n checkCells(nodePlan, \"node\", preflight);\n checkCells(edgePlan, \"edge\", preflight);\n checkIdTexts(snapshot.nodeCount, ids, options.mangle, preflight);\n for (const n of preflight) {\n if (n.code === PAJEK_LOSS.TEXT) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", n.message, {\n reason: \"pajek label\",\n column: n.column,\n count: n.count,\n });\n }\n }\n\n if (options.networkHeader && snapshot.meta.name !== null) {\n yield `*Network ${snapshot.meta.name}\\n`;\n }\n const firstMode = firstModeOf(snapshot);\n yield firstMode !== null && !Number.isNaN(firstMode)\n ? `*Vertices ${snapshot.nodeCount} ${firstMode}\\n`\n : `*Vertices ${snapshot.nodeCount}\\n`;\n yield* writeVertices(snapshot, ids, nodePlan, options.mangle);\n yield* writeLines(snapshot, edgePlan);\n}\n\n/**\n * The node plan without a user column named like the exporter's originalId key, which is\n * reserved under \"mangle\" (check() reports it as not written).\n * @param nodePlan - the node column plan\n * @param mangle - whether the original ids are written as parameters\n * @returns the plan to write\n */\nfunction withoutReservedKey(nodePlan: readonly PlannedColumn[], mangle: boolean): readonly PlannedColumn[] {\n if (!mangle) {\n return nodePlan;\n }\n return nodePlan.filter((p) => !(p.slot === \"param\" && p.column.meta.name === ORIGINAL_ID_KEY));\n}\n\n/**\n * The notes about the id texts a vertex line carries: an id written as a label or, under\n * \"mangle\", as the `graphty_originalId` parameter must be a Pajek label (E_PAJEK_TEXT otherwise),\n * and under \"mangle\" an original id whose text reads back as the other type under ids\n * \"canonical\" is reported (the importer coerces the parameter text like every id cell).\n * @param nodeCount - the node count\n * @param ids - the sanitised ids\n * @param mangle - whether the original ids are written as parameters\n * @param notes - where to record\n */\nfunction checkIdTexts(nodeCount: number, ids: SanitizedIds, mangle: boolean, notes: LossNote[]): void {\n let badText = 0;\n let typeChanged = 0;\n for (let i = 0; i < nodeCount; i++) {\n if (!ids.isChanged(i)) {\n continue;\n }\n const original = ids.originalAt(i);\n const text = idText(original);\n if (!isPajekLabel(text)) {\n badText++;\n } else if (mangle && typeof canonicalId(text) !== typeof original) {\n typeChanged++;\n }\n }\n if (badText > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT,\n `${badText} node id(s) hold a double quote or a line break; Pajek cannot write them as labels or parameters`,\n null,\n badText,\n ),\n );\n }\n if (typeChanged > 0) {\n notes.push(\n note(\n PAJEK_LOSS.ID_TEXT_TYPE,\n `${typeChanged} original id(s) read back from ${ORIGINAL_ID_KEY} as the other type under ids: \"canonical\" (a string \"1\" becomes 1, a number 1.5 becomes \"1.5\")`,\n null,\n typeChanged,\n ),\n );\n }\n}\n\n/**\n * The vertex lines: number, label, coordinates, shape, parameters and interval.\n * @param snapshot - the snapshot\n * @param ids - the sanitised ids\n * @param nodePlan - the node column plan\n * @param mangle - whether a renumbered vertex carries its original id as a parameter\n * @yields one line per vertex\n * @returns nothing\n */\nfunction* writeVertices(\n snapshot: GraphSnapshot,\n ids: SanitizedIds,\n nodePlan: readonly PlannedColumn[],\n mangle: boolean,\n): Generator<string, void, undefined> {\n let labels: Column | null = null;\n let position: Column | null = null;\n let shape: Column | null = null;\n let nodeSpells: Column | null = null;\n const nodeParams: Column[] = [];\n for (const { column, slot } of nodePlan) {\n switch (slot) {\n case \"label\":\n labels = column;\n break;\n case \"position\":\n position = column;\n break;\n case \"shape\":\n shape = column;\n break;\n case \"spells\":\n nodeSpells = column;\n break;\n case \"param\":\n nodeParams.push(column);\n break;\n case \"relation\":\n case \"skip\":\n break;\n default: {\n const name: string = slot;\n throw new Error(`unknown slot ${name}`);\n }\n }\n }\n const writeZ = position !== null && needsZ(position);\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const parts: string[] = [];\n if (position !== null) {\n const coordinates = coordinatesText(position, i, writeZ);\n if (coordinates !== null) {\n parts.push(coordinates);\n }\n }\n if (shape !== null && shape.isSet(i)) {\n const keyword = cellText(shape, i);\n if (SHAPES.has(keyword)) {\n parts.push(keyword);\n } else {\n parts.push(`${SHAPE_COLUMN} ${quotePajekLabel(keyword)}`);\n }\n }\n for (const column of nodeParams) {\n if (column.isSet(i)) {\n parts.push(`${column.meta.name} ${quotePajekLabel(cellText(column, i))}`);\n }\n }\n if (mangle && ids.isChanged(i)) {\n parts.push(`${ORIGINAL_ID_KEY} ${quotePajekLabel(idText(ids.originalAt(i)))}`);\n }\n if (nodeSpells !== null) {\n const spells = spellsText(nodeSpells, i);\n if (spells !== null) {\n parts.push(spells);\n }\n }\n const label = labelOf(labels, ids, i, parts.length > 0);\n let line = String(i + 1);\n if (label !== null) {\n // the importer decodes `&#dddd;` in labels, so a literal one is written with `&#38;`\n line += ` ${quotePajekLabel(encodeCharacterReferences(label))}`;\n }\n if (parts.length > 0) {\n line += ` ${parts.join(\" \")}`;\n }\n yield `${line}\\n`;\n }\n}\n\n/**\n * The line sections: runs of `*Arcs` / `*Edges` (with a relation number and name when the edge\n * has one), one line per written edge with its weight, parameters and interval.\n * @param snapshot - the snapshot\n * @param edgePlan - the edge column plan\n * @yields one line per section header and edge\n * @returns nothing\n */\nfunction* writeLines(snapshot: GraphSnapshot, edgePlan: readonly PlannedColumn[]): Generator<string, void, undefined> {\n const folding = pairFolding(snapshot, { foldMutual: true });\n const weights = explicitWeights(snapshot);\n const { src, dst } = snapshot.edgeList();\n let relation: Column | null = null;\n let edgeSpells: Column | null = null;\n const edgeParams: Column[] = [];\n for (const { column, slot } of edgePlan) {\n switch (slot) {\n case \"relation\":\n relation = column;\n break;\n case \"spells\":\n edgeSpells = column;\n break;\n case \"param\":\n edgeParams.push(column);\n break;\n case \"label\":\n case \"position\":\n case \"shape\":\n case \"skip\":\n break;\n default: {\n const name: string = slot;\n throw new Error(`unknown slot ${name}`);\n }\n }\n }\n const relationNumbers = new Map<string, number>();\n let currentKind: \"arcs\" | \"edges\" | null = null;\n let currentRelation: string | null = null;\n let sectionOpen = false;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n // a mutual pair (design section 3.6): both directions, written once as an undirected edge\n const directed = snapshot.directed && folding.sourceDirected(e) && !folding.isMutual(e);\n const kind = directed ? \"arcs\" : \"edges\";\n const relationName = relation !== null && relation.isSet(e) ? cellText(relation, e) : null;\n if (!sectionOpen || kind !== currentKind || relationName !== currentRelation) {\n currentKind = kind;\n currentRelation = relationName;\n sectionOpen = true;\n const keyword = kind === \"arcs\" ? \"*Arcs\" : \"*Edges\";\n if (relationName === null) {\n yield `${keyword}\\n`;\n } else {\n let number = relationNumbers.get(relationName);\n if (number === undefined) {\n number = relationNumbers.size + 1;\n relationNumbers.set(relationName, number);\n }\n yield `${keyword} :${number} ${quotePajekLabel(relationName)}\\n`;\n }\n }\n let line = `${src[e] + 1} ${dst[e] + 1}`;\n const weight = weights.text(e);\n if (weight !== null) {\n line += ` ${weight}`;\n }\n for (const column of edgeParams) {\n if (column.isSet(e)) {\n line += ` ${column.meta.name} ${quotePajekLabel(cellText(column, e))}`;\n }\n }\n if (edgeSpells !== null) {\n const spells = spellsText(edgeSpells, e);\n if (spells !== null) {\n line += ` ${spells}`;\n }\n }\n yield `${line}\\n`;\n }\n if (!sectionOpen) {\n yield snapshot.directed ? \"*Arcs\\n\" : \"*Edges\\n\";\n }\n}\n\n/**\n * Resolve the Pajek export options.\n * @param options - the caller's options\n * @returns the resolved format options; the common options are checked by resolveExportOptions\n */\nfunction resolvePajekOptions(options: (PajekExportOptions & CommonExportOptions) | undefined): {\n networkHeader: boolean;\n mangle: boolean;\n} {\n const common = resolveExportOptions(options);\n const value = options?.networkHeader;\n if (value !== undefined && typeof value !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option networkHeader: not a boolean\", {\n option: \"networkHeader\",\n found: typeof value,\n });\n }\n return { networkHeader: value ?? false, mangle: common.sanitizeIds === \"mangle\" };\n}\n\n/** The Pajek NET exporter. */\nexport const pajekExporter: GraphExporter<PajekExportOptions> = Object.freeze({\n format: \"pajek\",\n capabilities: CAPABILITIES,\n\n /**\n * Pre-flight: the generic capability gaps plus the Pajek-specific ones.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the loss notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): readonly LossNote[] {\n const resolved = resolveExportOptions(options);\n const { mangle } = resolvePajekOptions(options);\n const notes: LossNote[] = [];\n const planned = plan(snapshot.nodes, \"node\", notes);\n const nodePlan = withoutReservedKey(planned, mangle);\n const edgePlan = plan(snapshot.edges, \"edge\", notes);\n const ids = sanitizeIds(snapshot, CAPABILITIES.idCharset, mangle ? \"mangle\" : \"error\");\n checkIdTexts(snapshot.nodeCount, ids, mangle, notes);\n if (nodePlan.length !== planned.length) {\n const reserved = planned.find((p) => p.slot === \"param\" && p.column.meta.name === ORIGINAL_ID_KEY);\n if (reserved !== undefined) {\n notes.push(\n note(\n PAJEK_LOSS.KEY_DROPPED,\n `node column \"${ORIGINAL_ID_KEY}\" is the parameter the exporter writes the original ids under (sanitizeIds \"mangle\"); it is not written`,\n ORIGINAL_ID_KEY,\n reserved.column.length - reserved.column.nullCount,\n ),\n );\n }\n }\n // columns this exporter handles itself although the generic table says otherwise: the spells\n // list (written as an interval token, or reported above with the spells code), the shape\n // keyword and the relation name (dict columns written as keywords)\n const owned = new Set<string>();\n for (const { column, slot } of [...nodePlan, ...edgePlan]) {\n if (slot === \"shape\" || slot === \"relation\") {\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n } else if (slot === \"param\" && column.meta.domain === \"node\" && column.meta.name === SHAPE_COLUMN) {\n // the shape-as-parameter note already says the column reads back as string\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n }\n }\n for (const table of [snapshot.nodes, snapshot.edges]) {\n for (const column of table) {\n if (column.meta.role === \"spells\") {\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n }\n }\n }\n for (const n of checkCapabilities(snapshot, CAPABILITIES, resolved, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n })) {\n if (n.column !== null && (n.code === LOSS.LIST || n.code === LOSS.DTYPE)) {\n const domain = n.message.startsWith(\"node column\") ? \"node\" : \"edge\";\n if (owned.has(`${domain}:${n.column}`)) {\n continue;\n }\n }\n if (n.code === LOSS.COLUMN_NAME_CHANGED && n.message.startsWith(\"edge column\")) {\n // the label slot is a vertex slot; an edge label is a parameter under its own name\n continue;\n }\n notes.push(n);\n }\n labelNotes(snapshot, nodePlan, notes);\n for (const column of snapshot.edges) {\n if (column.meta.role === \"label\") {\n notes.push(\n note(\n LOSS.ROLE,\n `edge column \"${column.meta.name}\" (label) is written as a plain parameter; Pajek labels vertices only and the role is lost`,\n column.meta.name,\n column.length - column.nullCount,\n ),\n );\n }\n }\n checkCells(nodePlan, \"node\", notes);\n checkCells(edgePlan, \"edge\", notes);\n const folding = pairFolding(snapshot, { foldMutual: true });\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n PAJEK_LOSS.MUTUAL_AS_UNDIRECTED,\n `${folding.mutualCount} mutual pair(s) are written as undirected edges; the mutual mark is lost`,\n snapshot.edges.byRole(\"mutual\")?.meta.name ?? null,\n folding.mutualCount,\n ),\n );\n }\n if (Number.isNaN(firstModeOf(snapshot))) {\n notes.push(\n note(\n PAJEK_LOSS.FIRST_MODE_DROPPED,\n \"meta.extra.pajek.firstMode is not a count within 0..nodeCount; the two-mode header is not written\",\n ),\n );\n }\n return notes;\n },\n\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n const resolved = resolvePajekOptions(options);\n return encodeChunks(writeParts(snapshot, resolved));\n },\n\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): Promise<string> {\n const resolved = resolvePajekOptions(options);\n return joinText(writeParts(snapshot, resolved));\n },\n});\n","/**\n * The Pajek NET importer (design sections 8.4 and 8.6; research note 07 section 2.5): a\n * line-oriented streaming reader over the common LineReader that pushes scalars into the sink as\n * each line is read. `*Vertices N` declares vertices 1..N (0..N-1 for the zero-based files some\n * scripts write, detected from the first vertex line), so the id map of a well-formed file is\n * `identity` with offset 1; vertex lines add the label, the coordinates (the position role,\n * units \"file\"), the shape keyword and the `key value` parameters (a `graphty_originalId`\n * parameter, written by the exporter under `sanitizeIds: \"mangle\"`, is restored as the vertex's\n * id under `restoreMangledIds`); `*Arcs` sections are directed\n * and `*Edges` sections undirected, resolved through the common DirectionResolver under the\n * mixed-direction policy; the third column of a line is the weight unless `weightFrom` says\n * otherwise; `*Arcslist` / `*Edgeslist` adjacency lists and `*Matrix` rows are read too; time\n * interval tokens `[1-5,7-*]` become the spells role. A second network in one file is refused\n * with an issue. A project file's `*Partition` and `*Vector` objects become the node columns\n * `partition` (i32) and `vector` (f64), wherever they stand in the file; other project-file\n * sections (`*Events`, `*Permutation`, ...) are skipped with a warning.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type U32,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, RENAMED_CODE, ROLE_TAKEN_CODE, uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MULTIPLE_GRAPHS_CODE,\n OPTION_IGNORED_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { coerceIdText, ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { LineReader, throwIfAborted } from \"../../common/input.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n SINK_OPTION_CODE,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { isNumericText, TextCellWriter, WIDENING_UNSUPPORTED_CODE } from \"../../common/text.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n decodeCharacterReferences,\n isCommentOrBlank,\n isIntervalToken,\n isSectionLine,\n isShapeKeyword,\n isVertexNumber,\n LABEL_COLUMN,\n ORIGINAL_ID_KEY,\n parseIntervals,\n parseSectionHeader,\n PARTITION_COLUMN,\n POSITION_COLUMN,\n RELATION_COLUMN,\n type SectionHeader,\n SHAPE_COLUMN,\n SPELLS_COLUMN,\n tokenize,\n VALUE_COLUMN,\n VALUE_FIELD,\n VECTOR_COLUMN,\n} from \"./syntax.js\";\n\n/** The format-specific options of the Pajek importer. */\nexport interface PajekImportOptions {\n /**\n * The number of the first vertex: 1 (Pajek's rule), 0 (files written by zero-based scripts), or\n * \"auto\" (default): 0 when the first vertex line is numbered 0, 1 otherwise.\n */\n firstVertex?: 0 | 1 | \"auto\" | undefined;\n}\n\n/** Issue codes of the Pajek importer. */\nexport const PAJEK_ISSUE = Object.freeze({\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** Fatal: no `*Vertices` section (an empty file, or not a Pajek network). */\n NO_VERTICES: \"E_PAJEK_NO_VERTICES\",\n /** Fatal: `*Vertices` without a vertex count, one the sink cannot hold, or a first-mode count outside 0..N. */\n VERTICES_COUNT: \"E_PAJEK_VERTICES_COUNT\",\n /** A project file holds several networks; import() reads the first, importAll() reads every one. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** A data line before the first section header. */\n OUTSIDE_SECTION: \"E_PAJEK_OUTSIDE_SECTION\",\n /** A section header the importer cannot parse. */\n SYNTAX: SYNTAX_CODE,\n /** A double quote not closed before the end of the line. */\n UNTERMINATED_QUOTE: \"E_PAJEK_UNTERMINATED_QUOTE\",\n /** A vertex line the grammar does not accept. */\n VERTEX_LINE: \"E_PAJEK_VERTEX_LINE\",\n /** A vertex number outside the declared range. */\n VERTEX_RANGE: \"E_PAJEK_VERTEX_RANGE\",\n /** Fewer vertex lines than `*Vertices` declares, which the Pajek manual allows (vertices without a line have no label). */\n VERTEX_COUNT: \"W_PAJEK_VERTEX_COUNT\",\n /** A second line for the same vertex; the later values overwrite. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A line (arc, edge, list, matrix row, partition or vector value) the grammar does not accept. */\n LINE: \"E_PAJEK_LINE\",\n /** A line endpoint outside the declared vertex range (the core's code, forwarded). */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /** A malformed time interval token. */\n INTERVAL: \"E_PAJEK_INTERVAL\",\n /** A `*Matrix` section with the wrong number of rows (N, or N1 in a two-mode network). */\n MATRIX_ROWS: \"E_PAJEK_MATRIX_ROWS\",\n /** `*Matrix` rows longer than the column count; the extra values are ignored. */\n MATRIX_EXTRA: \"W_PAJEK_MATRIX_EXTRA\",\n /** A `*Partition` or `*Vector` whose value count differs from the network's vertex count; values beyond it are dropped, vertices without one are unset. */\n OBJECT_COUNT: \"E_PAJEK_OBJECT_COUNT\",\n /** A project-file section (`*Events`, `*Permutation`, ...) the importer does not read; its lines are skipped. */\n UNSUPPORTED_SECTION: \"W_PAJEK_UNSUPPORTED_SECTION\",\n /** Tokens after a section header the grammar does not account for. */\n HEADER_EXTRA: \"W_PAJEK_HEADER_EXTRA\",\n /** The file declares vertices but no line section. */\n NO_LINES: \"W_PAJEK_NO_LINES\",\n /** Vertex numbering starts at 0 rather than 1. */\n ZERO_BASED: \"W_PAJEK_ZERO_BASED\",\n /** Vertex lines mix two and three coordinates. */\n COORD_DIMS: \"W_PAJEK_COORD_DIMS\",\n /** Two vertices share a label under nodeIdFrom \"label\" and became one node. */\n LABEL_MERGED: \"W_PAJEK_LABEL_MERGED\",\n /** Two distinct label texts became one numeric id under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A parameter column of `2.0`-style text kept at the value-inferred dtype (the sink cannot widen). */\n WIDENING_UNSUPPORTED: WIDENING_UNSUPPORTED_CODE,\n /** A structural column (label, position, shape, spells, relation) renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: RENAMED_CODE,\n /** A structural column declared without its role because the sink already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two vertices carry the same `graphty_originalId` under restoreMangledIds and became one node. */\n ORIGINAL_ID_MERGED: \"W_PAJEK_ORIGINAL_ID_MERGED\",\n /** A vertex line's `graphty_originalId` came after a later vertex's line had created it under its number. */\n ORIGINAL_ID_UNRESTORED: \"W_PAJEK_ORIGINAL_ID_UNRESTORED\",\n /** A common option the importer has no use for (weightFrom naming a parameter and restoreMangledIds are honoured; long, hyperedges are not). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the caller passed that the caller's sink does not use (the shared W_SINK_OPTION). */\n SINK_OPTION: SINK_OPTION_CODE,\n});\n\n/** The common options the Pajek importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"restoreMangledIds\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: true, weightFrom: VALUE_FIELD };\n\n/** Lines between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst FIRST_VERTEX_VALUES: ReadonlySet<unknown> = new Set([0, 1, \"auto\"]);\n\nconst LABEL_DECL: ColumnDecl = {\n name: LABEL_COLUMN,\n dtype: \"string\",\n nullable: true,\n role: \"label\",\n origin: { format: \"pajek\", id: \"label\" },\n};\n\nconst SHAPE_DECL: ColumnDecl = {\n name: SHAPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n origin: { format: \"pajek\", id: \"shape\" },\n};\n\nconst RELATION_DECL: ColumnDecl = {\n name: RELATION_COLUMN,\n dtype: \"dict\",\n nullable: true,\n origin: { format: \"pajek\", id: \"relation\" },\n};\n\n/**\n * The spells column declaration of a domain (design section 5.1: a list of f64 pairs).\n * @returns a fresh declaration\n */\nfunction spellsDecl(): ColumnDecl {\n return {\n name: SPELLS_COLUMN,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n nullable: true,\n role: \"spells\",\n origin: { format: \"pajek\", id: \"interval\" },\n };\n}\n\n/**\n * The position column declaration (design section 5.2: f32 x 3, role position, units \"file\").\n * @param sourceDims - 2 or 3, the coordinate count of the first vertex line with coordinates\n * @returns a fresh declaration\n */\nfunction positionDecl(sourceDims: number): ColumnDecl {\n return {\n name: POSITION_COLUMN,\n dtype: \"f32\",\n components: 3,\n nullable: true,\n role: \"position\",\n origin: { format: \"pajek\", id: \"coordinates\" },\n extra: { sourceDims, units: \"file\" },\n };\n}\n\n/** A problem with one line, recorded as an issue by the per-line catch. */\nclass LineError extends Error {\n readonly category: \"parse-error\" | \"validation-error\" | \"missing-value\";\n\n readonly code: string;\n\n /**\n * Create a line error.\n * @param category - the issue category\n * @param code - the issue code\n * @param message - a plain-ASCII message\n */\n constructor(category: \"parse-error\" | \"validation-error\" | \"missing-value\", code: string, message: string) {\n super(message);\n this.name = \"PajekLineError\";\n this.category = category;\n this.code = code;\n }\n}\n\n/** What a vertex or line row carries besides its numbers, parsed before anything is written. */\ninterface RowExtras {\n /** Parameter keys, in order. */\n readonly keys: string[];\n /** Parameter value texts, aligned with keys. */\n readonly values: string[];\n /** The spells of an interval token, or null. */\n spells: [number, number][] | null;\n}\n\n/** The section the parser is in. */\ntype Section = \"none\" | \"vertices\" | \"lines\" | \"list\" | \"matrix\" | \"object\" | \"skip\";\n\n/**\n * A `*Partition` or `*Vector` object of a project file, buffered until the end of the network:\n * one may come before the network whose vertices it describes.\n */\ninterface ProjectObject {\n readonly kind: \"partition\" | \"vector\";\n /** The object's name from its header. */\n readonly name: string;\n /** The header's line number. */\n readonly line: number;\n /** The object's own `*Vertices N`, or null without one. */\n count: number | null;\n /** The value per vertex position; null for a line that could not be read. */\n readonly values: (number | null)[];\n}\n\n/**\n * Whether a number is an integer the i32 partition column can hold.\n * @param value - the number\n * @returns true for an i32 integer\n */\nfunction isI32(value: number): boolean {\n return Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;\n}\n\n/** A vertex number of an adjacency list: Pajek reads a negative one as its absolute value. */\nconst LIST_VERTEX = /^-?[0-9]+$/;\n\n/** The relation prefix `k:` of a line in a line section. */\nconst RELATION_PREFIX = /^([0-9]+):$/;\n\n/**\n * One import call's state machine: the sections, the vertex range, the columns declared so far\n * and the direction resolver.\n */\nclass PajekParser {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly resolver: DirectionResolver;\n\n private readonly coercer: IdCoercer;\n\n private readonly firstVertex: 0 | 1 | \"auto\";\n\n private section: Section = \"none\";\n\n /** The direction of the current line section. */\n private kind: EdgeKind = \"directed\";\n\n /** The relation name of the current line section, or null. */\n private relation: string | null = null;\n\n /** `*Vertices N`; -1 before the header. */\n private vertexCount = -1;\n\n /** The first-mode count of a two-mode network, or null. */\n private firstMode: number | null = null;\n\n private networkName: string | null = null;\n\n private base = 1;\n\n private baseKnown = false;\n\n private nodesCreated = false;\n\n private verticesDone = false;\n\n private sawLineSection = false;\n\n /** The direction of the first line section, for a network whose line sections are all empty. */\n private firstKind: EdgeKind = \"directed\";\n\n /** Set once the first line has fixed the sink's direction. */\n private directionSet = false;\n\n /** The names of the numbered relations (`*Arcs :k \"name\"`), for the `k:` line prefix. */\n private readonly relationNames = new Map<number, string>();\n\n /** The `*Partition` / `*Vector` objects read so far, written by finish(). */\n private readonly objects: ProjectObject[] = [];\n\n /** Set when the previous line was a project-object header, whose `*Vertices N` line comes next. */\n private objectHeader = false;\n\n /** Node index per vertex position (vertex number minus base). */\n private indexOfPos: U32 = new Uint32Array(0);\n\n /**\n * The node id per vertex position when the vertex lines decide the ids (nodeIdFrom \"label\",\n * or a restorable `graphty_originalId` under restoreMangledIds); null when the ids are the\n * vertex numbers and every vertex is created up front.\n */\n private idOfPos: NodeId[] | null = null;\n\n /** Which positions had a vertex line. */\n private seen: Uint8Array = new Uint8Array(0);\n\n private seenCount = 0;\n\n /**\n * Every position below this one already has an id in `idOfPos`: the high-water mark of the\n * gap-fill in `vertexLine`. Without it the gap-fill restarts at zero on every vertex line, which\n * is quadratic in the vertex count for a file whose lines are in ascending order -- which is the\n * order Pajek itself writes.\n */\n private filledBelow = 0;\n\n private matrixRows = 0;\n\n private coordDims = 0;\n\n private labelHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private positionHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private shapeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private nodeSpellsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private relationHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private edgeSpellsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly nodeParams = new Map<string, TextCellWriter>();\n\n /** Set when a header line starts the next network of a project file (that line is not consumed). */\n private ended = false;\n\n private readonly edgeParams = new Map<string, TextCellWriter>();\n\n /**\n * Create the parser for one import call.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param firstVertex - the firstVertex format option\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n firstVertex: 0 | 1 | \"auto\",\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.firstVertex = firstVertex;\n this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Handle one line; every problem of the line is recorded as an issue and the line skipped.\n * @param text - the line without its terminator\n * @param line - the 1-based line number\n * @returns true when the line is the header of the next network (not consumed: this network is complete)\n */\n line(text: string, line: number): boolean {\n if (isCommentOrBlank(text)) {\n return false;\n }\n const afterObjectHeader = this.objectHeader;\n this.objectHeader = false;\n try {\n if (isSectionLine(text)) {\n this.header(text, line, afterObjectHeader);\n return this.ended;\n }\n switch (this.section) {\n case \"none\":\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.OUTSIDE_SECTION,\n \"data before the first section header; a Pajek network starts with *Vertices\",\n );\n case \"vertices\":\n this.vertexLine(text, line);\n return false;\n case \"lines\":\n this.edgeLine(text, line);\n return false;\n case \"list\":\n this.listLine(text, line);\n return false;\n case \"matrix\":\n this.matrixLine(text, line);\n return false;\n case \"object\":\n this.objectLine(text);\n return false;\n case \"skip\":\n return false;\n default: {\n const name: string = this.section;\n throw new Error(`unknown section state ${name}`);\n }\n }\n } catch (err) {\n if (err instanceof LineError) {\n this.report.error(err.category, err.code, err.message, { line });\n return false;\n }\n this.report.recordError(err, { line });\n return false;\n }\n }\n\n /**\n * End of input: the vertex set is completed, a network without line sections gets the default\n * direction, and the metadata is written.\n */\n finish(): void {\n if (this.vertexCount < 0) {\n this.report.fail(PAJEK_ISSUE.NO_VERTICES, \"not a Pajek network: no *Vertices section found\");\n }\n this.endSection();\n this.finishVertices();\n if (!this.sawLineSection) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.NO_LINES,\n \"the file declares vertices but no *Arcs, *Edges, *Arcslist, *Edgeslist or *Matrix section\",\n );\n this.resolver.setHeader(this.options.defaultDirected);\n } else if (!this.directionSet) {\n // every line section was empty: the first header still says which way the network goes\n this.resolver.setHeader(this.firstKind === \"directed\");\n }\n const objects = this.writeObjects();\n if (this.coercer.mergeCount > 0) {\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ID_MERGED,\n `${this.coercer.mergeCount} label(s) merged into an id another label already produced under ids \"number\"`,\n );\n }\n const pajek = {\n ...(this.firstMode === null ? {} : { firstMode: this.firstMode }),\n ...(objects.length === 0 ? {} : { objects }),\n };\n const meta: GraphMetaPatch = {\n sourceFormat: \"pajek\",\n ...(this.networkName === null ? {} : { name: this.networkName }),\n ...(Object.keys(pajek).length === 0 ? {} : { extra: { pajek } }),\n };\n this.sink.setMeta(meta);\n }\n\n /**\n * Write every `*Partition` / `*Vector` object into its node column: `partition` (i32) or\n * `vector` (f64), a later object of the same kind in `partition#2`, `vector#2`, ... The value\n * of vertex k is the object's k-th value.\n * @returns the objects' Pajek names and the columns they went to, for meta.extra.pajek.objects\n */\n private writeObjects(): { kind: string; name: string; column: string }[] {\n const used = new Set<string>();\n const written: { kind: string; name: string; column: string }[] = [];\n for (const object of this.objects) {\n const where = { line: object.line };\n const partition = object.kind === \"partition\";\n const name = uniqueColumnName(partition ? PARTITION_COLUMN : VECTOR_COLUMN, null, (n) => used.has(n));\n used.add(name);\n const { handle, decl } = declareResolved(\n this.sink,\n \"node\",\n {\n name,\n dtype: partition ? \"i32\" : \"f64\",\n nullable: true,\n origin: { format: \"pajek\", id: object.kind },\n },\n this.report,\n where,\n );\n const n = Math.min(object.values.length, this.vertexCount);\n for (let pos = 0; pos < n; pos++) {\n const value = object.values[pos];\n if (value !== null) {\n this.sink.setNodeValue(handle, this.indexOfPos[pos], value);\n }\n }\n const declared = object.count ?? object.values.length;\n if (declared !== this.vertexCount || object.values.length !== declared) {\n this.report.error(\n \"validation-error\",\n PAJEK_ISSUE.OBJECT_COUNT,\n `*${partition ? \"Partition\" : \"Vector\"} \"${object.name}\" declares ${declared} vertices and holds ${object.values.length} value(s); the network has ${this.vertexCount}`,\n where,\n );\n }\n written.push({ kind: object.kind, name: object.name, column: decl.name });\n }\n return written;\n }\n\n // ============================================================ headers\n\n /**\n * A section header line.\n * @param text - the line\n * @param line - the line number\n * @param afterObjectHeader - the previous line was a `*Partition`, `*Vector` or skipped section header\n */\n private header(text: string, line: number, afterObjectHeader: boolean): void {\n const previous = this.section;\n this.endSection();\n const h = parseSectionHeader(text);\n if (h === null) {\n this.section = \"skip\";\n throw new LineError(\"parse-error\", PAJEK_ISSUE.SYNTAX, `cannot read the section header \"${text}\"`);\n }\n if (h.extra.length > 0) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.HEADER_EXTRA,\n `ignored ${h.extra.length} unexpected token(s) after *${h.keyword}: ${h.extra.join(\" \")}`,\n { line },\n );\n }\n switch (h.kind) {\n case \"network\":\n if (this.networkName !== null || this.vertexCount >= 0) {\n this.ended = true;\n return;\n }\n this.networkName = h.name ?? \"\";\n this.section = \"none\";\n return;\n case \"vertices\":\n if (afterObjectHeader) {\n // the `*Vertices N` line of a project object (*Partition, *Vector, a skipped\n // section), wherever it stands: never the network's own\n this.section = previous;\n if (previous === \"object\") {\n this.objects[this.objects.length - 1].count = h.count;\n }\n return;\n }\n if (this.vertexCount >= 0) {\n // a second `*Vertices` without a `*Network` header starts the next network\n this.ended = true;\n return;\n }\n this.verticesHeader(h, line);\n return;\n case \"arcs\":\n case \"edges\":\n this.lineSection(h, line, \"lines\", h.kind === \"arcs\" ? \"directed\" : \"undirected\");\n return;\n case \"arcslist\":\n case \"edgeslist\":\n this.lineSection(h, line, \"list\", h.kind === \"arcslist\" ? \"directed\" : \"undirected\");\n return;\n case \"matrix\":\n this.lineSection(h, line, \"matrix\", \"directed\");\n this.matrixRows = 0;\n return;\n case \"partition\":\n case \"vector\":\n this.objects.push({ kind: h.kind, name: h.name ?? \"\", line, count: null, values: [] });\n this.section = \"object\";\n this.objectHeader = true;\n return;\n case \"unsupported\":\n this.section = \"skip\";\n this.objectHeader = true;\n this.report.warning(\n \"unsupported\",\n PAJEK_ISSUE.UNSUPPORTED_SECTION,\n `the *${h.keyword} section is not supported; its lines are skipped`,\n { line },\n );\n return;\n default: {\n const name: string = h.kind;\n throw new Error(`unknown section kind ${name}`);\n }\n }\n }\n\n /**\n * `*Vertices N [N1]`.\n * @param h - the header\n * @param line - the line number\n */\n private verticesHeader(h: SectionHeader, line: number): void {\n if (h.count === null) {\n this.report.fail(PAJEK_ISSUE.VERTICES_COUNT, \"*Vertices needs a vertex count\", { line });\n }\n if (!Number.isSafeInteger(h.count)) {\n this.report.fail(PAJEK_ISSUE.VERTICES_COUNT, `*Vertices ${h.count}: not a count`, { line });\n }\n if (h.secondCount !== null && (h.secondCount < 0 || h.secondCount > h.count)) {\n this.report.fail(\n PAJEK_ISSUE.VERTICES_COUNT,\n `*Vertices ${h.count} ${h.secondCount}: the first-mode count is not within 0..${h.count}`,\n { line },\n );\n }\n try {\n // the declared count must be reservable (the sink is the authority on what it can hold,\n // E_TOO_LARGE beyond MAX_COUNT) before any vertex is materialised\n this.sink.reserve(h.count);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n this.report.fail(\n PAJEK_ISSUE.VERTICES_COUNT,\n `*Vertices ${h.count}: the sink cannot hold that many (${reason})`,\n {\n line,\n },\n );\n }\n this.vertexCount = h.count;\n if (h.secondCount !== null) {\n this.firstMode = h.secondCount;\n }\n this.section = \"vertices\";\n this.indexOfPos = new Uint32Array(h.count);\n this.seen = new Uint8Array(h.count);\n this.filledBelow = 0;\n if (this.options.nodeIdFrom === \"label\" || this.restoresIds()) {\n this.idOfPos = new Array<NodeId>(h.count);\n }\n if (this.firstVertex !== \"auto\") {\n this.setBase(this.firstVertex, line);\n }\n }\n\n /**\n * A line section header: the vertex set is completed and the kind switched. The sink's\n * direction (rule 1 of design section 8.4) is set by the first LINE, not the first header, so\n * an empty `*Arcs` before the `*Edges` of an undirected network does not make it directed.\n * @param h - the header\n * @param line - the line number\n * @param section - the parser state for the section\n * @param kind - the direction of its lines\n */\n private lineSection(h: SectionHeader, line: number, section: Section, kind: EdgeKind): void {\n if (this.vertexCount < 0) {\n this.report.fail(\n PAJEK_ISSUE.NO_VERTICES,\n `*${h.keyword} before *Vertices; a Pajek network starts with *Vertices`,\n { line },\n );\n }\n this.finishVertices();\n if (!this.sawLineSection) {\n this.sawLineSection = true;\n this.firstKind = kind;\n }\n this.section = section;\n this.kind = kind;\n this.relation = h.relation === null ? null : (h.name ?? String(h.relation));\n if (h.relation !== null) {\n this.relationNames.set(h.relation, this.relation ?? String(h.relation));\n }\n }\n\n /**\n * Checks that run when a section ends.\n */\n private endSection(): void {\n const rows = this.firstMode ?? this.vertexCount;\n if (this.section === \"matrix\" && this.matrixRows !== rows) {\n this.report.error(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_ROWS,\n `*Matrix has ${this.matrixRows} row(s); *Vertices declares ${rows}`,\n );\n }\n this.section = \"none\";\n }\n\n // ============================================================ vertices\n\n /**\n * Fix the vertex numbering base and, under nodeIdFrom \"id\" / \"index\", create the declared\n * vertices in number order so the id map is identity.\n * @param base - 0 or 1\n * @param line - the line number\n */\n private setBase(base: 0 | 1, line: number): void {\n this.base = base;\n this.baseKnown = true;\n if (base === 0) {\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ZERO_BASED,\n \"vertex numbering starts at 0; Pajek numbers vertices from 1\",\n { line },\n );\n }\n }\n\n /**\n * Push vertices base..base+N-1 in order (nodeIdFrom \"id\" / \"index\"), so the id map is identity;\n * called on the first vertex line (once it is known that the lines carry no `graphty_originalId`\n * parameter to restore) or when the vertex section ends without one.\n */\n private createNodes(): void {\n if (this.nodesCreated || this.idOfPos !== null) {\n return;\n }\n this.nodesCreated = true;\n const n = this.vertexCount;\n const { sink } = this;\n for (let pos = 0; pos < n; pos++) {\n this.indexOfPos[pos] = sink.addNode(this.idOfNumber(pos + this.base));\n }\n this.report.counts.nodes += n;\n }\n\n /**\n * The id of a vertex number under nodeIdFrom \"id\" (the number coerced by the ids rule) or\n * \"index\" (the position).\n * @param k - the vertex number\n * @returns the id\n */\n private idOfNumber(k: number): NodeId {\n if (this.options.nodeIdFrom === \"index\") {\n return k - this.base;\n }\n switch (this.options.ids) {\n case \"canonical\":\n case \"number\":\n return k;\n case \"keep\":\n case \"string\":\n return String(k);\n default:\n return coerceIdText(String(k), this.options.ids);\n }\n }\n\n /**\n * The id of a vertex position, for addEdge.\n * @param pos - the vertex number minus the base\n * @returns the id\n */\n private idAt(pos: number): NodeId {\n if (this.idOfPos !== null) {\n return this.idOfPos[pos];\n }\n return this.idOfNumber(pos + this.base);\n }\n\n /**\n * Complete the vertex set once the vertex section is over: vertices without a line are\n * created (under \"label\" or a restored `graphty_originalId` with their number as the id), and\n * a partial list is reported.\n */\n private finishVertices(): void {\n if (this.verticesDone) {\n return;\n }\n this.verticesDone = true;\n if (!this.baseKnown) {\n this.setBase(1, 0);\n }\n const n = this.vertexCount;\n this.createNodes();\n if (this.idOfPos !== null) {\n for (let pos = 0; pos < n; pos++) {\n if (this.idOfPos[pos] === undefined) {\n this.numberedNode(this.idOfPos, pos);\n }\n }\n }\n // a partial list: fewer lines than declared, counting the lines skipped after an error\n const lines = this.seenCount + this.report.counts.skippedNodes;\n if (this.seenCount > 0 && lines < n) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.VERTEX_COUNT,\n `*Vertices declares ${n} vertices but ${lines} vertex line(s) were read; the others have no label`,\n );\n }\n }\n\n /**\n * A vertex line: `number [label] [x y [z]] [shape] [key value ...] [interval]`.\n * @param text - the line\n * @param line - the line number\n */\n private vertexLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"node\");\n if (!isVertexNumber(tokens[0])) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.VERTEX_LINE,\n `a vertex line starts with a vertex number, not \"${tokens[0]}\"`,\n );\n }\n const k = Number(tokens[0]);\n if (!this.baseKnown) {\n this.setBase(k === 0 ? 0 : 1, line);\n }\n const pos = k - this.base;\n if (pos < 0 || pos >= this.vertexCount) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.VERTEX_RANGE,\n `vertex ${k} is outside ${this.base}..${this.base + this.vertexCount - 1}`,\n );\n }\n // parse everything before writing anything\n let i = 1;\n let label: string | null = null;\n if (tokens.length > 1 && !startsWithCoordinates(text, tokens)) {\n label = decodeCharacterReferences(tokens[1]);\n i = 2;\n }\n let x = 0;\n let y = 0;\n let z = 0;\n let dims = 0;\n if (i + 1 < tokens.length && isNumericText(tokens[i]) && isNumericText(tokens[i + 1])) {\n x = Number(tokens[i]);\n y = Number(tokens[i + 1]);\n i += 2;\n dims = 2;\n if (i < tokens.length && isNumericText(tokens[i])) {\n z = Number(tokens[i]);\n i++;\n dims = 3;\n }\n } else if (i < tokens.length && isNumericText(tokens[i])) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.VERTEX_LINE,\n `vertex ${k}: a single coordinate \"${tokens[i]}\"; coordinates are x y [z]`,\n );\n }\n let shape: string | null = null;\n if (i < tokens.length && isShapeKeyword(tokens[i])) {\n shape = tokens[i].toLowerCase();\n i++;\n }\n const extras = this.extras(tokens, i, \"node\");\n const restored = this.restoredId(extras);\n this.createNodes();\n // write\n const repeated = this.seen[pos] !== 0;\n if (repeated) {\n this.report.warning(\n \"merged\",\n PAJEK_ISSUE.DUPLICATE_NODE,\n `vertex ${k} has more than one line; the later values overwrite`,\n { line, element: String(k) },\n );\n } else {\n this.seen[pos] = 1;\n this.seenCount++;\n }\n let index: number;\n if (this.idOfPos !== null && !repeated && this.options.nodeIdFrom === \"label\") {\n index = this.deferredNode(this.idOfPos, pos, k, label, line, \"label\");\n } else if (this.idOfPos !== null && this.idOfPos[pos] === undefined) {\n // restore mode: the earlier positions without a line yet get their numbers first, so the\n // index order is the vertex number order whatever the line order (the identity id map\n // of an ordered file); then this vertex with its original id, or its number\n for (let p = this.filledBelow; p < pos; p++) {\n if (this.idOfPos[p] === undefined) {\n this.numberedNode(this.idOfPos, p);\n }\n }\n // after the loop on purpose: a throw part-way leaves the mark at its smaller, still\n // correct value and the next line re-scans the range\n if (pos > this.filledBelow) {\n this.filledBelow = pos;\n }\n index = this.deferredNode(this.idOfPos, pos, k, restored, line, \"originalId\");\n } else {\n index = this.indexOfPos[pos];\n if (restored !== null && !repeated) {\n // an out-of-order line: the vertex already exists under its number\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ORIGINAL_ID_UNRESTORED,\n `vertex ${k} carries ${ORIGINAL_ID_KEY} ${JSON.stringify(restored)} but a later vertex's line came first and created it under its number; the original id is not restored`,\n { line, element: String(k) },\n );\n }\n }\n const { sink } = this;\n if (label !== null) {\n if (this.labelHandle === INVALID_INDEX) {\n this.labelHandle = declareResolved(sink, \"node\", LABEL_DECL, this.report, { line }).handle;\n }\n sink.setNodeValue(this.labelHandle, index, label);\n }\n if (dims > 0) {\n if (this.positionHandle === INVALID_INDEX) {\n this.coordDims = dims;\n this.positionHandle = declareResolved(sink, \"node\", positionDecl(dims), this.report, { line }).handle;\n } else if (dims !== this.coordDims) {\n this.report.warnOnce(\n \"validation-error\",\n PAJEK_ISSUE.COORD_DIMS,\n `vertex lines mix ${this.coordDims} and ${dims} coordinates; the position column records sourceDims ${this.coordDims}`,\n { line, element: String(k) },\n );\n }\n sink.setNodeValue(this.positionHandle, index, [x, y, z]);\n }\n if (shape !== null) {\n if (this.shapeHandle === INVALID_INDEX && this.nodeParams.has(SHAPE_COLUMN)) {\n // an earlier `shape \"<text>\"` parameter owns the column: the keyword is written there\n this.writeParameter(\"node\", SHAPE_COLUMN, index, shape);\n } else {\n if (this.shapeHandle === INVALID_INDEX) {\n this.shapeHandle = declareResolved(sink, \"node\", SHAPE_DECL, this.report, { line }).handle;\n }\n sink.setNodeValue(this.shapeHandle, index, shape);\n }\n }\n for (let p = 0; p < extras.keys.length; p++) {\n this.writeParameter(\"node\", extras.keys[p], index, extras.values[p]);\n }\n if (extras.spells !== null) {\n if (this.nodeSpellsHandle === INVALID_INDEX) {\n this.nodeSpellsHandle = declareResolved(sink, \"node\", spellsDecl(), this.report, { line }).handle;\n }\n sink.setNodeValue(this.nodeSpellsHandle, index, extras.spells);\n }\n }\n\n /**\n * Whether a `graphty_originalId` parameter is restored as the vertex id: restoreMangledIds\n * under nodeIdFrom \"id\" (under \"label\" / \"index\" the parameter stays an ordinary column).\n * @returns true when the vertex lines may carry restorable ids\n */\n private restoresIds(): boolean {\n return this.options.restoreMangledIds && this.options.nodeIdFrom === \"id\";\n }\n\n /**\n * Push a vertex whose id is its number (restore mode, a position whose line has not come or\n * carries no original id; or the end of the vertex section under \"label\").\n * @param ids - the id per vertex position\n * @param pos - the vertex position\n */\n private numberedNode(ids: NodeId[], pos: number): void {\n const id = this.idOfNumber(pos + this.base);\n ids[pos] = id;\n this.indexOfPos[pos] = this.sink.addNode(id);\n this.report.counts.nodes++;\n }\n\n /**\n * The `graphty_originalId` parameter of a vertex line, taken out of the extras when it is to be\n * restored as the id (restoreMangledIds, under nodeIdFrom \"id\"); otherwise null and the\n * parameter stays an ordinary column.\n * @param extras - the parsed extras\n * @returns the original id text, or null\n */\n private restoredId(extras: RowExtras): string | null {\n if (!this.restoresIds()) {\n return null;\n }\n const at = extras.keys.indexOf(ORIGINAL_ID_KEY);\n if (at < 0) {\n return null;\n }\n const [text] = extras.values.splice(at, 1);\n extras.keys.splice(at, 1);\n return text;\n }\n\n /**\n * Push the node of a vertex line whose id comes from the line itself: its label under\n * nodeIdFrom \"label\", or its restored `graphty_originalId` (the number when the line carries\n * none), reporting a merge when the id was seen before.\n * @param ids - the id per vertex position\n * @param pos - the vertex position\n * @param k - the vertex number\n * @param text - the label or original id text, or null\n * @param line - the line number\n * @param from - which text the id comes from\n * @returns the node index\n */\n private deferredNode(\n ids: NodeId[],\n pos: number,\n k: number,\n text: string | null,\n line: number,\n from: \"label\" | \"originalId\",\n ): number {\n const id = text === null ? this.idOfNumber(k) : this.coercer.text(text);\n const before = this.sink.indexOf(id);\n const index = this.sink.addNode(id);\n ids[pos] = id;\n this.indexOfPos[pos] = index;\n this.report.counts.nodes++;\n if (before !== INVALID_INDEX) {\n this.report.warning(\n \"merged\",\n from === \"label\" ? PAJEK_ISSUE.LABEL_MERGED : PAJEK_ISSUE.ORIGINAL_ID_MERGED,\n from === \"label\"\n ? `vertex ${k} has the label ${JSON.stringify(String(id))} of an earlier vertex; both are one node`\n : `vertex ${k} has the ${ORIGINAL_ID_KEY} ${JSON.stringify(String(id))} of an earlier vertex; both are one node`,\n { line, element: String(k) },\n );\n }\n return index;\n }\n\n // ============================================================ lines\n\n /**\n * An arc or edge line: `u v [value] [key value ...] [interval]`.\n * @param text - the line\n * @param line - the line number\n */\n private edgeLine(text: string, line: number): void {\n let tokens = this.tokens(text, \"edge\");\n // a `k:` prefix puts this one line in relation k\n let { relation } = this;\n const prefix = RELATION_PREFIX.exec(tokens[0]);\n if (prefix !== null) {\n const k = Number(prefix[1]);\n relation = this.relationNames.get(k) ?? String(k);\n tokens = tokens.slice(1);\n }\n if (tokens.length < 2 || !isVertexNumber(tokens[0]) || !isVertexNumber(tokens[1])) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `a line starts with two vertex numbers, not \"${tokens.slice(0, 2).join(\" \")}\"`,\n );\n }\n const u = this.endpoint(Number(tokens[0]));\n const v = this.endpoint(Number(tokens[1]));\n let i = 2;\n let valueText: string | null = null;\n if (i < tokens.length && isNumericText(tokens[i])) {\n valueText = tokens[i];\n i++;\n }\n const extras = this.extras(tokens, i, \"edge\");\n const { weightFrom } = this.options;\n let weight: number | undefined;\n let valueIsWeight = false;\n if (isWeightField(VALUE_FIELD, weightFrom)) {\n valueIsWeight = true;\n if (valueText !== null) {\n weight = this.weightOf(valueText);\n }\n } else if (weightFrom !== null) {\n const at = extras.keys.indexOf(weightFrom);\n if (at >= 0) {\n weight = this.weightOf(extras.values[at]);\n extras.keys.splice(at, 1);\n extras.values.splice(at, 1);\n }\n }\n const e = this.pushEdge(u, v, weight, line);\n if (valueText !== null && !valueIsWeight) {\n // inferred like every parameter, so a re-import of the exporter's `value` parameter agrees\n this.writeParameter(\"edge\", VALUE_COLUMN, e, valueText);\n }\n this.writeEdgeExtras(e, extras, relation);\n }\n\n /**\n * An adjacency list line of `*Arcslist` / `*Edgeslist`: `v n1 n2 ...`; a negative vertex\n * number is read as its absolute value, as Pajek does.\n * @param text - the line\n * @param line - the line number\n */\n private listLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"edge\");\n for (const token of tokens) {\n if (!LIST_VERTEX.test(token)) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `an adjacency list holds vertex numbers only, not \"${token}\"`,\n );\n }\n }\n const u = this.endpoint(Math.abs(Number(tokens[0])));\n for (let i = 1; i < tokens.length; i++) {\n const v = this.endpoint(Math.abs(Number(tokens[i])));\n const e = this.pushEdge(u, v, undefined, line);\n this.writeRelation(e);\n }\n }\n\n /**\n * A `*Matrix` row, every non-zero entry an arc from the row's vertex with that value: N values\n * in a one-mode network; in a two-mode network (`*Vertices N N1`) the matrix is N1 rows of\n * N - N1 values, entry j of row i an arc from vertex i to vertex N1 + j.\n * @param text - the line\n * @param line - the line number\n */\n private matrixLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"edge\");\n const row = this.matrixRows;\n this.matrixRows++;\n const offset = this.firstMode ?? 0;\n const rows = this.firstMode ?? this.vertexCount;\n const columns = this.vertexCount - offset;\n if (row >= rows) {\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_ROWS,\n `*Matrix row ${row + 1} is beyond the ${rows} declared row(s)`,\n );\n }\n if (tokens.length < columns) {\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*Matrix row ${row + 1} has ${tokens.length} value(s); the matrix has ${columns} column(s)`,\n );\n }\n for (let j = 0; j < columns; j++) {\n if (!isNumericText(tokens[j])) {\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*Matrix row ${row + 1}: \"${tokens[j]}\" is not a number`,\n );\n }\n }\n if (tokens.length > columns) {\n this.report.warnOnce(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_EXTRA,\n `*Matrix row ${row + 1} has ${tokens.length} value(s) for ${columns} column(s); the extra values are ignored`,\n { line },\n );\n }\n for (let j = 0; j < columns; j++) {\n const value = Number(tokens[j]);\n if (value === 0) {\n continue;\n }\n const e = this.pushEdge(row, offset + j, value, line);\n this.writeRelation(e);\n }\n }\n\n /**\n * A value line of a `*Partition` (integers) or `*Vector` (numbers): the values of the next\n * vertices, usually one per line.\n * @param text - the line\n */\n private objectLine(text: string): void {\n const object = this.objects[this.objects.length - 1];\n const tokens = this.tokens(text, \"node\");\n for (const token of tokens) {\n if (!isNumericText(token) || (object.kind === \"partition\" && !isI32(Number(token)))) {\n // keep the later values on their vertices\n object.values.push(null);\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*${object.kind === \"partition\" ? \"Partition\" : \"Vector\"} \"${object.name}\": \"${token}\" is not ${object.kind === \"partition\" ? \"an integer\" : \"a number\"}`,\n );\n }\n }\n for (const token of tokens) {\n object.values.push(Number(token));\n }\n }\n\n /**\n * Push one line through the direction resolver, counting the logical edges it produced.\n * @param u - the source position\n * @param v - the target position\n * @param weight - the weight, or undefined for none\n * @param line - the line number\n * @returns the primary logical edge index\n */\n private pushEdge(u: number, v: number, weight: number | undefined, line: number): number {\n const { sink } = this;\n if (!this.directionSet) {\n this.directionSet = true;\n this.resolver.setHeader(this.kind === \"directed\", { line });\n }\n const before = sink.edgeCount;\n const e = this.resolver.addEdge(this.idAt(u), this.idAt(v), this.kind, weight, { line });\n this.report.counts.edges += sink.edgeCount - before;\n return e;\n }\n\n /**\n * Write the relation, parameters and spells of a line on its primary half.\n * @param e - the edge index\n * @param extras - the parsed extras\n * @param relation - the line's relation name, or null\n */\n private writeEdgeExtras(e: number, extras: RowExtras, relation: string | null): void {\n const { sink } = this;\n this.writeRelation(e, relation);\n for (let p = 0; p < extras.keys.length; p++) {\n this.writeParameter(\"edge\", extras.keys[p], e, extras.values[p]);\n }\n if (extras.spells !== null) {\n if (this.edgeSpellsHandle === INVALID_INDEX) {\n this.edgeSpellsHandle = declareResolved(sink, \"edge\", spellsDecl(), this.report).handle;\n }\n sink.setEdgeValue(this.edgeSpellsHandle, e, extras.spells);\n }\n }\n\n /**\n * Write a relation name on an edge: the current section's, unless a line prefix named another.\n * @param e - the edge index\n * @param relation - the relation name, or null for none\n */\n private writeRelation(e: number, relation: string | null = this.relation): void {\n if (relation === null) {\n return;\n }\n if (this.relationHandle === INVALID_INDEX) {\n this.relationHandle = declareResolved(this.sink, \"edge\", RELATION_DECL, this.report).handle;\n }\n this.sink.setEdgeValue(this.relationHandle, e, relation);\n }\n\n /**\n * A line endpoint: the vertex number checked against the declared range; a reference outside\n * it is a missing-value error and the line is skipped (Pajek's `*Vertices N` bounds the id space,\n * so addMissingNodes does not apply).\n * @param k - the vertex number\n * @returns the vertex position\n */\n private endpoint(k: number): number {\n const pos = k - this.base;\n if (pos < 0 || pos >= this.vertexCount) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"missing-value\",\n PAJEK_ISSUE.UNKNOWN_NODE,\n `vertex ${k} is outside ${this.base}..${this.base + this.vertexCount - 1}`,\n );\n }\n return pos;\n }\n\n /**\n * The weight of a line value text.\n * @param text - the text\n * @returns the weight; E_INVALID_WEIGHT is recorded by the caller's catch\n */\n private weightOf(text: string): number | undefined {\n try {\n return parseWeightText(text);\n } catch (err) {\n this.report.counts.skippedEdges++;\n throw err;\n }\n }\n\n // ============================================================ shared\n\n /**\n * Tokenize a data line.\n * @param text - the line\n * @param domain - what is skipped on an unterminated quote\n * @returns the tokens (at least one: blank lines never reach here)\n */\n private tokens(text: string, domain: \"node\" | \"edge\"): string[] {\n const tokens = tokenize(text);\n if (tokens === null) {\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n throw new LineError(\"parse-error\", PAJEK_ISSUE.UNTERMINATED_QUOTE, \"a double quote is not closed\");\n }\n return tokens;\n }\n\n /**\n * The `key value` parameters and the interval token at the end of a row, validated before\n * anything is written.\n * @param tokens - the row's tokens\n * @param start - the first token to read\n * @param domain - what is skipped when the row is malformed\n * @returns the parsed extras\n */\n private extras(tokens: readonly string[], start: number, domain: \"node\" | \"edge\"): RowExtras {\n const extras: RowExtras = { keys: [], values: [], spells: null };\n for (let i = start; i < tokens.length;) {\n const token = tokens[i];\n if (isIntervalToken(token)) {\n try {\n const spells = parseIntervals(token);\n // an empty `[]` is no spell at all\n extras.spells = spells.length === 0 ? null : spells;\n } catch (err) {\n this.skip(domain);\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.INTERVAL,\n err instanceof Error ? err.message : String(err),\n );\n }\n i++;\n continue;\n }\n if (i + 1 >= tokens.length) {\n this.skip(domain);\n throw new LineError(\n \"parse-error\",\n domain === \"node\" ? PAJEK_ISSUE.VERTEX_LINE : PAJEK_ISSUE.LINE,\n `parameter \"${token}\" has no value`,\n );\n }\n extras.keys.push(token);\n extras.values.push(tokens[i + 1]);\n i += 2;\n }\n return extras;\n }\n\n /**\n * Count a skipped element.\n * @param domain - node or edge\n */\n private skip(domain: \"node\" | \"edge\"): void {\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * Write one `key value` parameter cell through the column's text writer (the 5.1 grammar per\n * column, the lexical form kept). A `shape` parameter next to the shape keyword column goes\n * into that column (a dict takes any text), and a shape keyword next to a `shape` parameter\n * column into that one, so a file mixing the two spellings reads as one column.\n * @param domain - node or edge\n * @param key - the parameter key (the column name)\n * @param row - the node or edge index\n * @param text - the value text\n */\n private writeParameter(domain: \"node\" | \"edge\", key: string, row: number, text: string): void {\n if (domain === \"node\" && key === SHAPE_COLUMN && this.shapeHandle !== INVALID_INDEX) {\n this.sink.setNodeValue(this.shapeHandle, row, text);\n return;\n }\n const writers = domain === \"node\" ? this.nodeParams : this.edgeParams;\n let writer = writers.get(key);\n if (writer === undefined) {\n writer = new TextCellWriter(key, domain, this.sink, this.report);\n writers.set(key, writer);\n }\n writer.write(row, text);\n }\n}\n\n/**\n * Whether a vertex line has coordinates but no label: the token after the vertex number is bare\n * (not quoted) and starts a run of exactly two numbers, which cannot be a label and one\n * coordinate. A run of three stays a numeric label and x y (the NetworkX writer's `1 0 0.5 0.5`),\n * the one reading of it that keeps real files' labels.\n * @param text - the line\n * @param tokens - its tokens\n * @returns true when tokens[1] is the first coordinate\n */\nfunction startsWithCoordinates(text: string, tokens: readonly string[]): boolean {\n if (text.trimStart().slice(tokens[0].length).trimStart().startsWith('\"')) {\n return false;\n }\n let run = 0;\n while (1 + run < tokens.length && isNumericText(tokens[1 + run])) {\n run++;\n }\n return run === 2;\n}\n\n/**\n * Resolve the firstVertex option.\n * @param value - the caller's value\n * @returns 0, 1 or \"auto\"; E_UNSUPPORTED for anything else\n */\nfunction firstVertexOption(value: unknown): 0 | 1 | \"auto\" {\n if (value === undefined) {\n return \"auto\";\n }\n if (FIRST_VERTEX_VALUES.has(value)) {\n return value as 0 | 1 | \"auto\";\n }\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option firstVertex: ${JSON.stringify(value) ?? typeof value} is not 0, 1 or \"auto\"`,\n {\n option: \"firstVertex\",\n found: value,\n },\n );\n}\n\nconst HEAD_PATTERN = /^\\s*\\*(vertices|network)\\b/i;\n\n/** The Pajek NET importer. */\nexport const pajekImporter: GraphImporter<PajekImportOptions> = Object.freeze({\n format: \"pajek\",\n extensions: Object.freeze([\".net\", \".paj\"]),\n mimeTypes: Object.freeze([\"text/x-pajek\", \"text/plain\"]),\n\n /**\n * Confidence that the input is a Pajek network: it starts with `*Vertices` (or `*Network`).\n * @param head - the first bytes\n * @returns 0.9 for a `*Vertices` start, 0.8 for `*Network`, 0 otherwise\n */\n sniff(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\").decode(head.subarray(0, Math.min(head.byteLength, 512)));\n const match = HEAD_PATTERN.exec(text.startsWith(String.fromCharCode(0xfeff)) ? text.slice(1) : text);\n if (match === null) {\n return 0;\n }\n return match[1].toLowerCase() === \"vertices\" ? 0.9 : 0.8;\n },\n\n /**\n * Read a Pajek network into the sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - common and Pajek options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: PajekImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, DEFAULTS);\n const firstVertex = firstVertexOption(options?.firstVertex);\n const report = new ImportReportBuilder(\"pajek\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const parser = new PajekParser(sink, report, resolved, firstVertex);\n const reader = new LineReader(input, report, resolved);\n // after the first network: only its successors' headers are counted\n let rest: NetworkCounter | null = null;\n let restLine = 0;\n let sinceCheck = 0;\n for await (const text of reader) {\n if (rest !== null) {\n rest.line(text);\n } else if (parser.line(text, reader.line)) {\n rest = new NetworkCounter();\n rest.line(text);\n restLine = reader.line;\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(resolved.signal);\n }\n }\n parser.finish();\n if (rest !== null) {\n report.warning(\n \"unsupported\",\n PAJEK_ISSUE.MULTIPLE_GRAPHS,\n `the project file holds ${rest.count} more network(s) after the first; import() reads the first, importAll() reads every one`,\n { line: restLine },\n );\n }\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every network of a Pajek project file (`.paj`), each into its own sink. A network starts\n * at `*Network` or at a `*Vertices` that does not belong to a `*Partition` / `*Vector` section\n * (the `*Vertices N` line right after an object's header).\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the network with this index, called before its first push\n * @param options - common and Pajek options\n * @returns one report per network\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: PajekImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, DEFAULTS);\n const firstVertex = firstVertexOption(options?.firstVertex);\n const reports = [new ImportReportBuilder(\"pajek\", resolved.errorLimit)];\n reportUnusedOptions(options, reports[0], USED_OPTIONS);\n const open = (): PajekParser => {\n const report = reports[reports.length - 1];\n const sink = sinkFor(reports.length - 1);\n reportSinkOptions(sink, options, report);\n return new PajekParser(sink, report, resolved, firstVertex);\n };\n let parser = open();\n // decoding issues belong to the file, so they go to the first network's report\n const reader = new LineReader(input, reports[0], resolved);\n let sinceCheck = 0;\n for await (const text of reader) {\n if (parser.line(text, reader.line)) {\n parser.finish();\n reports.push(new ImportReportBuilder(\"pajek\", resolved.errorLimit));\n parser = open();\n parser.line(text, reader.line);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(resolved.signal);\n }\n }\n parser.finish();\n throwIfAborted(resolved.signal);\n return reports.map((r) => r.finish());\n },\n});\n\n/**\n * Counts the networks of the rest of a project file by their headers alone, with the parser's\n * rule: a network starts at `*Network` after a named or populated one, or at a `*Vertices` after a\n * populated one unless it is the line right after a project object's header (`*Partition`,\n * `*Vector`, a skipped section).\n */\nclass NetworkCounter {\n /** Networks started so far (the first header fed opens the first). */\n count = 0;\n\n private named = false;\n\n private populated = false;\n\n private afterObjectHeader = false;\n\n /**\n * Feed one line.\n * @param text - the line\n */\n line(text: string): void {\n if (isCommentOrBlank(text)) {\n return;\n }\n const { afterObjectHeader } = this;\n this.afterObjectHeader = false;\n if (!isSectionLine(text)) {\n return;\n }\n const h = parseSectionHeader(text);\n if (h === null) {\n return;\n }\n const { kind } = h;\n if (kind === \"partition\" || kind === \"vector\" || kind === \"unsupported\") {\n this.afterObjectHeader = true;\n } else if (kind === \"network\") {\n if (this.count === 0 || this.named || this.populated) {\n this.count++;\n this.populated = false;\n }\n this.named = true;\n } else if (kind === \"vertices\" && !afterObjectHeader) {\n if (this.count === 0 || this.populated) {\n this.count++;\n this.named = false;\n }\n this.populated = true;\n }\n }\n}\n\n"],"names":["n"],"mappings":"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"}
1
+ {"version":3,"file":"importer-zGLo8Dg_.js","sources":["../../src/formats/pajek/syntax.ts","../../src/formats/pajek/exporter.ts","../../src/formats/pajek/importer.ts"],"sourcesContent":["/**\n * The lexical layer of the Pajek NET format shared by the importer and the exporter (research\n * note 07 section 2.5): the line tokenizer (whitespace-separated tokens, double quotes group\n * spaces and are removed, no escape mechanism), the section headers (`*Vertices N [N1]`,\n * `*Arcs [:k [\"name\"]]`, `*Edges`, `*Arcslist`, `*Edgeslist`, `*Matrix`, `*Network name`,\n * `*Partition name`, `*Vector name` and the project-file sections the importer does not read), the\n * vertex shape keywords, the time interval tokens `[1-5,7-*]` that map to the spells role, the\n * `&#dddd;` character references of labels, and the column names both sides agree on.\n */\n\n/** The node column holding the vertex label (role label). */\nexport const LABEL_COLUMN = \"label\";\n\n/** The node column holding the vertex coordinates (role position, f32 x 3, units \"file\"). */\nexport const POSITION_COLUMN = \"position\";\n\n/** The node column holding the vertex shape keyword (dict, no role: Pajek has its own keyword set). */\nexport const SHAPE_COLUMN = \"shape\";\n\n/** The edge column holding the relation name of a `*Arcs :k \"name\"` section (dict). */\nexport const RELATION_COLUMN = \"relation\";\n\n/** The node or edge column holding Pajek time intervals (list of f64 pairs, role spells). */\nexport const SPELLS_COLUMN = \"spells\";\n\n/** The edge column holding the line value when `weightFrom` names another field or null. */\nexport const VALUE_COLUMN = \"value\";\n\n/** The `weightFrom` default: Pajek's third column is the line value (design section 8.4). */\nexport const VALUE_FIELD = \"value\";\n\n/** The node column holding the values of a `*Partition` object (i32). */\nexport const PARTITION_COLUMN = \"partition\";\n\n/** The node column holding the values of a `*Vector` object (f64). */\nexport const VECTOR_COLUMN = \"vector\";\n\n/**\n * The vertex shape keywords of the Pajek manual, lower-cased; a file may write them in any case\n * (use isShapeKeyword()).\n */\nexport const SHAPES: ReadonlySet<string> = new Set([\n \"ellipse\",\n \"box\",\n \"diamond\",\n \"triangle\",\n \"cross\",\n \"empty\",\n \"house\",\n \"man\",\n \"woman\",\n]);\n\n/**\n * Whether a token is a vertex shape keyword, in any case (`Ellipse`, `BOX`).\n * @param token - the token\n * @returns true for a shape keyword\n */\nexport function isShapeKeyword(token: string): boolean {\n return SHAPES.has(token.toLowerCase());\n}\n\n/** The section keywords the importer reads, lower-cased. */\ntype SectionKind =\n | \"network\"\n | \"vertices\"\n | \"arcs\"\n | \"edges\"\n | \"arcslist\"\n | \"edgeslist\"\n | \"matrix\"\n | \"partition\"\n | \"vector\"\n | \"unsupported\";\n\n/**\n * The parameter key the exporter writes a node's original id under when `sanitizeIds: \"mangle\"`\n * renumbers it (design section 8.5: the exporter names the attribute, `restoreMangledIds` reads\n * it back); a user column of that name is reserved under \"mangle\".\n */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/** A parsed section header line. */\nexport interface SectionHeader {\n /** The section kind. */\n readonly kind: SectionKind;\n /** The keyword as written, without the asterisk. */\n readonly keyword: string;\n /** The first count (`*Vertices N`), or null. */\n readonly count: number | null;\n /** The second count of a two-mode network (`*Vertices N N1`), or null. */\n readonly secondCount: number | null;\n /** The relation number of `*Arcs :k`, or null. */\n readonly relation: number | null;\n /** The relation or network name, or null. */\n readonly name: string | null;\n /** Tokens the grammar does not account for, for the importer to report. */\n readonly extra: readonly string[];\n}\n\nconst SECTION_KINDS: ReadonlyMap<string, SectionKind> = new Map([\n [\"network\", \"network\"],\n [\"vertices\", \"vertices\"],\n [\"arcs\", \"arcs\"],\n [\"edges\", \"edges\"],\n [\"arcslist\", \"arcslist\"],\n [\"edgeslist\", \"edgeslist\"],\n [\"matrix\", \"matrix\"],\n [\"partition\", \"partition\"],\n [\"vector\", \"vector\"],\n]);\n\nconst INTEGER_TEXT = /^[+-]?[0-9]+$/;\nconst TIME_POINT =\n /^(\\*|[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?)(?:-(\\*|[+-]?[0-9]+(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?))?$/;\n\n/**\n * Split one line into tokens: runs of non-whitespace, with double quotes grouping whitespace\n * into one token and removed from it (the shlex rule NetworkX applies; Pajek has no escapes, so a\n * quote never appears inside a token). An empty quoted string `\"\"` is one empty token. A token\n * that starts with `[` runs to the next `]` whatever whitespace it holds (when no other `[` comes\n * first), so a time set written `[ 1, 3 ]` is one token.\n * @param line - the line without its terminator\n * @returns the tokens, or null when a quote is not closed before the end of the line\n */\nexport function tokenize(line: string): string[] | null {\n const tokens: string[] = [];\n let current = \"\";\n let started = false;\n let quoted = false;\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 34) {\n quoted = !quoted;\n started = true;\n continue;\n }\n if (!quoted && !started && c === 91) {\n const close = line.indexOf(\"]\", i);\n if (close > i && line.lastIndexOf(\"[\", close) === i) {\n current += line.slice(i, close + 1);\n started = true;\n i = close;\n continue;\n }\n }\n if (!quoted && (c === 32 || c === 9 || c === 13 || c === 12 || c === 11)) {\n if (started) {\n tokens.push(current);\n current = \"\";\n started = false;\n }\n continue;\n }\n current += line[i];\n started = true;\n }\n if (quoted) {\n return null;\n }\n if (started) {\n tokens.push(current);\n }\n return tokens;\n}\n\n/**\n * Whether a line is a Pajek comment (`%` first) or blank.\n * @param line - the line\n * @returns true when the importer skips it\n */\nexport function isCommentOrBlank(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 32 || c === 9 || c === 13 || c === 12 || c === 11) {\n continue;\n }\n return c === 37;\n }\n return true;\n}\n\n/**\n * Whether a line starts a section (`*` first, after optional whitespace).\n * @param line - the line\n * @returns true for a header line\n */\nexport function isSectionLine(line: string): boolean {\n for (let i = 0; i < line.length; i++) {\n const c = line.charCodeAt(i);\n if (c === 32 || c === 9 || c === 13 || c === 12 || c === 11) {\n continue;\n }\n return c === 42;\n }\n return false;\n}\n\n/**\n * Parse a section header line: the keyword (case-insensitive), then `N [N1]` for `*Vertices`,\n * `[:k] [\"name\"]` for the line sections, the name for `*Network`. Anything else after the keyword\n * lands in `extra` so the importer can report it instead of dropping it.\n * @param line - a line isSectionLine() accepted\n * @returns the header, or null when the line has no keyword or a quote is unbalanced\n */\nexport function parseSectionHeader(line: string): SectionHeader | null {\n const tokens = tokenize(line.trimStart().slice(1));\n if (tokens === null || tokens.length === 0 || tokens[0].length === 0) {\n return null;\n }\n const keyword = tokens[0];\n const kind = SECTION_KINDS.get(keyword.toLowerCase()) ?? \"unsupported\";\n let count: number | null = null;\n let secondCount: number | null = null;\n let relation: number | null = null;\n let name: string | null = null;\n const extra: string[] = [];\n let i = 1;\n switch (kind) {\n case \"vertices\":\n if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {\n count = Number(tokens[i]);\n i++;\n if (i < tokens.length && INTEGER_TEXT.test(tokens[i])) {\n secondCount = Number(tokens[i]);\n i++;\n }\n }\n break;\n case \"arcs\":\n case \"edges\":\n case \"arcslist\":\n case \"edgeslist\":\n case \"matrix\":\n if (i < tokens.length && tokens[i].startsWith(\":\") && INTEGER_TEXT.test(tokens[i].slice(1))) {\n relation = Number(tokens[i].slice(1));\n i++;\n if (i < tokens.length) {\n name = tokens[i];\n i++;\n }\n }\n break;\n case \"network\":\n case \"partition\":\n case \"vector\":\n if (i < tokens.length) {\n name = tokens.slice(i).join(\" \");\n i = tokens.length;\n }\n break;\n case \"unsupported\":\n i = tokens.length;\n break;\n default: {\n const unknown: string = kind;\n throw new Error(`unknown section kind ${unknown}`);\n }\n }\n for (; i < tokens.length; i++) {\n extra.push(tokens[i]);\n }\n return { kind, keyword, count, secondCount, relation, name, extra };\n}\n\n/**\n * Whether a token is a Pajek integer (a vertex number, a count), without sign.\n * @param token - the token\n * @returns true for one or more ASCII digits\n */\nexport function isVertexNumber(token: string): boolean {\n if (token.length === 0) {\n return false;\n }\n for (let i = 0; i < token.length; i++) {\n const c = token.charCodeAt(i);\n if (c < 48 || c > 57) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Whether a token is a time interval list `[...]`.\n * @param token - the token\n * @returns true when it starts with `[` and ends with `]`\n */\nexport function isIntervalToken(token: string): boolean {\n return token.length >= 2 && token.startsWith(\"[\") && token.endsWith(\"]\");\n}\n\n/**\n * Parse a Pajek time interval token into spells: `[1-5,7-*]` is `[[1, 5], [7, Infinity]]`, a\n * single time point `[3]` is `[[3, 3]]`, `*` at either end is the corresponding infinity, blanks\n * around the parts are ignored and an empty `[]` is no spell at all.\n * @param token - a token isIntervalToken() accepted\n * @returns the spells as [start, end] pairs (empty for `[]`)\n */\nexport function parseIntervals(token: string): [number, number][] {\n const body = token.slice(1, -1);\n if (body.trim().length === 0) {\n return [];\n }\n const spells: [number, number][] = [];\n for (const part of body.split(\",\")) {\n const match = TIME_POINT.exec(part.replace(/\\s+/g, \"\"));\n if (match === null) {\n throw new Error(`malformed time interval ${token}: \"${part}\" is not a-b, a-* or a`);\n }\n const start = match[1] === \"*\" ? -Infinity : Number(match[1]);\n const endText = match[2];\n let end: number;\n if (endText === undefined) {\n end = start;\n } else if (endText === \"*\") {\n end = Infinity;\n } else {\n end = Number(endText);\n }\n if (start > end) {\n throw new Error(`malformed time interval ${token}: ${match[1]} is after ${endText ?? \"\"}`);\n }\n spells.push([start, end]);\n }\n return spells;\n}\n\nconst CHARACTER_REFERENCE = /&#(?:[xX]([0-9a-fA-F]{1,6})|([0-9]{1,7}));/g;\n\n/**\n * Decode the `&#dddd;` and `&#xhhhh;` character references of a label, as Pajek does; a reference\n * outside the Unicode range is left as written.\n * @param text - the label as written\n * @returns the decoded label\n */\nexport function decodeCharacterReferences(text: string): string {\n if (!text.includes(\"&#\")) {\n return text;\n }\n return text.replace(CHARACTER_REFERENCE, (whole, hex: string | undefined, dec: string | undefined) => {\n const code = hex === undefined ? Number(dec) : Number.parseInt(hex, 16);\n return code <= 0x10ffff ? String.fromCodePoint(code) : whole;\n });\n}\n\n/**\n * Protect a label whose text would read back as a character reference: the `&` of every\n * `&#...;` run is written as `&#38;`, the inverse of decodeCharacterReferences().\n * @param text - the label text\n * @returns the text to write\n */\nexport function encodeCharacterReferences(text: string): string {\n if (!text.includes(\"&#\")) {\n return text;\n }\n return text.replace(CHARACTER_REFERENCE, (whole) => `&#38;${whole.slice(1)}`);\n}\n\n/**\n * Write spells as a Pajek time interval token, the inverse of parseIntervals().\n * @param spells - [start, end] pairs\n * @returns the token, e.g. `[1-5,7-*]`\n */\nexport function formatIntervals(spells: readonly (readonly [number, number])[]): string {\n const parts: string[] = [];\n for (const [start, end] of spells) {\n const s = start === -Infinity ? \"*\" : String(start);\n if (start === end) {\n parts.push(s);\n } else {\n parts.push(`${s}-${end === Infinity ? \"*\" : String(end)}`);\n }\n }\n return `[${parts.join(\",\")}]`;\n}\n\n/**\n * Whether a text can be written as a bare parameter key on a vertex or line row: non-empty, no\n * whitespace or quote, not an interval token, not a number (a number after the label is a\n * coordinate, at the third position of a line row the value) and not a shape keyword.\n * @param text - the candidate key (a column name)\n * @returns true when the importer reads it back as a key\n */\nexport function isParameterKey(text: string): boolean {\n if (text.length === 0 || /[\\s\"]/.test(text) || text.startsWith(\"[\") || text.startsWith(\"*\")) {\n return false;\n }\n if (isShapeKeyword(text)) {\n return false;\n }\n return !/^[+-]?(\\.[0-9]|[0-9])/.test(text);\n}\n","/**\n * The Pajek NET exporter (design section 8.5; research note 07 sections 2.5 and 9): vertices are\n * numbered 1..N in index order (the `dense-1-based` id charset: an id that is not its 1-based\n * index survives as the label only, which check() reports as W_ID_RENUMBERED; under\n * `sanitizeIds: \"mangle\"` it is also written as a `graphty_originalId` parameter the importer\n * restores under `restoreMangledIds`), the label role\n * column is the label, the position role column the coordinates, a `shape` column the shape\n * keyword, every other writable column a `key value` parameter and the spells role a time\n * interval token. Logical edges are written in index order in runs of `*Arcs` (directed) and\n * `*Edges` (undirected) sections, folding expanded pairs back through the pair role and reading\n * attributes from the primary half, so a mixed file round-trips in its original edge order. The\n * weight is written for edges whose weight was explicit (the role-weight column's validity).\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot, type NodeId } from \"@graphty/graph-format\";\n\nimport { pairFolding } from \"../../common/direction.js\";\nimport { isPajekLabel, quotePajekLabel } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS, type SanitizedIds, sanitizeIds } from \"../../common/export.js\";\nimport { formatDecimal, formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { canonicalId } from \"../../common/ids.js\";\nimport { resolveExportOptions } from \"../../common/options.js\";\nimport { inferTextDtype } from \"../../common/text.js\";\nimport { explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport {\n encodeCharacterReferences,\n formatIntervals,\n isParameterKey,\n LABEL_COLUMN,\n ORIGINAL_ID_KEY,\n POSITION_COLUMN,\n RELATION_COLUMN,\n SHAPE_COLUMN,\n SHAPES,\n} from \"./syntax.js\";\n\n/** The format-specific options of the Pajek exporter. */\nexport interface PajekExportOptions {\n /**\n * Write a `*Network <name>` header line (the .paj project-file convention) when the snapshot's\n * meta.name is set; default false, since plain .net readers do not expect it.\n */\n networkHeader?: boolean | undefined;\n}\n\n/**\n * The LossNote codes of the Pajek exporter's check(): the Pajek-specific ones and, aliased, the\n * shared ones it records itself (`LOSS` holds the rest of the generic pre-flight's codes). A key\n * is the code without its severity and format prefixes.\n */\nexport const PAJEK_LOSS = Object.freeze({\n /** A label or text value holds a double quote or a line break; export() will throw E_UNSUPPORTED. */\n TEXT: \"E_PAJEK_TEXT\",\n /** A column whose name cannot be a parameter key (whitespace, a quote, numeric, a shape keyword); skipped. */\n KEY_DROPPED: \"W_PAJEK_KEY_DROPPED\",\n /** A label role column that is not text; its values are written as text and re-import as string. */\n LABEL_AS_TEXT: \"W_PAJEK_LABEL_AS_TEXT\",\n /** A non-finite f64 value; written as Infinity / NaN text, which re-imports as string. */\n NONFINITE_AS_TEXT: \"W_PAJEK_NONFINITE_AS_TEXT\",\n /** A mutual pair; written as one undirected edge, the mark lost. */\n MUTUAL_AS_UNDIRECTED: LOSS.MUTUAL_AS_UNDIRECTED,\n /** A start / end / timestamp role column; Pajek intervals are written from the spells role only. */\n TEMPORAL_DROPPED: LOSS.TEMPORAL,\n /** A position column with a stride other than 2 or 3. */\n POSITION_STRIDE: \"W_PAJEK_POSITION_STRIDE\",\n /** meta.extra.pajek.firstMode is not a count within 0..N; the two-mode header is not written. */\n FIRST_MODE_DROPPED: \"W_PAJEK_FIRST_MODE_DROPPED\",\n /** A role column Pajek has no slot for (kind, ...) written as a plain parameter; the role is lost. */\n ROLE_DROPPED: LOSS.ROLE,\n /** A `shape` column with a value outside the shape keywords is written as a parameter (a string on re-import). */\n SHAPE_AS_PARAMETER: \"W_PAJEK_SHAPE_AS_PARAMETER\",\n /** A vertex line with coordinates, a shape or parameters needs a label: the id text is written and reads back as a label. */\n LABEL_GAINED: \"W_PAJEK_LABEL_GAINED\",\n /** A role-less node column named `label` reads back with the label role (its values become the vertex labels). */\n ROLE_ASSUMED: LOSS.ROLE_ASSUMED,\n /** Under sanitizeIds \"mangle\": an original id whose text reads back as the other type under ids \"canonical\". */\n ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,\n /** Parameter text that looks like a number or a boolean reads back as one (parameters are untyped, design 5.1). */\n TEXT_INFERRED: LOSS.TEXT_INFERRED,\n});\n\n/** The roles Pajek has a slot for beyond the structural, position and temporal ones. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\"]);\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({ label: \"label\", position: POSITION_COLUMN });\n\n/** The roles the exporter handles structurally rather than as parameters. */\nconst STRUCTURAL_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n]);\n\n/** The roles the generic checker reports for a format without viz, hierarchy or open-interval support. */\nconst CHECKED_ROLES: ReadonlySet<string> = new Set([\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Roles the generic checker lets through under temporal \"spells\" that Pajek cannot write. */\nconst DROPPED_TEMPORAL_ROLES: ReadonlySet<string> = new Set([\"start\", \"end\", \"timestamp\", \"timestamps\"]);\n\nconst CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: true,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"dense-1-based\",\n dtypes: [\"f64\", \"i32\", \"bool\", \"string\"],\n temporal: \"spells\",\n positions: true,\n});\n\n/** Where a column's values go on a row. */\ntype Slot = \"label\" | \"position\" | \"shape\" | \"spells\" | \"relation\" | \"param\" | \"skip\";\n\n/** A column with its resolved slot, for the write loops. */\ninterface PlannedColumn {\n readonly column: Column;\n readonly slot: Slot;\n}\n\n/**\n * Decide the slot of every column of a table.\n * @param table - the node or edge table\n * @param domain - node or edge\n * @param notes - the note list check() fills; null when writing\n * @returns the plan, in declaration order\n */\nfunction plan(table: Iterable<Column>, domain: \"node\" | \"edge\", notes: LossNote[] | null): PlannedColumn[] {\n const planned: PlannedColumn[] = [];\n const rows = (column: Column): number => column.length - column.nullCount;\n for (const column of table) {\n const { meta } = column;\n const { role, name, dtype } = meta;\n if (role === \"label\" && domain === \"node\") {\n if (dtype !== \"string\" && dtype !== \"dict\" && notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.LABEL_AS_TEXT,\n `node column \"${name}\" (label) is ${dtype}; labels are text and re-import as string`,\n name,\n rows(column),\n ),\n );\n }\n planned.push({ column, slot: \"label\" });\n continue;\n }\n if (role === \"position\") {\n if (domain === \"node\" && (meta.components === 2 || meta.components === 3)) {\n planned.push({ column, slot: \"position\" });\n } else if (notes !== null && domain === \"node\") {\n notes.push(\n note(\n PAJEK_LOSS.POSITION_STRIDE,\n `node column \"${name}\" (position) has ${meta.components} components; Pajek coordinates are x y [z]`,\n name,\n rows(column),\n ),\n );\n } else if (notes !== null) {\n notes.push(\n note(LOSS.POSITIONS, `edge column \"${name}\" (position) cannot be written`, name, rows(column)),\n );\n }\n continue;\n }\n if (role === \"spells\") {\n if (\n dtype === \"list\" &&\n (meta.itemDtype === \"f64\" || meta.itemDtype === \"i32\" || meta.itemDtype === \"f32\")\n ) {\n planned.push({ column, slot: \"spells\" });\n continue;\n }\n if (notes !== null) {\n notes.push(\n note(\n LOSS.SPELLS,\n `${domain} column \"${name}\" (spells) is not a list of number pairs; it cannot be written`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n if (role !== null && DROPPED_TEMPORAL_ROLES.has(role)) {\n if (notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.TEMPORAL_DROPPED,\n `${domain} column \"${name}\" (${role}) cannot be written; Pajek intervals come from the spells role`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n if (role !== null && (STRUCTURAL_ROLES.has(role) || CHECKED_ROLES.has(role))) {\n // structural columns are folded into the topology; viz and hierarchy roles are reported by the generic checker\n continue;\n }\n if (domain === \"edge\" && role === \"id\") {\n continue;\n }\n if (dtype === \"list\" || dtype === \"json\") {\n // reported by the generic checker (lists: false, json: false)\n continue;\n }\n if (domain === \"node\" && name === SHAPE_COLUMN && (dtype === \"dict\" || dtype === \"string\")) {\n if (allShapeKeywords(column)) {\n planned.push({ column, slot: \"shape\" });\n continue;\n }\n // a value outside the keywords: the whole column is a `shape \"<text>\"` parameter, which the\n // importer reads back as one string column (a change for a dict column only)\n if (notes !== null && dtype === \"dict\") {\n notes.push(\n note(\n PAJEK_LOSS.SHAPE_AS_PARAMETER,\n `node column \"${name}\" holds values outside the Pajek shape keywords; it is written as a parameter and reads back as string`,\n name,\n rows(column),\n ),\n );\n }\n planned.push({ column, slot: \"param\" });\n continue;\n }\n if (domain === \"edge\" && name === RELATION_COLUMN && (dtype === \"dict\" || dtype === \"string\")) {\n planned.push({ column, slot: \"relation\" });\n continue;\n }\n if (!isParameterKey(name)) {\n if (notes !== null) {\n notes.push(\n note(\n PAJEK_LOSS.KEY_DROPPED,\n `${domain} column \"${name}\" cannot be a Pajek parameter key; it is not written`,\n name,\n rows(column),\n ),\n );\n }\n continue;\n }\n planned.push({ column, slot: \"param\" });\n }\n return planned;\n}\n\n/**\n * The notes about vertex labels: Pajek's grammar puts the label second, so a vertex line that\n * carries coordinates, a shape, parameters or an interval needs one, and a node without a label\n * value gets its id text written there (it reads back as a label); a role-less column named\n * `label` reads back with the label role.\n * @param snapshot - the snapshot\n * @param nodePlan - the node column plan\n * @param notes - where to record\n */\nfunction labelNotes(snapshot: GraphSnapshot, nodePlan: readonly PlannedColumn[], notes: LossNote[]): void {\n let labels: Column | null = null;\n let carried = 0;\n for (const { column, slot } of nodePlan) {\n if (slot === \"label\") {\n labels = column;\n } else if (slot !== \"skip\" && slot !== \"relation\") {\n carried++;\n }\n }\n const plain = [...snapshot.nodes].find((c) => c.meta.role === null && c.meta.name === LABEL_COLUMN);\n if (plain !== undefined) {\n notes.push(\n note(\n PAJEK_LOSS.ROLE_ASSUMED,\n `node column \"${LABEL_COLUMN}\" has no role; written as a parameter, it reads back as the vertex label (role label)`,\n LABEL_COLUMN,\n plain.length - plain.nullCount,\n ),\n );\n }\n if (carried === 0) {\n return;\n }\n let gained = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n if (labels === null || !labels.isSet(i)) {\n gained++;\n }\n }\n if (gained > 0) {\n notes.push(\n note(\n PAJEK_LOSS.LABEL_GAINED,\n `${gained} vertex line(s) carry coordinates, a shape or parameters and need a label; the id text is written there and reads back as a label`,\n labels === null ? LABEL_COLUMN : labels.meta.name,\n gained,\n ),\n );\n }\n}\n\n/**\n * Whether every set value of a shape column is a Pajek shape keyword.\n * @param column - the shape column (string or dict)\n * @returns true when the shape slot can hold the column\n */\nfunction allShapeKeywords(column: Column): boolean {\n for (let r = 0; r < column.length; r++) {\n if (column.isSet(r) && !SHAPES.has(column.value(r) as string)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Build a frozen LossNote.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n * @returns the note\n */\nfunction note(code: string, message: string, column: string | null = null, count: number | null = null): LossNote {\n return Object.freeze({ code, message, column, count });\n}\n\n/**\n * The text of one numeric cell: integers as digits, f64 with a decimal point guaranteed so the\n * importer's inference keeps the dtype, f32 as the shortest fround-round-trip decimal.\n * @param value - the value\n * @param dtype - the column dtype\n * @returns the text\n */\nfunction numberText(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\"): string {\n switch (dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return formatF32(value);\n case \"f64\":\n return formatDecimal(value, \"f64\");\n default: {\n const name: string = dtype;\n throw new Error(`unknown numeric dtype ${name}`);\n }\n }\n}\n\n/**\n * The text of a set cell as a parameter value or label, before quoting.\n * @param column - the column\n * @param row - the row\n * @returns the text\n */\nfunction cellText(column: Column, row: number): string {\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const value = column.value(row);\n if (typeof value === \"number\") {\n return numberText(value, column.dtype);\n }\n const parts: string[] = [];\n const vector = value as ArrayLike<number>;\n for (let k = 0; k < vector.length; k++) {\n parts.push(numberText(vector[k], column.dtype));\n }\n return parts.join(\" \");\n }\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n case \"dict\":\n case \"string\":\n return column.value(row) as string;\n case \"list\":\n case \"json\":\n return JSON.stringify(column.value(row));\n default: {\n const name: string = (column as Column).dtype;\n throw new Error(`unknown dtype ${name}`);\n }\n }\n}\n\n/**\n * Count the cells of a plan that cannot be written (text with a quote or line break, non-finite\n * f64) or read back typed (parameter text that looks like a number or a boolean) and add the notes.\n * @param planned - the plan\n * @param domain - node or edge\n * @param notes - the note list\n */\nfunction checkCells(planned: readonly PlannedColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, slot } of planned) {\n if (slot === \"position\" || slot === \"spells\") {\n continue;\n }\n const { name } = column.meta;\n let badText = 0;\n let nonFinite = 0;\n let typed = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n if (column.dtype === \"f64\" || column.dtype === \"f32\") {\n const value = column.value(r);\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n nonFinite++;\n }\n } else if (value !== undefined && !Array.from(value).every((v) => Number.isFinite(v))) {\n nonFinite++;\n }\n } else if (column.dtype === \"string\" || column.dtype === \"dict\") {\n const text = column.value(r) as string;\n if (!isPajekLabel(text)) {\n badText++;\n } else if (slot === \"param\" && inferTextDtype(text) !== \"string\") {\n typed++;\n }\n }\n }\n if (badText > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT,\n `${badText} value(s) of ${domain} column \"${name}\" hold a double quote or a line break; Pajek cannot write them`,\n name,\n badText,\n ),\n );\n }\n if (typed > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT_INFERRED,\n `${typed} value(s) of ${domain} column \"${name}\" look like numbers or booleans; Pajek parameters are untyped and they read back as such`,\n name,\n typed,\n ),\n );\n }\n if (nonFinite > 0) {\n notes.push(\n note(\n PAJEK_LOSS.NONFINITE_AS_TEXT,\n `${nonFinite} non-finite value(s) of ${domain} column \"${name}\" are written as text`,\n name,\n nonFinite,\n ),\n );\n }\n }\n}\n\n/**\n * The first-mode count to write in `*Vertices N N1`, from meta.extra.pajek.firstMode.\n * @param snapshot - the snapshot\n * @returns the count, or null when absent or invalid\n */\nfunction firstModeOf(snapshot: GraphSnapshot): number | null {\n const { pajek } = snapshot.meta.extra;\n if (typeof pajek !== \"object\" || pajek === null) {\n return null;\n }\n const value = (pajek as { firstMode?: unknown }).firstMode;\n if (value === undefined) {\n return null;\n }\n if (typeof value === \"number\" && Number.isInteger(value) && value >= 0 && value <= snapshot.nodeCount) {\n return value;\n }\n return NaN;\n}\n\n/**\n * The label of a vertex: the label column's value when set, the id's text when the id is not\n * the vertex number, otherwise null (no label needed). A label is forced when something follows\n * it on the line, because Pajek's grammar puts the label second.\n * @param labels - the label column, or null\n * @param ids - the sanitised ids\n * @param i - the node index\n * @param needed - whether the line has more after the label\n * @returns the label text, or null\n */\nfunction labelOf(labels: Column | null, ids: SanitizedIds, i: number, needed: boolean): string | null {\n if (labels !== null && labels.isSet(i)) {\n return cellText(labels, i);\n }\n if (needed || ids.isChanged(i)) {\n return idText(ids.originalAt(i));\n }\n return null;\n}\n\n/**\n * The text of an id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n return typeof id === \"number\" ? formatF64(id) : id;\n}\n\n/**\n * The spells text of a row, or null when unset or empty.\n * @param column - the spells list column\n * @param row - the row\n * @returns the interval token or null\n */\nfunction spellsText(column: Column, row: number): string | null {\n if (column.dtype !== \"list\" || !column.isSet(row)) {\n return null;\n }\n const items = column.sliceOf(row);\n if (items.length === 0) {\n return null;\n }\n const pairs: [number, number][] = [];\n for (const item of items) {\n const pair = item as ArrayLike<number>;\n pairs.push([pair[0], pair[1]]);\n }\n return formatIntervals(pairs);\n}\n\n/**\n * The coordinates text of a vertex, or null when unset.\n * @param column - the position column (2 or 3 components)\n * @param i - the node index\n * @param writeZ - whether z is written for a 3-component column\n * @returns \"x y\" or \"x y z\", or null\n */\nfunction coordinatesText(column: Column, i: number, writeZ: boolean): string | null {\n if (!column.isSet(i)) {\n return null;\n }\n const dtype = column.dtype as \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\";\n const vector = column.value(i) as ArrayLike<number>;\n const x = numberText(vector[0], dtype);\n const y = numberText(vector[1], dtype);\n if (column.meta.components === 3 && writeZ) {\n return `${x} ${y} ${numberText(vector[2], dtype)}`;\n }\n return `${x} ${y}`;\n}\n\n/**\n * Whether a 3-component position column needs its z written: the importer recorded sourceDims 3,\n * or any set row has a non-zero z (never drop data because of a 2-D hint).\n * @param column - the position column\n * @returns true when z is written\n */\nfunction needsZ(column: Column): boolean {\n if (column.meta.components !== 3) {\n return false;\n }\n if (column.meta.extra.sourceDims !== 2) {\n return true;\n }\n for (let i = 0; i < column.length; i++) {\n if (column.isSet(i)) {\n const vector = column.value(i) as ArrayLike<number>;\n if (vector[2] !== 0) {\n return true;\n }\n }\n }\n return false;\n}\n\n/**\n * The text parts of a Pajek document, one per line.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param options.networkHeader - whether the `*Network` line is written\n * @param options.mangle - whether the original ids are written as `graphty_originalId` parameters\n * @yields lines with their terminator\n * @returns nothing\n */\nfunction* writeParts(\n snapshot: GraphSnapshot,\n options: { networkHeader: boolean; mangle: boolean },\n): Generator<string, void, undefined> {\n const ids = sanitizeIds(snapshot, CAPABILITIES.idCharset, options.mangle ? \"mangle\" : \"error\");\n const nodePlan = withoutReservedKey(plan(snapshot.nodes, \"node\", null), options.mangle);\n const edgePlan = plan(snapshot.edges, \"edge\", null);\n // fail before writing anything when a text cannot be written (the check() E_ note)\n const preflight: LossNote[] = [];\n checkCells(nodePlan, \"node\", preflight);\n checkCells(edgePlan, \"edge\", preflight);\n checkIdTexts(snapshot.nodeCount, ids, options.mangle, preflight);\n for (const n of preflight) {\n if (n.code === PAJEK_LOSS.TEXT) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", n.message, {\n reason: \"pajek label\",\n column: n.column,\n count: n.count,\n });\n }\n }\n\n if (options.networkHeader && snapshot.meta.name !== null) {\n yield `*Network ${snapshot.meta.name}\\n`;\n }\n const firstMode = firstModeOf(snapshot);\n yield firstMode !== null && !Number.isNaN(firstMode)\n ? `*Vertices ${snapshot.nodeCount} ${firstMode}\\n`\n : `*Vertices ${snapshot.nodeCount}\\n`;\n yield* writeVertices(snapshot, ids, nodePlan, options.mangle);\n yield* writeLines(snapshot, edgePlan);\n}\n\n/**\n * The node plan without a user column named like the exporter's originalId key, which is\n * reserved under \"mangle\" (check() reports it as not written).\n * @param nodePlan - the node column plan\n * @param mangle - whether the original ids are written as parameters\n * @returns the plan to write\n */\nfunction withoutReservedKey(nodePlan: readonly PlannedColumn[], mangle: boolean): readonly PlannedColumn[] {\n if (!mangle) {\n return nodePlan;\n }\n return nodePlan.filter((p) => !(p.slot === \"param\" && p.column.meta.name === ORIGINAL_ID_KEY));\n}\n\n/**\n * The notes about the id texts a vertex line carries: an id written as a label or, under\n * \"mangle\", as the `graphty_originalId` parameter must be a Pajek label (E_PAJEK_TEXT otherwise),\n * and under \"mangle\" an original id whose text reads back as the other type under ids\n * \"canonical\" is reported (the importer coerces the parameter text like every id cell).\n * @param nodeCount - the node count\n * @param ids - the sanitised ids\n * @param mangle - whether the original ids are written as parameters\n * @param notes - where to record\n */\nfunction checkIdTexts(nodeCount: number, ids: SanitizedIds, mangle: boolean, notes: LossNote[]): void {\n let badText = 0;\n let typeChanged = 0;\n for (let i = 0; i < nodeCount; i++) {\n if (!ids.isChanged(i)) {\n continue;\n }\n const original = ids.originalAt(i);\n const text = idText(original);\n if (!isPajekLabel(text)) {\n badText++;\n } else if (mangle && typeof canonicalId(text) !== typeof original) {\n typeChanged++;\n }\n }\n if (badText > 0) {\n notes.push(\n note(\n PAJEK_LOSS.TEXT,\n `${badText} node id(s) hold a double quote or a line break; Pajek cannot write them as labels or parameters`,\n null,\n badText,\n ),\n );\n }\n if (typeChanged > 0) {\n notes.push(\n note(\n PAJEK_LOSS.ID_TEXT_TYPE,\n `${typeChanged} original id(s) read back from ${ORIGINAL_ID_KEY} as the other type under ids: \"canonical\" (a string \"1\" becomes 1, a number 1.5 becomes \"1.5\")`,\n null,\n typeChanged,\n ),\n );\n }\n}\n\n/**\n * The vertex lines: number, label, coordinates, shape, parameters and interval.\n * @param snapshot - the snapshot\n * @param ids - the sanitised ids\n * @param nodePlan - the node column plan\n * @param mangle - whether a renumbered vertex carries its original id as a parameter\n * @yields one line per vertex\n * @returns nothing\n */\nfunction* writeVertices(\n snapshot: GraphSnapshot,\n ids: SanitizedIds,\n nodePlan: readonly PlannedColumn[],\n mangle: boolean,\n): Generator<string, void, undefined> {\n let labels: Column | null = null;\n let position: Column | null = null;\n let shape: Column | null = null;\n let nodeSpells: Column | null = null;\n const nodeParams: Column[] = [];\n for (const { column, slot } of nodePlan) {\n switch (slot) {\n case \"label\":\n labels = column;\n break;\n case \"position\":\n position = column;\n break;\n case \"shape\":\n shape = column;\n break;\n case \"spells\":\n nodeSpells = column;\n break;\n case \"param\":\n nodeParams.push(column);\n break;\n case \"relation\":\n case \"skip\":\n break;\n default: {\n const name: string = slot;\n throw new Error(`unknown slot ${name}`);\n }\n }\n }\n const writeZ = position !== null && needsZ(position);\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const parts: string[] = [];\n if (position !== null) {\n const coordinates = coordinatesText(position, i, writeZ);\n if (coordinates !== null) {\n parts.push(coordinates);\n }\n }\n if (shape !== null && shape.isSet(i)) {\n const keyword = cellText(shape, i);\n if (SHAPES.has(keyword)) {\n parts.push(keyword);\n } else {\n parts.push(`${SHAPE_COLUMN} ${quotePajekLabel(keyword)}`);\n }\n }\n for (const column of nodeParams) {\n if (column.isSet(i)) {\n parts.push(`${column.meta.name} ${quotePajekLabel(cellText(column, i))}`);\n }\n }\n if (mangle && ids.isChanged(i)) {\n parts.push(`${ORIGINAL_ID_KEY} ${quotePajekLabel(idText(ids.originalAt(i)))}`);\n }\n if (nodeSpells !== null) {\n const spells = spellsText(nodeSpells, i);\n if (spells !== null) {\n parts.push(spells);\n }\n }\n const label = labelOf(labels, ids, i, parts.length > 0);\n let line = String(i + 1);\n if (label !== null) {\n // the importer decodes `&#dddd;` in labels, so a literal one is written with `&#38;`\n line += ` ${quotePajekLabel(encodeCharacterReferences(label))}`;\n }\n if (parts.length > 0) {\n line += ` ${parts.join(\" \")}`;\n }\n yield `${line}\\n`;\n }\n}\n\n/**\n * The line sections: runs of `*Arcs` / `*Edges` (with a relation number and name when the edge\n * has one), one line per written edge with its weight, parameters and interval.\n * @param snapshot - the snapshot\n * @param edgePlan - the edge column plan\n * @yields one line per section header and edge\n * @returns nothing\n */\nfunction* writeLines(snapshot: GraphSnapshot, edgePlan: readonly PlannedColumn[]): Generator<string, void, undefined> {\n const folding = pairFolding(snapshot, { foldMutual: true });\n const weights = explicitWeights(snapshot);\n const { src, dst } = snapshot.edgeList();\n let relation: Column | null = null;\n let edgeSpells: Column | null = null;\n const edgeParams: Column[] = [];\n for (const { column, slot } of edgePlan) {\n switch (slot) {\n case \"relation\":\n relation = column;\n break;\n case \"spells\":\n edgeSpells = column;\n break;\n case \"param\":\n edgeParams.push(column);\n break;\n case \"label\":\n case \"position\":\n case \"shape\":\n case \"skip\":\n break;\n default: {\n const name: string = slot;\n throw new Error(`unknown slot ${name}`);\n }\n }\n }\n const relationNumbers = new Map<string, number>();\n let currentKind: \"arcs\" | \"edges\" | null = null;\n let currentRelation: string | null = null;\n let sectionOpen = false;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n // a mutual pair (design section 3.6): both directions, written once as an undirected edge\n const directed = snapshot.directed && folding.sourceDirected(e) && !folding.isMutual(e);\n const kind = directed ? \"arcs\" : \"edges\";\n const relationName = relation !== null && relation.isSet(e) ? cellText(relation, e) : null;\n if (!sectionOpen || kind !== currentKind || relationName !== currentRelation) {\n currentKind = kind;\n currentRelation = relationName;\n sectionOpen = true;\n const keyword = kind === \"arcs\" ? \"*Arcs\" : \"*Edges\";\n if (relationName === null) {\n yield `${keyword}\\n`;\n } else {\n let number = relationNumbers.get(relationName);\n if (number === undefined) {\n number = relationNumbers.size + 1;\n relationNumbers.set(relationName, number);\n }\n yield `${keyword} :${number} ${quotePajekLabel(relationName)}\\n`;\n }\n }\n let line = `${src[e] + 1} ${dst[e] + 1}`;\n const weight = weights.text(e);\n if (weight !== null) {\n line += ` ${weight}`;\n }\n for (const column of edgeParams) {\n if (column.isSet(e)) {\n line += ` ${column.meta.name} ${quotePajekLabel(cellText(column, e))}`;\n }\n }\n if (edgeSpells !== null) {\n const spells = spellsText(edgeSpells, e);\n if (spells !== null) {\n line += ` ${spells}`;\n }\n }\n yield `${line}\\n`;\n }\n if (!sectionOpen) {\n yield snapshot.directed ? \"*Arcs\\n\" : \"*Edges\\n\";\n }\n}\n\n/**\n * Resolve the Pajek export options.\n * @param options - the caller's options\n * @returns the resolved format options; the common options are checked by resolveExportOptions\n */\nfunction resolvePajekOptions(options: (PajekExportOptions & CommonExportOptions) | undefined): {\n networkHeader: boolean;\n mangle: boolean;\n} {\n const common = resolveExportOptions(options);\n const value = options?.networkHeader;\n if (value !== undefined && typeof value !== \"boolean\") {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option networkHeader: not a boolean\", {\n option: \"networkHeader\",\n found: typeof value,\n });\n }\n return { networkHeader: value ?? false, mangle: common.sanitizeIds === \"mangle\" };\n}\n\n/** The Pajek NET exporter. */\nexport const pajekExporter: GraphExporter<PajekExportOptions> = Object.freeze({\n format: \"pajek\",\n capabilities: CAPABILITIES,\n\n /**\n * Pre-flight: the generic capability gaps plus the Pajek-specific ones.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the loss notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): readonly LossNote[] {\n const resolved = resolveExportOptions(options);\n const { mangle } = resolvePajekOptions(options);\n const notes: LossNote[] = [];\n const planned = plan(snapshot.nodes, \"node\", notes);\n const nodePlan = withoutReservedKey(planned, mangle);\n const edgePlan = plan(snapshot.edges, \"edge\", notes);\n const ids = sanitizeIds(snapshot, CAPABILITIES.idCharset, mangle ? \"mangle\" : \"error\");\n checkIdTexts(snapshot.nodeCount, ids, mangle, notes);\n if (nodePlan.length !== planned.length) {\n const reserved = planned.find((p) => p.slot === \"param\" && p.column.meta.name === ORIGINAL_ID_KEY);\n if (reserved !== undefined) {\n notes.push(\n note(\n PAJEK_LOSS.KEY_DROPPED,\n `node column \"${ORIGINAL_ID_KEY}\" is the parameter the exporter writes the original ids under (sanitizeIds \"mangle\"); it is not written`,\n ORIGINAL_ID_KEY,\n reserved.column.length - reserved.column.nullCount,\n ),\n );\n }\n }\n // columns this exporter handles itself although the generic table says otherwise: the spells\n // list (written as an interval token, or reported above with the spells code), the shape\n // keyword and the relation name (dict columns written as keywords)\n const owned = new Set<string>();\n for (const { column, slot } of [...nodePlan, ...edgePlan]) {\n if (slot === \"shape\" || slot === \"relation\") {\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n } else if (slot === \"param\" && column.meta.domain === \"node\" && column.meta.name === SHAPE_COLUMN) {\n // the shape-as-parameter note already says the column reads back as string\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n }\n }\n for (const table of [snapshot.nodes, snapshot.edges]) {\n for (const column of table) {\n if (column.meta.role === \"spells\") {\n owned.add(`${column.meta.domain}:${column.meta.name}`);\n }\n }\n }\n for (const n of checkCapabilities(snapshot, CAPABILITIES, resolved, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n })) {\n if (n.column !== null && (n.code === LOSS.LIST || n.code === LOSS.DTYPE)) {\n const domain = n.message.startsWith(\"node column\") ? \"node\" : \"edge\";\n if (owned.has(`${domain}:${n.column}`)) {\n continue;\n }\n }\n if (n.code === LOSS.COLUMN_NAME_CHANGED && n.message.startsWith(\"edge column\")) {\n // the label slot is a vertex slot; an edge label is a parameter under its own name\n continue;\n }\n notes.push(n);\n }\n labelNotes(snapshot, nodePlan, notes);\n for (const column of snapshot.edges) {\n if (column.meta.role === \"label\") {\n notes.push(\n note(\n LOSS.ROLE,\n `edge column \"${column.meta.name}\" (label) is written as a plain parameter; Pajek labels vertices only and the role is lost`,\n column.meta.name,\n column.length - column.nullCount,\n ),\n );\n }\n }\n checkCells(nodePlan, \"node\", notes);\n checkCells(edgePlan, \"edge\", notes);\n const folding = pairFolding(snapshot, { foldMutual: true });\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n PAJEK_LOSS.MUTUAL_AS_UNDIRECTED,\n `${folding.mutualCount} mutual pair(s) are written as undirected edges; the mutual mark is lost`,\n snapshot.edges.byRole(\"mutual\")?.meta.name ?? null,\n folding.mutualCount,\n ),\n );\n }\n if (Number.isNaN(firstModeOf(snapshot))) {\n notes.push(\n note(\n PAJEK_LOSS.FIRST_MODE_DROPPED,\n \"meta.extra.pajek.firstMode is not a count within 0..nodeCount; the two-mode header is not written\",\n ),\n );\n }\n return notes;\n },\n\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n const resolved = resolvePajekOptions(options);\n return encodeChunks(writeParts(snapshot, resolved));\n },\n\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - export options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: PajekExportOptions & CommonExportOptions): Promise<string> {\n const resolved = resolvePajekOptions(options);\n return joinText(writeParts(snapshot, resolved));\n },\n});\n","/**\n * The Pajek NET importer (design sections 8.4 and 8.6; research note 07 section 2.5): a\n * line-oriented streaming reader over the common LineReader that pushes scalars into the sink as\n * each line is read. `*Vertices N` declares vertices 1..N (0..N-1 for the zero-based files some\n * scripts write, detected from the first vertex line), so the id map of a well-formed file is\n * `identity` with offset 1; vertex lines add the label, the coordinates (the position role,\n * units \"file\"), the shape keyword and the `key value` parameters (a `graphty_originalId`\n * parameter, written by the exporter under `sanitizeIds: \"mangle\"`, is restored as the vertex's\n * id under `restoreMangledIds`); `*Arcs` sections are directed\n * and `*Edges` sections undirected, resolved through the common DirectionResolver under the\n * mixed-direction policy; the third column of a line is the weight unless `weightFrom` says\n * otherwise; `*Arcslist` / `*Edgeslist` adjacency lists and `*Matrix` rows are read too; time\n * interval tokens `[1-5,7-*]` become the spells role. A second network in one file is refused\n * with an issue. A project file's `*Partition` and `*Vector` objects become the node columns\n * `partition` (i32) and `vector` (f64), wherever they stand in the file; other project-file\n * sections (`*Events`, `*Permutation`, ...) are skipped with a warning.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type U32,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, RENAMED_CODE, ROLE_TAKEN_CODE, uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ENCODING_FALLBACK_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MULTIPLE_GRAPHS_CODE,\n OPTION_IGNORED_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver, type EdgeKind } from \"../../common/direction.js\";\nimport { coerceIdText, ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { LineReader, throwIfAborted } from \"../../common/input.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n SINK_OPTION_CODE,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { isNumericText, TextCellWriter, WIDENING_UNSUPPORTED_CODE } from \"../../common/text.js\";\nimport { isWeightField, parseWeightText } from \"../../common/weights.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n decodeCharacterReferences,\n isCommentOrBlank,\n isIntervalToken,\n isSectionLine,\n isShapeKeyword,\n isVertexNumber,\n LABEL_COLUMN,\n ORIGINAL_ID_KEY,\n parseIntervals,\n parseSectionHeader,\n PARTITION_COLUMN,\n POSITION_COLUMN,\n RELATION_COLUMN,\n type SectionHeader,\n SHAPE_COLUMN,\n SPELLS_COLUMN,\n tokenize,\n VALUE_COLUMN,\n VALUE_FIELD,\n VECTOR_COLUMN,\n} from \"./syntax.js\";\n\n/** The format-specific options of the Pajek importer. */\nexport interface PajekImportOptions {\n /**\n * The number of the first vertex: 1 (Pajek's rule), 0 (files written by zero-based scripts), or\n * \"auto\" (default): 0 when the first vertex line is numbered 0, 1 otherwise.\n */\n firstVertex?: 0 | 1 | \"auto\" | undefined;\n}\n\n/** Issue codes of the Pajek importer. */\nexport const PAJEK_ISSUE = Object.freeze({\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** Fatal: no `*Vertices` section (an empty file, or not a Pajek network). */\n NO_VERTICES: \"E_PAJEK_NO_VERTICES\",\n /** Fatal: `*Vertices` without a vertex count, one the sink cannot hold, or a first-mode count outside 0..N. */\n VERTICES_COUNT: \"E_PAJEK_VERTICES_COUNT\",\n /** A project file holds several networks; import() reads the first, importAll() reads every one. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** A data line before the first section header. */\n OUTSIDE_SECTION: \"E_PAJEK_OUTSIDE_SECTION\",\n /** A section header the importer cannot parse. */\n SYNTAX: SYNTAX_CODE,\n /** A double quote not closed before the end of the line. */\n UNTERMINATED_QUOTE: \"E_PAJEK_UNTERMINATED_QUOTE\",\n /** A vertex line the grammar does not accept. */\n VERTEX_LINE: \"E_PAJEK_VERTEX_LINE\",\n /** A vertex number outside the declared range. */\n VERTEX_RANGE: \"E_PAJEK_VERTEX_RANGE\",\n /** Fewer vertex lines than `*Vertices` declares, which the Pajek manual allows (vertices without a line have no label). */\n VERTEX_COUNT: \"W_PAJEK_VERTEX_COUNT\",\n /** A second line for the same vertex; the later values overwrite. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A line (arc, edge, list, matrix row, partition or vector value) the grammar does not accept. */\n LINE: \"E_PAJEK_LINE\",\n /** A line endpoint outside the declared vertex range (the core's code, forwarded). */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /** A malformed time interval token. */\n INTERVAL: \"E_PAJEK_INTERVAL\",\n /** A `*Matrix` section with the wrong number of rows (N, or N1 in a two-mode network). */\n MATRIX_ROWS: \"E_PAJEK_MATRIX_ROWS\",\n /** `*Matrix` rows longer than the column count; the extra values are ignored. */\n MATRIX_EXTRA: \"W_PAJEK_MATRIX_EXTRA\",\n /** A `*Partition` or `*Vector` whose value count differs from the network's vertex count; values beyond it are dropped, vertices without one are unset. */\n OBJECT_COUNT: \"E_PAJEK_OBJECT_COUNT\",\n /** A project-file section (`*Events`, `*Permutation`, ...) the importer does not read; its lines are skipped. */\n UNSUPPORTED_SECTION: \"W_PAJEK_UNSUPPORTED_SECTION\",\n /** Tokens after a section header the grammar does not account for. */\n HEADER_EXTRA: \"W_PAJEK_HEADER_EXTRA\",\n /** The file declares vertices but no line section. */\n NO_LINES: \"W_PAJEK_NO_LINES\",\n /** Vertex numbering starts at 0 rather than 1. */\n ZERO_BASED: \"W_PAJEK_ZERO_BASED\",\n /** Vertex lines mix two and three coordinates. */\n COORD_DIMS: \"W_PAJEK_COORD_DIMS\",\n /** Two vertices share a label under nodeIdFrom \"label\" and became one node. */\n LABEL_MERGED: \"W_PAJEK_LABEL_MERGED\",\n /** Two distinct label texts became one numeric id under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A parameter column of `2.0`-style text kept at the value-inferred dtype (the sink cannot widen). */\n WIDENING_UNSUPPORTED: WIDENING_UNSUPPORTED_CODE,\n /** A structural column (label, position, shape, spells, relation) renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: RENAMED_CODE,\n /** A structural column declared without its role because the sink already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two vertices carry the same `graphty_originalId` under restoreMangledIds and became one node. */\n ORIGINAL_ID_MERGED: \"W_PAJEK_ORIGINAL_ID_MERGED\",\n /** A vertex line's `graphty_originalId` came after a later vertex's line had created it under its number. */\n ORIGINAL_ID_UNRESTORED: \"W_PAJEK_ORIGINAL_ID_UNRESTORED\",\n /** A common option the importer has no use for (weightFrom naming a parameter and restoreMangledIds are honoured; long, hyperedges are not). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the caller passed that the caller's sink does not use (the shared W_SINK_OPTION). */\n SINK_OPTION: SINK_OPTION_CODE,\n});\n\n/** The common options the Pajek importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"restoreMangledIds\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: true, weightFrom: VALUE_FIELD };\n\n/** Lines between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst FIRST_VERTEX_VALUES: ReadonlySet<unknown> = new Set([0, 1, \"auto\"]);\n\nconst LABEL_DECL: ColumnDecl = {\n name: LABEL_COLUMN,\n dtype: \"string\",\n nullable: true,\n role: \"label\",\n origin: { format: \"pajek\", id: \"label\" },\n};\n\nconst SHAPE_DECL: ColumnDecl = {\n name: SHAPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n origin: { format: \"pajek\", id: \"shape\" },\n};\n\nconst RELATION_DECL: ColumnDecl = {\n name: RELATION_COLUMN,\n dtype: \"dict\",\n nullable: true,\n origin: { format: \"pajek\", id: \"relation\" },\n};\n\n/**\n * The spells column declaration of a domain (design section 5.1: a list of f64 pairs).\n * @returns a fresh declaration\n */\nfunction spellsDecl(): ColumnDecl {\n return {\n name: SPELLS_COLUMN,\n dtype: \"list\",\n itemDtype: \"f64\",\n itemComponents: 2,\n nullable: true,\n role: \"spells\",\n origin: { format: \"pajek\", id: \"interval\" },\n };\n}\n\n/**\n * The position column declaration (design section 5.2: f32 x 3, role position, units \"file\").\n * @param sourceDims - 2 or 3, the coordinate count of the first vertex line with coordinates\n * @returns a fresh declaration\n */\nfunction positionDecl(sourceDims: number): ColumnDecl {\n return {\n name: POSITION_COLUMN,\n dtype: \"f32\",\n components: 3,\n nullable: true,\n role: \"position\",\n origin: { format: \"pajek\", id: \"coordinates\" },\n extra: { sourceDims, units: \"file\" },\n };\n}\n\n/** A problem with one line, recorded as an issue by the per-line catch. */\nclass LineError extends Error {\n readonly category: \"parse-error\" | \"validation-error\" | \"missing-value\";\n\n readonly code: string;\n\n /**\n * Create a line error.\n * @param category - the issue category\n * @param code - the issue code\n * @param message - a plain-ASCII message\n */\n constructor(category: \"parse-error\" | \"validation-error\" | \"missing-value\", code: string, message: string) {\n super(message);\n this.name = \"PajekLineError\";\n this.category = category;\n this.code = code;\n }\n}\n\n/** What a vertex or line row carries besides its numbers, parsed before anything is written. */\ninterface RowExtras {\n /** Parameter keys, in order. */\n readonly keys: string[];\n /** Parameter value texts, aligned with keys. */\n readonly values: string[];\n /** The spells of an interval token, or null. */\n spells: [number, number][] | null;\n}\n\n/** The section the parser is in. */\ntype Section = \"none\" | \"vertices\" | \"lines\" | \"list\" | \"matrix\" | \"object\" | \"skip\";\n\n/**\n * A `*Partition` or `*Vector` object of a project file, buffered until the end of the network:\n * one may come before the network whose vertices it describes.\n */\ninterface ProjectObject {\n readonly kind: \"partition\" | \"vector\";\n /** The object's name from its header. */\n readonly name: string;\n /** The header's line number. */\n readonly line: number;\n /** The object's own `*Vertices N`, or null without one. */\n count: number | null;\n /** The value per vertex position; null for a line that could not be read. */\n readonly values: (number | null)[];\n}\n\n/**\n * Whether a number is an integer the i32 partition column can hold.\n * @param value - the number\n * @returns true for an i32 integer\n */\nfunction isI32(value: number): boolean {\n return Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;\n}\n\n/** A vertex number of an adjacency list: Pajek reads a negative one as its absolute value. */\nconst LIST_VERTEX = /^-?[0-9]+$/;\n\n/** The relation prefix `k:` of a line in a line section. */\nconst RELATION_PREFIX = /^([0-9]+):$/;\n\n/**\n * One import call's state machine: the sections, the vertex range, the columns declared so far\n * and the direction resolver.\n */\nclass PajekParser {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly resolver: DirectionResolver;\n\n private readonly coercer: IdCoercer;\n\n private readonly firstVertex: 0 | 1 | \"auto\";\n\n private section: Section = \"none\";\n\n /** The direction of the current line section. */\n private kind: EdgeKind = \"directed\";\n\n /** The relation name of the current line section, or null. */\n private relation: string | null = null;\n\n /** `*Vertices N`; -1 before the header. */\n private vertexCount = -1;\n\n /** The first-mode count of a two-mode network, or null. */\n private firstMode: number | null = null;\n\n private networkName: string | null = null;\n\n private base = 1;\n\n private baseKnown = false;\n\n private nodesCreated = false;\n\n private verticesDone = false;\n\n private sawLineSection = false;\n\n /** The direction of the first line section, for a network whose line sections are all empty. */\n private firstKind: EdgeKind = \"directed\";\n\n /** Set once the first line has fixed the sink's direction. */\n private directionSet = false;\n\n /** The names of the numbered relations (`*Arcs :k \"name\"`), for the `k:` line prefix. */\n private readonly relationNames = new Map<number, string>();\n\n /** The `*Partition` / `*Vector` objects read so far, written by finish(). */\n private readonly objects: ProjectObject[] = [];\n\n /** Set when the previous line was a project-object header, whose `*Vertices N` line comes next. */\n private objectHeader = false;\n\n /** Node index per vertex position (vertex number minus base). */\n private indexOfPos: U32 = new Uint32Array(0);\n\n /**\n * The node id per vertex position when the vertex lines decide the ids (nodeIdFrom \"label\",\n * or a restorable `graphty_originalId` under restoreMangledIds); null when the ids are the\n * vertex numbers and every vertex is created up front.\n */\n private idOfPos: NodeId[] | null = null;\n\n /** Which positions had a vertex line. */\n private seen: Uint8Array = new Uint8Array(0);\n\n private seenCount = 0;\n\n /**\n * Every position below this one already has an id in `idOfPos`: the high-water mark of the\n * gap-fill in `vertexLine`. Without it the gap-fill restarts at zero on every vertex line, which\n * is quadratic in the vertex count for a file whose lines are in ascending order -- which is the\n * order Pajek itself writes.\n */\n private filledBelow = 0;\n\n private matrixRows = 0;\n\n private coordDims = 0;\n\n private labelHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private positionHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private shapeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private nodeSpellsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private relationHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private edgeSpellsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private readonly nodeParams = new Map<string, TextCellWriter>();\n\n /** Set when a header line starts the next network of a project file (that line is not consumed). */\n private ended = false;\n\n private readonly edgeParams = new Map<string, TextCellWriter>();\n\n /**\n * Create the parser for one import call.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param firstVertex - the firstVertex format option\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n firstVertex: 0 | 1 | \"auto\",\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.firstVertex = firstVertex;\n this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Handle one line; every problem of the line is recorded as an issue and the line skipped.\n * @param text - the line without its terminator\n * @param line - the 1-based line number\n * @returns true when the line is the header of the next network (not consumed: this network is complete)\n */\n line(text: string, line: number): boolean {\n if (isCommentOrBlank(text)) {\n return false;\n }\n const afterObjectHeader = this.objectHeader;\n this.objectHeader = false;\n try {\n if (isSectionLine(text)) {\n this.header(text, line, afterObjectHeader);\n return this.ended;\n }\n switch (this.section) {\n case \"none\":\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.OUTSIDE_SECTION,\n \"data before the first section header; a Pajek network starts with *Vertices\",\n );\n case \"vertices\":\n this.vertexLine(text, line);\n return false;\n case \"lines\":\n this.edgeLine(text, line);\n return false;\n case \"list\":\n this.listLine(text, line);\n return false;\n case \"matrix\":\n this.matrixLine(text, line);\n return false;\n case \"object\":\n this.objectLine(text);\n return false;\n case \"skip\":\n return false;\n default: {\n const name: string = this.section;\n throw new Error(`unknown section state ${name}`);\n }\n }\n } catch (err) {\n if (err instanceof LineError) {\n this.report.error(err.category, err.code, err.message, { line });\n return false;\n }\n this.report.recordError(err, { line });\n return false;\n }\n }\n\n /**\n * End of input: the vertex set is completed, a network without line sections gets the default\n * direction, and the metadata is written.\n */\n finish(): void {\n if (this.vertexCount < 0) {\n this.report.fail(PAJEK_ISSUE.NO_VERTICES, \"not a Pajek network: no *Vertices section found\");\n }\n this.endSection();\n this.finishVertices();\n if (!this.sawLineSection) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.NO_LINES,\n \"the file declares vertices but no *Arcs, *Edges, *Arcslist, *Edgeslist or *Matrix section\",\n );\n this.resolver.setHeader(this.options.defaultDirected);\n } else if (!this.directionSet) {\n // every line section was empty: the first header still says which way the network goes\n this.resolver.setHeader(this.firstKind === \"directed\");\n }\n const objects = this.writeObjects();\n if (this.coercer.mergeCount > 0) {\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ID_MERGED,\n `${this.coercer.mergeCount} label(s) merged into an id another label already produced under ids \"number\"`,\n );\n }\n const pajek = {\n ...(this.firstMode === null ? {} : { firstMode: this.firstMode }),\n ...(objects.length === 0 ? {} : { objects }),\n };\n const meta: GraphMetaPatch = {\n sourceFormat: \"pajek\",\n ...(this.networkName === null ? {} : { name: this.networkName }),\n ...(Object.keys(pajek).length === 0 ? {} : { extra: { pajek } }),\n };\n this.sink.setMeta(meta);\n }\n\n /**\n * Write every `*Partition` / `*Vector` object into its node column: `partition` (i32) or\n * `vector` (f64), a later object of the same kind in `partition#2`, `vector#2`, ... The value\n * of vertex k is the object's k-th value.\n * @returns the objects' Pajek names and the columns they went to, for meta.extra.pajek.objects\n */\n private writeObjects(): { kind: string; name: string; column: string }[] {\n const used = new Set<string>();\n const written: { kind: string; name: string; column: string }[] = [];\n for (const object of this.objects) {\n const where = { line: object.line };\n const partition = object.kind === \"partition\";\n const name = uniqueColumnName(partition ? PARTITION_COLUMN : VECTOR_COLUMN, null, (n) => used.has(n));\n used.add(name);\n const { handle, decl } = declareResolved(\n this.sink,\n \"node\",\n {\n name,\n dtype: partition ? \"i32\" : \"f64\",\n nullable: true,\n origin: { format: \"pajek\", id: object.kind },\n },\n this.report,\n where,\n );\n const n = Math.min(object.values.length, this.vertexCount);\n for (let pos = 0; pos < n; pos++) {\n const value = object.values[pos];\n if (value !== null) {\n this.sink.setNodeValue(handle, this.indexOfPos[pos], value);\n }\n }\n const declared = object.count ?? object.values.length;\n if (declared !== this.vertexCount || object.values.length !== declared) {\n this.report.error(\n \"validation-error\",\n PAJEK_ISSUE.OBJECT_COUNT,\n `*${partition ? \"Partition\" : \"Vector\"} \"${object.name}\" declares ${declared} vertices and holds ${object.values.length} value(s); the network has ${this.vertexCount}`,\n where,\n );\n }\n written.push({ kind: object.kind, name: object.name, column: decl.name });\n }\n return written;\n }\n\n // ============================================================ headers\n\n /**\n * A section header line.\n * @param text - the line\n * @param line - the line number\n * @param afterObjectHeader - the previous line was a `*Partition`, `*Vector` or skipped section header\n */\n private header(text: string, line: number, afterObjectHeader: boolean): void {\n const previous = this.section;\n this.endSection();\n const h = parseSectionHeader(text);\n if (h === null) {\n this.section = \"skip\";\n throw new LineError(\"parse-error\", PAJEK_ISSUE.SYNTAX, `cannot read the section header \"${text}\"`);\n }\n if (h.extra.length > 0) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.HEADER_EXTRA,\n `ignored ${h.extra.length} unexpected token(s) after *${h.keyword}: ${h.extra.join(\" \")}`,\n { line },\n );\n }\n switch (h.kind) {\n case \"network\":\n if (this.networkName !== null || this.vertexCount >= 0) {\n this.ended = true;\n return;\n }\n this.networkName = h.name ?? \"\";\n this.section = \"none\";\n return;\n case \"vertices\":\n if (afterObjectHeader) {\n // the `*Vertices N` line of a project object (*Partition, *Vector, a skipped\n // section), wherever it stands: never the network's own\n this.section = previous;\n if (previous === \"object\") {\n this.objects[this.objects.length - 1].count = h.count;\n }\n return;\n }\n if (this.vertexCount >= 0) {\n // a second `*Vertices` without a `*Network` header starts the next network\n this.ended = true;\n return;\n }\n this.verticesHeader(h, line);\n return;\n case \"arcs\":\n case \"edges\":\n this.lineSection(h, line, \"lines\", h.kind === \"arcs\" ? \"directed\" : \"undirected\");\n return;\n case \"arcslist\":\n case \"edgeslist\":\n this.lineSection(h, line, \"list\", h.kind === \"arcslist\" ? \"directed\" : \"undirected\");\n return;\n case \"matrix\":\n this.lineSection(h, line, \"matrix\", \"directed\");\n this.matrixRows = 0;\n return;\n case \"partition\":\n case \"vector\":\n this.objects.push({ kind: h.kind, name: h.name ?? \"\", line, count: null, values: [] });\n this.section = \"object\";\n this.objectHeader = true;\n return;\n case \"unsupported\":\n this.section = \"skip\";\n this.objectHeader = true;\n this.report.warning(\n \"unsupported\",\n PAJEK_ISSUE.UNSUPPORTED_SECTION,\n `the *${h.keyword} section is not supported; its lines are skipped`,\n { line },\n );\n return;\n default: {\n const name: string = h.kind;\n throw new Error(`unknown section kind ${name}`);\n }\n }\n }\n\n /**\n * `*Vertices N [N1]`.\n * @param h - the header\n * @param line - the line number\n */\n private verticesHeader(h: SectionHeader, line: number): void {\n if (h.count === null) {\n this.report.fail(PAJEK_ISSUE.VERTICES_COUNT, \"*Vertices needs a vertex count\", { line });\n }\n if (!Number.isSafeInteger(h.count)) {\n this.report.fail(PAJEK_ISSUE.VERTICES_COUNT, `*Vertices ${h.count}: not a count`, { line });\n }\n if (h.secondCount !== null && (h.secondCount < 0 || h.secondCount > h.count)) {\n this.report.fail(\n PAJEK_ISSUE.VERTICES_COUNT,\n `*Vertices ${h.count} ${h.secondCount}: the first-mode count is not within 0..${h.count}`,\n { line },\n );\n }\n try {\n // the declared count must be reservable (the sink is the authority on what it can hold,\n // E_TOO_LARGE beyond MAX_COUNT) before any vertex is materialised\n this.sink.reserve(h.count);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n this.report.fail(\n PAJEK_ISSUE.VERTICES_COUNT,\n `*Vertices ${h.count}: the sink cannot hold that many (${reason})`,\n {\n line,\n },\n );\n }\n this.vertexCount = h.count;\n if (h.secondCount !== null) {\n this.firstMode = h.secondCount;\n }\n this.section = \"vertices\";\n this.indexOfPos = new Uint32Array(h.count);\n this.seen = new Uint8Array(h.count);\n this.filledBelow = 0;\n if (this.options.nodeIdFrom === \"label\" || this.restoresIds()) {\n this.idOfPos = new Array<NodeId>(h.count);\n }\n if (this.firstVertex !== \"auto\") {\n this.setBase(this.firstVertex, line);\n }\n }\n\n /**\n * A line section header: the vertex set is completed and the kind switched. The sink's\n * direction (rule 1 of design section 8.4) is set by the first LINE, not the first header, so\n * an empty `*Arcs` before the `*Edges` of an undirected network does not make it directed.\n * @param h - the header\n * @param line - the line number\n * @param section - the parser state for the section\n * @param kind - the direction of its lines\n */\n private lineSection(h: SectionHeader, line: number, section: Section, kind: EdgeKind): void {\n if (this.vertexCount < 0) {\n this.report.fail(\n PAJEK_ISSUE.NO_VERTICES,\n `*${h.keyword} before *Vertices; a Pajek network starts with *Vertices`,\n { line },\n );\n }\n this.finishVertices();\n if (!this.sawLineSection) {\n this.sawLineSection = true;\n this.firstKind = kind;\n }\n this.section = section;\n this.kind = kind;\n this.relation = h.relation === null ? null : (h.name ?? String(h.relation));\n if (h.relation !== null) {\n this.relationNames.set(h.relation, this.relation ?? String(h.relation));\n }\n }\n\n /**\n * Checks that run when a section ends.\n */\n private endSection(): void {\n const rows = this.firstMode ?? this.vertexCount;\n if (this.section === \"matrix\" && this.matrixRows !== rows) {\n this.report.error(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_ROWS,\n `*Matrix has ${this.matrixRows} row(s); *Vertices declares ${rows}`,\n );\n }\n this.section = \"none\";\n }\n\n // ============================================================ vertices\n\n /**\n * Fix the vertex numbering base and, under nodeIdFrom \"id\" / \"index\", create the declared\n * vertices in number order so the id map is identity.\n * @param base - 0 or 1\n * @param line - the line number\n */\n private setBase(base: 0 | 1, line: number): void {\n this.base = base;\n this.baseKnown = true;\n if (base === 0) {\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ZERO_BASED,\n \"vertex numbering starts at 0; Pajek numbers vertices from 1\",\n { line },\n );\n }\n }\n\n /**\n * Push vertices base..base+N-1 in order (nodeIdFrom \"id\" / \"index\"), so the id map is identity;\n * called on the first vertex line (once it is known that the lines carry no `graphty_originalId`\n * parameter to restore) or when the vertex section ends without one.\n */\n private createNodes(): void {\n if (this.nodesCreated || this.idOfPos !== null) {\n return;\n }\n this.nodesCreated = true;\n const n = this.vertexCount;\n const { sink } = this;\n for (let pos = 0; pos < n; pos++) {\n this.indexOfPos[pos] = sink.addNode(this.idOfNumber(pos + this.base));\n }\n this.report.counts.nodes += n;\n }\n\n /**\n * The id of a vertex number under nodeIdFrom \"id\" (the number coerced by the ids rule) or\n * \"index\" (the position).\n * @param k - the vertex number\n * @returns the id\n */\n private idOfNumber(k: number): NodeId {\n if (this.options.nodeIdFrom === \"index\") {\n return k - this.base;\n }\n switch (this.options.ids) {\n case \"canonical\":\n case \"number\":\n return k;\n case \"keep\":\n case \"string\":\n return String(k);\n default:\n return coerceIdText(String(k), this.options.ids);\n }\n }\n\n /**\n * The id of a vertex position, for addEdge.\n * @param pos - the vertex number minus the base\n * @returns the id\n */\n private idAt(pos: number): NodeId {\n if (this.idOfPos !== null) {\n return this.idOfPos[pos];\n }\n return this.idOfNumber(pos + this.base);\n }\n\n /**\n * Complete the vertex set once the vertex section is over: vertices without a line are\n * created (under \"label\" or a restored `graphty_originalId` with their number as the id), and\n * a partial list is reported.\n */\n private finishVertices(): void {\n if (this.verticesDone) {\n return;\n }\n this.verticesDone = true;\n if (!this.baseKnown) {\n this.setBase(1, 0);\n }\n const n = this.vertexCount;\n this.createNodes();\n if (this.idOfPos !== null) {\n for (let pos = 0; pos < n; pos++) {\n if (this.idOfPos[pos] === undefined) {\n this.numberedNode(this.idOfPos, pos);\n }\n }\n }\n // a partial list: fewer lines than declared, counting the lines skipped after an error\n const lines = this.seenCount + this.report.counts.skippedNodes;\n if (this.seenCount > 0 && lines < n) {\n this.report.warning(\n \"validation-error\",\n PAJEK_ISSUE.VERTEX_COUNT,\n `*Vertices declares ${n} vertices but ${lines} vertex line(s) were read; the others have no label`,\n );\n }\n }\n\n /**\n * A vertex line: `number [label] [x y [z]] [shape] [key value ...] [interval]`.\n * @param text - the line\n * @param line - the line number\n */\n private vertexLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"node\");\n if (!isVertexNumber(tokens[0])) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.VERTEX_LINE,\n `a vertex line starts with a vertex number, not \"${tokens[0]}\"`,\n );\n }\n const k = Number(tokens[0]);\n if (!this.baseKnown) {\n this.setBase(k === 0 ? 0 : 1, line);\n }\n const pos = k - this.base;\n if (pos < 0 || pos >= this.vertexCount) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.VERTEX_RANGE,\n `vertex ${k} is outside ${this.base}..${this.base + this.vertexCount - 1}`,\n );\n }\n // parse everything before writing anything\n let i = 1;\n let label: string | null = null;\n if (tokens.length > 1 && !startsWithCoordinates(text, tokens)) {\n label = decodeCharacterReferences(tokens[1]);\n i = 2;\n }\n let x = 0;\n let y = 0;\n let z = 0;\n let dims = 0;\n if (i + 1 < tokens.length && isNumericText(tokens[i]) && isNumericText(tokens[i + 1])) {\n x = Number(tokens[i]);\n y = Number(tokens[i + 1]);\n i += 2;\n dims = 2;\n if (i < tokens.length && isNumericText(tokens[i])) {\n z = Number(tokens[i]);\n i++;\n dims = 3;\n }\n } else if (i < tokens.length && isNumericText(tokens[i])) {\n this.report.counts.skippedNodes++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.VERTEX_LINE,\n `vertex ${k}: a single coordinate \"${tokens[i]}\"; coordinates are x y [z]`,\n );\n }\n let shape: string | null = null;\n if (i < tokens.length && isShapeKeyword(tokens[i])) {\n shape = tokens[i].toLowerCase();\n i++;\n }\n const extras = this.extras(tokens, i, \"node\");\n const restored = this.restoredId(extras);\n this.createNodes();\n // write\n const repeated = this.seen[pos] !== 0;\n if (repeated) {\n this.report.warning(\n \"merged\",\n PAJEK_ISSUE.DUPLICATE_NODE,\n `vertex ${k} has more than one line; the later values overwrite`,\n { line, element: String(k) },\n );\n } else {\n this.seen[pos] = 1;\n this.seenCount++;\n }\n let index: number;\n if (this.idOfPos !== null && !repeated && this.options.nodeIdFrom === \"label\") {\n index = this.deferredNode(this.idOfPos, pos, k, label, line, \"label\");\n } else if (this.idOfPos !== null && this.idOfPos[pos] === undefined) {\n // restore mode: the earlier positions without a line yet get their numbers first, so the\n // index order is the vertex number order whatever the line order (the identity id map\n // of an ordered file); then this vertex with its original id, or its number\n for (let p = this.filledBelow; p < pos; p++) {\n if (this.idOfPos[p] === undefined) {\n this.numberedNode(this.idOfPos, p);\n }\n }\n // after the loop on purpose: a throw part-way leaves the mark at its smaller, still\n // correct value and the next line re-scans the range\n if (pos > this.filledBelow) {\n this.filledBelow = pos;\n }\n index = this.deferredNode(this.idOfPos, pos, k, restored, line, \"originalId\");\n } else {\n index = this.indexOfPos[pos];\n if (restored !== null && !repeated) {\n // an out-of-order line: the vertex already exists under its number\n this.report.warning(\n \"coercion\",\n PAJEK_ISSUE.ORIGINAL_ID_UNRESTORED,\n `vertex ${k} carries ${ORIGINAL_ID_KEY} ${JSON.stringify(restored)} but a later vertex's line came first and created it under its number; the original id is not restored`,\n { line, element: String(k) },\n );\n }\n }\n const { sink } = this;\n if (label !== null) {\n if (this.labelHandle === INVALID_INDEX) {\n this.labelHandle = declareResolved(sink, \"node\", LABEL_DECL, this.report, { line }).handle;\n }\n sink.setNodeValue(this.labelHandle, index, label);\n }\n if (dims > 0) {\n if (this.positionHandle === INVALID_INDEX) {\n this.coordDims = dims;\n this.positionHandle = declareResolved(sink, \"node\", positionDecl(dims), this.report, { line }).handle;\n } else if (dims !== this.coordDims) {\n this.report.warnOnce(\n \"validation-error\",\n PAJEK_ISSUE.COORD_DIMS,\n `vertex lines mix ${this.coordDims} and ${dims} coordinates; the position column records sourceDims ${this.coordDims}`,\n { line, element: String(k) },\n );\n }\n sink.setNodeValue(this.positionHandle, index, [x, y, z]);\n }\n if (shape !== null) {\n if (this.shapeHandle === INVALID_INDEX && this.nodeParams.has(SHAPE_COLUMN)) {\n // an earlier `shape \"<text>\"` parameter owns the column: the keyword is written there\n this.writeParameter(\"node\", SHAPE_COLUMN, index, shape);\n } else {\n if (this.shapeHandle === INVALID_INDEX) {\n this.shapeHandle = declareResolved(sink, \"node\", SHAPE_DECL, this.report, { line }).handle;\n }\n sink.setNodeValue(this.shapeHandle, index, shape);\n }\n }\n for (let p = 0; p < extras.keys.length; p++) {\n this.writeParameter(\"node\", extras.keys[p], index, extras.values[p]);\n }\n if (extras.spells !== null) {\n if (this.nodeSpellsHandle === INVALID_INDEX) {\n this.nodeSpellsHandle = declareResolved(sink, \"node\", spellsDecl(), this.report, { line }).handle;\n }\n sink.setNodeValue(this.nodeSpellsHandle, index, extras.spells);\n }\n }\n\n /**\n * Whether a `graphty_originalId` parameter is restored as the vertex id: restoreMangledIds\n * under nodeIdFrom \"id\" (under \"label\" / \"index\" the parameter stays an ordinary column).\n * @returns true when the vertex lines may carry restorable ids\n */\n private restoresIds(): boolean {\n return this.options.restoreMangledIds && this.options.nodeIdFrom === \"id\";\n }\n\n /**\n * Push a vertex whose id is its number (restore mode, a position whose line has not come or\n * carries no original id; or the end of the vertex section under \"label\").\n * @param ids - the id per vertex position\n * @param pos - the vertex position\n */\n private numberedNode(ids: NodeId[], pos: number): void {\n const id = this.idOfNumber(pos + this.base);\n ids[pos] = id;\n this.indexOfPos[pos] = this.sink.addNode(id);\n this.report.counts.nodes++;\n }\n\n /**\n * The `graphty_originalId` parameter of a vertex line, taken out of the extras when it is to be\n * restored as the id (restoreMangledIds, under nodeIdFrom \"id\"); otherwise null and the\n * parameter stays an ordinary column.\n * @param extras - the parsed extras\n * @returns the original id text, or null\n */\n private restoredId(extras: RowExtras): string | null {\n if (!this.restoresIds()) {\n return null;\n }\n const at = extras.keys.indexOf(ORIGINAL_ID_KEY);\n if (at < 0) {\n return null;\n }\n const [text] = extras.values.splice(at, 1);\n extras.keys.splice(at, 1);\n return text;\n }\n\n /**\n * Push the node of a vertex line whose id comes from the line itself: its label under\n * nodeIdFrom \"label\", or its restored `graphty_originalId` (the number when the line carries\n * none), reporting a merge when the id was seen before.\n * @param ids - the id per vertex position\n * @param pos - the vertex position\n * @param k - the vertex number\n * @param text - the label or original id text, or null\n * @param line - the line number\n * @param from - which text the id comes from\n * @returns the node index\n */\n private deferredNode(\n ids: NodeId[],\n pos: number,\n k: number,\n text: string | null,\n line: number,\n from: \"label\" | \"originalId\",\n ): number {\n const id = text === null ? this.idOfNumber(k) : this.coercer.text(text);\n const before = this.sink.indexOf(id);\n const index = this.sink.addNode(id);\n ids[pos] = id;\n this.indexOfPos[pos] = index;\n this.report.counts.nodes++;\n if (before !== INVALID_INDEX) {\n this.report.warning(\n \"merged\",\n from === \"label\" ? PAJEK_ISSUE.LABEL_MERGED : PAJEK_ISSUE.ORIGINAL_ID_MERGED,\n from === \"label\"\n ? `vertex ${k} has the label ${JSON.stringify(String(id))} of an earlier vertex; both are one node`\n : `vertex ${k} has the ${ORIGINAL_ID_KEY} ${JSON.stringify(String(id))} of an earlier vertex; both are one node`,\n { line, element: String(k) },\n );\n }\n return index;\n }\n\n // ============================================================ lines\n\n /**\n * An arc or edge line: `u v [value] [key value ...] [interval]`.\n * @param text - the line\n * @param line - the line number\n */\n private edgeLine(text: string, line: number): void {\n let tokens = this.tokens(text, \"edge\");\n // a `k:` prefix puts this one line in relation k\n let { relation } = this;\n const prefix = RELATION_PREFIX.exec(tokens[0]);\n if (prefix !== null) {\n const k = Number(prefix[1]);\n relation = this.relationNames.get(k) ?? String(k);\n tokens = tokens.slice(1);\n }\n if (tokens.length < 2 || !isVertexNumber(tokens[0]) || !isVertexNumber(tokens[1])) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `a line starts with two vertex numbers, not \"${tokens.slice(0, 2).join(\" \")}\"`,\n );\n }\n const u = this.endpoint(Number(tokens[0]));\n const v = this.endpoint(Number(tokens[1]));\n let i = 2;\n let valueText: string | null = null;\n if (i < tokens.length && isNumericText(tokens[i])) {\n valueText = tokens[i];\n i++;\n }\n const extras = this.extras(tokens, i, \"edge\");\n const { weightFrom } = this.options;\n let weight: number | undefined;\n let valueIsWeight = false;\n if (isWeightField(VALUE_FIELD, weightFrom)) {\n valueIsWeight = true;\n if (valueText !== null) {\n weight = this.weightOf(valueText);\n }\n } else if (weightFrom !== null) {\n const at = extras.keys.indexOf(weightFrom);\n if (at >= 0) {\n weight = this.weightOf(extras.values[at]);\n extras.keys.splice(at, 1);\n extras.values.splice(at, 1);\n }\n }\n const e = this.pushEdge(u, v, weight, line);\n if (valueText !== null && !valueIsWeight) {\n // inferred like every parameter, so a re-import of the exporter's `value` parameter agrees\n this.writeParameter(\"edge\", VALUE_COLUMN, e, valueText);\n }\n this.writeEdgeExtras(e, extras, relation);\n }\n\n /**\n * An adjacency list line of `*Arcslist` / `*Edgeslist`: `v n1 n2 ...`; a negative vertex\n * number is read as its absolute value, as Pajek does.\n * @param text - the line\n * @param line - the line number\n */\n private listLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"edge\");\n for (const token of tokens) {\n if (!LIST_VERTEX.test(token)) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `an adjacency list holds vertex numbers only, not \"${token}\"`,\n );\n }\n }\n const u = this.endpoint(Math.abs(Number(tokens[0])));\n for (let i = 1; i < tokens.length; i++) {\n const v = this.endpoint(Math.abs(Number(tokens[i])));\n const e = this.pushEdge(u, v, undefined, line);\n this.writeRelation(e);\n }\n }\n\n /**\n * A `*Matrix` row, every non-zero entry an arc from the row's vertex with that value: N values\n * in a one-mode network; in a two-mode network (`*Vertices N N1`) the matrix is N1 rows of\n * N - N1 values, entry j of row i an arc from vertex i to vertex N1 + j.\n * @param text - the line\n * @param line - the line number\n */\n private matrixLine(text: string, line: number): void {\n const tokens = this.tokens(text, \"edge\");\n const row = this.matrixRows;\n this.matrixRows++;\n const offset = this.firstMode ?? 0;\n const rows = this.firstMode ?? this.vertexCount;\n const columns = this.vertexCount - offset;\n if (row >= rows) {\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_ROWS,\n `*Matrix row ${row + 1} is beyond the ${rows} declared row(s)`,\n );\n }\n if (tokens.length < columns) {\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*Matrix row ${row + 1} has ${tokens.length} value(s); the matrix has ${columns} column(s)`,\n );\n }\n for (let j = 0; j < columns; j++) {\n if (!isNumericText(tokens[j])) {\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*Matrix row ${row + 1}: \"${tokens[j]}\" is not a number`,\n );\n }\n }\n if (tokens.length > columns) {\n this.report.warnOnce(\n \"validation-error\",\n PAJEK_ISSUE.MATRIX_EXTRA,\n `*Matrix row ${row + 1} has ${tokens.length} value(s) for ${columns} column(s); the extra values are ignored`,\n { line },\n );\n }\n for (let j = 0; j < columns; j++) {\n const value = Number(tokens[j]);\n if (value === 0) {\n continue;\n }\n const e = this.pushEdge(row, offset + j, value, line);\n this.writeRelation(e);\n }\n }\n\n /**\n * A value line of a `*Partition` (integers) or `*Vector` (numbers): the values of the next\n * vertices, usually one per line.\n * @param text - the line\n */\n private objectLine(text: string): void {\n const object = this.objects[this.objects.length - 1];\n const tokens = this.tokens(text, \"node\");\n for (const token of tokens) {\n if (!isNumericText(token) || (object.kind === \"partition\" && !isI32(Number(token)))) {\n // keep the later values on their vertices\n object.values.push(null);\n throw new LineError(\n \"parse-error\",\n PAJEK_ISSUE.LINE,\n `*${object.kind === \"partition\" ? \"Partition\" : \"Vector\"} \"${object.name}\": \"${token}\" is not ${object.kind === \"partition\" ? \"an integer\" : \"a number\"}`,\n );\n }\n }\n for (const token of tokens) {\n object.values.push(Number(token));\n }\n }\n\n /**\n * Push one line through the direction resolver, counting the logical edges it produced.\n * @param u - the source position\n * @param v - the target position\n * @param weight - the weight, or undefined for none\n * @param line - the line number\n * @returns the primary logical edge index\n */\n private pushEdge(u: number, v: number, weight: number | undefined, line: number): number {\n const { sink } = this;\n if (!this.directionSet) {\n this.directionSet = true;\n this.resolver.setHeader(this.kind === \"directed\", { line });\n }\n const before = sink.edgeCount;\n const e = this.resolver.addEdge(this.idAt(u), this.idAt(v), this.kind, weight, { line });\n this.report.counts.edges += sink.edgeCount - before;\n return e;\n }\n\n /**\n * Write the relation, parameters and spells of a line on its primary half.\n * @param e - the edge index\n * @param extras - the parsed extras\n * @param relation - the line's relation name, or null\n */\n private writeEdgeExtras(e: number, extras: RowExtras, relation: string | null): void {\n const { sink } = this;\n this.writeRelation(e, relation);\n for (let p = 0; p < extras.keys.length; p++) {\n this.writeParameter(\"edge\", extras.keys[p], e, extras.values[p]);\n }\n if (extras.spells !== null) {\n if (this.edgeSpellsHandle === INVALID_INDEX) {\n this.edgeSpellsHandle = declareResolved(sink, \"edge\", spellsDecl(), this.report).handle;\n }\n sink.setEdgeValue(this.edgeSpellsHandle, e, extras.spells);\n }\n }\n\n /**\n * Write a relation name on an edge: the current section's, unless a line prefix named another.\n * @param e - the edge index\n * @param relation - the relation name, or null for none\n */\n private writeRelation(e: number, relation: string | null = this.relation): void {\n if (relation === null) {\n return;\n }\n if (this.relationHandle === INVALID_INDEX) {\n this.relationHandle = declareResolved(this.sink, \"edge\", RELATION_DECL, this.report).handle;\n }\n this.sink.setEdgeValue(this.relationHandle, e, relation);\n }\n\n /**\n * A line endpoint: the vertex number checked against the declared range; a reference outside\n * it is a missing-value error and the line is skipped (Pajek's `*Vertices N` bounds the id space,\n * so addMissingNodes does not apply).\n * @param k - the vertex number\n * @returns the vertex position\n */\n private endpoint(k: number): number {\n const pos = k - this.base;\n if (pos < 0 || pos >= this.vertexCount) {\n this.report.counts.skippedEdges++;\n throw new LineError(\n \"missing-value\",\n PAJEK_ISSUE.UNKNOWN_NODE,\n `vertex ${k} is outside ${this.base}..${this.base + this.vertexCount - 1}`,\n );\n }\n return pos;\n }\n\n /**\n * The weight of a line value text.\n * @param text - the text\n * @returns the weight; E_INVALID_WEIGHT is recorded by the caller's catch\n */\n private weightOf(text: string): number | undefined {\n try {\n return parseWeightText(text);\n } catch (err) {\n this.report.counts.skippedEdges++;\n throw err;\n }\n }\n\n // ============================================================ shared\n\n /**\n * Tokenize a data line.\n * @param text - the line\n * @param domain - what is skipped on an unterminated quote\n * @returns the tokens (at least one: blank lines never reach here)\n */\n private tokens(text: string, domain: \"node\" | \"edge\"): string[] {\n const tokens = tokenize(text);\n if (tokens === null) {\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n throw new LineError(\"parse-error\", PAJEK_ISSUE.UNTERMINATED_QUOTE, \"a double quote is not closed\");\n }\n return tokens;\n }\n\n /**\n * The `key value` parameters and the interval token at the end of a row, validated before\n * anything is written.\n * @param tokens - the row's tokens\n * @param start - the first token to read\n * @param domain - what is skipped when the row is malformed\n * @returns the parsed extras\n */\n private extras(tokens: readonly string[], start: number, domain: \"node\" | \"edge\"): RowExtras {\n const extras: RowExtras = { keys: [], values: [], spells: null };\n for (let i = start; i < tokens.length;) {\n const token = tokens[i];\n if (isIntervalToken(token)) {\n try {\n const spells = parseIntervals(token);\n // an empty `[]` is no spell at all\n extras.spells = spells.length === 0 ? null : spells;\n } catch (err) {\n this.skip(domain);\n throw new LineError(\n \"validation-error\",\n PAJEK_ISSUE.INTERVAL,\n err instanceof Error ? err.message : String(err),\n );\n }\n i++;\n continue;\n }\n if (i + 1 >= tokens.length) {\n this.skip(domain);\n throw new LineError(\n \"parse-error\",\n domain === \"node\" ? PAJEK_ISSUE.VERTEX_LINE : PAJEK_ISSUE.LINE,\n `parameter \"${token}\" has no value`,\n );\n }\n extras.keys.push(token);\n extras.values.push(tokens[i + 1]);\n i += 2;\n }\n return extras;\n }\n\n /**\n * Count a skipped element.\n * @param domain - node or edge\n */\n private skip(domain: \"node\" | \"edge\"): void {\n if (domain === \"node\") {\n this.report.counts.skippedNodes++;\n } else {\n this.report.counts.skippedEdges++;\n }\n }\n\n /**\n * Write one `key value` parameter cell through the column's text writer (the 5.1 grammar per\n * column, the lexical form kept). A `shape` parameter next to the shape keyword column goes\n * into that column (a dict takes any text), and a shape keyword next to a `shape` parameter\n * column into that one, so a file mixing the two spellings reads as one column.\n * @param domain - node or edge\n * @param key - the parameter key (the column name)\n * @param row - the node or edge index\n * @param text - the value text\n */\n private writeParameter(domain: \"node\" | \"edge\", key: string, row: number, text: string): void {\n if (domain === \"node\" && key === SHAPE_COLUMN && this.shapeHandle !== INVALID_INDEX) {\n this.sink.setNodeValue(this.shapeHandle, row, text);\n return;\n }\n const writers = domain === \"node\" ? this.nodeParams : this.edgeParams;\n let writer = writers.get(key);\n if (writer === undefined) {\n writer = new TextCellWriter(key, domain, this.sink, this.report);\n writers.set(key, writer);\n }\n writer.write(row, text);\n }\n}\n\n/**\n * Whether a vertex line has coordinates but no label: the token after the vertex number is bare\n * (not quoted) and starts a run of exactly two numbers, which cannot be a label and one\n * coordinate. A run of three stays a numeric label and x y (the NetworkX writer's `1 0 0.5 0.5`),\n * the one reading of it that keeps real files' labels.\n * @param text - the line\n * @param tokens - its tokens\n * @returns true when tokens[1] is the first coordinate\n */\nfunction startsWithCoordinates(text: string, tokens: readonly string[]): boolean {\n if (text.trimStart().slice(tokens[0].length).trimStart().startsWith('\"')) {\n return false;\n }\n let run = 0;\n while (1 + run < tokens.length && isNumericText(tokens[1 + run])) {\n run++;\n }\n return run === 2;\n}\n\n/**\n * Resolve the firstVertex option.\n * @param value - the caller's value\n * @returns 0, 1 or \"auto\"; E_UNSUPPORTED for anything else\n */\nfunction firstVertexOption(value: unknown): 0 | 1 | \"auto\" {\n if (value === undefined) {\n return \"auto\";\n }\n if (FIRST_VERTEX_VALUES.has(value)) {\n return value as 0 | 1 | \"auto\";\n }\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option firstVertex: ${JSON.stringify(value) ?? typeof value} is not 0, 1 or \"auto\"`,\n {\n option: \"firstVertex\",\n found: value,\n },\n );\n}\n\nconst HEAD_PATTERN = /^\\s*\\*(vertices|network)\\b/i;\n\n/** The Pajek NET importer. */\nexport const pajekImporter: GraphImporter<PajekImportOptions> = Object.freeze({\n format: \"pajek\",\n extensions: Object.freeze([\".net\", \".paj\"]),\n mimeTypes: Object.freeze([\"text/x-pajek\", \"text/plain\"]),\n\n /**\n * Confidence that the input is a Pajek network: it starts with `*Vertices` (or `*Network`).\n * @param head - the first bytes\n * @returns 0.9 for a `*Vertices` start, 0.8 for `*Network`, 0 otherwise\n */\n sniff(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\").decode(head.subarray(0, Math.min(head.byteLength, 512)));\n const match = HEAD_PATTERN.exec(text.startsWith(String.fromCharCode(0xfeff)) ? text.slice(1) : text);\n if (match === null) {\n return 0;\n }\n return match[1].toLowerCase() === \"vertices\" ? 0.9 : 0.8;\n },\n\n /**\n * Read a Pajek network into the sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - common and Pajek options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: PajekImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, DEFAULTS);\n const firstVertex = firstVertexOption(options?.firstVertex);\n const report = new ImportReportBuilder(\"pajek\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const parser = new PajekParser(sink, report, resolved, firstVertex);\n const reader = new LineReader(input, report, resolved);\n // after the first network: only its successors' headers are counted\n let rest: NetworkCounter | null = null;\n let restLine = 0;\n let sinceCheck = 0;\n for await (const text of reader) {\n if (rest !== null) {\n rest.line(text);\n } else if (parser.line(text, reader.line)) {\n rest = new NetworkCounter();\n rest.line(text);\n restLine = reader.line;\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(resolved.signal);\n }\n }\n parser.finish();\n if (rest !== null) {\n report.warning(\n \"unsupported\",\n PAJEK_ISSUE.MULTIPLE_GRAPHS,\n `the project file holds ${rest.count} more network(s) after the first; import() reads the first, importAll() reads every one`,\n { line: restLine },\n );\n }\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every network of a Pajek project file (`.paj`), each into its own sink. A network starts\n * at `*Network` or at a `*Vertices` that does not belong to a `*Partition` / `*Vector` section\n * (the `*Vertices N` line right after an object's header).\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the network with this index, called before its first push\n * @param options - common and Pajek options\n * @returns one report per network\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: PajekImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, DEFAULTS);\n const firstVertex = firstVertexOption(options?.firstVertex);\n const reports = [new ImportReportBuilder(\"pajek\", resolved.errorLimit)];\n reportUnusedOptions(options, reports[0], USED_OPTIONS);\n const open = (): PajekParser => {\n const report = reports[reports.length - 1];\n const sink = sinkFor(reports.length - 1);\n reportSinkOptions(sink, options, report);\n return new PajekParser(sink, report, resolved, firstVertex);\n };\n let parser = open();\n // decoding issues belong to the file, so they go to the first network's report\n const reader = new LineReader(input, reports[0], resolved);\n let sinceCheck = 0;\n for await (const text of reader) {\n if (parser.line(text, reader.line)) {\n parser.finish();\n reports.push(new ImportReportBuilder(\"pajek\", resolved.errorLimit));\n parser = open();\n parser.line(text, reader.line);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(resolved.signal);\n }\n }\n parser.finish();\n throwIfAborted(resolved.signal);\n return reports.map((r) => r.finish());\n },\n});\n\n/**\n * Counts the networks of the rest of a project file by their headers alone, with the parser's\n * rule: a network starts at `*Network` after a named or populated one, or at a `*Vertices` after a\n * populated one unless it is the line right after a project object's header (`*Partition`,\n * `*Vector`, a skipped section).\n */\nclass NetworkCounter {\n /** Networks started so far (the first header fed opens the first). */\n count = 0;\n\n private named = false;\n\n private populated = false;\n\n private afterObjectHeader = false;\n\n /**\n * Feed one line.\n * @param text - the line\n */\n line(text: string): void {\n if (isCommentOrBlank(text)) {\n return;\n }\n const { afterObjectHeader } = this;\n this.afterObjectHeader = false;\n if (!isSectionLine(text)) {\n return;\n }\n const h = parseSectionHeader(text);\n if (h === null) {\n return;\n }\n const { kind } = h;\n if (kind === \"partition\" || kind === \"vector\" || kind === \"unsupported\") {\n this.afterObjectHeader = true;\n } else if (kind === \"network\") {\n if (this.count === 0 || this.named || this.populated) {\n this.count++;\n this.populated = false;\n }\n this.named = true;\n } else if (kind === \"vertices\" && !afterObjectHeader) {\n if (this.count === 0 || this.populated) {\n this.count++;\n this.named = false;\n }\n this.populated = true;\n }\n }\n}\n\n"],"names":["n"],"mappings":"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"}