@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
package/dist/gml.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"gml.js","sources":["../src/formats/gml/syntax.ts","../src/formats/gml/exporter.ts","../src/formats/gml/importer.ts","../src/formats/gml/index.ts"],"sourcesContent":["/**\n * The GML lexical layer shared by the importer and the exporter (research note 07 section 2.2,\n * NetworkX readwrite/gml.py as the reference reader): the token list a whole GML text lexes into,\n * the structural validation that guarantees every later walk sees balanced `key value` pairs, the\n * value grammar (int, real, quoted string with `&#NN;` character references, `[ ... ]` record),\n * the NetworkX list conventions (`_networkx_list_start`, `\"[]\"`) and the key charset.\n *\n * Tokens are kept in typed arrays (kind, start, end, line, matching bracket) rather than objects:\n * the token list is the one intermediate structure of the GML importer, and it costs 17 bytes per\n * token instead of an object per node.\n */\n\nimport { SYNTAX_CODE } from \"../../common/codes.js\";\nimport { decodeGmlString } from \"../../common/escape.js\";\n\n/** A bare word: a key, or `INF` / `NAN` at a value position. */\nexport const TOKEN_WORD = 0;\n/** An integer literal. */\nexport const TOKEN_INT = 1;\n/** A real literal, including the non-finite spellings. */\nexport const TOKEN_REAL = 2;\n/** A double-quoted string; start / end delimit the body between the quotes. */\nexport const TOKEN_STRING = 3;\n/** `[`. */\nexport const TOKEN_OPEN = 4;\n/** `]`. */\nexport const TOKEN_CLOSE = 5;\n\n/** The kind of one token. */\ntype TokenKind = 0 | 1 | 2 | 3 | 4 | 5;\n\n/** The NetworkX marker that starts a one-element list written as repeated keys. */\nexport const LIST_START_MARKER = \"_networkx_list_start\";\n\n/** The string NetworkX writes for an empty list. */\nexport const EMPTY_LIST_TEXT = \"[]\";\n\n/** The string NetworkX writes for an empty tuple, read as an empty list too. */\nexport const EMPTY_TUPLE_TEXT = \"()\";\n\n/** The node key the exporter writes a mangled node's original id into (design section 8.5). */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/**\n * Issue code of every grammar violation (shared with the other text formats; the message carries\n * the detail): a bare token that is neither a key nor a number, an unclosed string, an unclosed\n * `[`, a `]` with no open `[`, a value without a key or a key without a value.\n */\nexport const SYNTAX_STRUCTURE_CODE = SYNTAX_CODE;\n/** The code of an untokenisable bare token (E_SYNTAX). */\nexport const SYNTAX_TOKEN_CODE = SYNTAX_CODE;\n/** The code of an unclosed string (E_SYNTAX). */\nexport const SYNTAX_STRING_CODE = SYNTAX_CODE;\n/** The code of an unclosed `[` (E_SYNTAX). */\nexport const SYNTAX_BRACKET_CODE = SYNTAX_CODE;\n\nconst KEY_TEXT = /^[A-Za-z_][0-9A-Za-z_]*$/;\nconst STRICT_KEY_TEXT = /^[A-Za-z][0-9A-Za-z_]*$/;\nconst INT_TEXT = /^[+-]?[0-9]+$/;\nconst REAL_TEXT = /^[+-]?(?:(?:[0-9]+\\.[0-9]*|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)$/;\nconst NON_FINITE_TEXT = /^[+-]?(?:inf|infinity|nan)$/i;\nconst NON_FINITE_WORD = /^(?:inf|infinity|nan)$/i;\n\n/**\n * A lexical or structural error of a GML text, with the 1-based line it was found on. The importer\n * turns it into a fatal parse-error issue.\n */\nexport class GmlSyntaxError extends Error {\n /** The issue code. */\n readonly code: string;\n\n /** The 1-based line. */\n readonly line: number;\n\n /**\n * Create a syntax error.\n * @param code - the issue code\n * @param message - a plain-ASCII message\n * @param line - the 1-based line\n */\n constructor(code: string, message: string, line: number) {\n super(message);\n this.name = \"GmlSyntaxError\";\n this.code = code;\n this.line = line;\n }\n}\n\n/**\n * The tokens of one GML text, structurally validated: every `[` has its matching `]` recorded and\n * every key is followed by a value, so walkers need no error paths.\n */\nexport class GmlTokens {\n /** The source text the offsets index into. */\n readonly text: string;\n\n /** The kind of every token. */\n kind: Uint8Array;\n\n /** The start offset of every token (a string's body start). */\n start: Uint32Array;\n\n /** The end offset (exclusive) of every token (a string's body end). */\n end: Uint32Array;\n\n /** The 1-based line of every token. */\n line: Uint32Array;\n\n /** For an open bracket, the index of its matching close bracket; 0 elsewhere. */\n match: Uint32Array;\n\n /** The number of tokens. */\n count = 0;\n\n /** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */\n onUnknownEntity: ((entity: string, line: number) => void) | null = null;\n\n /**\n * Create an empty token list over a text.\n * @param text - the source text\n * @param capacity - the initial capacity\n */\n constructor(text: string, capacity = 1024) {\n this.text = text;\n this.kind = new Uint8Array(capacity);\n this.start = new Uint32Array(capacity);\n this.end = new Uint32Array(capacity);\n this.line = new Uint32Array(capacity);\n this.match = new Uint32Array(0);\n }\n\n /**\n * Append a token.\n * @param kind - the kind\n * @param start - the start offset\n * @param end - the end offset\n * @param line - the 1-based line\n */\n push(kind: TokenKind, start: number, end: number, line: number): void {\n if (this.count === this.kind.length) {\n this.grow();\n }\n const i = this.count++;\n this.kind[i] = kind;\n this.start[i] = start;\n this.end[i] = end;\n this.line[i] = line;\n }\n\n /**\n * The raw text of a token (a string's body without the quotes, entities undecoded).\n * @param i - the token index\n * @returns the text\n */\n textOf(i: number): string {\n return this.text.slice(this.start[i], this.end[i]);\n }\n\n /**\n * The decoded value of a string token.\n * @param i - the token index\n * @returns the body with character references decoded\n */\n stringOf(i: number): string {\n const text = this.textOf(i);\n if (text.indexOf(\"&\") < 0) {\n return text;\n }\n const report = this.onUnknownEntity;\n return decodeGmlString(text, report === null ? undefined : (entity) => { report(entity, this.line[i]); });\n }\n\n /**\n * Whether a token is a `[` or `]`.\n * @param i - the token index\n * @returns true for a bracket\n */\n isBracket(i: number): boolean {\n return this.kind[i] >= TOKEN_OPEN;\n }\n\n /**\n * The index of the pair following the pair whose key is at `key`.\n * @param key - the index of a key token\n * @returns the index after the pair's value (after the matching `]` for a record)\n */\n nextPair(key: number): number {\n const value = key + 1;\n return this.kind[value] === TOKEN_OPEN ? this.match[value] + 1 : value + 1;\n }\n\n /** Double every array. */\n private grow(): void {\n const capacity = this.kind.length * 2;\n const kind = new Uint8Array(capacity);\n kind.set(this.kind);\n this.kind = kind;\n const start = new Uint32Array(capacity);\n start.set(this.start);\n this.start = start;\n const end = new Uint32Array(capacity);\n end.set(this.end);\n this.end = end;\n const line = new Uint32Array(capacity);\n line.set(this.line);\n this.line = line;\n }\n}\n\n/**\n * Lex and structurally validate a whole GML text.\n *\n * Lexical rules (NetworkX): whitespace separates tokens; `#` outside a string starts a comment\n * that runs to the end of the line; a string is delimited by double quotes and must close on its\n * line (there is no escape mechanism; `&#NN;` references are decoded later); `[` and `]` are\n * single-character tokens; every other run of characters is a key (`[A-Za-z_][0-9A-Za-z_]*`),\n * an integer (`[+-]?[0-9]+`), a real (with a decimal point or an exponent, or `INF` / `NAN` in\n * any case with an optional sign) or an error.\n *\n * Structural rules: the text is a sequence of `key value` pairs where a value is a number, a\n * string, `INF` / `NAN`, or a bracketed sequence of pairs; every `[` has a `]`.\n * @param text - the GML text\n * @returns the validated tokens; GmlSyntaxError with the line of the first problem\n */\nexport function tokenizeGml(text: string): GmlTokens {\n const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));\n const n = text.length;\n let i = 0;\n let line = 1;\n while (i < n) {\n const c = text.charCodeAt(i);\n if (c === 10) {\n line++;\n i++;\n } else if (c === 13) {\n line++;\n i++;\n if (i < n && text.charCodeAt(i) === 10) {\n i++;\n }\n } else if (c === 32 || c === 9 || c === 11 || c === 12) {\n i++;\n } else if (c === 35) {\n i = endOfLine(text, i);\n } else if (c === 91) {\n tokens.push(TOKEN_OPEN, i, i + 1, line);\n i++;\n } else if (c === 93) {\n tokens.push(TOKEN_CLOSE, i, i + 1, line);\n i++;\n } else if (c === 34) {\n const close = text.indexOf('\"', i + 1);\n const eol = endOfLine(text, i + 1);\n if (close < 0 || close > eol) {\n throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string at line ${line}`, line);\n }\n tokens.push(TOKEN_STRING, i + 1, close, line);\n i = close + 1;\n } else {\n let j = i + 1;\n while (j < n && !isDelimiter(text.charCodeAt(j))) {\n j++;\n }\n tokens.push(classifyBare(text, i, j, line), i, j, line);\n i = j;\n }\n }\n validateStructure(tokens);\n return tokens;\n}\n\n/**\n * The offset of the line terminator at or after `from`, or the text length.\n * @param text - the text\n * @param from - the offset to search from\n * @returns the offset of the next `\\n` or `\\r`\n */\nfunction endOfLine(text: string, from: number): number {\n const n = text.length;\n for (let i = from; i < n; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || c === 13) {\n return i;\n }\n }\n return n;\n}\n\n/**\n * Whether a character ends a bare token.\n * @param c - the char code\n * @returns true for whitespace, brackets, a quote or `#`\n */\nfunction isDelimiter(c: number): boolean {\n return (\n c === 32 ||\n c === 9 ||\n c === 10 ||\n c === 13 ||\n c === 11 ||\n c === 12 ||\n c === 91 ||\n c === 93 ||\n c === 34 ||\n c === 35\n );\n}\n\n/**\n * Classify a bare token.\n * @param text - the text\n * @param start - the token start\n * @param end - the token end\n * @param line - the token line, for the error\n * @returns WORD, INT or REAL; GmlSyntaxError for anything else\n */\nfunction classifyBare(text: string, start: number, end: number, line: number): TokenKind {\n const token = text.slice(start, end);\n if (KEY_TEXT.test(token)) {\n return TOKEN_WORD;\n }\n if (INT_TEXT.test(token)) {\n return TOKEN_INT;\n }\n if (REAL_TEXT.test(token) || NON_FINITE_TEXT.test(token)) {\n return TOKEN_REAL;\n }\n const shown = token.length > 20 ? `${token.slice(0, 20)}...` : token;\n throw new GmlSyntaxError(SYNTAX_TOKEN_CODE, `cannot tokenize \"${shown}\" at line ${line}`, line);\n}\n\n/**\n * Check the `key value` structure and record the matching bracket of every `[`.\n * @param tokens - the lexed tokens\n */\nfunction validateStructure(tokens: GmlTokens): void {\n const { count, kind } = tokens;\n const match = new Uint32Array(count);\n const stack: number[] = [];\n let i = 0;\n while (i < count) {\n const k = kind[i];\n if (k === TOKEN_CLOSE) {\n const open = stack.pop();\n if (open === undefined) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `unexpected \"]\" at line ${tokens.line[i]}: no open \"[\"`,\n tokens.line[i],\n );\n }\n match[open] = i;\n i++;\n continue;\n }\n if (k !== TOKEN_WORD) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a key at line ${tokens.line[i]}, found ${describeToken(tokens, i)}`,\n tokens.line[i],\n );\n }\n const value = i + 1;\n if (value >= count) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `key \"${tokens.textOf(i)}\" at line ${tokens.line[i]} has no value`,\n tokens.line[i],\n );\n }\n const vk = kind[value];\n if (vk === TOKEN_OPEN) {\n stack.push(value);\n } else if (vk === TOKEN_CLOSE || (vk === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value)))) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a value for key \"${tokens.textOf(i)}\" at line ${tokens.line[i]}, found ${describeToken(tokens, value)}`,\n tokens.line[value],\n );\n }\n i = value + 1;\n }\n if (stack.length > 0) {\n const open = stack[stack.length - 1];\n throw new GmlSyntaxError(\n SYNTAX_BRACKET_CODE,\n `unexpected end of input: ${stack.length} bracket(s) still open, the last opened at line ${tokens.line[open]}`,\n tokens.line[open],\n );\n }\n tokens.match = match;\n}\n\n/**\n * A short description of a token for messages.\n * @param tokens - the tokens\n * @param i - the token index\n * @returns the quoted text or the bracket\n */\nfunction describeToken(tokens: GmlTokens, i: number): string {\n switch (tokens.kind[i]) {\n case TOKEN_OPEN:\n return '\"[\"';\n case TOKEN_CLOSE:\n return '\"]\"';\n case TOKEN_STRING:\n return `the string \"${tokens.textOf(i)}\"`;\n default:\n return `\"${tokens.textOf(i)}\"`;\n }\n}\n\n/**\n * The numeric value of an INT or REAL token (or a WORD that is `INF` / `NAN` at a value position).\n * @param text - the token text\n * @returns the number; Infinity / -Infinity / NaN for the non-finite spellings\n */\nexport function numberOfText(text: string): number {\n if (NON_FINITE_TEXT.test(text)) {\n const lower = text.toLowerCase();\n if (lower.endsWith(\"nan\")) {\n return NaN;\n }\n return lower.startsWith(\"-\") ? -Infinity : Infinity;\n }\n return Number(text);\n}\n\n/**\n * Whether a value token is one of the non-finite bare words (`INF`, `NAN`), which lex as words.\n * @param tokens - the tokens\n * @param i - the value token index\n * @returns true when the word is a real\n */\nexport function isNonFiniteWord(tokens: GmlTokens, i: number): boolean {\n return tokens.kind[i] === TOKEN_WORD && NON_FINITE_WORD.test(tokens.textOf(i));\n}\n\n/**\n * Whether a text is a GML key the strict grammar accepts (`[A-Za-z][0-9A-Za-z_]*`, what NetworkX\n * writes and reads).\n * @param text - the candidate key\n * @returns true when it can be written as a key\n */\nexport function isGmlKey(text: string): boolean {\n return STRICT_KEY_TEXT.test(text);\n}\n\n/**\n * Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading\n * non-letter is prefixed with `x` (the exporter's `sanitizeKeys: \"mangle\"`).\n * @param text - the text\n * @returns a valid key\n */\nexport function mangleGmlKey(text: string): string {\n const body = text.replace(/[^0-9A-Za-z_]/g, \"_\");\n return /^[A-Za-z]/.test(body) ? body : `x${body}`;\n}\n\n/** One open record while parseRecord() walks the tokens without recursion. */\ninterface RecordFrame {\n readonly record: Record<string, unknown>;\n listKeys: Set<string> | null;\n /** The index of the record's `]`. */\n readonly close: number;\n /** The next key token to read. */\n next: number;\n /** The key the record is stored under in its parent, or null for the root. */\n readonly key: string | null;\n}\n\n/**\n * Parse a bracketed record into a JSON object (design section 8.5: nested GML records map to\n * `json`). Values follow the value grammar; repeated keys become arrays with the NetworkX\n * conventions: the `_networkx_list_start` marker starts a list so a one-element list survives,\n * `\"[]\"` and `\"()\"` are empty lists, and a key seen twice without the marker becomes a\n * two-element array. Nested records are walked with an explicit stack, so the nesting depth is\n * bounded by memory, not by the call stack.\n * @param tokens - the validated tokens\n * @param open - the index of the record's `[`\n * @returns a null-prototype object\n */\nexport function parseRecord(tokens: GmlTokens, open: number): Record<string, unknown> {\n const root = Object.create(null) as Record<string, unknown>;\n const stack: RecordFrame[] = [\n { record: root, listKeys: null, close: tokens.match[open], next: open + 1, key: null },\n ];\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame.next >= frame.close) {\n stack.pop();\n if (frame.key !== null) {\n storeValue(stack[stack.length - 1], frame.key, frame.record);\n }\n continue;\n }\n const p = frame.next;\n frame.next = tokens.nextPair(p);\n const key = tokens.textOf(p);\n const v = p + 1;\n if (tokens.kind[v] === TOKEN_STRING) {\n const text = tokens.stringOf(v);\n if (text === LIST_START_MARKER) {\n frame.record[key] = [];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n continue;\n }\n storeValue(frame, key, text === EMPTY_LIST_TEXT || text === EMPTY_TUPLE_TEXT ? [] : text);\n } else if (tokens.kind[v] === TOKEN_OPEN) {\n stack.push({\n record: Object.create(null) as Record<string, unknown>,\n listKeys: null,\n close: tokens.match[v],\n next: v + 1,\n key,\n });\n } else {\n storeValue(frame, key, numberOfText(tokens.textOf(v)));\n }\n }\n return root;\n}\n\n/**\n * Store one value under a key: appended to the key's list when the key is a list, paired with the\n * earlier value when the key repeats, set otherwise.\n * @param frame - the open record\n * @param key - the key\n * @param value - the value\n */\nfunction storeValue(frame: RecordFrame, key: string, value: unknown): void {\n const { record } = frame;\n if (frame.listKeys !== null && frame.listKeys.has(key)) {\n (record[key] as unknown[]).push(value);\n } else if (key in record) {\n record[key] = [record[key], value];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n } else {\n record[key] = value;\n }\n}\n\n/**\n * The JSON value of a non-string value token: a number, or a record.\n * @param tokens - the tokens\n * @param v - the value token index (INT, REAL, non-finite WORD or OPEN)\n * @returns the value\n */\nexport function scalarOrRecord(tokens: GmlTokens, v: number): unknown {\n return tokens.kind[v] === TOKEN_OPEN ? parseRecord(tokens, v) : numberOfText(tokens.textOf(v));\n}\n","/**\n * The GML exporter (design section 8.5, research note 07 sections 2.2 and 9): writes a snapshot in\n * the NetworkX dialect of GML. Node ids must be integers (`idCharset: \"integer\"`; `sanitizeIds:\n * \"mangle\"` renumbers the others and keeps the original in a `graphty_originalId` key the importer\n * restores); columns are written per dtype (`int` for the integer dtypes, `real` with a decimal\n * point guaranteed for f32 / f64 so the dtype survives a re-import, quoted strings with `&#NN;`\n * references, repeated keys for lists with the `_networkx_list_start` marker for one-element\n * lists and `\"[]\"` for empty ones, nested records for json objects); the position role becomes\n * `graphics [ x y z ]` merged with the node's `graphics` json record; graph columns are written\n * inside `graph [ ]` (or at the top level when the importer found them there); `Creator` and\n * `Version` come from the metadata.\n *\n * check() reports, before anything is written, the capability gaps of the common check plus the\n * GML-specific ones: json columns holding numbers (JSON cannot keep the int / real distinction:\n * `W_GML_RECORD_NUMBER_TYPE`), booleans (written 1 / 0) or nulls (omitted), arrays nested in\n * arrays (no GML spelling; export() throws), column names and record keys that are not GML keys\n * or collide with the structural keys (`E_GML_INVALID_KEY` / `E_GML_RESERVED_KEY`, or\n * `W_GML_KEY_MANGLED` under `sanitizeKeys: \"mangle\"`), and graphics / position overlaps.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n GraphFormatError,\n type GraphSnapshot,\n type JsonColumn,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { DICT_SAMPLE_ROWS, DictHeuristic } from \"../../common/attributes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteGmlString } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n countMixedEdges,\n LOSS,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatGmlReal, formatInteger } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { type ExplicitWeights, 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 { EMPTY_LIST_TEXT, isGmlKey, LIST_START_MARKER, mangleGmlKey, ORIGINAL_ID_KEY } from \"./syntax.js\";\n\n/** The format-specific options of the GML exporter. */\nexport interface GmlExportOptions {\n /**\n * The edge key explicit weights are written under; by default the key the GML importer read\n * them from (`meta.weightOrigin.id` when the snapshot came from GML), else `value`.\n */\n weightKey?: string | undefined;\n /**\n * \"error\" (default): a column name or record key that is not a GML key (`[A-Za-z][0-9A-Za-z_]*`)\n * or collides with a structural key makes export() throw; \"mangle\": such keys are rewritten\n * (`.` and other characters become `_`, collisions get a `_2` suffix) and check() reports them.\n */\n sanitizeKeys?: \"error\" | \"mangle\" | undefined;\n}\n\n/** Loss code: a json column holds numbers; JSON cannot keep GML's int / real distinction (design section 8.5). */\nexport const RECORD_NUMBER_TYPE_CODE = \"W_GML_RECORD_NUMBER_TYPE\";\n/** Loss code: a json column holds booleans, written as 1 / 0. */\nexport const RECORD_BOOLEAN_CODE = \"W_GML_RECORD_BOOLEAN\";\n/** Loss code: a json column holds nulls, which GML cannot write; the key (or the row) is omitted. */\nexport const RECORD_NULL_CODE = \"W_GML_RECORD_NULL\";\n/** Loss code: a json column holds an array inside an array, which GML cannot write; export() throws. */\nexport const NESTED_ARRAY_CODE = \"E_GML_NESTED_ARRAY\";\n/** Loss code: a json column holds arrays as row values; written as repeated keys, they re-import as a list column. */\nexport const JSON_ARRAY_CODE = \"W_GML_JSON_ARRAY\";\n/** Loss code: a column name or record key is not a GML key; export() throws unless sanitizeKeys is \"mangle\". */\nexport const INVALID_KEY_CODE = \"E_GML_INVALID_KEY\";\n/** Loss code: a column name collides with a structural GML key; export() throws unless sanitizeKeys is \"mangle\". */\nexport const RESERVED_KEY_CODE = \"E_GML_RESERVED_KEY\";\n/** Loss code: keys rewritten under sanitizeKeys \"mangle\". */\nexport const KEY_MANGLED_CODE = \"W_GML_KEY_MANGLED\";\n/** Loss code: a position column with more than three components; x, y and z are written. */\nexport const POSITION_COMPONENTS_CODE = \"W_GML_POSITION_COMPONENTS\";\n/** Loss code: a node's graphics record has x / y / z keys the position column replaces. */\nexport const GRAPHICS_OVERRIDDEN_CODE = \"W_GML_GRAPHICS_OVERRIDDEN\";\n/** Loss code: a node's graphics value is not a record and cannot hold the position; export() throws. */\nexport const GRAPHICS_CONFLICT_CODE = \"E_GML_GRAPHICS_CONFLICT\";\n\n/** The default weight key (design section 8.4: GML weights are read from `value` by default). */\nexport const DEFAULT_WEIGHT_KEY = \"value\";\n\n/** The roles GML has a key for (`label`, the edge `id` and `key`); every other role is reported. */\nconst KEPT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"key\"]);\n\n/** The key the importer maps each kept role back from (the column name after re-import). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"label\",\n id: \"id\",\n key: \"key\",\n});\n\nconst GML_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"integer\",\n dtypes: [\"i32\", \"f64\", \"string\", \"dict\", \"json\"],\n components: false,\n lists: true,\n json: true,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** Roles whose columns are never written as attributes (structural, or dropped per the capabilities). */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\nconst NODE_RESERVED: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_RESERVED: ReadonlySet<string> = new Set([\"source\", \"target\", \"directed\"]);\nconst GRAPH_RESERVED: ReadonlySet<string> = new Set([\"node\", \"edge\", \"directed\", \"multigraph\"]);\nconst TOP_RESERVED: ReadonlySet<string> = new Set([\"graph\"]);\nconst NUMBER_TEXT = /^[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;\n\n/** The resolved options of one export. */\ninterface GmlExportPlan {\n readonly common: ResolvedExportOptions;\n readonly weightKey: string;\n readonly mangle: boolean;\n}\n\n/** What one json column holds that GML cannot write exactly. */\ninterface JsonStats {\n numbers: number;\n booleans: number;\n nulls: number;\n nestedArrays: number;\n arrays: number;\n invalidKeys: number;\n}\n\n/** The kinds of value already counted for one row while inspecting a json value. */\ninterface SeenFlags {\n numbers: boolean;\n booleans: boolean;\n nulls: boolean;\n nested: boolean;\n}\n\n/** The columns of one table selected for writing, with their keys. */\ninterface WrittenColumn {\n readonly column: Column;\n readonly key: string;\n}\n\n/**\n * Resolve the options of one export call.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planOf(snapshot: GraphSnapshot, options: (GmlExportOptions & CommonExportOptions) | undefined): GmlExportPlan {\n const common = resolveExportOptions(options);\n const mode = options?.sanitizeKeys ?? \"error\";\n if (mode !== \"error\" && mode !== \"mangle\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option sanitizeKeys: ${JSON.stringify(mode)} is not \"error\" or \"mangle\"`,\n {\n option: \"sanitizeKeys\",\n found: mode,\n },\n );\n }\n let weightKey = options?.weightKey;\n if (weightKey === undefined) {\n const origin = snapshot.meta.weightOrigin;\n weightKey = origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : DEFAULT_WEIGHT_KEY;\n } else if (typeof weightKey !== \"string\" || !isGmlKey(weightKey)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option weightKey: ${JSON.stringify(weightKey)} is not a GML key`, {\n option: \"weightKey\",\n found: weightKey,\n });\n }\n return { common, weightKey, mangle: mode === \"mangle\" };\n}\n\n/**\n * Whether a column is written as an attribute (its role is neither structural nor dropped).\n * @param column - the column\n * @returns true when written\n */\nfunction isWritten(column: Column): boolean {\n const { role } = column.meta;\n return role === null || !SKIPPED_ROLES.has(role);\n}\n\n/**\n * The key a column is written under.\n * @param meta - the column metadata\n * @returns origin.id when the column came from GML (the key it was read from), else the name\n */\nfunction preferredKey(meta: ColumnMeta): string {\n const { origin } = meta;\n return origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : meta.name;\n}\n\n/**\n * Whether a snapshot has explicit weights to write.\n * @param snapshot - the snapshot\n * @returns true when weighted\n */\nfunction hasWeights(snapshot: GraphSnapshot): boolean {\n return snapshot.flags.weighted;\n}\n\n/**\n * Whether the graph column is a top-level key (the importer's `extra.gmlTopLevel`).\n * @param column - the column\n * @returns true for a top-level key\n */\nfunction isTopLevel(column: Column): boolean {\n return column.meta.extra.gmlTopLevel === true;\n}\n\n/**\n * The text of a `Version` value: bare when it is a number text, quoted otherwise.\n * @param text - the version text\n * @returns the GML value\n */\nfunction versionText(text: string): string {\n return NUMBER_TEXT.test(text) ? text : quoteGmlString(text);\n}\n\n/**\n * Select the written columns of a table and assign their keys, recording invalid and reserved\n * keys as notes (or rewriting them under mangle).\n * @param table - the columns\n * @param reserved - the structural keys of the table\n * @param label - the table name for messages\n * @param plan - the export plan\n * @param notes - where to record\n * @param filter - an extra selection predicate\n * @returns the written columns with their keys\n */\nfunction selectColumns(\n table: Iterable<Column>,\n reserved: ReadonlySet<string>,\n label: string,\n plan: GmlExportPlan,\n notes: LossNote[] | null,\n filter: (column: Column) => boolean = (): boolean => true,\n): WrittenColumn[] {\n const used = new Set<string>(reserved);\n const out: WrittenColumn[] = [];\n for (const column of table) {\n if (!isWritten(column) || !filter(column)) {\n continue;\n }\n const preferred = preferredKey(column.meta);\n let key = preferred;\n const valid = isGmlKey(preferred);\n const taken = used.has(preferred);\n if (!valid || taken) {\n const code = valid ? RESERVED_KEY_CODE : INVALID_KEY_CODE;\n let why = \"is not a GML key\";\n if (valid) {\n why = reserved.has(preferred) ? \"collides with a structural GML key\" : \"repeats another column's key\";\n }\n if (!plan.mangle) {\n if (notes === null) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `${label} column \"${column.meta.name}\" ${why}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column: column.meta.name,\n key: preferred,\n },\n );\n }\n notes.push(\n note(\n code,\n `${label} column \"${column.meta.name}\" ${why}; export() will throw unless sanitizeKeys is \"mangle\"`,\n column.meta.name,\n ),\n );\n continue;\n }\n key = uniqueKey(valid ? preferred : mangleGmlKey(preferred), used);\n notes?.push(\n note(\n KEY_MANGLED_CODE,\n `${label} column \"${column.meta.name}\" is written as \"${key}\"`,\n column.meta.name,\n ),\n );\n }\n used.add(key);\n out.push({ column, key });\n }\n return out;\n}\n\n/**\n * A key not yet used: the base, else base_2, base_3...\n * @param base - a valid key\n * @param used - the keys taken\n * @returns a free key\n */\nfunction uniqueKey(base: string, used: ReadonlySet<string>): string {\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n return candidate;\n}\n\n/**\n * Build a frozen note.\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 * Inspect a JSON value for what GML cannot write exactly.\n * @param value - the value\n * @param stats - the counters to update (each counted at most once per call for numbers / booleans / nulls)\n * @param inArray - whether the value is an array item\n * @param seen - the flags already counted for this row\n */\nfunction inspectJson(value: unknown, stats: JsonStats, inArray: boolean, seen: SeenFlags): void {\n if (value === null) {\n if (!seen.nulls) {\n seen.nulls = true;\n stats.nulls++;\n }\n return;\n }\n switch (typeof value) {\n case \"number\":\n if (!seen.numbers) {\n seen.numbers = true;\n stats.numbers++;\n }\n return;\n case \"boolean\":\n if (!seen.booleans) {\n seen.booleans = true;\n stats.booleans++;\n }\n return;\n case \"string\":\n return;\n default:\n break;\n }\n if (Array.isArray(value)) {\n if (inArray && !seen.nested) {\n seen.nested = true;\n stats.nestedArrays++;\n }\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n return;\n }\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!isGmlKey(key)) {\n stats.invalidKeys++;\n }\n inspectJson(record[key], stats, false, seen);\n }\n}\n\n/**\n * The GML-specific notes of one table's json columns.\n * @param columns - the written columns\n * @param label - the table name\n * @param plan - the export plan\n * @param notes - where to record\n */\nfunction jsonNotes(columns: readonly WrittenColumn[], label: string, plan: GmlExportPlan, notes: LossNote[]): void {\n for (const { column } of columns) {\n const stats = jsonStatsOf(column);\n if (stats === null) {\n continue;\n }\n const { name } = column.meta;\n const where = `${label} column \"${name}\"`;\n if (stats.numbers > 0) {\n notes.push(\n note(\n RECORD_NUMBER_TYPE_CODE,\n `${where} holds numbers in ${stats.numbers} row(s); GML records cannot keep the int / real distinction`,\n name,\n stats.numbers,\n ),\n );\n }\n if (stats.booleans > 0) {\n notes.push(\n note(\n RECORD_BOOLEAN_CODE,\n `${where} holds booleans in ${stats.booleans} row(s); written as 1 / 0`,\n name,\n stats.booleans,\n ),\n );\n }\n if (stats.nulls > 0) {\n notes.push(\n note(\n RECORD_NULL_CODE,\n `${where} holds nulls in ${stats.nulls} row(s); GML has no null, the key is omitted`,\n name,\n stats.nulls,\n ),\n );\n }\n if (stats.arrays > 0) {\n notes.push(\n note(\n JSON_ARRAY_CODE,\n `${where} holds arrays as values in ${stats.arrays} row(s); written as repeated keys, they re-import as a list`,\n name,\n stats.arrays,\n ),\n );\n }\n if (stats.nestedArrays > 0) {\n notes.push(\n note(\n NESTED_ARRAY_CODE,\n `${where} holds arrays nested in arrays in ${stats.nestedArrays} row(s); GML cannot write them and export() will throw`,\n name,\n stats.nestedArrays,\n ),\n );\n }\n if (stats.invalidKeys > 0) {\n notes.push(\n plan.mangle\n ? note(\n KEY_MANGLED_CODE,\n `${where}: ${stats.invalidKeys} record key(s) are not GML keys and are rewritten`,\n name,\n stats.invalidKeys,\n )\n : note(\n INVALID_KEY_CODE,\n `${where}: ${stats.invalidKeys} record key(s) are not GML keys; export() will throw unless sanitizeKeys is \"mangle\"`,\n name,\n stats.invalidKeys,\n ),\n );\n }\n }\n}\n\n/**\n * The json statistics of a json column, or of a list column with json items; null for other dtypes.\n * @param column - the column\n * @returns the stats, or null\n */\nfunction jsonStatsOf(column: Column): JsonStats | null {\n const stats: JsonStats = { numbers: 0, booleans: 0, nulls: 0, nestedArrays: 0, arrays: 0, invalidKeys: 0 };\n if (column.dtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const value = column.values[r];\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n if (Array.isArray(value)) {\n stats.arrays++;\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n } else {\n inspectJson(value, stats, false, seen);\n }\n }\n return stats;\n }\n if (column.dtype === \"list\" && column.meta.itemDtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n for (const item of column.sliceOf(r)) {\n inspectJson(item, stats, true, seen);\n }\n }\n return stats;\n }\n return null;\n}\n\n/**\n * The node position column when it can be mapped to graphics x / y / z: a numeric scalar column\n * with the position role.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction positionColumn(snapshot: GraphSnapshot): Column | null {\n const column = snapshot.nodes.byRole(\"position\");\n if (column === null) {\n return null;\n }\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return column;\n default:\n return null;\n }\n}\n\n/**\n * The node `graphics` json column, when present.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction graphicsColumn(snapshot: GraphSnapshot): JsonColumn | null {\n return snapshot.nodes.typed(\"graphics\", \"json\");\n}\n\n/**\n * The GML-specific notes about the position / graphics mapping.\n * @param snapshot - the snapshot\n * @param notes - where to record\n */\nfunction graphicsNotes(snapshot: GraphSnapshot, notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n if (position.meta.components > 3) {\n notes.push(\n note(\n POSITION_COMPONENTS_CODE,\n `node column \"${position.meta.name}\" has ${position.meta.components} components; only x, y and z are written`,\n position.meta.name,\n position.length - position.nullCount,\n ),\n );\n }\n const graphics = graphicsColumn(snapshot);\n if (graphics === null) {\n return;\n }\n let overridden = 0;\n let conflicts = 0;\n for (let r = 0; r < snapshot.nodeCount; r++) {\n if (!position.isSet(r) || !graphics.isSet(r)) {\n continue;\n }\n const value = graphics.values[r];\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n conflicts++;\n } else if (\"x\" in value || \"y\" in value || \"z\" in value) {\n overridden++;\n }\n }\n if (overridden > 0) {\n notes.push(\n note(\n GRAPHICS_OVERRIDDEN_CODE,\n `${overridden} node graphics record(s) have x / y / z keys the position column replaces`,\n \"graphics\",\n overridden,\n ),\n );\n }\n if (conflicts > 0) {\n notes.push(\n note(\n GRAPHICS_CONFLICT_CODE,\n `${conflicts} node graphics value(s) are not records and cannot hold the position; export() will throw`,\n \"graphics\",\n conflicts,\n ),\n );\n }\n}\n\n/**\n * What the importer's own rules change on re-import of the written columns: an all-unset column\n * vanishes (GML writes cells, never declarations), a role-less column named like a role key\n * gains the role, and the dictionary heuristic of design section 5.4 turns a low-cardinality\n * string column into a dict (or a wide dict into a string).\n * @param columns - the written columns\n * @param domain - node or edge\n * @param notes - where to record\n */\nfunction reimportNotes(columns: readonly WrittenColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, key } of columns) {\n const { meta } = column;\n const set = column.length - column.nullCount;\n if (set === 0) {\n notes.push(\n note(\n LOSS.EMPTY_COLUMN,\n `${domain} column \"${meta.name}\" has no set cell and is not written: GML writes cells, never declarations`,\n meta.name,\n 0,\n ),\n );\n continue;\n }\n if (meta.role === null && (key === \"label\" || (domain === \"edge\" && (key === \"id\" || key === \"key\")))) {\n notes.push(\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${meta.name}\" is written under \"${key}\" and reads back with the ${key === \"label\" ? \"label\" : key} role`,\n meta.name,\n set,\n ),\n );\n continue;\n }\n if (column.dtype === \"list\" || !(column.dtype === \"string\" || column.dtype === \"dict\")) {\n continue;\n }\n const heuristic = new DictHeuristic(DICT_SAMPLE_ROWS);\n for (let r = 0; r < column.length && !heuristic.decided; r++) {\n if (column.isSet(r)) {\n heuristic.observe(column.value(r) as string);\n }\n }\n const readsAsDict = heuristic.decide() === \"dict\";\n if (column.dtype === \"string\" && readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as dict (low cardinality)`,\n meta.name,\n null,\n ),\n );\n } else if (column.dtype === \"dict\" && !readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as string (cardinality too high for a dict)`,\n meta.name,\n null,\n ),\n );\n }\n }\n}\n\n/**\n * The importer names the graphics-derived position column `position`, or `position#graphics`\n * when a plain `position` key is written next to it (design section 5.6); a position column\n * named otherwise reads back under that name.\n * @param snapshot - the snapshot\n * @param nodeColumns - the written node columns\n * @param notes - where to record\n */\nfunction positionNameNote(snapshot: GraphSnapshot, nodeColumns: readonly WrittenColumn[], notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n const { name } = position.meta;\n const plainPosition = nodeColumns.some((c) => c.key === \"position\");\n const reimportName = plainPosition ? \"position#graphics\" : \"position\";\n if (name !== reimportName) {\n notes.push(\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `node column \"${name}\" (position) is written as the graphics x / y / z keys and reads back as \"${reimportName}\"`,\n name,\n position.length - position.nullCount,\n ),\n );\n }\n}\n\n/**\n * Pre-flight: the common capability notes plus the GML-specific ones.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\nfunction check(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planOf(snapshot, options);\n const notes = checkCapabilities(snapshot, GML_CAPABILITIES, plan.common, {\n positionDtype: \"f64\",\n roles: KEPT_ROLES,\n roleNames: ROLE_NAMES,\n });\n const nodeReserved = new Set(NODE_RESERVED);\n if (\n (plan.common.sanitizeIds === \"mangle\" && countMangled(snapshot) > 0) ||\n snapshot.nodes.byRole(\"originalId\") !== null\n ) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n const nodeColumns = selectColumns(snapshot.nodes, nodeReserved, \"node\", plan, notes);\n const edgeColumns = selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, notes, (c) => c !== edgeIds);\n const graphColumns = selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, notes, (c) => !isTopLevel(c));\n const topColumns = selectColumns(snapshot.graph, topReserved, \"top-level\", plan, notes, isTopLevel);\n jsonNotes(nodeColumns, \"node\", plan, notes);\n jsonNotes(edgeColumns, \"edge\", plan, notes);\n jsonNotes(graphColumns, \"graph\", plan, notes);\n jsonNotes(topColumns, \"top-level\", plan, notes);\n graphicsNotes(snapshot, notes);\n positionNameNote(snapshot, nodeColumns, notes);\n reimportNotes(nodeColumns, \"node\", notes);\n reimportNotes(edgeColumns, \"edge\", notes);\n if (!hasWeights(snapshot)) {\n const clash = edgeColumns.find((c) => c.key === plan.weightKey);\n if (clash !== undefined) {\n notes.push(\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${clash.column.meta.name}\" is written under \"${plan.weightKey}\", the key the importer reads THE weight from; it reads back as the weight, not as a column`,\n clash.column.meta.name,\n clash.column.length - clash.column.nullCount,\n ),\n );\n }\n }\n const folding = pairFolding(snapshot);\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair(s) are written as two directed edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n ),\n );\n }\n return Object.freeze(notes);\n}\n\n/**\n * The structural keys of the edge table: source, target, the weight key when weights are written,\n * and `id` when a role-id column is written as the edge id.\n * @param snapshot - the snapshot\n * @param plan - the export plan\n * @param edgeIds - the role-id edge column, or null\n * @returns the reserved keys\n */\nfunction edgeReservedKeys(snapshot: GraphSnapshot, plan: GmlExportPlan, edgeIds: Column | null): Set<string> {\n const reserved = new Set(EDGE_RESERVED);\n if (hasWeights(snapshot)) {\n reserved.add(plan.weightKey);\n }\n if (edgeIds !== null) {\n reserved.add(\"id\");\n }\n return reserved;\n}\n\n/**\n * The structural keys of the top level: graph, plus Creator and Version when the metadata writes them.\n * @param snapshot - the snapshot\n * @returns the reserved keys\n */\nfunction topReservedKeys(snapshot: GraphSnapshot): Set<string> {\n const reserved = new Set(TOP_RESERVED);\n if (snapshot.meta.creator !== null) {\n reserved.add(\"Creator\");\n }\n if (snapshot.meta.sourceFormat === \"gml\" && snapshot.meta.sourceVersion !== null) {\n reserved.add(\"Version\");\n }\n return reserved;\n}\n\n/**\n * How many node ids are not safe integers (what sanitizeIds \"mangle\" rewrites).\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countMangled(snapshot: GraphSnapshot): number {\n let count = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id !== \"number\" || !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n// ============================================================ writing\n\n/**\n * The GML text of a real: the shortest text of the dtype with a decimal point guaranteed\n * (`2.0`, `1.0e-7`), the NetworkX spellings `+INF` / `-INF` / `NAN` for the non-finite values.\n * @param value - the value\n * @param dtype - the dtype the value came from (f32 uses the fround-shortest text)\n * @returns the text\n */\nexport function gmlRealText(value: number, dtype: \"f32\" | \"f64\" | \"i32\" | \"u32\" | \"u8\" = \"f64\"): string {\n return formatGmlReal(value, dtype);\n}\n\n/**\n * The GML text of a number by the dtype and origin of its column: an integer text for the integer\n * dtypes and for an f64 column that came from GML `int` values, a real text otherwise.\n * @param value - the value\n * @param meta - the column metadata\n * @returns the text\n */\nfunction numberText(value: number, meta: ColumnMeta): string {\n switch (meta.dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return gmlRealText(value, \"f32\");\n default:\n if (meta.origin?.type === \"int\" && Number.isInteger(value)) {\n return formatInteger(value);\n }\n return gmlRealText(value, \"f64\");\n }\n}\n\n/**\n * The GML text of a JSON scalar inside a record: integers as int, other numbers as real, strings\n * quoted, booleans as 1 / 0.\n * @param value - the scalar\n * @returns the text\n */\nfunction jsonScalarText(value: number | string | boolean): string {\n switch (typeof value) {\n case \"number\":\n return Number.isInteger(value) ? formatInteger(value) : gmlRealText(value, \"f64\");\n case \"boolean\":\n return value ? \"1\" : \"0\";\n default:\n return quoteGmlString(value);\n }\n}\n\n/**\n * The GML text of a list item or components lane by the item dtype.\n * @param item - the item\n * @param itemDtype - the list's item dtype\n * @param meta - the list column metadata\n * @returns the text\n */\nfunction itemText(item: unknown, itemDtype: string, meta: ColumnMeta): string {\n switch (typeof item) {\n case \"number\":\n switch (itemDtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(item);\n case \"f32\":\n return gmlRealText(item, \"f32\");\n case \"json\":\n return jsonScalarText(item);\n default:\n return meta.origin?.type === \"int\" && Number.isInteger(item)\n ? formatInteger(item)\n : gmlRealText(item, \"f64\");\n }\n case \"boolean\":\n return item ? \"1\" : \"0\";\n case \"string\":\n return quoteGmlString(item);\n default:\n throw new GraphFormatError(\n \"E_COLUMN_TYPE\",\n `column \"${meta.name}\": a ${typeof item} list item cannot be written as GML`,\n {\n column: meta.name,\n found: typeof item,\n },\n );\n }\n}\n\n/** Writes lines with indentation into an array of parts. */\nclass GmlWriter {\n private readonly lines: string[] = [];\n\n private readonly mangle: boolean;\n\n /**\n * Create a writer.\n * @param mangle - whether record keys are rewritten rather than refused\n */\n constructor(mangle: boolean) {\n this.mangle = mangle;\n }\n\n /**\n * Take the lines written so far as one string.\n * @returns the text; the writer is empty afterwards\n */\n take(): string {\n const text = this.lines.join(\"\");\n this.lines.length = 0;\n return text;\n }\n\n /**\n * Write one `key value` line.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value text\n */\n line(indent: string, key: string, value: string): void {\n this.lines.push(`${indent}${key} ${value}\\n`);\n }\n\n /**\n * Write a raw line.\n * @param text - the line without its terminator\n */\n raw(text: string): void {\n this.lines.push(`${text}\\n`);\n }\n\n /**\n * Write one column cell of a row.\n * @param indent - the indentation\n * @param key - the key\n * @param column - the column\n * @param row - the row\n */\n cell(indent: string, key: string, column: Column, row: number): void {\n const { meta, dtype } = column;\n switch (dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const { components } = meta;\n if (components === 1) {\n this.line(indent, key, numberText(column.data[row], meta));\n } else {\n for (let k = 0; k < components; k++) {\n this.line(indent, key, numberText(column.data[row * components + k], meta));\n }\n }\n return;\n }\n case \"bool\":\n this.line(indent, key, column.value(row) === true ? \"1\" : \"0\");\n return;\n case \"dict\":\n case \"string\":\n this.line(indent, key, quoteGmlString(column.value(row) ?? \"\"));\n return;\n case \"list\":\n this.list(indent, key, column.sliceOf(row), meta.itemDtype ?? \"string\", meta);\n return;\n case \"json\":\n this.json(indent, key, column.values[row], meta.name);\n return;\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n }\n\n /**\n * Write a list as repeated keys with the NetworkX conventions.\n * @param indent - the indentation\n * @param key - the key\n * @param items - the items\n * @param itemDtype - the item dtype\n * @param meta - the column metadata\n */\n private list(indent: string, key: string, items: readonly unknown[], itemDtype: string, meta: ColumnMeta): void {\n if (items.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (items.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of items) {\n if (itemDtype === \"json\" && typeof item === \"object\") {\n this.json(indent, key, item, meta.name, true);\n } else {\n this.line(indent, key, itemText(item, itemDtype, meta));\n }\n }\n }\n\n /**\n * Write a JSON value: a record for an object, repeated keys for an array, a scalar otherwise;\n * null writes nothing.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value\n * @param column - the column name, for errors\n * @param inArray - whether the value is an array item (an array here has no GML spelling)\n */\n private json(indent: string, key: string, value: unknown, column: string, inArray = false): void {\n if (value === null || value === undefined) {\n return;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": an array nested in an array cannot be written as GML`,\n {\n reason: \"nested array\",\n column,\n },\n );\n }\n if (value.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (value.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of value) {\n this.json(indent, key, item, column, true);\n }\n return;\n }\n if (typeof value === \"object\") {\n this.record(indent, key, value as Record<string, unknown>, column);\n return;\n }\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") {\n this.line(indent, key, jsonScalarText(value));\n return;\n }\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `column \"${column}\": a ${typeof value} cannot be written as GML`, {\n column,\n found: typeof value,\n });\n }\n\n /**\n * Write a record `key [ ... ]`.\n * @param indent - the indentation\n * @param key - the key\n * @param record - the object\n * @param column - the column name, for errors\n * @param extra - lines to write first (the position of a graphics record), or null\n */\n record(\n indent: string,\n key: string,\n record: Record<string, unknown>,\n column: string,\n extra: readonly [string, string][] | null = null,\n ): void {\n this.raw(`${indent}${key} [`);\n const inner = `${indent} `;\n const used = new Set<string>();\n if (extra !== null) {\n for (const [k, v] of extra) {\n this.line(inner, k, v);\n used.add(k);\n }\n }\n for (const name of Object.keys(record)) {\n if (used.has(name) && extra !== null && (name === \"x\" || name === \"y\" || name === \"z\")) {\n continue;\n }\n const written = this.recordKey(name, used, column);\n used.add(written);\n this.json(inner, written, record[name], column);\n }\n this.raw(`${indent}]`);\n }\n\n /**\n * The key a record field is written under.\n * @param name - the field name\n * @param used - the keys already written in the record\n * @param column - the column name, for errors\n * @returns a valid, unused key; E_UNSUPPORTED for an invalid key unless mangling\n */\n private recordKey(name: string, used: ReadonlySet<string>, column: string): string {\n if (isGmlKey(name) && !used.has(name)) {\n return name;\n }\n if (!this.mangle) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": record key \"${name}\" ${isGmlKey(name) ? \"repeats a key\" : \"is not a GML key\"}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column,\n key: name,\n },\n );\n }\n return uniqueKey(isGmlKey(name) ? name : mangleGmlKey(name), used);\n }\n}\n\n/** Everything the writer needs, resolved once before the first line. */\ninterface WriteContext {\n readonly snapshot: GraphSnapshot;\n readonly plan: GmlExportPlan;\n readonly ids: SanitizedIds;\n readonly writeDirected: boolean;\n readonly foldPairs: boolean;\n readonly nodeColumns: readonly WrittenColumn[];\n readonly edgeColumns: readonly WrittenColumn[];\n readonly graphColumns: readonly WrittenColumn[];\n readonly topColumns: readonly WrittenColumn[];\n readonly position: Column | null;\n readonly graphics: JsonColumn | null;\n readonly originalIds: Column | null;\n readonly edgeIds: Column | null;\n readonly weights: ExplicitWeights;\n readonly folding: PairFolding;\n}\n\n/**\n * Resolve everything export() needs, throwing for what check() reported as an error.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the context\n */\nfunction contextOf(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): WriteContext {\n const plan = planOf(snapshot, options);\n const ids = sanitizeIds(snapshot, \"integer\", plan.common.sanitizeIds);\n const mixed = countMixedEdges(snapshot);\n if (mixed > 0 && plan.common.onMixedDirection === \"error\") {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${mixed} undirected edge(s) in a directed graph; GML has no mixed direction (onMixedDirection: \"error\")`,\n {\n reason: \"mixed direction\",\n count: mixed,\n },\n );\n }\n // design 8.5: exporters fold expanded pairs back; under \"directed\" the folded edge is written\n // once, as one directed edge, under \"undirected\" the whole graph is written undirected\n const foldPairs = mixed > 0;\n const writeDirected = snapshot.directed && plan.common.onMixedDirection !== \"undirected\";\n const originalIds = snapshot.nodes.byRole(\"originalId\");\n const nodeReserved = new Set(NODE_RESERVED);\n if (ids.changed > 0 || originalIds !== null) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n return {\n snapshot,\n plan,\n ids,\n writeDirected,\n foldPairs,\n nodeColumns: selectColumns(\n snapshot.nodes,\n nodeReserved,\n \"node\",\n plan,\n null,\n (c) => !(c.meta.name === \"graphics\" && c.dtype === \"json\"),\n ),\n edgeColumns: selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, null, (c) => c !== edgeIds),\n graphColumns: selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, null, (c) => !isTopLevel(c)),\n topColumns: selectColumns(snapshot.graph, topReserved, \"top-level\", plan, null, isTopLevel),\n position: positionColumn(snapshot),\n graphics: graphicsColumn(snapshot),\n originalIds,\n edgeIds,\n weights: explicitWeights(snapshot),\n folding: pairFolding(snapshot),\n };\n}\n\n/**\n * The GML text of an id written into `graphty_originalId`: quoted for a string, a number text\n * otherwise (an integer as int, else real, so the importer restores the same typed value).\n * @param id - the original id\n * @returns the text\n */\nfunction originalIdText(id: NodeId): string {\n if (typeof id === \"string\") {\n return quoteGmlString(id);\n }\n return Number.isSafeInteger(id) ? formatInteger(id) : gmlRealText(id, \"f64\");\n}\n\n/**\n * The parts of the document.\n * @param context - the resolved context\n * @yields one string per header line, node or edge\n * @returns nothing\n */\nfunction* gmlParts(context: WriteContext): Generator<string, void, undefined> {\n const { snapshot, plan, ids } = context;\n const w = new GmlWriter(plan.mangle);\n const { meta } = snapshot;\n if (meta.creator !== null) {\n w.line(\"\", \"Creator\", quoteGmlString(meta.creator));\n }\n if (meta.sourceFormat === \"gml\" && meta.sourceVersion !== null) {\n w.line(\"\", \"Version\", versionText(meta.sourceVersion));\n }\n for (const { column, key } of context.topColumns) {\n if (column.isSet(0)) {\n w.cell(\"\", key, column, 0);\n }\n }\n w.raw(\"graph [\");\n w.line(\" \", \"directed\", context.writeDirected ? \"1\" : \"0\");\n const multigraph = meta.declaredMultigraph ?? (snapshot.flags.multigraph ? true : null);\n if (multigraph !== null) {\n w.line(\" \", \"multigraph\", multigraph ? \"1\" : \"0\");\n }\n for (const { column, key } of context.graphColumns) {\n if (column.isSet(0)) {\n w.cell(\" \", key, column, 0);\n }\n }\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.raw(\" node [\");\n w.line(\" \", \"id\", formatInteger(ids.idAt(i) as number));\n if (ids.isChanged(i)) {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(ids.originalAt(i)));\n } else if (context.originalIds !== null && context.originalIds.isSet(i)) {\n const original = context.originalIds.value(i);\n if (typeof original === \"string\" || typeof original === \"number\") {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(original));\n }\n }\n for (const { column, key } of context.nodeColumns) {\n if (column.isSet(i)) {\n w.cell(\" \", key, column, i);\n }\n }\n writeGraphics(w, context, i);\n w.raw(\" ]\");\n yield w.take();\n }\n const el = snapshot.edgeList();\n const origin = meta.weightOrigin;\n const integerWeights = origin !== null && origin.type === \"int\";\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (context.foldPairs && context.folding.folded(e)) {\n continue;\n }\n w.raw(\" edge [\");\n w.line(\" \", \"source\", formatInteger(ids.idAt(el.src[e]) as number));\n w.line(\" \", \"target\", formatInteger(ids.idAt(el.dst[e]) as number));\n if (context.edgeIds !== null && context.edgeIds.isSet(e)) {\n w.cell(\" \", \"id\", context.edgeIds, e);\n }\n if (context.weights.isExplicit(e)) {\n const weight = context.weights.value(e);\n const text =\n integerWeights && Number.isInteger(weight)\n ? formatInteger(weight)\n : gmlRealText(weight, context.weights.dtype);\n w.line(\" \", plan.weightKey, text);\n }\n for (const { column, key } of context.edgeColumns) {\n if (column.isSet(e)) {\n w.cell(\" \", key, column, e);\n }\n }\n w.raw(\" ]\");\n yield w.take();\n }\n w.raw(\"]\");\n yield w.take();\n}\n\n/**\n * Write a node's `graphics [ ... ]` record from the position column and the graphics json column.\n * @param w - the writer\n * @param context - the context\n * @param i - the node\n */\nfunction writeGraphics(w: GmlWriter, context: WriteContext, i: number): void {\n const { position, graphics } = context;\n const hasPosition = position !== null && position.isSet(i);\n const graphicsValue = graphics !== null && graphics.isSet(i) ? graphics.values[i] : undefined;\n if (!hasPosition) {\n if (graphics !== null && graphicsValue !== undefined) {\n w.cell(\" \", \"graphics\", graphics, i);\n }\n return;\n }\n const numeric = position as Column & { readonly data: ArrayLike<number> };\n const { components } = numeric.meta;\n const lanes = Math.min(components, 3);\n const extra: [string, string][] = [];\n const names = [\"x\", \"y\", \"z\"];\n for (let k = 0; k < lanes; k++) {\n extra.push([names[k], numberText(numeric.data[i * components + k], numeric.meta)]);\n }\n let record: Record<string, unknown> = {};\n if (graphicsValue !== undefined) {\n if (typeof graphicsValue !== \"object\" || graphicsValue === null || Array.isArray(graphicsValue)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `node ${i}: the graphics value is not a record and cannot hold the position`,\n {\n reason: \"graphics conflict\",\n node: i,\n },\n );\n }\n record = graphicsValue as Record<string, unknown>;\n }\n w.record(\" \", \"graphics\", record, \"graphics\", extra);\n}\n\n/** The GML exporter plugin. */\nexport const gmlExporter: GraphExporter<GmlExportOptions> = Object.freeze({\n format: \"gml\",\n capabilities: GML_CAPABILITIES,\n check,\n /**\n * Write the snapshot as UTF-8 chunks; the context is resolved on the first pull, so the\n * errors check() announced surface from the iteration.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(lazyParts(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): Promise<string> {\n return joinText(lazyParts(snapshot, options));\n },\n});\n\n/**\n * The document parts, with the context resolved when iteration starts.\n * @param snapshot - the snapshot\n * @param options - the options\n * @yields the parts\n * @returns nothing\n */\nfunction* lazyParts(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): Generator<string, void, undefined> {\n yield* gmlParts(contextOf(snapshot, options));\n}\n","/**\n * The GML importer (design sections 8.4 and 8.5, research note 07 section 2.2): reads a whole GML\n * text (GML awaits the whole text, 8.4), lexes it once into a typed token list, derives the column\n * schema of every node, edge and graph key in a first walk (GML types are lexical per value, so\n * the column dtype is the union of the value classes seen: `int` -> i32, `real` -> f64, `string`\n * -> string, a nested `[ ]` record -> json, a repeated key -> list; the class is recorded in\n * `origin.type` per column as 8.5 requires), then pushes scalars into the sink in a second walk:\n * every node block first, then every edge block, so node indices follow the file's node order\n * and forward edge references resolve.\n *\n * Conventions honoured: NetworkX's `_networkx_list_start` marker and `\"[]\"` empty lists, `&#NN;`\n * character references in strings, `Creator` / `Version` top-level metadata, `directed 0|1` and\n * `multigraph 0|1` graph flags, comments, keys and values on one line or split across lines, and\n * a `graphics [ x y z ]` node record mapped to the `position` role (note 07 section 9) with the\n * remaining graphics keys kept as a json column.\n *\n * Node ids are the `id` keys under `nodeIdFrom: \"id\"`, the `label` under `\"label\"`, and the node's\n * ordinal under `\"index\"`; `source` / `target` always resolve through the `id` keys. The GML spec\n * types ids as integers; a string id (written by NetworkX and Gephi) is accepted under the `ids`\n * rule with one warning per file, and a real or record id is a validation error. A node's\n * `graphty_originalId` key written by the exporter's `sanitizeIds: \"mangle\"` restores the\n * original id under `restoreMangledIds` (the default).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ColumnRole,\n type Dtype,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, DictHeuristic, uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n COLUMN_RENAMED_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE as SHARED_NO_GRAPH_CODE,\n PRECISION_CODE as SHARED_PRECISION_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText, weightFromValue } from \"../../common/weights.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EMPTY_LIST_TEXT,\n EMPTY_TUPLE_TEXT,\n GmlSyntaxError,\n type GmlTokens,\n LIST_START_MARKER,\n numberOfText,\n ORIGINAL_ID_KEY,\n parseRecord,\n scalarOrRecord,\n TOKEN_INT,\n TOKEN_OPEN,\n TOKEN_REAL,\n TOKEN_STRING,\n TOKEN_WORD,\n tokenizeGml,\n} from \"./syntax.js\";\n\n/** The format-specific options of the GML importer. */\nexport interface GmlImportOptions {\n /**\n * Map a node's `graphics [ x y z ]` record to a `position` column with the position role\n * (default true); false keeps the whole record in the `graphics` json column.\n */\n positions?: boolean | undefined;\n /** Apply the dictionary heuristic of design section 5.4 to string columns (default true). */\n dictionaries?: boolean | undefined;\n}\n\n/** Issue code: the text holds no `graph [ ... ]` block. */\nexport const NO_GRAPH_CODE = SHARED_NO_GRAPH_CODE;\n/** Issue code: the text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one. */\nexport const SECOND_GRAPH_CODE = MULTIPLE_GRAPHS_CODE;\n/** Issue code: a node block has no `id` key. */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n/** Issue code: a node block has no `label` key under `nodeIdFrom: \"label\"`. */\nexport const MISSING_LABEL_CODE = \"E_GML_MISSING_LABEL\";\n/** Issue code: an edge block has no `source` or no `target` key. */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n/** Issue code: an `id`, `source` or `target` value is neither an integer nor a string. */\nexport const ID_TYPE_CODE = \"E_GML_ID_TYPE\";\n/** Issue code: string `id`, `source` or `target` values, outside the GML spec's integer ids; warned once per file. */\nexport const STRING_ID_CODE = \"W_GML_STRING_ID\";\n/** Issue code: a node id (or label under `nodeIdFrom: \"label\"`) is declared twice; later keys overwrite. */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n/** Issue code: a structural key (`id`, `source`, `target`) appears twice in one block. */\nexport const REPEATED_KEY_CODE = \"E_GML_REPEATED_KEY\";\n/** Issue code: a `node` or `edge` key whose value is not a `[ ... ]` block. */\nexport const ELEMENT_TYPE_CODE = \"E_GML_ELEMENT_TYPE\";\n/** Issue code: a `directed` or `multigraph` flag that is not an integer. */\nexport const FLAG_TYPE_CODE = \"E_GML_FLAG_TYPE\";\n/** Issue code: a `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or one repeated. */\nexport const FLAG_VALUE_CODE = \"W_GML_FLAG_VALUE\";\n\n/** A flag written as a quoted integer, surrounding spaces allowed. */\nconst QUOTED_INT = /^\\s*[+-]?[0-9]+\\s*$/;\n/** Issue code: a named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity; it is kept as written. */\nexport const UNKNOWN_ENTITY_CODE = \"W_GML_UNKNOWN_ENTITY\";\n/** Issue code: an integer beyond 2^53 stored as the nearest f64 (design section 5.1). */\nexport const PRECISION_CODE = SHARED_PRECISION_CODE;\n/** Issue code: the sink already holds a column of the name with another declaration; renamed `<name>#<key>`. */\nexport const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;\n/** Issue code: the sink already holds a column with the role; the column is declared without it. */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n/** Loss code: under `nodeIdFrom` \"label\" / \"index\" the integer `id` keys are not kept. */\nexport const ID_DROPPED_CODE = \"W_GML_ID_DROPPED\";\n\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"value\" };\n\nconst KIND_INT = 1;\nconst KIND_REAL = 2;\nconst KIND_STRING = 4;\nconst KIND_RECORD = 8;\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/** How many elements are pushed between abort-signal checks. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"restoreMangledIds\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** The element sequence number of the graph block's own keys. */\nconst GRAPH_SEQ = -1;\n/** The element sequence number of the top-level keys. */\nconst TOP_SEQ = -2;\n\n/** The GML value class a column stores. */\ntype GmlKind = \"int\" | \"real\" | \"string\" | \"record\";\n\n/** What the first walk learns about one key of one table. */\ninterface KeySchema {\n /** The key as written. */\n readonly key: string;\n /** The union of value classes seen (KIND_* bits). */\n kinds: number;\n /** Whether the key repeats within one element, or uses a list marker. */\n list: boolean;\n /** The element sequence the key was last seen in. */\n lastSeq: number;\n /** Whether an integer outside the i32 range was seen. */\n wide: boolean;\n /** Whether an integer beyond 2^53 was seen. */\n unsafe: boolean;\n /** The dictionary heuristic while every value is a string, else null. */\n dict: DictHeuristic | null;\n /** Node `graphics` only: some row has numeric x and y. */\n position: boolean;\n /** Node `graphics` only: some row keeps keys besides the position. */\n rest: boolean;\n}\n\n/** The column a key maps to in the second walk. */\ninterface ColumnPlan {\n /** The key as written. */\n readonly key: string;\n /** The column name (renamed `<name>#<key>` when the sink held the name with another shape). */\n name: string;\n /** The column dtype. */\n readonly dtype: Dtype;\n /** The list item dtype, or null. */\n readonly itemDtype: ScalarDtype | null;\n /** How scalar values (or list items) are converted. */\n readonly kind: GmlKind;\n /** Whether the column is a list. */\n readonly list: boolean;\n /** The role, or null. */\n readonly role: ColumnRole | null;\n /** Whether the values come from the top level of the file (graph table only). */\n readonly top: boolean;\n /** Node `graphics` with the position mapping: the position column plan, or null. */\n readonly position: ColumnPlan | null;\n /** Node `graphics` with the position mapping: the json column of the remaining keys, or null. */\n readonly rest: ColumnPlan | null;\n /** The handle once declared. */\n handle: ColumnHandle;\n /** Whether the declaration was attempted (a failed one reuses the sink's column or is null). */\n declared: boolean;\n /** The list items of the current element. */\n items: unknown[] | null;\n /** The element sequence the items belong to. */\n seq: number;\n}\n\n/** A table's plans by key. */\ntype PlanMap = Map<string, ColumnPlan>;\n\n/**\n * Whether a key gets a role in its table (design section 5.6 applied to GML keys).\n * @param domain - the table\n * @param key - the key\n * @returns the role, or null\n */\nfunction roleOf(domain: \"node\" | \"edge\" | \"graph\", key: string): ColumnRole | null {\n if (key === \"label\" && domain !== \"graph\") {\n return \"label\";\n }\n if (domain === \"edge\") {\n if (key === \"id\") {\n return \"id\";\n }\n if (key === \"key\") {\n return \"key\";\n }\n }\n return null;\n}\n\n/** One import call. */\nclass GmlImport {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly positions: boolean;\n\n private readonly dictionaries: boolean;\n\n private readonly coercer: IdCoercer;\n\n private tokens: GmlTokens | null = null;\n\n /** How many `graph [ ... ]` blocks the text holds (known after the scan). */\n graphCount = 0;\n\n private resolver: DirectionResolver | null = null;\n\n private readonly nodeSchema = new Map<string, KeySchema>();\n\n private readonly edgeSchema = new Map<string, KeySchema>();\n\n private readonly graphSchema = new Map<string, KeySchema>();\n\n private readonly topSchema = new Map<string, KeySchema>();\n\n private readonly nodePlans: PlanMap = new Map();\n\n private readonly edgePlans: PlanMap = new Map();\n\n private readonly graphPlans: PlanMap = new Map();\n\n private readonly topPlans: PlanMap = new Map();\n\n private readonly graphNames = new Set<string>();\n\n private graphOpen = -1;\n\n private directedToken = -1;\n\n private multigraphToken = -1;\n\n private creatorToken = -1;\n\n private versionToken = -1;\n\n private nodeCount = 0;\n\n private edgeCount = 0;\n\n private weightKinds = 0;\n\n private hasOriginalId = false;\n\n private headerDirected = false;\n\n private seq = 0;\n\n private nodeOrdinal = 0;\n\n private elementsSinceCheck = 0;\n\n /** The sink id every file id maps to when they differ (label / index / restored ids), else null. */\n private idMap: Map<NodeId, NodeId> | null = null;\n\n /** Node indices declared by a node block of this import, for duplicate detection. */\n private declared = new Uint32Array(64);\n\n /** The list plans touched by the current node or edge. */\n private readonly touched: ColumnPlan[] = [];\n\n /** The list plans touched by the graph table's keys. */\n private readonly graphTouched: ColumnPlan[] = [];\n\n /** The sequence number of the current node or edge, which its list items belong to. */\n private seqNow = 0;\n\n /**\n * Create one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param format - the format-specific options\n * @param which - which `graph [ ... ]` block to read (0: the first)\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n format: GmlImportOptions | undefined,\n private readonly which = 0,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.positions = format?.positions ?? true;\n this.dictionaries = format?.dictionaries ?? true;\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Run the import over the tokens of a text.\n * @param tokens - the whole text, tokenized (tokenize())\n */\n run(tokens: GmlTokens): void {\n this.tokens = tokens;\n tokens.onUnknownEntity = (entity, line) => {\n this.report.warnOnce(\n \"parse-error\",\n UNKNOWN_ENTITY_CODE,\n `unknown character entity ${entity} is kept as written`,\n { line, element: entity },\n `${UNKNOWN_ENTITY_CODE}:${entity}`,\n );\n };\n this.scan();\n this.push();\n }\n\n // ============================================================ pass 1: the schema\n\n /**\n * Walk the top level: find the graph block, the metadata keys and the top-level attributes,\n * and derive every table's schema.\n */\n private scan(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n const record = t.kind[v] === TOKEN_OPEN;\n if (key === \"graph\" && record) {\n if (this.graphCount++ === this.which) {\n this.graphOpen = v;\n this.scanGraph(v);\n }\n } else if (key === \"Creator\" && !record && this.creatorToken < 0) {\n this.creatorToken = v;\n } else if (key === \"Version\" && !record && this.versionToken < 0) {\n this.versionToken = v;\n } else {\n this.observe(this.topSchema, \"graph\", key, v, TOP_SEQ);\n }\n }\n if (this.graphOpen < 0) {\n this.report.fail(NO_GRAPH_CODE, \"the input contains no graph [ ... ] block\", { line: null });\n }\n }\n\n /**\n * Walk the graph block for the schema.\n * @param open - the index of the block's `[`\n */\n private scanGraph(open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.nodeCount++;\n this.scanElement(\"node\", v);\n }\n break;\n case \"edge\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.edgeCount++;\n this.scanElement(\"edge\", v);\n }\n break;\n case \"directed\":\n if (this.directedToken < 0) {\n this.directedToken = v;\n }\n break;\n case \"multigraph\":\n if (this.multigraphToken < 0) {\n this.multigraphToken = v;\n }\n break;\n default:\n this.observe(this.graphSchema, \"graph\", key, v, GRAPH_SEQ);\n }\n }\n }\n\n /**\n * Walk one node or edge block for the schema.\n * @param domain - node or edge\n * @param open - the block's `[`\n */\n private scanElement(domain: \"node\" | \"edge\", open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n const seq = this.seq++;\n const schema = domain === \"node\" ? this.nodeSchema : this.edgeSchema;\n const { weightFrom, restoreMangledIds } = this.options;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n if (domain === \"node\") {\n if (key === \"id\") {\n continue;\n }\n if (key === ORIGINAL_ID_KEY && restoreMangledIds) {\n this.hasOriginalId = true;\n continue;\n }\n } else {\n if (key === \"source\" || key === \"target\" || key === \"directed\") {\n continue;\n }\n if (key === weightFrom) {\n this.weightKinds |= kindBit(t, v);\n continue;\n }\n }\n this.observe(schema, domain, key, v, seq);\n }\n }\n\n /**\n * Record one value of one key in a table's schema.\n * @param schema - the table's schema\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n * @param seq - the element sequence number\n */\n private observe(\n schema: Map<string, KeySchema>,\n domain: \"node\" | \"edge\" | \"graph\",\n key: string,\n v: number,\n seq: number,\n ): void {\n const t = this.requireTokens();\n let entry = schema.get(key);\n if (entry === undefined) {\n entry = {\n key,\n kinds: 0,\n list: false,\n lastSeq: seq,\n wide: false,\n unsafe: false,\n dict: this.dictionaries && roleOf(domain, key) === null ? new DictHeuristic() : null,\n position: false,\n rest: false,\n };\n schema.set(key, entry);\n } else if (entry.lastSeq === seq) {\n entry.list = true;\n } else {\n entry.lastSeq = seq;\n }\n switch (t.kind[v]) {\n case TOKEN_STRING: {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n entry.list = true;\n return;\n }\n entry.kinds |= KIND_STRING;\n if (entry.dict !== null && !entry.dict.decided) {\n entry.dict.observe(raw);\n }\n return;\n }\n case TOKEN_INT: {\n entry.kinds |= KIND_INT;\n const n = Number(t.textOf(v));\n if (n < I32_MIN || n > I32_MAX) {\n entry.wide = true;\n if (!Number.isSafeInteger(n)) {\n entry.unsafe = true;\n }\n }\n return;\n }\n case TOKEN_OPEN:\n entry.kinds |= KIND_RECORD;\n if (domain === \"node\" && key === \"graphics\" && this.positions) {\n this.inspectGraphics(entry, v);\n }\n return;\n default:\n entry.kinds |= KIND_REAL;\n }\n }\n\n /**\n * Note whether a node's graphics record carries a position (numeric x and y) and whether\n * anything besides the position remains.\n * @param entry - the graphics schema entry\n * @param open - the record's `[`\n */\n private inspectGraphics(entry: KeySchema, open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n let x = false;\n let y = false;\n let other = false;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const numeric = t.kind[p + 1] === TOKEN_INT || t.kind[p + 1] === TOKEN_REAL;\n if (key === \"x\" && numeric && !x) {\n x = true;\n } else if (key === \"y\" && numeric && !y) {\n y = true;\n } else if (!(key === \"z\" && numeric)) {\n other = true;\n }\n }\n const positioned = x && y;\n entry.position ||= positioned;\n entry.rest ||= positioned ? other : true;\n }\n\n // ============================================================ pass 2: the push\n\n /** Declare what the schema needs, set the header and push every element. */\n private push(): void {\n const { sink, report, options } = this;\n const t = this.requireTokens();\n sink.reserve(this.nodeCount, this.edgeCount);\n this.buildPlans();\n this.setMetadata();\n this.headerDirected = this.readFlag(this.directedToken, \"directed\") ?? options.defaultDirected;\n const resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n resolver.setHeader(this.headerDirected, {\n line: this.directedToken >= 0 ? t.line[this.directedToken] : t.line[this.graphOpen],\n });\n this.resolver = resolver;\n if (options.nodeIdFrom !== \"id\" || this.hasOriginalId) {\n this.idMap = new Map();\n }\n if (options.nodeIdFrom !== \"id\") {\n report.loss(\n ID_DROPPED_CODE,\n `node ids taken from the ${options.nodeIdFrom}; the integer id keys are not kept as a column`,\n null,\n this.nodeCount,\n );\n }\n this.pushTopLevel();\n this.pushNodes();\n this.pushEdges();\n }\n\n /** Turn every schema entry into a column plan. */\n private buildPlans(): void {\n for (const [key, entry] of this.nodeSchema) {\n this.nodePlans.set(key, this.planOf(\"node\", entry));\n }\n for (const [key, entry] of this.edgeSchema) {\n this.edgePlans.set(key, this.planOf(\"edge\", entry));\n }\n for (const [key, entry] of this.graphSchema) {\n this.graphPlans.set(key, this.planOf(\"graph\", entry));\n }\n for (const [key, entry] of this.topSchema) {\n this.topPlans.set(key, this.planOf(\"graph\", entry, true));\n }\n }\n\n /**\n * The plan of one schema entry.\n * @param domain - the table\n * @param entry - the schema entry\n * @param top - whether the key is a top-level one (graph table)\n * @returns the plan\n */\n private planOf(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, top = false): ColumnPlan {\n const kind = kindOf(entry);\n let scalar: ScalarDtype = dtypeOfKind(kind, entry);\n if (\n scalar === \"string\" &&\n !entry.list &&\n entry.dict !== null &&\n entry.kinds === KIND_STRING &&\n entry.dict.decide() === \"dict\"\n ) {\n scalar = \"dict\";\n }\n if (entry.unsafe) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${domain} key \"${entry.key}\" holds integers beyond 2^53; they are stored as the nearest f64`,\n { element: entry.key },\n `${PRECISION_CODE}:${domain}:${entry.key}`,\n );\n }\n const name = domain === \"graph\" ? this.uniqueGraphName(entry.key) : entry.key;\n let itemDtype: ScalarDtype | null = null;\n if (entry.list) {\n itemDtype = scalar === \"dict\" ? \"string\" : scalar;\n }\n const plan: ColumnPlan = {\n key: entry.key,\n name,\n dtype: entry.list ? \"list\" : scalar,\n itemDtype,\n kind,\n list: entry.list,\n role: roleOf(domain, entry.key),\n top,\n position: null,\n rest: null,\n handle: INVALID_INDEX as ColumnHandle,\n declared: false,\n items: null,\n seq: Number.NEGATIVE_INFINITY,\n };\n if (\n domain === \"node\" &&\n entry.key === \"graphics\" &&\n entry.position &&\n entry.kinds === KIND_RECORD &&\n !entry.list\n ) {\n const taken = (candidate: string): boolean =>\n this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;\n const position: ColumnPlan = {\n ...plan,\n name: uniqueColumnName(\"position\", \"graphics\", taken),\n dtype: \"f64\",\n itemDtype: null,\n kind: \"real\",\n role: \"position\",\n };\n const rest: ColumnPlan | null = entry.rest ? { ...plan } : null;\n return { ...plan, position, rest };\n }\n return plan;\n }\n\n /**\n * A graph column name not yet used by this import (top-level and in-graph keys share the table).\n * @param key - the key\n * @returns the name\n */\n private uniqueGraphName(key: string): string {\n const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));\n this.graphNames.add(name);\n return name;\n }\n\n /** Set the graph metadata: source format, creator, version, multigraph flag, weight origin. */\n private setMetadata(): void {\n const t = this.requireTokens();\n const { sink, options } = this;\n const textOf = (v: number): string => (t.kind[v] === TOKEN_STRING ? t.stringOf(v) : t.textOf(v));\n const multigraph = this.readFlag(this.multigraphToken, \"multigraph\");\n sink.setMeta({\n sourceFormat: \"gml\",\n creator: this.creatorToken >= 0 ? textOf(this.creatorToken) : undefined,\n sourceVersion: this.versionToken >= 0 ? textOf(this.versionToken) : undefined,\n declaredMultigraph: multigraph ?? undefined,\n weightOrigin:\n this.weightKinds !== 0 && options.weightFrom !== null\n ? {\n format: \"gml\",\n id: options.weightFrom,\n title: null,\n type: this.weightKinds === KIND_INT ? \"int\" : \"real\",\n namespace: null,\n }\n : undefined,\n // The header as written, so a reader can say which words set the direction and tell\n // `directed 0` from a file that relies on the specification's default.\n extra: this.directedToken >= 0 ? { gml: { directed: textOf(this.directedToken) } } : undefined,\n });\n }\n\n /**\n * Read a `directed` / `multigraph` flag token.\n * @param v - the value token, or -1 when absent\n * @param name - the flag name, for issues\n * @returns the flag, or null when absent or not an integer\n */\n private readFlag(v: number, name: string): boolean | null {\n if (v < 0) {\n return null;\n }\n const t = this.requireTokens();\n // Files in the wild write the flag as a quoted integer (`directed \"1\"`); read it, with a warning.\n const quoted = t.kind[v] === TOKEN_STRING && QUOTED_INT.test(t.stringOf(v));\n if (quoted) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is written as the string ${describeValue(t, v)}; read as an integer`,\n { line: t.line[v], element: name },\n );\n } else if (t.kind[v] !== TOKEN_INT) {\n this.report.error(\n \"validation-error\",\n FLAG_TYPE_CODE,\n `flag \"${name}\" must be the integer 0 or 1, found ${describeValue(t, v)}`,\n { line: t.line[v], element: name },\n );\n return null;\n }\n const n = Number(quoted ? t.stringOf(v) : t.textOf(v));\n if (n !== 0 && n !== 1) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is ${n}; read as ${n !== 0 ? \"1\" : \"0\"}`,\n { line: t.line[v], element: name },\n );\n }\n return n !== 0;\n }\n\n /** Push the top-level attributes (every top-level key but graph, Creator and Version). */\n private pushTopLevel(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const v = p + 1;\n if (v === this.graphOpen || v === this.creatorToken || v === this.versionToken) {\n continue;\n }\n const plan = this.topPlans.get(t.textOf(p));\n if (plan !== undefined) {\n this.writeGraph(plan, v, TOP_SEQ);\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every node block and the graph block's own attributes, in file order. */\n private pushNodes(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.importNode(v);\n } else {\n this.badElement(\"node\", p);\n this.report.counts.skippedNodes++;\n }\n break;\n case \"edge\":\n break;\n case \"directed\":\n case \"multigraph\":\n if (v !== this.directedToken && v !== this.multigraphToken) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `graph flag \"${key}\" repeated; the first value stands`,\n { line: t.line[p], element: key },\n );\n }\n break;\n default: {\n const plan = this.graphPlans.get(key);\n if (plan !== undefined) {\n this.writeGraph(plan, v, GRAPH_SEQ);\n }\n }\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every edge block, in file order. */\n private pushEdges(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n let ordinal = 0;\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n if (t.textOf(p) !== \"edge\") {\n continue;\n }\n const v = p + 1;\n if (t.kind[v] === TOKEN_OPEN) {\n this.importEdge(v, ordinal);\n } else {\n this.badElement(\"edge\", p);\n this.report.counts.skippedEdges++;\n }\n ordinal++;\n }\n }\n\n /**\n * Record a `node` / `edge` key whose value is not a block.\n * @param what - node or edge\n * @param p - the key token\n */\n private badElement(what: string, p: number): void {\n const t = this.requireTokens();\n this.report.error(\n \"validation-error\",\n ELEMENT_TYPE_CODE,\n `${what} must be a [ ... ] block, found ${describeValue(t, p + 1)}`,\n { line: t.line[p], element: what },\n );\n }\n\n /**\n * Push one node block.\n * @param open - the block's `[`\n */\n private importNode(open: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const ordinal = this.nodeOrdinal++;\n this.checkAbort();\n let index: number;\n let sinkId: NodeId;\n try {\n let idTok = -1;\n let labelTok = -1;\n let originalTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\") {\n idTok = this.structuralToken(idTok, p, \"id\");\n } else if (key === \"label\") {\n labelTok = labelTok < 0 ? p + 1 : labelTok;\n } else if (key === ORIGINAL_ID_KEY && options.restoreMangledIds) {\n originalTok = originalTok < 0 ? p + 1 : originalTok;\n }\n }\n if (idTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no id\", { reason: \"missing id\" });\n }\n // the file id under the ids rule, so `id 1` and `source \"1\"` meet in idMap (except under\n // \"keep\", where the integer 1 and the string \"1\" are different ids by design)\n const fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, \"id\"));\n if (originalTok >= 0) {\n sinkId = this.restoredId(originalTok);\n } else {\n switch (options.nodeIdFrom) {\n case \"label\":\n if (labelTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no label\", {\n reason: \"missing label\",\n });\n }\n sinkId = this.coerceValueToken(labelTok);\n break;\n case \"index\":\n sinkId = ordinal;\n break;\n default:\n sinkId = fileId;\n }\n }\n if (this.idMap !== null) {\n this.idMap.set(fileId, sinkId);\n }\n index = sink.addNode(sinkId);\n } catch (err) {\n this.recordNodeError(err, line);\n report.counts.skippedNodes++;\n return;\n }\n if (this.isDeclared(index)) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${JSON.stringify(sinkId)} is declared twice; later keys overwrite`,\n { line, element: String(sinkId) },\n );\n } else {\n this.markDeclared(index);\n report.counts.nodes++;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\" || (key === ORIGINAL_ID_KEY && options.restoreMangledIds)) {\n continue;\n }\n const plan = this.nodePlans.get(key);\n if (plan !== undefined) {\n this.writeNode(plan, index, p + 1);\n }\n }\n this.flushLists(\"node\", index);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element: String(sinkId) });\n }\n }\n\n /**\n * Push one edge block.\n * @param open - the block's `[`\n * @param ordinal - the edge's ordinal among edge blocks, for messages\n */\n private importEdge(open: number, ordinal: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const element = `edge #${ordinal}`;\n this.checkAbort();\n let edge: number;\n try {\n let sourceTok = -1;\n let targetTok = -1;\n let weightTok = -1;\n let directedTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\") {\n sourceTok = this.structuralToken(sourceTok, p, \"source\");\n } else if (key === \"target\") {\n targetTok = this.structuralToken(targetTok, p, \"target\");\n } else if (key === \"directed\") {\n directedTok = this.structuralToken(directedTok, p, \"directed\");\n } else if (key === options.weightFrom) {\n weightTok = p + 1;\n }\n }\n if (sourceTok < 0 || targetTok < 0) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge has no ${sourceTok < 0 ? \"source\" : \"target\"}`, {\n reason: \"missing endpoint\",\n });\n }\n const source = this.endpoint(sourceTok, \"source\");\n const target = this.endpoint(targetTok, \"target\");\n const weight = weightTok >= 0 ? this.weightOf(weightTok) : undefined;\n const before = sink.edgeCount;\n const sourceNew = sink.indexOf(source) === INVALID_INDEX;\n const targetNew = source !== target && sink.indexOf(target) === INVALID_INDEX;\n // an edge-level `directed` key overrides the graph's flag for that edge (mixed graphs)\n const directed = this.readFlag(directedTok, \"directed\") ?? this.headerDirected;\n edge = this.requireResolver().addEdge(source, target, directed ? \"directed\" : \"undirected\", weight, {\n line,\n element,\n });\n report.counts.edges += sink.edgeCount - before;\n // endpoints the file never declares (addMissingNodes) are nodes of the sink too\n report.counts.nodes += (sourceNew ? 1 : 0) + (targetNew ? 1 : 0);\n } catch (err) {\n this.recordEdgeError(err, line, element);\n report.counts.skippedEdges++;\n return;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\" || key === \"target\" || key === \"directed\" || key === options.weightFrom) {\n continue;\n }\n const plan = this.edgePlans.get(key);\n if (plan !== undefined) {\n this.writeEdge(plan, edge, p + 1);\n }\n }\n this.flushLists(\"edge\", edge);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element });\n }\n }\n\n // ============================================================ ids and weights\n\n /**\n * Note a structural key token, refusing a repeat.\n * @param previous - the token seen before, or -1\n * @param p - the key token\n * @param key - the key name\n * @returns the value token\n */\n private structuralToken(previous: number, p: number, key: string): number {\n if (previous >= 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", `key \"${key}\" appears twice in one block`, {\n reason: \"duplicate key\",\n key,\n });\n }\n return p + 1;\n }\n\n /**\n * The value of an id / source / target token: an integer (the GML spec's type) as a number, a\n * string (NetworkX and Gephi write them) as its text with one warning per file.\n * @param v - the value token\n * @param key - the key name, for the error\n * @returns the number or the string\n */\n private fileIdOf(v: number, key: string): number | string {\n const t = this.requireTokens();\n if (t.kind[v] === TOKEN_STRING) {\n this.report.warnOnce(\n \"validation-error\",\n STRING_ID_CODE,\n `${key} is the string \"${t.textOf(v)}\"; GML ids are integers, string ids are kept under the ids rule`,\n { line: t.line[v], element: t.stringOf(v) },\n );\n return t.stringOf(v);\n }\n if (t.kind[v] !== TOKEN_INT) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${key} must be an integer or a string, found ${describeValue(t, v)}`,\n {\n reason: \"not an integer\",\n key,\n value: t.kind[v] === TOKEN_OPEN ? \"[...]\" : t.textOf(v),\n },\n );\n }\n return Number(t.textOf(v));\n }\n\n /**\n * Coerce an id / source / target value under the `ids` rule: a string by its text, an integer\n * through coerceInteger().\n * @param v - the value token\n * @param id - its value (fileIdOf())\n * @returns the id\n */\n private coerceFileId(v: number, id: number | string): NodeId {\n return typeof id === \"string\" ? this.coercer.text(id) : this.coerceInteger(v, id);\n }\n\n /**\n * Coerce an integer id token under the `ids` rule: a safe integer passes as a typed number\n * (so `01` is 1 and `-0` is 0), a larger one goes through the text rule (a string under\n * \"canonical\"), and \"string\" keeps the text as written.\n * @param v - the value token\n * @param n - its numeric value\n * @returns the id\n */\n private coerceInteger(v: number, n: number): NodeId {\n if (Number.isSafeInteger(n) && this.coercer.mode !== \"string\") {\n return this.coercer.value(n);\n }\n return this.coercer.text(this.requireTokens().textOf(v));\n }\n\n /**\n * Coerce a label token under the `ids` rule: a string by its text, a number as a typed value.\n * @param v - the value token\n * @returns the id\n */\n private coerceValueToken(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return this.coercer.text(t.stringOf(v));\n case TOKEN_INT:\n return this.coerceInteger(v, Number(t.textOf(v)));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", \"label must be a string or a number, found a record\", {\n reason: \"record label\",\n });\n default:\n return this.coercer.value(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * The id a `graphty_originalId` key restores: typed, never coerced (the exporter wrote it exactly).\n * @param v - the value token\n * @returns the original id\n */\n private restoredId(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return t.stringOf(v);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", `${ORIGINAL_ID_KEY} must be a string or a number`, {\n reason: \"record original id\",\n });\n default:\n return numberOfText(t.textOf(v));\n }\n }\n\n /**\n * Resolve a source / target token to a sink id.\n * @param v - the value token\n * @param key - source or target\n * @returns the id\n */\n private endpoint(v: number, key: string): NodeId {\n const id = this.coerceFileId(v, this.fileIdOf(v, key));\n return this.idMap?.get(id) ?? id;\n }\n\n /**\n * The weight of an edge from its weight token.\n * @param v - the value token\n * @returns the weight; E_INVALID_WEIGHT for a record or non-numeric text\n */\n private weightOf(v: number): number | undefined {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return parseWeightText(t.stringOf(v));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"edge weight is a record\", { value: \"[...]\" });\n default:\n return weightFromValue(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * Record a node-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n */\n private recordNodeError(err: unknown, line: number): void {\n const { report } = this;\n if (err instanceof GraphFormatError && err.code === \"E_INVALID_ID\") {\n const { reason } = err.details;\n switch (reason) {\n case \"missing id\":\n report.error(\"missing-value\", MISSING_ID_CODE, err.message, { line, element: \"node\" });\n return;\n case \"missing label\":\n report.error(\"missing-value\", MISSING_LABEL_CODE, err.message, { line, element: \"node\" });\n return;\n case \"duplicate key\":\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element: \"node\" });\n return;\n case \"not an integer\":\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element: \"node\" });\n return;\n default:\n break;\n }\n }\n report.recordError(err, { line, element: \"node\" });\n }\n\n /**\n * Record an edge-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n * @param element - the edge description\n */\n private recordEdgeError(err: unknown, line: number, element: string): void {\n const { report } = this;\n if (err instanceof GraphFormatError) {\n const { reason } = err.details;\n if (err.code === \"E_UNKNOWN_NODE\" && reason === \"missing endpoint\") {\n report.error(\"missing-value\", MISSING_ENDPOINT_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"duplicate key\") {\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"not an integer\") {\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element });\n return;\n }\n }\n report.recordError(err, { line, element });\n }\n\n // ============================================================ values\n\n /**\n * Write one node value.\n * @param plan - the key's plan\n * @param index - the node index\n * @param v - the value token\n */\n private writeNode(plan: ColumnPlan, index: number, v: number): void {\n if (plan.position !== null) {\n this.writeGraphics(plan, index, v);\n return;\n }\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setNodeValue(this.handleOf(plan, \"node\"), index, this.scalarOf(plan, v));\n }\n\n /**\n * Write one edge value.\n * @param plan - the key's plan\n * @param edge - the edge index\n * @param v - the value token\n */\n private writeEdge(plan: ColumnPlan, edge: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setEdgeValue(this.handleOf(plan, \"edge\"), edge, this.scalarOf(plan, v));\n }\n\n /**\n * Write one graph value.\n * @param plan - the key's plan\n * @param v - the value token\n * @param seq - TOP_SEQ or GRAPH_SEQ\n */\n private writeGraph(plan: ColumnPlan, v: number, seq: number): void {\n if (plan.list) {\n this.collectItem(plan, v, seq, this.graphTouched);\n return;\n }\n this.sink.setGraphValue(plan.name, this.scalarOf(plan, v), graphDecl(plan));\n }\n\n /**\n * Write a node's graphics record: the position column from x / y / z, the remaining keys to\n * the json column.\n * @param plan - the graphics plan\n * @param index - the node index\n * @param v - the value token (a record)\n */\n private writeGraphics(plan: ColumnPlan, index: number, v: number): void {\n const t = this.requireTokens();\n const { sink } = this;\n const record = parseRecord(t, v);\n const { x, y, z } = record;\n const positionPlan = plan.position;\n if (positionPlan !== null && typeof x === \"number\" && typeof y === \"number\") {\n sink.setNodeValue(this.handleOf(positionPlan, \"node\"), index, [x, y, typeof z === \"number\" ? z : 0]);\n delete record.x;\n delete record.y;\n if (typeof z === \"number\") {\n delete record.z;\n }\n if (plan.rest !== null && Object.keys(record).length > 0) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, record);\n }\n return;\n }\n if (plan.rest !== null) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, record);\n }\n }\n\n /**\n * Collect one list item.\n * @param plan - the list plan\n * @param v - the value token\n * @param seq - the sequence number of the element the item belongs to\n * @param touched - the plans touched by that element\n */\n private collectItem(plan: ColumnPlan, v: number, seq: number, touched: ColumnPlan[]): void {\n const t = this.requireTokens();\n if (plan.seq !== seq) {\n plan.seq = seq;\n plan.items = [];\n touched.push(plan);\n }\n if (t.kind[v] === TOKEN_STRING) {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n return;\n }\n }\n (plan.items as unknown[]).push(this.scalarOf(plan, v));\n }\n\n /**\n * Start a node or edge: later list items belong to it.\n * @param seq - the element's sequence number\n */\n private beginElement(seq: number): void {\n this.seqNow = seq;\n this.touched.length = 0;\n }\n\n /**\n * Write the lists collected for the current node or edge.\n * @param domain - node or edge\n * @param row - the row\n */\n private flushLists(domain: \"node\" | \"edge\", row: number): void {\n const { sink, touched } = this;\n for (const plan of touched) {\n const handle = this.handleOf(plan, domain);\n if (domain === \"node\") {\n sink.setNodeValue(handle, row, plan.items);\n } else {\n sink.setEdgeValue(handle, row, plan.items);\n }\n plan.items = null;\n }\n touched.length = 0;\n }\n\n /** Write the lists collected for the graph table. */\n private flushGraphLists(): void {\n const { sink, graphTouched } = this;\n for (const plan of graphTouched) {\n sink.setGraphValue(plan.name, plan.items, graphDecl(plan));\n plan.items = null;\n }\n graphTouched.length = 0;\n }\n\n /**\n * The JS value of a scalar value token (or list item) under a plan's storage class.\n * @param plan - the plan\n * @param v - the value token\n * @returns the value to push\n */\n private scalarOf(plan: ColumnPlan, v: number): unknown {\n const t = this.requireTokens();\n const kind = t.kind[v];\n switch (plan.kind) {\n case \"int\":\n return Number(t.textOf(v));\n case \"real\":\n return numberOfText(t.textOf(v));\n case \"string\":\n return kind === TOKEN_STRING ? t.stringOf(v) : t.textOf(v);\n default:\n return kind === TOKEN_STRING ? t.stringOf(v) : scalarOrRecord(t, v);\n }\n }\n\n /**\n * The handle of a plan's column, declaring it on first use. A declaration the sink refuses\n * because a column of the name exists with another declaration falls back to that column\n * (reported once); a taken role is dropped (reported once).\n * @param plan - the plan\n * @param domain - node or edge\n * @returns the handle\n */\n private handleOf(plan: ColumnPlan, domain: \"node\" | \"edge\"): ColumnHandle {\n if (plan.declared) {\n return plan.handle;\n }\n plan.declared = true;\n const { sink, report } = this;\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.role === \"position\") {\n decl.components = 3;\n }\n if (plan.role !== null) {\n decl.role = plan.role;\n }\n const resolved = declareResolved(sink, domain, decl, report, { element: plan.name });\n plan.handle = resolved.handle;\n if (resolved.renamed) {\n plan.name = resolved.decl.name;\n }\n return plan.handle;\n }\n\n // ============================================================ bookkeeping\n\n /**\n * Whether a node index was declared by a node block of this import.\n * @param index - the node index\n * @returns true when declared\n */\n private isDeclared(index: number): boolean {\n const word = index >>> 5;\n return word < this.declared.length && ((this.declared[word] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark a node index as declared.\n * @param index - the node index\n */\n private markDeclared(index: number): void {\n const word = index >>> 5;\n if (word >= this.declared.length) {\n const grown = new Uint32Array(Math.max(word + 1, this.declared.length * 2));\n grown.set(this.declared);\n this.declared = grown;\n }\n this.declared[word] |= 1 << (index & 31);\n }\n\n /** Check the abort signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The tokens, which exist after run() lexed the text.\n * @returns the tokens\n */\n private requireTokens(): GmlTokens {\n if (this.tokens === null) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"the GML text was not lexed\", { reason: \"no tokens\" });\n }\n return this.tokens;\n }\n\n /**\n * The direction resolver, which exists once the header was set.\n * @returns the resolver\n */\n private requireResolver(): DirectionResolver {\n if (this.resolver === null) {\n throw new GraphFormatError(\"E_DIRECTED\", \"the header was not set\", { reason: \"no resolver\" });\n }\n return this.resolver;\n }\n}\n\n/**\n * The KIND_* bit of a value token.\n * @param t - the tokens\n * @param v - the value token\n * @returns the bit\n */\nfunction kindBit(t: GmlTokens, v: number): number {\n switch (t.kind[v]) {\n case TOKEN_INT:\n return KIND_INT;\n case TOKEN_STRING:\n return KIND_STRING;\n case TOKEN_OPEN:\n return KIND_RECORD;\n default:\n return KIND_REAL;\n }\n}\n\n/**\n * The storage class of a schema entry: the widest value class seen.\n * @param entry - the entry\n * @returns the class\n */\nfunction kindOf(entry: KeySchema): GmlKind {\n if ((entry.kinds & KIND_RECORD) !== 0) {\n return \"record\";\n }\n if ((entry.kinds & KIND_STRING) !== 0) {\n return \"string\";\n }\n if ((entry.kinds & KIND_REAL) !== 0) {\n return \"real\";\n }\n return \"int\";\n}\n\n/**\n * The scalar dtype of a storage class.\n * @param kind - the class\n * @param entry - the entry (a wide int keeps origin int but stores f64)\n * @returns the dtype\n */\nfunction dtypeOfKind(kind: GmlKind, entry: KeySchema): ScalarDtype {\n switch (kind) {\n case \"int\":\n return entry.wide ? \"f64\" : \"i32\";\n case \"real\":\n return \"f64\";\n case \"string\":\n return \"string\";\n default:\n return \"json\";\n }\n}\n\n/**\n * The origin.type text of a plan: the GML value class of its values (`int` for wide integers\n * stored as f64 too, so the exporter writes them without a decimal point).\n * @param plan - the plan\n * @returns the type text\n */\nfunction originTypeOf(plan: ColumnPlan): string {\n return plan.kind;\n}\n\n/**\n * The declaration patch of a graph column.\n * @param plan - the plan\n * @returns the decl for setGraphValue\n */\nfunction graphDecl(plan: ColumnPlan): ColumnDecl {\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.top) {\n decl.extra = { gmlTopLevel: true };\n }\n return decl;\n}\n\n/**\n * A short description of a value token for messages.\n * @param t - the tokens\n * @param v - the value token\n * @returns the description\n */\nfunction describeValue(t: GmlTokens, v: number): string {\n switch (t.kind[v]) {\n case TOKEN_OPEN:\n return \"a record\";\n case TOKEN_STRING:\n return `the string \"${t.textOf(v)}\"`;\n case TOKEN_REAL:\n return `the real ${t.textOf(v)}`;\n case TOKEN_WORD:\n return `the word ${t.textOf(v)}`;\n default:\n return t.textOf(v);\n }\n}\n\nconst SNIFF_GRAPH_START = /^(?:\\s|#[^\\n]*\\n)*graph\\s*\\[/;\nconst SNIFF_GRAPH_ANYWHERE = /(?:^|\\s)graph\\s*\\[/;\nconst SNIFF_KEY_START = /^(?:\\s|#[^\\n]*\\n)*[A-Za-z_][0-9A-Za-z_]*\\s+(?:\"|[+-]?[0-9.]|\\[)/;\n\n/**\n * Confidence that a head of bytes is GML: a `graph [` opener, or key-value text with a `graph [`\n * somewhere in the head.\n * @param head - the first bytes of the input\n * @returns 0.95 for a leading `graph [`, 0.85 for key-value text containing one, 0.4 for key-value text, 0 otherwise\n */\nfunction sniffGml(head: Uint8Array): number {\n let text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n if (text.charCodeAt(0) === 0xfeff) {\n text = text.slice(1);\n }\n if (SNIFF_GRAPH_START.test(text)) {\n return 0.95;\n }\n if (SNIFF_KEY_START.test(text)) {\n return SNIFF_GRAPH_ANYWHERE.test(text) ? 0.85 : 0.4;\n }\n return 0;\n}\n\n/** The GML importer plugin. */\nexport const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({\n format: \"gml\",\n extensions: Object.freeze([\".gml\"]),\n mimeTypes: Object.freeze([\"text/x-gml\", \"text/plain\"]),\n sniff: sniffGml,\n /**\n * Read a GML text into a sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const tokens = tokenize(await readText(input, report, resolved), report);\n throwIfAborted(resolved.signal);\n const gml = new GmlImport(sink, report, resolved, options);\n gml.run(tokens);\n if (gml.graphCount > 1) {\n report.warning(\n \"unsupported\",\n SECOND_GRAPH_CODE,\n `the input holds ${gml.graphCount - 1} more graph block(s) after the first; import() reads the first, importAll() reads every one`,\n );\n }\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every `graph [ ... ]` block of a GML text, each into its own sink; the top-level keys\n * (Creator, Version, ...) apply to each.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph block\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const first = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const tokens = tokenize(await readText(input, first, resolved), first);\n const reports: ImportReport[] = [];\n let count = 1;\n for (let i = 0; i < count; i++) {\n throwIfAborted(resolved.signal);\n const report = i === 0 ? first : new ImportReportBuilder(\"gml\", resolved.errorLimit);\n const sink = sinkFor(i);\n reportSinkOptions(sink, options, report);\n const gml = new GmlImport(sink, report, resolved, options, i);\n gml.run(tokens);\n count = gml.graphCount;\n reports.push(report.finish());\n }\n throwIfAborted(resolved.signal);\n return reports;\n },\n});\n\n/**\n * Tokenize a GML text; a syntax error is fatal.\n * @param text - the whole text\n * @param report - where the syntax error is recorded\n * @returns the tokens\n */\nfunction tokenize(text: string, report: ImportReportBuilder): GmlTokens {\n try {\n return tokenizeGml(text);\n } catch (err) {\n if (err instanceof GmlSyntaxError) {\n report.fail(err.code, err.message, { line: err.line });\n }\n throw err;\n }\n}\n","/**\n * The `@graphty/graph-io/gml` subpath (design section 8.2): the GML importer and exporter, their\n * option types, and their issue and loss-note codes grouped in two tables.\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n ENCODING_FALLBACK_CODE,\n ID_MERGED_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MIXED_DIRECTION_CODE,\n OPTION_IGNORED_CODE,\n SINK_OPTION_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport {\n GRAPHICS_CONFLICT_CODE,\n GRAPHICS_OVERRIDDEN_CODE,\n INVALID_KEY_CODE,\n JSON_ARRAY_CODE,\n KEY_MANGLED_CODE,\n NESTED_ARRAY_CODE,\n POSITION_COMPONENTS_CODE,\n RECORD_BOOLEAN_CODE,\n RECORD_NULL_CODE,\n RECORD_NUMBER_TYPE_CODE,\n RESERVED_KEY_CODE,\n} from \"./exporter.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ELEMENT_TYPE_CODE,\n FLAG_TYPE_CODE,\n FLAG_VALUE_CODE,\n ID_DROPPED_CODE,\n ID_TYPE_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_LABEL_CODE,\n NO_GRAPH_CODE,\n PRECISION_CODE,\n REPEATED_KEY_CODE,\n ROLE_TAKEN_CODE,\n SECOND_GRAPH_CODE,\n STRING_ID_CODE,\n UNKNOWN_ENTITY_CODE,\n} from \"./importer.js\";\n\nexport { gmlExporter, type GmlExportOptions } from \"./exporter.js\";\nexport { gmlImporter, type GmlImportOptions } from \"./importer.js\";\n\n/**\n * The issue codes the GML importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the GML-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const GML_ISSUE = Object.freeze({\n /** A grammar violation: an untokenisable bare token, an unclosed string or `[`, a stray `]`, a key without a value (fatal). */\n SYNTAX: SYNTAX_CODE,\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 /** No `graph [` block (fatal). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** More than one `graph` block (fatal). */\n MULTIPLE_GRAPHS: SECOND_GRAPH_CODE,\n /** A node without an `id`. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without a `label` under nodeIdFrom \"label\". */\n MISSING_LABEL: MISSING_LABEL_CODE,\n /** An edge without `source` or `target`. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id, source or target that is neither an integer nor a string. */\n ID_TYPE: ID_TYPE_CODE,\n /** String node ids, sources or targets (outside the spec's integers), kept under the ids rule; warned once. */\n STRING_ID: STRING_ID_CODE,\n /** A node id declared twice (later keys overwrite). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A structural key repeated in one element. */\n REPEATED_KEY: REPEATED_KEY_CODE,\n /** A `node` / `edge` key whose value is not a record. */\n ELEMENT_TYPE: ELEMENT_TYPE_CODE,\n /** A `directed` / `multigraph` flag that is not an integer. */\n FLAG_TYPE: FLAG_TYPE_CODE,\n /** A `directed` / `multigraph` flag outside 0 / 1, or repeated. */\n FLAG_VALUE: FLAG_VALUE_CODE,\n /** A named entity in a string that no table decodes; kept as written. */\n UNKNOWN_ENTITY: UNKNOWN_ENTITY_CODE,\n /** An integer beyond 2^53 rounded to f64. */\n PRECISION: PRECISION_CODE,\n /** A column renamed `<name>#<key>` because the sink held the name with another shape. */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column declared without its role because the sink already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A common option the importer has no use for was given. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n /** Under nodeIdFrom \"label\" / \"index\" the integer ids are not kept (a loss note). */\n ID_DROPPED: ID_DROPPED_CODE,\n});\n\n/** The loss-note codes the GML exporter's check() reports beyond the shared LOSS table, by name. */\nexport const GML_LOSS = Object.freeze({\n /** A json column holds numbers; GML records cannot keep int versus real (design section 8.5). */\n RECORD_NUMBER_TYPE: RECORD_NUMBER_TYPE_CODE,\n /** A json column holds booleans, written 1 / 0. */\n RECORD_BOOLEAN: RECORD_BOOLEAN_CODE,\n /** A json column holds nulls, omitted. */\n RECORD_NULL: RECORD_NULL_CODE,\n /** An array inside an array; export() throws. */\n NESTED_ARRAY: NESTED_ARRAY_CODE,\n /** A json row that is an array, written as repeated keys. */\n JSON_ARRAY: JSON_ARRAY_CODE,\n /** A column name or record key outside the GML key grammar. */\n INVALID_KEY: INVALID_KEY_CODE,\n /** A column named like a structural key. */\n RESERVED_KEY: RESERVED_KEY_CODE,\n /** A key rewritten under sanitizeKeys \"mangle\". */\n KEY_MANGLED: KEY_MANGLED_CODE,\n /** A position column with more than three components. */\n POSITION_COMPONENTS: POSITION_COMPONENTS_CODE,\n /** A graphics record whose x / y / z the position column overrides. */\n GRAPHICS_OVERRIDDEN: GRAPHICS_OVERRIDDEN_CODE,\n /** A graphics record that cannot hold the position. */\n GRAPHICS_CONFLICT: GRAPHICS_CONFLICT_CODE,\n});\n"],"names":["SHARED_NO_GRAPH_CODE","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_PRECISION_CODE","SHARED_ROLE_TAKEN_CODE"],"mappings":"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"}
1
+ {"version":3,"file":"gml.js","sources":["../src/formats/gml/syntax.ts","../src/formats/gml/exporter.ts","../src/formats/gml/importer.ts","../src/formats/gml/index.ts"],"sourcesContent":["/**\n * The GML lexical layer shared by the importer and the exporter (research note 07 section 2.2,\n * NetworkX readwrite/gml.py as the reference reader): the token list a whole GML text lexes into,\n * the structural validation that guarantees every later walk sees balanced `key value` pairs, the\n * value grammar (int, real, quoted string with `&#NN;` character references, `[ ... ]` record),\n * the NetworkX list conventions (`_networkx_list_start`, `\"[]\"`) and the key charset.\n *\n * Tokens are kept in typed arrays (kind, start, end, line, matching bracket) rather than objects:\n * the token list is the one intermediate structure of the GML importer, and it costs 17 bytes per\n * token instead of an object per node.\n */\n\nimport { SYNTAX_CODE } from \"../../common/codes.js\";\nimport { decodeGmlString } from \"../../common/escape.js\";\n\n/** A bare word: a key, or `INF` / `NAN` at a value position. */\nexport const TOKEN_WORD = 0;\n/** An integer literal. */\nexport const TOKEN_INT = 1;\n/** A real literal, including the non-finite spellings. */\nexport const TOKEN_REAL = 2;\n/** A double-quoted string; start / end delimit the body between the quotes. */\nexport const TOKEN_STRING = 3;\n/** `[`. */\nexport const TOKEN_OPEN = 4;\n/** `]`. */\nexport const TOKEN_CLOSE = 5;\n\n/** The kind of one token. */\ntype TokenKind = 0 | 1 | 2 | 3 | 4 | 5;\n\n/** The NetworkX marker that starts a one-element list written as repeated keys. */\nexport const LIST_START_MARKER = \"_networkx_list_start\";\n\n/** The string NetworkX writes for an empty list. */\nexport const EMPTY_LIST_TEXT = \"[]\";\n\n/** The string NetworkX writes for an empty tuple, read as an empty list too. */\nexport const EMPTY_TUPLE_TEXT = \"()\";\n\n/** The node key the exporter writes a mangled node's original id into (design section 8.5). */\nexport const ORIGINAL_ID_KEY = \"graphty_originalId\";\n\n/**\n * Issue code of every grammar violation (shared with the other text formats; the message carries\n * the detail): a bare token that is neither a key nor a number, an unclosed string, an unclosed\n * `[`, a `]` with no open `[`, a value without a key or a key without a value.\n */\nexport const SYNTAX_STRUCTURE_CODE = SYNTAX_CODE;\n/** The code of an untokenisable bare token (E_SYNTAX). */\nexport const SYNTAX_TOKEN_CODE = SYNTAX_CODE;\n/** The code of an unclosed string (E_SYNTAX). */\nexport const SYNTAX_STRING_CODE = SYNTAX_CODE;\n/** The code of an unclosed `[` (E_SYNTAX). */\nexport const SYNTAX_BRACKET_CODE = SYNTAX_CODE;\n\nconst KEY_TEXT = /^[A-Za-z_][0-9A-Za-z_]*$/;\nconst STRICT_KEY_TEXT = /^[A-Za-z][0-9A-Za-z_]*$/;\nconst INT_TEXT = /^[+-]?[0-9]+$/;\nconst REAL_TEXT = /^[+-]?(?:(?:[0-9]+\\.[0-9]*|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)$/;\nconst NON_FINITE_TEXT = /^[+-]?(?:inf|infinity|nan)$/i;\nconst NON_FINITE_WORD = /^(?:inf|infinity|nan)$/i;\n\n/**\n * A lexical or structural error of a GML text, with the 1-based line it was found on. The importer\n * turns it into a fatal parse-error issue.\n */\nexport class GmlSyntaxError extends Error {\n /** The issue code. */\n readonly code: string;\n\n /** The 1-based line. */\n readonly line: number;\n\n /**\n * Create a syntax error.\n * @param code - the issue code\n * @param message - a plain-ASCII message\n * @param line - the 1-based line\n */\n constructor(code: string, message: string, line: number) {\n super(message);\n this.name = \"GmlSyntaxError\";\n this.code = code;\n this.line = line;\n }\n}\n\n/**\n * The tokens of one GML text, structurally validated: every `[` has its matching `]` recorded and\n * every key is followed by a value, so walkers need no error paths.\n */\nexport class GmlTokens {\n /** The source text the offsets index into. */\n readonly text: string;\n\n /** The kind of every token. */\n kind: Uint8Array;\n\n /** The start offset of every token (a string's body start). */\n start: Uint32Array;\n\n /** The end offset (exclusive) of every token (a string's body end). */\n end: Uint32Array;\n\n /** The 1-based line of every token. */\n line: Uint32Array;\n\n /** For an open bracket, the index of its matching close bracket; 0 elsewhere. */\n match: Uint32Array;\n\n /** The number of tokens. */\n count = 0;\n\n /** Called by stringOf() with each named entity it cannot decode and the token's line, when set. */\n onUnknownEntity: ((entity: string, line: number) => void) | null = null;\n\n /**\n * Create an empty token list over a text.\n * @param text - the source text\n * @param capacity - the initial capacity\n */\n constructor(text: string, capacity = 1024) {\n this.text = text;\n this.kind = new Uint8Array(capacity);\n this.start = new Uint32Array(capacity);\n this.end = new Uint32Array(capacity);\n this.line = new Uint32Array(capacity);\n this.match = new Uint32Array(0);\n }\n\n /**\n * Append a token.\n * @param kind - the kind\n * @param start - the start offset\n * @param end - the end offset\n * @param line - the 1-based line\n */\n push(kind: TokenKind, start: number, end: number, line: number): void {\n if (this.count === this.kind.length) {\n this.grow();\n }\n const i = this.count++;\n this.kind[i] = kind;\n this.start[i] = start;\n this.end[i] = end;\n this.line[i] = line;\n }\n\n /**\n * The raw text of a token (a string's body without the quotes, entities undecoded).\n * @param i - the token index\n * @returns the text\n */\n textOf(i: number): string {\n return this.text.slice(this.start[i], this.end[i]);\n }\n\n /**\n * The decoded value of a string token.\n * @param i - the token index\n * @returns the body with character references decoded\n */\n stringOf(i: number): string {\n const text = this.textOf(i);\n if (text.indexOf(\"&\") < 0) {\n return text;\n }\n const report = this.onUnknownEntity;\n return decodeGmlString(text, report === null ? undefined : (entity) => { report(entity, this.line[i]); });\n }\n\n /**\n * Whether a token is a `[` or `]`.\n * @param i - the token index\n * @returns true for a bracket\n */\n isBracket(i: number): boolean {\n return this.kind[i] >= TOKEN_OPEN;\n }\n\n /**\n * The index of the pair following the pair whose key is at `key`.\n * @param key - the index of a key token\n * @returns the index after the pair's value (after the matching `]` for a record)\n */\n nextPair(key: number): number {\n const value = key + 1;\n return this.kind[value] === TOKEN_OPEN ? this.match[value] + 1 : value + 1;\n }\n\n /** Double every array. */\n private grow(): void {\n const capacity = this.kind.length * 2;\n const kind = new Uint8Array(capacity);\n kind.set(this.kind);\n this.kind = kind;\n const start = new Uint32Array(capacity);\n start.set(this.start);\n this.start = start;\n const end = new Uint32Array(capacity);\n end.set(this.end);\n this.end = end;\n const line = new Uint32Array(capacity);\n line.set(this.line);\n this.line = line;\n }\n}\n\n/**\n * Lex and structurally validate a whole GML text.\n *\n * Lexical rules (NetworkX): whitespace separates tokens; `#` outside a string starts a comment\n * that runs to the end of the line; a string is delimited by double quotes and must close on its\n * line (there is no escape mechanism; `&#NN;` references are decoded later); `[` and `]` are\n * single-character tokens; every other run of characters is a key (`[A-Za-z_][0-9A-Za-z_]*`),\n * an integer (`[+-]?[0-9]+`), a real (with a decimal point or an exponent, or `INF` / `NAN` in\n * any case with an optional sign) or an error.\n *\n * Structural rules: the text is a sequence of `key value` pairs where a value is a number, a\n * string, `INF` / `NAN`, or a bracketed sequence of pairs; every `[` has a `]`.\n * @param text - the GML text\n * @returns the validated tokens; GmlSyntaxError with the line of the first problem\n */\nexport function tokenizeGml(text: string): GmlTokens {\n const tokens = new GmlTokens(text, Math.max(1024, text.length >>> 3));\n const n = text.length;\n let i = 0;\n let line = 1;\n while (i < n) {\n const c = text.charCodeAt(i);\n if (c === 10) {\n line++;\n i++;\n } else if (c === 13) {\n line++;\n i++;\n if (i < n && text.charCodeAt(i) === 10) {\n i++;\n }\n } else if (c === 32 || c === 9 || c === 11 || c === 12) {\n i++;\n } else if (c === 35) {\n i = endOfLine(text, i);\n } else if (c === 91) {\n tokens.push(TOKEN_OPEN, i, i + 1, line);\n i++;\n } else if (c === 93) {\n tokens.push(TOKEN_CLOSE, i, i + 1, line);\n i++;\n } else if (c === 34) {\n const close = text.indexOf('\"', i + 1);\n const eol = endOfLine(text, i + 1);\n if (close < 0 || close > eol) {\n throw new GmlSyntaxError(SYNTAX_STRING_CODE, `unclosed string at line ${line}`, line);\n }\n tokens.push(TOKEN_STRING, i + 1, close, line);\n i = close + 1;\n } else {\n let j = i + 1;\n while (j < n && !isDelimiter(text.charCodeAt(j))) {\n j++;\n }\n tokens.push(classifyBare(text, i, j, line), i, j, line);\n i = j;\n }\n }\n validateStructure(tokens);\n return tokens;\n}\n\n/**\n * The offset of the line terminator at or after `from`, or the text length.\n * @param text - the text\n * @param from - the offset to search from\n * @returns the offset of the next `\\n` or `\\r`\n */\nfunction endOfLine(text: string, from: number): number {\n const n = text.length;\n for (let i = from; i < n; i++) {\n const c = text.charCodeAt(i);\n if (c === 10 || c === 13) {\n return i;\n }\n }\n return n;\n}\n\n/**\n * Whether a character ends a bare token.\n * @param c - the char code\n * @returns true for whitespace, brackets, a quote or `#`\n */\nfunction isDelimiter(c: number): boolean {\n return (\n c === 32 ||\n c === 9 ||\n c === 10 ||\n c === 13 ||\n c === 11 ||\n c === 12 ||\n c === 91 ||\n c === 93 ||\n c === 34 ||\n c === 35\n );\n}\n\n/**\n * Classify a bare token.\n * @param text - the text\n * @param start - the token start\n * @param end - the token end\n * @param line - the token line, for the error\n * @returns WORD, INT or REAL; GmlSyntaxError for anything else\n */\nfunction classifyBare(text: string, start: number, end: number, line: number): TokenKind {\n const token = text.slice(start, end);\n if (KEY_TEXT.test(token)) {\n return TOKEN_WORD;\n }\n if (INT_TEXT.test(token)) {\n return TOKEN_INT;\n }\n if (REAL_TEXT.test(token) || NON_FINITE_TEXT.test(token)) {\n return TOKEN_REAL;\n }\n const shown = token.length > 20 ? `${token.slice(0, 20)}...` : token;\n throw new GmlSyntaxError(SYNTAX_TOKEN_CODE, `cannot tokenize \"${shown}\" at line ${line}`, line);\n}\n\n/**\n * Check the `key value` structure and record the matching bracket of every `[`.\n * @param tokens - the lexed tokens\n */\nfunction validateStructure(tokens: GmlTokens): void {\n const { count, kind } = tokens;\n const match = new Uint32Array(count);\n const stack: number[] = [];\n let i = 0;\n while (i < count) {\n const k = kind[i];\n if (k === TOKEN_CLOSE) {\n const open = stack.pop();\n if (open === undefined) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `unexpected \"]\" at line ${tokens.line[i]}: no open \"[\"`,\n tokens.line[i],\n );\n }\n match[open] = i;\n i++;\n continue;\n }\n if (k !== TOKEN_WORD) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a key at line ${tokens.line[i]}, found ${describeToken(tokens, i)}`,\n tokens.line[i],\n );\n }\n const value = i + 1;\n if (value >= count) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `key \"${tokens.textOf(i)}\" at line ${tokens.line[i]} has no value`,\n tokens.line[i],\n );\n }\n const vk = kind[value];\n if (vk === TOKEN_OPEN) {\n stack.push(value);\n } else if (vk === TOKEN_CLOSE || (vk === TOKEN_WORD && !NON_FINITE_WORD.test(tokens.textOf(value)))) {\n throw new GmlSyntaxError(\n SYNTAX_STRUCTURE_CODE,\n `expected a value for key \"${tokens.textOf(i)}\" at line ${tokens.line[i]}, found ${describeToken(tokens, value)}`,\n tokens.line[value],\n );\n }\n i = value + 1;\n }\n if (stack.length > 0) {\n const open = stack[stack.length - 1];\n throw new GmlSyntaxError(\n SYNTAX_BRACKET_CODE,\n `unexpected end of input: ${stack.length} bracket(s) still open, the last opened at line ${tokens.line[open]}`,\n tokens.line[open],\n );\n }\n tokens.match = match;\n}\n\n/**\n * A short description of a token for messages.\n * @param tokens - the tokens\n * @param i - the token index\n * @returns the quoted text or the bracket\n */\nfunction describeToken(tokens: GmlTokens, i: number): string {\n switch (tokens.kind[i]) {\n case TOKEN_OPEN:\n return '\"[\"';\n case TOKEN_CLOSE:\n return '\"]\"';\n case TOKEN_STRING:\n return `the string \"${tokens.textOf(i)}\"`;\n default:\n return `\"${tokens.textOf(i)}\"`;\n }\n}\n\n/**\n * The numeric value of an INT or REAL token (or a WORD that is `INF` / `NAN` at a value position).\n * @param text - the token text\n * @returns the number; Infinity / -Infinity / NaN for the non-finite spellings\n */\nexport function numberOfText(text: string): number {\n if (NON_FINITE_TEXT.test(text)) {\n const lower = text.toLowerCase();\n if (lower.endsWith(\"nan\")) {\n return NaN;\n }\n return lower.startsWith(\"-\") ? -Infinity : Infinity;\n }\n return Number(text);\n}\n\n/**\n * Whether a value token is one of the non-finite bare words (`INF`, `NAN`), which lex as words.\n * @param tokens - the tokens\n * @param i - the value token index\n * @returns true when the word is a real\n */\nexport function isNonFiniteWord(tokens: GmlTokens, i: number): boolean {\n return tokens.kind[i] === TOKEN_WORD && NON_FINITE_WORD.test(tokens.textOf(i));\n}\n\n/**\n * Whether a text is a GML key the strict grammar accepts (`[A-Za-z][0-9A-Za-z_]*`, what NetworkX\n * writes and reads).\n * @param text - the candidate key\n * @returns true when it can be written as a key\n */\nexport function isGmlKey(text: string): boolean {\n return STRICT_KEY_TEXT.test(text);\n}\n\n/**\n * Rewrite a text as a GML key: every character outside `[0-9A-Za-z_]` becomes `_` and a leading\n * non-letter is prefixed with `x` (the exporter's `sanitizeKeys: \"mangle\"`).\n * @param text - the text\n * @returns a valid key\n */\nexport function mangleGmlKey(text: string): string {\n const body = text.replace(/[^0-9A-Za-z_]/g, \"_\");\n return /^[A-Za-z]/.test(body) ? body : `x${body}`;\n}\n\n/** One open record while parseRecord() walks the tokens without recursion. */\ninterface RecordFrame {\n readonly record: Record<string, unknown>;\n listKeys: Set<string> | null;\n /** The index of the record's `]`. */\n readonly close: number;\n /** The next key token to read. */\n next: number;\n /** The key the record is stored under in its parent, or null for the root. */\n readonly key: string | null;\n}\n\n/**\n * Parse a bracketed record into a JSON object (design section 8.5: nested GML records map to\n * `json`). Values follow the value grammar; repeated keys become arrays with the NetworkX\n * conventions: the `_networkx_list_start` marker starts a list so a one-element list survives,\n * `\"[]\"` and `\"()\"` are empty lists, and a key seen twice without the marker becomes a\n * two-element array. Nested records are walked with an explicit stack, so the nesting depth is\n * bounded by memory, not by the call stack.\n * @param tokens - the validated tokens\n * @param open - the index of the record's `[`\n * @returns a null-prototype object\n */\nexport function parseRecord(tokens: GmlTokens, open: number): Record<string, unknown> {\n const root = Object.create(null) as Record<string, unknown>;\n const stack: RecordFrame[] = [\n { record: root, listKeys: null, close: tokens.match[open], next: open + 1, key: null },\n ];\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n if (frame.next >= frame.close) {\n stack.pop();\n if (frame.key !== null) {\n storeValue(stack[stack.length - 1], frame.key, frame.record);\n }\n continue;\n }\n const p = frame.next;\n frame.next = tokens.nextPair(p);\n const key = tokens.textOf(p);\n const v = p + 1;\n if (tokens.kind[v] === TOKEN_STRING) {\n const text = tokens.stringOf(v);\n if (text === LIST_START_MARKER) {\n frame.record[key] = [];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n continue;\n }\n storeValue(frame, key, text === EMPTY_LIST_TEXT || text === EMPTY_TUPLE_TEXT ? [] : text);\n } else if (tokens.kind[v] === TOKEN_OPEN) {\n stack.push({\n record: Object.create(null) as Record<string, unknown>,\n listKeys: null,\n close: tokens.match[v],\n next: v + 1,\n key,\n });\n } else {\n storeValue(frame, key, numberOfText(tokens.textOf(v)));\n }\n }\n return root;\n}\n\n/**\n * Store one value under a key: appended to the key's list when the key is a list, paired with the\n * earlier value when the key repeats, set otherwise.\n * @param frame - the open record\n * @param key - the key\n * @param value - the value\n */\nfunction storeValue(frame: RecordFrame, key: string, value: unknown): void {\n const { record } = frame;\n if (frame.listKeys !== null && frame.listKeys.has(key)) {\n (record[key] as unknown[]).push(value);\n } else if (key in record) {\n record[key] = [record[key], value];\n frame.listKeys ??= new Set();\n frame.listKeys.add(key);\n } else {\n record[key] = value;\n }\n}\n\n/**\n * The JSON value of a non-string value token: a number, or a record.\n * @param tokens - the tokens\n * @param v - the value token index (INT, REAL, non-finite WORD or OPEN)\n * @returns the value\n */\nexport function scalarOrRecord(tokens: GmlTokens, v: number): unknown {\n return tokens.kind[v] === TOKEN_OPEN ? parseRecord(tokens, v) : numberOfText(tokens.textOf(v));\n}\n","/**\n * The GML exporter (design section 8.5, research note 07 sections 2.2 and 9): writes a snapshot in\n * the NetworkX dialect of GML. Node ids must be integers (`idCharset: \"integer\"`; `sanitizeIds:\n * \"mangle\"` renumbers the others and keeps the original in a `graphty_originalId` key the importer\n * restores); columns are written per dtype (`int` for the integer dtypes, `real` with a decimal\n * point guaranteed for f32 / f64 so the dtype survives a re-import, quoted strings with `&#NN;`\n * references, repeated keys for lists with the `_networkx_list_start` marker for one-element\n * lists and `\"[]\"` for empty ones, nested records for json objects); the position role becomes\n * `graphics [ x y z ]` merged with the node's `graphics` json record; graph columns are written\n * inside `graph [ ]` (or at the top level when the importer found them there); `Creator` and\n * `Version` come from the metadata.\n *\n * check() reports, before anything is written, the capability gaps of the common check plus the\n * GML-specific ones: json columns holding numbers (JSON cannot keep the int / real distinction:\n * `W_GML_RECORD_NUMBER_TYPE`), booleans (written 1 / 0) or nulls (omitted), arrays nested in\n * arrays (no GML spelling; export() throws), column names and record keys that are not GML keys\n * or collide with the structural keys (`E_GML_INVALID_KEY` / `E_GML_RESERVED_KEY`, or\n * `W_GML_KEY_MANGLED` under `sanitizeKeys: \"mangle\"`), and graphics / position overlaps.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n GraphFormatError,\n type GraphSnapshot,\n type JsonColumn,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { DICT_SAMPLE_ROWS, DictHeuristic } from \"../../common/attributes.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteGmlString } from \"../../common/escape.js\";\nimport {\n capabilities,\n checkCapabilities,\n countMixedEdges,\n LOSS,\n type SanitizedIds,\n sanitizeIds,\n} from \"../../common/export.js\";\nimport { formatGmlReal, formatInteger } from \"../../common/format.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { type ExplicitWeights, 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 { EMPTY_LIST_TEXT, isGmlKey, LIST_START_MARKER, mangleGmlKey, ORIGINAL_ID_KEY } from \"./syntax.js\";\n\n/** The format-specific options of the GML exporter. */\nexport interface GmlExportOptions {\n /**\n * The edge key explicit weights are written under; by default the key the GML importer read\n * them from (`meta.weightOrigin.id` when the snapshot came from GML), else `value`.\n */\n weightKey?: string | undefined;\n /**\n * \"error\" (default): a column name or record key that is not a GML key (`[A-Za-z][0-9A-Za-z_]*`)\n * or collides with a structural key makes export() throw; \"mangle\": such keys are rewritten\n * (`.` and other characters become `_`, collisions get a `_2` suffix) and check() reports them.\n */\n sanitizeKeys?: \"error\" | \"mangle\" | undefined;\n}\n\n/** Loss code: a json column holds numbers; JSON cannot keep GML's int / real distinction (design section 8.5). */\nexport const RECORD_NUMBER_TYPE_CODE = \"W_GML_RECORD_NUMBER_TYPE\";\n/** Loss code: a json column holds booleans, written as 1 / 0. */\nexport const RECORD_BOOLEAN_CODE = \"W_GML_RECORD_BOOLEAN\";\n/** Loss code: a json column holds nulls, which GML cannot write; the key (or the row) is omitted. */\nexport const RECORD_NULL_CODE = \"W_GML_RECORD_NULL\";\n/** Loss code: a json column holds an array inside an array, which GML cannot write; export() throws. */\nexport const NESTED_ARRAY_CODE = \"E_GML_NESTED_ARRAY\";\n/** Loss code: a json column holds arrays as row values; written as repeated keys, they re-import as a list column. */\nexport const JSON_ARRAY_CODE = \"W_GML_JSON_ARRAY\";\n/** Loss code: a column name or record key is not a GML key; export() throws unless sanitizeKeys is \"mangle\". */\nexport const INVALID_KEY_CODE = \"E_GML_INVALID_KEY\";\n/** Loss code: a column name collides with a structural GML key; export() throws unless sanitizeKeys is \"mangle\". */\nexport const RESERVED_KEY_CODE = \"E_GML_RESERVED_KEY\";\n/** Loss code: keys rewritten under sanitizeKeys \"mangle\". */\nexport const KEY_MANGLED_CODE = \"W_GML_KEY_MANGLED\";\n/** Loss code: a position column with more than three components; x, y and z are written. */\nexport const POSITION_COMPONENTS_CODE = \"W_GML_POSITION_COMPONENTS\";\n/** Loss code: a node's graphics record has x / y / z keys the position column replaces. */\nexport const GRAPHICS_OVERRIDDEN_CODE = \"W_GML_GRAPHICS_OVERRIDDEN\";\n/** Loss code: a node's graphics value is not a record and cannot hold the position; export() throws. */\nexport const GRAPHICS_CONFLICT_CODE = \"E_GML_GRAPHICS_CONFLICT\";\n\n/** The default weight key (design section 8.4: GML weights are read from `value` by default). */\nexport const DEFAULT_WEIGHT_KEY = \"value\";\n\n/** The roles GML has a key for (`label`, the edge `id` and `key`); every other role is reported. */\nconst KEPT_ROLES: ReadonlySet<string> = new Set([\"label\", \"id\", \"key\"]);\n\n/** The key the importer maps each kept role back from (the column name after re-import). */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"label\",\n id: \"id\",\n key: \"key\",\n});\n\nconst GML_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"optional\",\n idCharset: \"integer\",\n dtypes: [\"i32\", \"f64\", \"string\", \"dict\", \"json\"],\n components: false,\n lists: true,\n json: true,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** Roles whose columns are never written as attributes (structural, or dropped per the capabilities). */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\nconst NODE_RESERVED: ReadonlySet<string> = new Set([\"id\"]);\nconst EDGE_RESERVED: ReadonlySet<string> = new Set([\"source\", \"target\", \"directed\"]);\nconst GRAPH_RESERVED: ReadonlySet<string> = new Set([\"node\", \"edge\", \"directed\", \"multigraph\"]);\nconst TOP_RESERVED: ReadonlySet<string> = new Set([\"graph\"]);\nconst NUMBER_TEXT = /^[+-]?(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;\n\n/** The resolved options of one export. */\ninterface GmlExportPlan {\n readonly common: ResolvedExportOptions;\n readonly weightKey: string;\n readonly mangle: boolean;\n}\n\n/** What one json column holds that GML cannot write exactly. */\ninterface JsonStats {\n numbers: number;\n booleans: number;\n nulls: number;\n nestedArrays: number;\n arrays: number;\n invalidKeys: number;\n}\n\n/** The kinds of value already counted for one row while inspecting a json value. */\ninterface SeenFlags {\n numbers: boolean;\n booleans: boolean;\n nulls: boolean;\n nested: boolean;\n}\n\n/** The columns of one table selected for writing, with their keys. */\ninterface WrittenColumn {\n readonly column: Column;\n readonly key: string;\n}\n\n/**\n * Resolve the options of one export call.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction planOf(snapshot: GraphSnapshot, options: (GmlExportOptions & CommonExportOptions) | undefined): GmlExportPlan {\n const common = resolveExportOptions(options);\n const mode = options?.sanitizeKeys ?? \"error\";\n if (mode !== \"error\" && mode !== \"mangle\") {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option sanitizeKeys: ${JSON.stringify(mode)} is not \"error\" or \"mangle\"`,\n {\n option: \"sanitizeKeys\",\n found: mode,\n },\n );\n }\n let weightKey = options?.weightKey;\n if (weightKey === undefined) {\n const origin = snapshot.meta.weightOrigin;\n weightKey = origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : DEFAULT_WEIGHT_KEY;\n } else if (typeof weightKey !== \"string\" || !isGmlKey(weightKey)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option weightKey: ${JSON.stringify(weightKey)} is not a GML key`, {\n option: \"weightKey\",\n found: weightKey,\n });\n }\n return { common, weightKey, mangle: mode === \"mangle\" };\n}\n\n/**\n * Whether a column is written as an attribute (its role is neither structural nor dropped).\n * @param column - the column\n * @returns true when written\n */\nfunction isWritten(column: Column): boolean {\n const { role } = column.meta;\n return role === null || !SKIPPED_ROLES.has(role);\n}\n\n/**\n * The key a column is written under.\n * @param meta - the column metadata\n * @returns origin.id when the column came from GML (the key it was read from), else the name\n */\nfunction preferredKey(meta: ColumnMeta): string {\n const { origin } = meta;\n return origin !== null && origin.format === \"gml\" && origin.id !== null ? origin.id : meta.name;\n}\n\n/**\n * Whether a snapshot has explicit weights to write.\n * @param snapshot - the snapshot\n * @returns true when weighted\n */\nfunction hasWeights(snapshot: GraphSnapshot): boolean {\n return snapshot.flags.weighted;\n}\n\n/**\n * Whether the graph column is a top-level key (the importer's `extra.gmlTopLevel`).\n * @param column - the column\n * @returns true for a top-level key\n */\nfunction isTopLevel(column: Column): boolean {\n return column.meta.extra.gmlTopLevel === true;\n}\n\n/**\n * The text of a `Version` value: bare when it is a number text, quoted otherwise.\n * @param text - the version text\n * @returns the GML value\n */\nfunction versionText(text: string): string {\n return NUMBER_TEXT.test(text) ? text : quoteGmlString(text);\n}\n\n/**\n * Select the written columns of a table and assign their keys, recording invalid and reserved\n * keys as notes (or rewriting them under mangle).\n * @param table - the columns\n * @param reserved - the structural keys of the table\n * @param label - the table name for messages\n * @param plan - the export plan\n * @param notes - where to record\n * @param filter - an extra selection predicate\n * @returns the written columns with their keys\n */\nfunction selectColumns(\n table: Iterable<Column>,\n reserved: ReadonlySet<string>,\n label: string,\n plan: GmlExportPlan,\n notes: LossNote[] | null,\n filter: (column: Column) => boolean = (): boolean => true,\n): WrittenColumn[] {\n const used = new Set<string>(reserved);\n const out: WrittenColumn[] = [];\n for (const column of table) {\n if (!isWritten(column) || !filter(column)) {\n continue;\n }\n const preferred = preferredKey(column.meta);\n let key = preferred;\n const valid = isGmlKey(preferred);\n const taken = used.has(preferred);\n if (!valid || taken) {\n const code = valid ? RESERVED_KEY_CODE : INVALID_KEY_CODE;\n let why = \"is not a GML key\";\n if (valid) {\n why = reserved.has(preferred) ? \"collides with a structural GML key\" : \"repeats another column's key\";\n }\n if (!plan.mangle) {\n if (notes === null) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `${label} column \"${column.meta.name}\" ${why}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column: column.meta.name,\n key: preferred,\n },\n );\n }\n notes.push(\n note(\n code,\n `${label} column \"${column.meta.name}\" ${why}; export() will throw unless sanitizeKeys is \"mangle\"`,\n column.meta.name,\n ),\n );\n continue;\n }\n key = uniqueKey(valid ? preferred : mangleGmlKey(preferred), used);\n notes?.push(\n note(\n KEY_MANGLED_CODE,\n `${label} column \"${column.meta.name}\" is written as \"${key}\"`,\n column.meta.name,\n ),\n );\n }\n used.add(key);\n out.push({ column, key });\n }\n return out;\n}\n\n/**\n * A key not yet used: the base, else base_2, base_3...\n * @param base - a valid key\n * @param used - the keys taken\n * @returns a free key\n */\nfunction uniqueKey(base: string, used: ReadonlySet<string>): string {\n let candidate = base;\n for (let k = 2; used.has(candidate); k++) {\n candidate = `${base}_${k}`;\n }\n return candidate;\n}\n\n/**\n * Build a frozen note.\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 * Inspect a JSON value for what GML cannot write exactly.\n * @param value - the value\n * @param stats - the counters to update (each counted at most once per call for numbers / booleans / nulls)\n * @param inArray - whether the value is an array item\n * @param seen - the flags already counted for this row\n */\nfunction inspectJson(value: unknown, stats: JsonStats, inArray: boolean, seen: SeenFlags): void {\n if (value === null) {\n if (!seen.nulls) {\n seen.nulls = true;\n stats.nulls++;\n }\n return;\n }\n switch (typeof value) {\n case \"number\":\n if (!seen.numbers) {\n seen.numbers = true;\n stats.numbers++;\n }\n return;\n case \"boolean\":\n if (!seen.booleans) {\n seen.booleans = true;\n stats.booleans++;\n }\n return;\n case \"string\":\n return;\n default:\n break;\n }\n if (Array.isArray(value)) {\n if (inArray && !seen.nested) {\n seen.nested = true;\n stats.nestedArrays++;\n }\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n return;\n }\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!isGmlKey(key)) {\n stats.invalidKeys++;\n }\n inspectJson(record[key], stats, false, seen);\n }\n}\n\n/**\n * The GML-specific notes of one table's json columns.\n * @param columns - the written columns\n * @param label - the table name\n * @param plan - the export plan\n * @param notes - where to record\n */\nfunction jsonNotes(columns: readonly WrittenColumn[], label: string, plan: GmlExportPlan, notes: LossNote[]): void {\n for (const { column } of columns) {\n const stats = jsonStatsOf(column);\n if (stats === null) {\n continue;\n }\n const { name } = column.meta;\n const where = `${label} column \"${name}\"`;\n if (stats.numbers > 0) {\n notes.push(\n note(\n RECORD_NUMBER_TYPE_CODE,\n `${where} holds numbers in ${stats.numbers} row(s); GML records cannot keep the int / real distinction`,\n name,\n stats.numbers,\n ),\n );\n }\n if (stats.booleans > 0) {\n notes.push(\n note(\n RECORD_BOOLEAN_CODE,\n `${where} holds booleans in ${stats.booleans} row(s); written as 1 / 0`,\n name,\n stats.booleans,\n ),\n );\n }\n if (stats.nulls > 0) {\n notes.push(\n note(\n RECORD_NULL_CODE,\n `${where} holds nulls in ${stats.nulls} row(s); GML has no null, the key is omitted`,\n name,\n stats.nulls,\n ),\n );\n }\n if (stats.arrays > 0) {\n notes.push(\n note(\n JSON_ARRAY_CODE,\n `${where} holds arrays as values in ${stats.arrays} row(s); written as repeated keys, they re-import as a list`,\n name,\n stats.arrays,\n ),\n );\n }\n if (stats.nestedArrays > 0) {\n notes.push(\n note(\n NESTED_ARRAY_CODE,\n `${where} holds arrays nested in arrays in ${stats.nestedArrays} row(s); GML cannot write them and export() will throw`,\n name,\n stats.nestedArrays,\n ),\n );\n }\n if (stats.invalidKeys > 0) {\n notes.push(\n plan.mangle\n ? note(\n KEY_MANGLED_CODE,\n `${where}: ${stats.invalidKeys} record key(s) are not GML keys and are rewritten`,\n name,\n stats.invalidKeys,\n )\n : note(\n INVALID_KEY_CODE,\n `${where}: ${stats.invalidKeys} record key(s) are not GML keys; export() will throw unless sanitizeKeys is \"mangle\"`,\n name,\n stats.invalidKeys,\n ),\n );\n }\n }\n}\n\n/**\n * The json statistics of a json column, or of a list column with json items; null for other dtypes.\n * @param column - the column\n * @returns the stats, or null\n */\nfunction jsonStatsOf(column: Column): JsonStats | null {\n const stats: JsonStats = { numbers: 0, booleans: 0, nulls: 0, nestedArrays: 0, arrays: 0, invalidKeys: 0 };\n if (column.dtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const value = column.values[r];\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n if (Array.isArray(value)) {\n stats.arrays++;\n for (const item of value) {\n inspectJson(item, stats, true, seen);\n }\n } else {\n inspectJson(value, stats, false, seen);\n }\n }\n return stats;\n }\n if (column.dtype === \"list\" && column.meta.itemDtype === \"json\") {\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n const seen: SeenFlags = { numbers: false, booleans: false, nulls: false, nested: false };\n for (const item of column.sliceOf(r)) {\n inspectJson(item, stats, true, seen);\n }\n }\n return stats;\n }\n return null;\n}\n\n/**\n * The node position column when it can be mapped to graphics x / y / z: a numeric scalar column\n * with the position role.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction positionColumn(snapshot: GraphSnapshot): Column | null {\n const column = snapshot.nodes.byRole(\"position\");\n if (column === null) {\n return null;\n }\n switch (column.dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return column;\n default:\n return null;\n }\n}\n\n/**\n * The node `graphics` json column, when present.\n * @param snapshot - the snapshot\n * @returns the column, or null\n */\nfunction graphicsColumn(snapshot: GraphSnapshot): JsonColumn | null {\n return snapshot.nodes.typed(\"graphics\", \"json\");\n}\n\n/**\n * The GML-specific notes about the position / graphics mapping.\n * @param snapshot - the snapshot\n * @param notes - where to record\n */\nfunction graphicsNotes(snapshot: GraphSnapshot, notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n if (position.meta.components > 3) {\n notes.push(\n note(\n POSITION_COMPONENTS_CODE,\n `node column \"${position.meta.name}\" has ${position.meta.components} components; only x, y and z are written`,\n position.meta.name,\n position.length - position.nullCount,\n ),\n );\n }\n const graphics = graphicsColumn(snapshot);\n if (graphics === null) {\n return;\n }\n let overridden = 0;\n let conflicts = 0;\n for (let r = 0; r < snapshot.nodeCount; r++) {\n if (!position.isSet(r) || !graphics.isSet(r)) {\n continue;\n }\n const value = graphics.values[r];\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n conflicts++;\n } else if (\"x\" in value || \"y\" in value || \"z\" in value) {\n overridden++;\n }\n }\n if (overridden > 0) {\n notes.push(\n note(\n GRAPHICS_OVERRIDDEN_CODE,\n `${overridden} node graphics record(s) have x / y / z keys the position column replaces`,\n \"graphics\",\n overridden,\n ),\n );\n }\n if (conflicts > 0) {\n notes.push(\n note(\n GRAPHICS_CONFLICT_CODE,\n `${conflicts} node graphics value(s) are not records and cannot hold the position; export() will throw`,\n \"graphics\",\n conflicts,\n ),\n );\n }\n}\n\n/**\n * What the importer's own rules change on re-import of the written columns: an all-unset column\n * vanishes (GML writes cells, never declarations), a role-less column named like a role key\n * gains the role, and the dictionary heuristic of design section 5.4 turns a low-cardinality\n * string column into a dict (or a wide dict into a string).\n * @param columns - the written columns\n * @param domain - node or edge\n * @param notes - where to record\n */\nfunction reimportNotes(columns: readonly WrittenColumn[], domain: \"node\" | \"edge\", notes: LossNote[]): void {\n for (const { column, key } of columns) {\n const { meta } = column;\n const set = column.length - column.nullCount;\n if (set === 0) {\n notes.push(\n note(\n LOSS.EMPTY_COLUMN,\n `${domain} column \"${meta.name}\" has no set cell and is not written: GML writes cells, never declarations`,\n meta.name,\n 0,\n ),\n );\n continue;\n }\n if (meta.role === null && (key === \"label\" || (domain === \"edge\" && (key === \"id\" || key === \"key\")))) {\n notes.push(\n note(\n LOSS.ROLE_ASSUMED,\n `${domain} column \"${meta.name}\" is written under \"${key}\" and reads back with the ${key === \"label\" ? \"label\" : key} role`,\n meta.name,\n set,\n ),\n );\n continue;\n }\n if (column.dtype === \"list\" || !(column.dtype === \"string\" || column.dtype === \"dict\")) {\n continue;\n }\n const heuristic = new DictHeuristic(DICT_SAMPLE_ROWS);\n for (let r = 0; r < column.length && !heuristic.decided; r++) {\n if (column.isSet(r)) {\n heuristic.observe(column.value(r) as string);\n }\n }\n const readsAsDict = heuristic.decide() === \"dict\";\n if (column.dtype === \"string\" && readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as dict (low cardinality)`,\n meta.name,\n null,\n ),\n );\n } else if (column.dtype === \"dict\" && !readsAsDict) {\n notes.push(\n note(\n LOSS.STORAGE_CLASS,\n `${domain} column \"${meta.name}\" reads back as string (cardinality too high for a dict)`,\n meta.name,\n null,\n ),\n );\n }\n }\n}\n\n/**\n * The importer names the graphics-derived position column `position`, or `position#graphics`\n * when a plain `position` key is written next to it (design section 5.6); a position column\n * named otherwise reads back under that name.\n * @param snapshot - the snapshot\n * @param nodeColumns - the written node columns\n * @param notes - where to record\n */\nfunction positionNameNote(snapshot: GraphSnapshot, nodeColumns: readonly WrittenColumn[], notes: LossNote[]): void {\n const position = positionColumn(snapshot);\n if (position === null) {\n return;\n }\n const { name } = position.meta;\n const plainPosition = nodeColumns.some((c) => c.key === \"position\");\n const reimportName = plainPosition ? \"position#graphics\" : \"position\";\n if (name !== reimportName) {\n notes.push(\n note(\n LOSS.COLUMN_NAME_CHANGED,\n `node column \"${name}\" (position) is written as the graphics x / y / z keys and reads back as \"${reimportName}\"`,\n name,\n position.length - position.nullCount,\n ),\n );\n }\n}\n\n/**\n * Pre-flight: the common capability notes plus the GML-specific ones.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the notes, empty when the export is exact\n */\nfunction check(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): readonly LossNote[] {\n const plan = planOf(snapshot, options);\n const notes = checkCapabilities(snapshot, GML_CAPABILITIES, plan.common, {\n positionDtype: \"f64\",\n roles: KEPT_ROLES,\n roleNames: ROLE_NAMES,\n });\n const nodeReserved = new Set(NODE_RESERVED);\n if (\n (plan.common.sanitizeIds === \"mangle\" && countMangled(snapshot) > 0) ||\n snapshot.nodes.byRole(\"originalId\") !== null\n ) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n const nodeColumns = selectColumns(snapshot.nodes, nodeReserved, \"node\", plan, notes);\n const edgeColumns = selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, notes, (c) => c !== edgeIds);\n const graphColumns = selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, notes, (c) => !isTopLevel(c));\n const topColumns = selectColumns(snapshot.graph, topReserved, \"top-level\", plan, notes, isTopLevel);\n jsonNotes(nodeColumns, \"node\", plan, notes);\n jsonNotes(edgeColumns, \"edge\", plan, notes);\n jsonNotes(graphColumns, \"graph\", plan, notes);\n jsonNotes(topColumns, \"top-level\", plan, notes);\n graphicsNotes(snapshot, notes);\n positionNameNote(snapshot, nodeColumns, notes);\n reimportNotes(nodeColumns, \"node\", notes);\n reimportNotes(edgeColumns, \"edge\", notes);\n if (!hasWeights(snapshot)) {\n const clash = edgeColumns.find((c) => c.key === plan.weightKey);\n if (clash !== undefined) {\n notes.push(\n note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${clash.column.meta.name}\" is written under \"${plan.weightKey}\", the key the importer reads THE weight from; it reads back as the weight, not as a column`,\n clash.column.meta.name,\n clash.column.length - clash.column.nullCount,\n ),\n );\n }\n }\n const folding = pairFolding(snapshot);\n if (folding.mutualCount > 0) {\n notes.push(\n note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair(s) are written as two directed edges; the mutual mark is lost`,\n null,\n folding.mutualCount,\n ),\n );\n }\n return Object.freeze(notes);\n}\n\n/**\n * The structural keys of the edge table: source, target, the weight key when weights are written,\n * and `id` when a role-id column is written as the edge id.\n * @param snapshot - the snapshot\n * @param plan - the export plan\n * @param edgeIds - the role-id edge column, or null\n * @returns the reserved keys\n */\nfunction edgeReservedKeys(snapshot: GraphSnapshot, plan: GmlExportPlan, edgeIds: Column | null): Set<string> {\n const reserved = new Set(EDGE_RESERVED);\n if (hasWeights(snapshot)) {\n reserved.add(plan.weightKey);\n }\n if (edgeIds !== null) {\n reserved.add(\"id\");\n }\n return reserved;\n}\n\n/**\n * The structural keys of the top level: graph, plus Creator and Version when the metadata writes them.\n * @param snapshot - the snapshot\n * @returns the reserved keys\n */\nfunction topReservedKeys(snapshot: GraphSnapshot): Set<string> {\n const reserved = new Set(TOP_RESERVED);\n if (snapshot.meta.creator !== null) {\n reserved.add(\"Creator\");\n }\n if (snapshot.meta.sourceFormat === \"gml\" && snapshot.meta.sourceVersion !== null) {\n reserved.add(\"Version\");\n }\n return reserved;\n}\n\n/**\n * How many node ids are not safe integers (what sanitizeIds \"mangle\" rewrites).\n * @param snapshot - the snapshot\n * @returns the count\n */\nfunction countMangled(snapshot: GraphSnapshot): number {\n let count = 0;\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const id = snapshot.ids.idOf(i);\n if (typeof id !== \"number\" || !Number.isSafeInteger(id)) {\n count++;\n }\n }\n return count;\n}\n\n// ============================================================ writing\n\n/**\n * The GML text of a number by the dtype and origin of its column: an integer text for the integer\n * dtypes and for an f64 column that came from GML `int` values, a real text otherwise.\n * @param value - the value\n * @param meta - the column metadata\n * @returns the text\n */\nfunction numberText(value: number, meta: ColumnMeta): string {\n switch (meta.dtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(value);\n case \"f32\":\n return formatGmlReal(value, \"f32\");\n default:\n if (meta.origin?.type === \"int\" && Number.isInteger(value)) {\n return formatInteger(value);\n }\n return formatGmlReal(value, \"f64\");\n }\n}\n\n/**\n * The GML text of a JSON scalar inside a record: integers as int, other numbers as real, strings\n * quoted, booleans as 1 / 0.\n * @param value - the scalar\n * @returns the text\n */\nfunction jsonScalarText(value: number | string | boolean): string {\n switch (typeof value) {\n case \"number\":\n return Number.isInteger(value) ? formatInteger(value) : formatGmlReal(value, \"f64\");\n case \"boolean\":\n return value ? \"1\" : \"0\";\n default:\n return quoteGmlString(value);\n }\n}\n\n/**\n * The GML text of a list item or components lane by the item dtype.\n * @param item - the item\n * @param itemDtype - the list's item dtype\n * @param meta - the list column metadata\n * @returns the text\n */\nfunction itemText(item: unknown, itemDtype: string, meta: ColumnMeta): string {\n switch (typeof item) {\n case \"number\":\n switch (itemDtype) {\n case \"i32\":\n case \"u32\":\n case \"u8\":\n return formatInteger(item);\n case \"f32\":\n return formatGmlReal(item, \"f32\");\n case \"json\":\n return jsonScalarText(item);\n default:\n return meta.origin?.type === \"int\" && Number.isInteger(item)\n ? formatInteger(item)\n : formatGmlReal(item, \"f64\");\n }\n case \"boolean\":\n return item ? \"1\" : \"0\";\n case \"string\":\n return quoteGmlString(item);\n default:\n throw new GraphFormatError(\n \"E_COLUMN_TYPE\",\n `column \"${meta.name}\": a ${typeof item} list item cannot be written as GML`,\n {\n column: meta.name,\n found: typeof item,\n },\n );\n }\n}\n\n/** Writes lines with indentation into an array of parts. */\nclass GmlWriter {\n private readonly lines: string[] = [];\n\n private readonly mangle: boolean;\n\n /**\n * Create a writer.\n * @param mangle - whether record keys are rewritten rather than refused\n */\n constructor(mangle: boolean) {\n this.mangle = mangle;\n }\n\n /**\n * Take the lines written so far as one string.\n * @returns the text; the writer is empty afterwards\n */\n take(): string {\n const text = this.lines.join(\"\");\n this.lines.length = 0;\n return text;\n }\n\n /**\n * Write one `key value` line.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value text\n */\n line(indent: string, key: string, value: string): void {\n this.lines.push(`${indent}${key} ${value}\\n`);\n }\n\n /**\n * Write a raw line.\n * @param text - the line without its terminator\n */\n raw(text: string): void {\n this.lines.push(`${text}\\n`);\n }\n\n /**\n * Write one column cell of a row.\n * @param indent - the indentation\n * @param key - the key\n * @param column - the column\n * @param row - the row\n */\n cell(indent: string, key: string, column: Column, row: number): void {\n const { meta, dtype } = column;\n switch (dtype) {\n case \"f32\":\n case \"f64\":\n case \"i32\":\n case \"u32\":\n case \"u8\": {\n const { components } = meta;\n if (components === 1) {\n this.line(indent, key, numberText(column.data[row], meta));\n } else {\n for (let k = 0; k < components; k++) {\n this.line(indent, key, numberText(column.data[row * components + k], meta));\n }\n }\n return;\n }\n case \"bool\":\n this.line(indent, key, column.value(row) === true ? \"1\" : \"0\");\n return;\n case \"dict\":\n case \"string\":\n this.line(indent, key, quoteGmlString(column.value(row) ?? \"\"));\n return;\n case \"list\":\n this.list(indent, key, column.sliceOf(row), meta.itemDtype ?? \"string\", meta);\n return;\n case \"json\":\n this.json(indent, key, column.values[row], meta.name);\n return;\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n }\n\n /**\n * Write a list as repeated keys with the NetworkX conventions.\n * @param indent - the indentation\n * @param key - the key\n * @param items - the items\n * @param itemDtype - the item dtype\n * @param meta - the column metadata\n */\n private list(indent: string, key: string, items: readonly unknown[], itemDtype: string, meta: ColumnMeta): void {\n if (items.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (items.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of items) {\n if (itemDtype === \"json\" && typeof item === \"object\") {\n this.json(indent, key, item, meta.name, true);\n } else {\n this.line(indent, key, itemText(item, itemDtype, meta));\n }\n }\n }\n\n /**\n * Write a JSON value: a record for an object, repeated keys for an array, a scalar otherwise;\n * null writes nothing.\n * @param indent - the indentation\n * @param key - the key\n * @param value - the value\n * @param column - the column name, for errors\n * @param inArray - whether the value is an array item (an array here has no GML spelling)\n */\n private json(indent: string, key: string, value: unknown, column: string, inArray = false): void {\n if (value === null || value === undefined) {\n return;\n }\n if (Array.isArray(value)) {\n if (inArray) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": an array nested in an array cannot be written as GML`,\n {\n reason: \"nested array\",\n column,\n },\n );\n }\n if (value.length === 0) {\n this.line(indent, key, quoteGmlString(EMPTY_LIST_TEXT));\n return;\n }\n if (value.length === 1) {\n this.line(indent, key, quoteGmlString(LIST_START_MARKER));\n }\n for (const item of value) {\n this.json(indent, key, item, column, true);\n }\n return;\n }\n if (typeof value === \"object\") {\n this.record(indent, key, value as Record<string, unknown>, column);\n return;\n }\n if (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\") {\n this.line(indent, key, jsonScalarText(value));\n return;\n }\n throw new GraphFormatError(\"E_COLUMN_TYPE\", `column \"${column}\": a ${typeof value} cannot be written as GML`, {\n column,\n found: typeof value,\n });\n }\n\n /**\n * Write a record `key [ ... ]`.\n * @param indent - the indentation\n * @param key - the key\n * @param record - the object\n * @param column - the column name, for errors\n * @param extra - lines to write first (the position of a graphics record), or null\n */\n record(\n indent: string,\n key: string,\n record: Record<string, unknown>,\n column: string,\n extra: readonly [string, string][] | null = null,\n ): void {\n this.raw(`${indent}${key} [`);\n const inner = `${indent} `;\n const used = new Set<string>();\n if (extra !== null) {\n for (const [k, v] of extra) {\n this.line(inner, k, v);\n used.add(k);\n }\n }\n for (const name of Object.keys(record)) {\n if (used.has(name) && extra !== null && (name === \"x\" || name === \"y\" || name === \"z\")) {\n continue;\n }\n const written = this.recordKey(name, used, column);\n used.add(written);\n this.json(inner, written, record[name], column);\n }\n this.raw(`${indent}]`);\n }\n\n /**\n * The key a record field is written under.\n * @param name - the field name\n * @param used - the keys already written in the record\n * @param column - the column name, for errors\n * @returns a valid, unused key; E_UNSUPPORTED for an invalid key unless mangling\n */\n private recordKey(name: string, used: ReadonlySet<string>, column: string): string {\n if (isGmlKey(name) && !used.has(name)) {\n return name;\n }\n if (!this.mangle) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `column \"${column}\": record key \"${name}\" ${isGmlKey(name) ? \"repeats a key\" : \"is not a GML key\"}; pass sanitizeKeys: \"mangle\" to rewrite it`,\n {\n reason: \"gml key\",\n column,\n key: name,\n },\n );\n }\n return uniqueKey(isGmlKey(name) ? name : mangleGmlKey(name), used);\n }\n}\n\n/** Everything the writer needs, resolved once before the first line. */\ninterface WriteContext {\n readonly snapshot: GraphSnapshot;\n readonly plan: GmlExportPlan;\n readonly ids: SanitizedIds;\n readonly writeDirected: boolean;\n readonly foldPairs: boolean;\n readonly nodeColumns: readonly WrittenColumn[];\n readonly edgeColumns: readonly WrittenColumn[];\n readonly graphColumns: readonly WrittenColumn[];\n readonly topColumns: readonly WrittenColumn[];\n readonly position: Column | null;\n readonly graphics: JsonColumn | null;\n readonly originalIds: Column | null;\n readonly edgeIds: Column | null;\n readonly weights: ExplicitWeights;\n readonly folding: PairFolding;\n}\n\n/**\n * Resolve everything export() needs, throwing for what check() reported as an error.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the context\n */\nfunction contextOf(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): WriteContext {\n const plan = planOf(snapshot, options);\n const ids = sanitizeIds(snapshot, \"integer\", plan.common.sanitizeIds);\n const mixed = countMixedEdges(snapshot);\n if (mixed > 0 && plan.common.onMixedDirection === \"error\") {\n throw new GraphFormatError(\n \"E_DIRECTED\",\n `${mixed} undirected edge(s) in a directed graph; GML has no mixed direction (onMixedDirection: \"error\")`,\n {\n reason: \"mixed direction\",\n count: mixed,\n },\n );\n }\n // design 8.5: exporters fold expanded pairs back; under \"directed\" the folded edge is written\n // once, as one directed edge, under \"undirected\" the whole graph is written undirected\n const foldPairs = mixed > 0;\n const writeDirected = snapshot.directed && plan.common.onMixedDirection !== \"undirected\";\n const originalIds = snapshot.nodes.byRole(\"originalId\");\n const nodeReserved = new Set(NODE_RESERVED);\n if (ids.changed > 0 || originalIds !== null) {\n nodeReserved.add(ORIGINAL_ID_KEY);\n }\n const edgeIds = snapshot.edges.byRole(\"id\");\n const edgeReserved = edgeReservedKeys(snapshot, plan, edgeIds);\n const topReserved = topReservedKeys(snapshot);\n return {\n snapshot,\n plan,\n ids,\n writeDirected,\n foldPairs,\n nodeColumns: selectColumns(\n snapshot.nodes,\n nodeReserved,\n \"node\",\n plan,\n null,\n (c) => !(c.meta.name === \"graphics\" && c.dtype === \"json\"),\n ),\n edgeColumns: selectColumns(snapshot.edges, edgeReserved, \"edge\", plan, null, (c) => c !== edgeIds),\n graphColumns: selectColumns(snapshot.graph, GRAPH_RESERVED, \"graph\", plan, null, (c) => !isTopLevel(c)),\n topColumns: selectColumns(snapshot.graph, topReserved, \"top-level\", plan, null, isTopLevel),\n position: positionColumn(snapshot),\n graphics: graphicsColumn(snapshot),\n originalIds,\n edgeIds,\n weights: explicitWeights(snapshot),\n folding: pairFolding(snapshot),\n };\n}\n\n/**\n * The GML text of an id written into `graphty_originalId`: quoted for a string, a number text\n * otherwise (an integer as int, else real, so the importer restores the same typed value).\n * @param id - the original id\n * @returns the text\n */\nfunction originalIdText(id: NodeId): string {\n if (typeof id === \"string\") {\n return quoteGmlString(id);\n }\n return Number.isSafeInteger(id) ? formatInteger(id) : formatGmlReal(id, \"f64\");\n}\n\n/**\n * The parts of the document.\n * @param context - the resolved context\n * @yields one string per header line, node or edge\n * @returns nothing\n */\nfunction* gmlParts(context: WriteContext): Generator<string, void, undefined> {\n const { snapshot, plan, ids } = context;\n const w = new GmlWriter(plan.mangle);\n const { meta } = snapshot;\n if (meta.creator !== null) {\n w.line(\"\", \"Creator\", quoteGmlString(meta.creator));\n }\n if (meta.sourceFormat === \"gml\" && meta.sourceVersion !== null) {\n w.line(\"\", \"Version\", versionText(meta.sourceVersion));\n }\n for (const { column, key } of context.topColumns) {\n if (column.isSet(0)) {\n w.cell(\"\", key, column, 0);\n }\n }\n w.raw(\"graph [\");\n w.line(\" \", \"directed\", context.writeDirected ? \"1\" : \"0\");\n const multigraph = meta.declaredMultigraph ?? (snapshot.flags.multigraph ? true : null);\n if (multigraph !== null) {\n w.line(\" \", \"multigraph\", multigraph ? \"1\" : \"0\");\n }\n for (const { column, key } of context.graphColumns) {\n if (column.isSet(0)) {\n w.cell(\" \", key, column, 0);\n }\n }\n yield w.take();\n for (let i = 0; i < snapshot.nodeCount; i++) {\n w.raw(\" node [\");\n w.line(\" \", \"id\", formatInteger(ids.idAt(i) as number));\n if (ids.isChanged(i)) {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(ids.originalAt(i)));\n } else if (context.originalIds !== null && context.originalIds.isSet(i)) {\n const original = context.originalIds.value(i);\n if (typeof original === \"string\" || typeof original === \"number\") {\n w.line(\" \", ORIGINAL_ID_KEY, originalIdText(original));\n }\n }\n for (const { column, key } of context.nodeColumns) {\n if (column.isSet(i)) {\n w.cell(\" \", key, column, i);\n }\n }\n writeGraphics(w, context, i);\n w.raw(\" ]\");\n yield w.take();\n }\n const el = snapshot.edgeList();\n const origin = meta.weightOrigin;\n const integerWeights = origin !== null && origin.type === \"int\";\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (context.foldPairs && context.folding.folded(e)) {\n continue;\n }\n w.raw(\" edge [\");\n w.line(\" \", \"source\", formatInteger(ids.idAt(el.src[e]) as number));\n w.line(\" \", \"target\", formatInteger(ids.idAt(el.dst[e]) as number));\n if (context.edgeIds !== null && context.edgeIds.isSet(e)) {\n w.cell(\" \", \"id\", context.edgeIds, e);\n }\n if (context.weights.isExplicit(e)) {\n const weight = context.weights.value(e);\n const text =\n integerWeights && Number.isInteger(weight)\n ? formatInteger(weight)\n : formatGmlReal(weight, context.weights.dtype);\n w.line(\" \", plan.weightKey, text);\n }\n for (const { column, key } of context.edgeColumns) {\n if (column.isSet(e)) {\n w.cell(\" \", key, column, e);\n }\n }\n w.raw(\" ]\");\n yield w.take();\n }\n w.raw(\"]\");\n yield w.take();\n}\n\n/**\n * Write a node's `graphics [ ... ]` record from the position column and the graphics json column.\n * @param w - the writer\n * @param context - the context\n * @param i - the node\n */\nfunction writeGraphics(w: GmlWriter, context: WriteContext, i: number): void {\n const { position, graphics } = context;\n const hasPosition = position !== null && position.isSet(i);\n const graphicsValue = graphics !== null && graphics.isSet(i) ? graphics.values[i] : undefined;\n if (!hasPosition) {\n if (graphics !== null && graphicsValue !== undefined) {\n w.cell(\" \", \"graphics\", graphics, i);\n }\n return;\n }\n const numeric = position as Column & { readonly data: ArrayLike<number> };\n const { components } = numeric.meta;\n const lanes = Math.min(components, 3);\n const extra: [string, string][] = [];\n const names = [\"x\", \"y\", \"z\"];\n for (let k = 0; k < lanes; k++) {\n extra.push([names[k], numberText(numeric.data[i * components + k], numeric.meta)]);\n }\n let record: Record<string, unknown> = {};\n if (graphicsValue !== undefined) {\n if (typeof graphicsValue !== \"object\" || graphicsValue === null || Array.isArray(graphicsValue)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `node ${i}: the graphics value is not a record and cannot hold the position`,\n {\n reason: \"graphics conflict\",\n node: i,\n },\n );\n }\n record = graphicsValue as Record<string, unknown>;\n }\n w.record(\" \", \"graphics\", record, \"graphics\", extra);\n}\n\n/** The GML exporter plugin. */\nexport const gmlExporter: GraphExporter<GmlExportOptions> = Object.freeze({\n format: \"gml\",\n capabilities: GML_CAPABILITIES,\n check,\n /**\n * Write the snapshot as UTF-8 chunks; the context is resolved on the first pull, so the\n * errors check() announced surface from the iteration.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(lazyParts(snapshot, options));\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - the options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: GmlExportOptions & CommonExportOptions): Promise<string> {\n return joinText(lazyParts(snapshot, options));\n },\n});\n\n/**\n * The document parts, with the context resolved when iteration starts.\n * @param snapshot - the snapshot\n * @param options - the options\n * @yields the parts\n * @returns nothing\n */\nfunction* lazyParts(\n snapshot: GraphSnapshot,\n options: (GmlExportOptions & CommonExportOptions) | undefined,\n): Generator<string, void, undefined> {\n yield* gmlParts(contextOf(snapshot, options));\n}\n","/**\n * The GML importer (design sections 8.4 and 8.5, research note 07 section 2.2): reads a whole GML\n * text (GML awaits the whole text, 8.4), lexes it once into a typed token list, derives the column\n * schema of every node, edge and graph key in a first walk (GML types are lexical per value, so\n * the column dtype is the union of the value classes seen: `int` -> i32, `real` -> f64, `string`\n * -> string, a nested `[ ]` record -> json, a repeated key -> list; the class is recorded in\n * `origin.type` per column as 8.5 requires), then pushes scalars into the sink in a second walk:\n * every node block first, then every edge block, so node indices follow the file's node order\n * and forward edge references resolve.\n *\n * Conventions honoured: NetworkX's `_networkx_list_start` marker and `\"[]\"` empty lists, `&#NN;`\n * character references in strings, `Creator` / `Version` top-level metadata, `directed 0|1` and\n * `multigraph 0|1` graph flags, comments, keys and values on one line or split across lines, and\n * a `graphics [ x y z ]` node record mapped to the `position` role (note 07 section 9) with the\n * remaining graphics keys kept as a json column.\n *\n * Node ids are the `id` keys under `nodeIdFrom: \"id\"`, the `label` under `\"label\"`, and the node's\n * ordinal under `\"index\"`; `source` / `target` always resolve through the `id` keys. The GML spec\n * types ids as integers; a string id (written by NetworkX and Gephi) is accepted under the `ids`\n * rule with one warning per file, and a real or record id is a validation error. A node's\n * `graphty_originalId` key written by the exporter's `sanitizeIds: \"mangle\"` restores the\n * original id under `restoreMangledIds` (the default).\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type ColumnRole,\n type Dtype,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, DictHeuristic, uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n COLUMN_RENAMED_CODE,\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE as SHARED_NO_GRAPH_CODE,\n PRECISION_CODE as SHARED_PRECISION_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { readText, throwIfAborted } from \"../../common/input.js\";\nimport {\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText, weightFromValue } from \"../../common/weights.js\";\nimport { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from \"../../types.js\";\nimport {\n EMPTY_LIST_TEXT,\n EMPTY_TUPLE_TEXT,\n GmlSyntaxError,\n type GmlTokens,\n LIST_START_MARKER,\n numberOfText,\n ORIGINAL_ID_KEY,\n parseRecord,\n scalarOrRecord,\n TOKEN_INT,\n TOKEN_OPEN,\n TOKEN_REAL,\n TOKEN_STRING,\n TOKEN_WORD,\n tokenizeGml,\n} from \"./syntax.js\";\n\n/** The format-specific options of the GML importer. */\nexport interface GmlImportOptions {\n /**\n * Map a node's `graphics [ x y z ]` record to a `position` column with the position role\n * (default true); false keeps the whole record in the `graphics` json column.\n */\n positions?: boolean | undefined;\n /** Apply the dictionary heuristic of design section 5.4 to string columns (default true). */\n dictionaries?: boolean | undefined;\n}\n\n/** Issue code: the text holds no `graph [ ... ]` block. */\nexport const NO_GRAPH_CODE = SHARED_NO_GRAPH_CODE;\n/** Issue code: the text holds more than one `graph [ ... ]` block; import() reads the first, importAll() every one. */\nexport const SECOND_GRAPH_CODE = MULTIPLE_GRAPHS_CODE;\n/** Issue code: a node block has no `id` key. */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n/** Issue code: a node block has no `label` key under `nodeIdFrom: \"label\"`. */\nexport const MISSING_LABEL_CODE = \"E_GML_MISSING_LABEL\";\n/** Issue code: an edge block has no `source` or no `target` key. */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n/** Issue code: an `id`, `source` or `target` value is neither an integer nor a string. */\nexport const ID_TYPE_CODE = \"E_GML_ID_TYPE\";\n/** Issue code: string `id`, `source` or `target` values, outside the GML spec's integer ids; warned once per file. */\nexport const STRING_ID_CODE = \"W_GML_STRING_ID\";\n/** Issue code: a node id (or label under `nodeIdFrom: \"label\"`) is declared twice; later keys overwrite. */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n/** Issue code: a structural key (`id`, `source`, `target`) appears twice in one block. */\nexport const REPEATED_KEY_CODE = \"E_GML_REPEATED_KEY\";\n/** Issue code: a `node` or `edge` key whose value is not a `[ ... ]` block. */\nexport const ELEMENT_TYPE_CODE = \"E_GML_ELEMENT_TYPE\";\n/** Issue code: a `directed` or `multigraph` flag that is not an integer. */\nexport const FLAG_TYPE_CODE = \"E_GML_FLAG_TYPE\";\n/** Issue code: a `directed` / `multigraph` flag that is not 0 or 1 (read as its truth value), one written as a quoted integer, or one repeated. */\nexport const FLAG_VALUE_CODE = \"W_GML_FLAG_VALUE\";\n\n/** A flag written as a quoted integer, surrounding spaces allowed. */\nconst QUOTED_INT = /^\\s*[+-]?[0-9]+\\s*$/;\n/** Issue code: a named entity in a string that is neither an XML nor an ISO-8859-1 HTML entity; it is kept as written. */\nexport const UNKNOWN_ENTITY_CODE = \"W_GML_UNKNOWN_ENTITY\";\n/** Issue code: an integer beyond 2^53 stored as the nearest f64 (design section 5.1). */\nexport const PRECISION_CODE = SHARED_PRECISION_CODE;\n/** Issue code: the sink already holds a column of the name with another declaration; renamed `<name>#<key>`. */\nexport const COLUMN_RENAMED_CODE_GML = COLUMN_RENAMED_CODE;\n/** Issue code: the sink already holds a column with the role; the column is declared without it. */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n/** Loss code: under `nodeIdFrom` \"label\" / \"index\" the integer `id` keys are not kept. */\nexport const ID_DROPPED_CODE = \"W_GML_ID_DROPPED\";\n\nconst FORMAT_DEFAULTS: ImportFormatDefaults = { ids: \"canonical\", defaultDirected: false, weightFrom: \"value\" };\n\nconst KIND_INT = 1;\nconst KIND_REAL = 2;\nconst KIND_STRING = 4;\nconst KIND_RECORD = 8;\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/** How many elements are pushed between abort-signal checks. */\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The common options the GML importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"nodeIdFrom\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"defaultDirected\",\n \"weightFrom\",\n \"weightDtype\",\n \"restoreMangledIds\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** The element sequence number of the graph block's own keys. */\nconst GRAPH_SEQ = -1;\n/** The element sequence number of the top-level keys. */\nconst TOP_SEQ = -2;\n\n/** The GML value class a column stores. */\ntype GmlKind = \"int\" | \"real\" | \"string\" | \"record\";\n\n/** What the first walk learns about one key of one table. */\ninterface KeySchema {\n /** The key as written. */\n readonly key: string;\n /** The union of value classes seen (KIND_* bits). */\n kinds: number;\n /** Whether the key repeats within one element, or uses a list marker. */\n list: boolean;\n /** The element sequence the key was last seen in. */\n lastSeq: number;\n /** Whether an integer outside the i32 range was seen. */\n wide: boolean;\n /** Whether an integer beyond 2^53 was seen. */\n unsafe: boolean;\n /** The dictionary heuristic while every value is a string, else null. */\n dict: DictHeuristic | null;\n /** Node `graphics` only: some row has numeric x and y. */\n position: boolean;\n /** Node `graphics` only: some row keeps keys besides the position. */\n rest: boolean;\n}\n\n/** The column a key maps to in the second walk. */\ninterface ColumnPlan {\n /** The key as written. */\n readonly key: string;\n /** The column name (renamed `<name>#<key>` when the sink held the name with another shape). */\n name: string;\n /** The column dtype. */\n readonly dtype: Dtype;\n /** The list item dtype, or null. */\n readonly itemDtype: ScalarDtype | null;\n /** How scalar values (or list items) are converted. */\n readonly kind: GmlKind;\n /** Whether the column is a list. */\n readonly list: boolean;\n /** The role, or null. */\n readonly role: ColumnRole | null;\n /** Whether the values come from the top level of the file (graph table only). */\n readonly top: boolean;\n /** Node `graphics` with the position mapping: the position column plan, or null. */\n readonly position: ColumnPlan | null;\n /** Node `graphics` with the position mapping: the json column of the remaining keys, or null. */\n readonly rest: ColumnPlan | null;\n /** The handle once declared. */\n handle: ColumnHandle;\n /** Whether the declaration was attempted (a failed one reuses the sink's column or is null). */\n declared: boolean;\n /** The list items of the current element. */\n items: unknown[] | null;\n /** The element sequence the items belong to. */\n seq: number;\n}\n\n/** A table's plans by key. */\ntype PlanMap = Map<string, ColumnPlan>;\n\n/**\n * Whether a key gets a role in its table (design section 5.6 applied to GML keys).\n * @param domain - the table\n * @param key - the key\n * @returns the role, or null\n */\nfunction roleOf(domain: \"node\" | \"edge\" | \"graph\", key: string): ColumnRole | null {\n if (key === \"label\" && domain !== \"graph\") {\n return \"label\";\n }\n if (domain === \"edge\") {\n if (key === \"id\") {\n return \"id\";\n }\n if (key === \"key\") {\n return \"key\";\n }\n }\n return null;\n}\n\n/** One import call. */\nclass GmlImport {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly positions: boolean;\n\n private readonly dictionaries: boolean;\n\n private readonly coercer: IdCoercer;\n\n private tokens: GmlTokens | null = null;\n\n /** How many `graph [ ... ]` blocks the text holds (known after the scan). */\n graphCount = 0;\n\n private resolver: DirectionResolver | null = null;\n\n private readonly nodeSchema = new Map<string, KeySchema>();\n\n private readonly edgeSchema = new Map<string, KeySchema>();\n\n private readonly graphSchema = new Map<string, KeySchema>();\n\n private readonly topSchema = new Map<string, KeySchema>();\n\n private readonly nodePlans: PlanMap = new Map();\n\n private readonly edgePlans: PlanMap = new Map();\n\n private readonly graphPlans: PlanMap = new Map();\n\n private readonly topPlans: PlanMap = new Map();\n\n private readonly graphNames = new Set<string>();\n\n private graphOpen = -1;\n\n private directedToken = -1;\n\n private multigraphToken = -1;\n\n private creatorToken = -1;\n\n private versionToken = -1;\n\n private nodeCount = 0;\n\n private edgeCount = 0;\n\n private weightKinds = 0;\n\n private hasOriginalId = false;\n\n private headerDirected = false;\n\n private seq = 0;\n\n private nodeOrdinal = 0;\n\n private elementsSinceCheck = 0;\n\n /** The sink id every file id maps to when they differ (label / index / restored ids), else null. */\n private idMap: Map<NodeId, NodeId> | null = null;\n\n /** Node indices declared by a node block of this import, for duplicate detection. */\n private declared = new Uint32Array(64);\n\n /** The list plans touched by the current node or edge. */\n private readonly touched: ColumnPlan[] = [];\n\n /** The list plans touched by the graph table's keys. */\n private readonly graphTouched: ColumnPlan[] = [];\n\n /** The sequence number of the current node or edge, which its list items belong to. */\n private seqNow = 0;\n\n /**\n * Create one import.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved common options\n * @param format - the format-specific options\n * @param which - which `graph [ ... ]` block to read (0: the first)\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n format: GmlImportOptions | undefined,\n private readonly which = 0,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.positions = format?.positions ?? true;\n this.dictionaries = format?.dictionaries ?? true;\n this.coercer = new IdCoercer(options.ids);\n }\n\n /**\n * Run the import over the tokens of a text.\n * @param tokens - the whole text, tokenized (tokenize())\n */\n run(tokens: GmlTokens): void {\n this.tokens = tokens;\n tokens.onUnknownEntity = (entity, line) => {\n this.report.warnOnce(\n \"parse-error\",\n UNKNOWN_ENTITY_CODE,\n `unknown character entity ${entity} is kept as written`,\n { line, element: entity },\n `${UNKNOWN_ENTITY_CODE}:${entity}`,\n );\n };\n this.scan();\n this.push();\n }\n\n // ============================================================ pass 1: the schema\n\n /**\n * Walk the top level: find the graph block, the metadata keys and the top-level attributes,\n * and derive every table's schema.\n */\n private scan(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n const record = t.kind[v] === TOKEN_OPEN;\n if (key === \"graph\" && record) {\n if (this.graphCount++ === this.which) {\n this.graphOpen = v;\n this.scanGraph(v);\n }\n } else if (key === \"Creator\" && !record && this.creatorToken < 0) {\n this.creatorToken = v;\n } else if (key === \"Version\" && !record && this.versionToken < 0) {\n this.versionToken = v;\n } else {\n this.observe(this.topSchema, \"graph\", key, v, TOP_SEQ);\n }\n }\n if (this.graphOpen < 0) {\n this.report.fail(NO_GRAPH_CODE, \"the input contains no graph [ ... ] block\", { line: null });\n }\n }\n\n /**\n * Walk the graph block for the schema.\n * @param open - the index of the block's `[`\n */\n private scanGraph(open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.nodeCount++;\n this.scanElement(\"node\", v);\n }\n break;\n case \"edge\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.edgeCount++;\n this.scanElement(\"edge\", v);\n }\n break;\n case \"directed\":\n if (this.directedToken < 0) {\n this.directedToken = v;\n }\n break;\n case \"multigraph\":\n if (this.multigraphToken < 0) {\n this.multigraphToken = v;\n }\n break;\n default:\n this.observe(this.graphSchema, \"graph\", key, v, GRAPH_SEQ);\n }\n }\n }\n\n /**\n * Walk one node or edge block for the schema.\n * @param domain - node or edge\n * @param open - the block's `[`\n */\n private scanElement(domain: \"node\" | \"edge\", open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n const seq = this.seq++;\n const schema = domain === \"node\" ? this.nodeSchema : this.edgeSchema;\n const { weightFrom, restoreMangledIds } = this.options;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n if (domain === \"node\") {\n if (key === \"id\") {\n continue;\n }\n if (key === ORIGINAL_ID_KEY && restoreMangledIds) {\n this.hasOriginalId = true;\n continue;\n }\n } else {\n if (key === \"source\" || key === \"target\" || key === \"directed\") {\n continue;\n }\n if (key === weightFrom) {\n this.weightKinds |= kindBit(t, v);\n continue;\n }\n }\n this.observe(schema, domain, key, v, seq);\n }\n }\n\n /**\n * Record one value of one key in a table's schema.\n * @param schema - the table's schema\n * @param domain - the table\n * @param key - the key\n * @param v - the value token\n * @param seq - the element sequence number\n */\n private observe(\n schema: Map<string, KeySchema>,\n domain: \"node\" | \"edge\" | \"graph\",\n key: string,\n v: number,\n seq: number,\n ): void {\n const t = this.requireTokens();\n let entry = schema.get(key);\n if (entry === undefined) {\n entry = {\n key,\n kinds: 0,\n list: false,\n lastSeq: seq,\n wide: false,\n unsafe: false,\n dict: this.dictionaries && roleOf(domain, key) === null ? new DictHeuristic() : null,\n position: false,\n rest: false,\n };\n schema.set(key, entry);\n } else if (entry.lastSeq === seq) {\n entry.list = true;\n } else {\n entry.lastSeq = seq;\n }\n switch (t.kind[v]) {\n case TOKEN_STRING: {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n entry.list = true;\n return;\n }\n entry.kinds |= KIND_STRING;\n if (entry.dict !== null && !entry.dict.decided) {\n entry.dict.observe(raw);\n }\n return;\n }\n case TOKEN_INT: {\n entry.kinds |= KIND_INT;\n const n = Number(t.textOf(v));\n if (n < I32_MIN || n > I32_MAX) {\n entry.wide = true;\n if (!Number.isSafeInteger(n)) {\n entry.unsafe = true;\n }\n }\n return;\n }\n case TOKEN_OPEN:\n entry.kinds |= KIND_RECORD;\n if (domain === \"node\" && key === \"graphics\" && this.positions) {\n this.inspectGraphics(entry, v);\n }\n return;\n default:\n entry.kinds |= KIND_REAL;\n }\n }\n\n /**\n * Note whether a node's graphics record carries a position (numeric x and y) and whether\n * anything besides the position remains.\n * @param entry - the graphics schema entry\n * @param open - the record's `[`\n */\n private inspectGraphics(entry: KeySchema, open: number): void {\n const t = this.requireTokens();\n const close = t.match[open];\n let x = false;\n let y = false;\n let other = false;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const numeric = t.kind[p + 1] === TOKEN_INT || t.kind[p + 1] === TOKEN_REAL;\n if (key === \"x\" && numeric && !x) {\n x = true;\n } else if (key === \"y\" && numeric && !y) {\n y = true;\n } else if (!(key === \"z\" && numeric)) {\n other = true;\n }\n }\n const positioned = x && y;\n entry.position ||= positioned;\n entry.rest ||= positioned ? other : true;\n }\n\n // ============================================================ pass 2: the push\n\n /** Declare what the schema needs, set the header and push every element. */\n private push(): void {\n const { sink, report, options } = this;\n const t = this.requireTokens();\n sink.reserve(this.nodeCount, this.edgeCount);\n this.buildPlans();\n this.setMetadata();\n this.headerDirected = this.readFlag(this.directedToken, \"directed\") ?? options.defaultDirected;\n const resolver = new DirectionResolver(sink, report, options.onMixedDirection);\n resolver.setHeader(this.headerDirected, {\n line: this.directedToken >= 0 ? t.line[this.directedToken] : t.line[this.graphOpen],\n });\n this.resolver = resolver;\n if (options.nodeIdFrom !== \"id\" || this.hasOriginalId) {\n this.idMap = new Map();\n }\n if (options.nodeIdFrom !== \"id\") {\n report.loss(\n ID_DROPPED_CODE,\n `node ids taken from the ${options.nodeIdFrom}; the integer id keys are not kept as a column`,\n null,\n this.nodeCount,\n );\n }\n this.pushTopLevel();\n this.pushNodes();\n this.pushEdges();\n }\n\n /** Turn every schema entry into a column plan. */\n private buildPlans(): void {\n for (const [key, entry] of this.nodeSchema) {\n this.nodePlans.set(key, this.planOf(\"node\", entry));\n }\n for (const [key, entry] of this.edgeSchema) {\n this.edgePlans.set(key, this.planOf(\"edge\", entry));\n }\n for (const [key, entry] of this.graphSchema) {\n this.graphPlans.set(key, this.planOf(\"graph\", entry));\n }\n for (const [key, entry] of this.topSchema) {\n this.topPlans.set(key, this.planOf(\"graph\", entry, true));\n }\n }\n\n /**\n * The plan of one schema entry.\n * @param domain - the table\n * @param entry - the schema entry\n * @param top - whether the key is a top-level one (graph table)\n * @returns the plan\n */\n private planOf(domain: \"node\" | \"edge\" | \"graph\", entry: KeySchema, top = false): ColumnPlan {\n const kind = kindOf(entry);\n let scalar: ScalarDtype = dtypeOfKind(kind, entry);\n if (\n scalar === \"string\" &&\n !entry.list &&\n entry.dict !== null &&\n entry.kinds === KIND_STRING &&\n entry.dict.decide() === \"dict\"\n ) {\n scalar = \"dict\";\n }\n if (entry.unsafe) {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${domain} key \"${entry.key}\" holds integers beyond 2^53; they are stored as the nearest f64`,\n { element: entry.key },\n `${PRECISION_CODE}:${domain}:${entry.key}`,\n );\n }\n const name = domain === \"graph\" ? this.uniqueGraphName(entry.key) : entry.key;\n let itemDtype: ScalarDtype | null = null;\n if (entry.list) {\n itemDtype = scalar === \"dict\" ? \"string\" : scalar;\n }\n const plan: ColumnPlan = {\n key: entry.key,\n name,\n dtype: entry.list ? \"list\" : scalar,\n itemDtype,\n kind,\n list: entry.list,\n role: roleOf(domain, entry.key),\n top,\n position: null,\n rest: null,\n handle: INVALID_INDEX as ColumnHandle,\n declared: false,\n items: null,\n seq: Number.NEGATIVE_INFINITY,\n };\n if (\n domain === \"node\" &&\n entry.key === \"graphics\" &&\n entry.position &&\n entry.kinds === KIND_RECORD &&\n !entry.list\n ) {\n const taken = (candidate: string): boolean =>\n this.nodeSchema.has(candidate) || this.sink.nodeColumn(candidate) !== INVALID_INDEX;\n const position: ColumnPlan = {\n ...plan,\n name: uniqueColumnName(\"position\", \"graphics\", taken),\n dtype: \"f64\",\n itemDtype: null,\n kind: \"real\",\n role: \"position\",\n };\n const rest: ColumnPlan | null = entry.rest ? { ...plan } : null;\n return { ...plan, position, rest };\n }\n return plan;\n }\n\n /**\n * A graph column name not yet used by this import (top-level and in-graph keys share the table).\n * @param key - the key\n * @returns the name\n */\n private uniqueGraphName(key: string): string {\n const name = uniqueColumnName(key, key, (candidate) => this.graphNames.has(candidate));\n this.graphNames.add(name);\n return name;\n }\n\n /** Set the graph metadata: source format, creator, version, multigraph flag, weight origin. */\n private setMetadata(): void {\n const t = this.requireTokens();\n const { sink, options } = this;\n const textOf = (v: number): string => (t.kind[v] === TOKEN_STRING ? t.stringOf(v) : t.textOf(v));\n const multigraph = this.readFlag(this.multigraphToken, \"multigraph\");\n sink.setMeta({\n sourceFormat: \"gml\",\n creator: this.creatorToken >= 0 ? textOf(this.creatorToken) : undefined,\n sourceVersion: this.versionToken >= 0 ? textOf(this.versionToken) : undefined,\n declaredMultigraph: multigraph ?? undefined,\n weightOrigin:\n this.weightKinds !== 0 && options.weightFrom !== null\n ? {\n format: \"gml\",\n id: options.weightFrom,\n title: null,\n type: this.weightKinds === KIND_INT ? \"int\" : \"real\",\n namespace: null,\n }\n : undefined,\n // The header as written, so a reader can say which words set the direction and tell\n // `directed 0` from a file that relies on the specification's default.\n extra: this.directedToken >= 0 ? { gml: { directed: textOf(this.directedToken) } } : undefined,\n });\n }\n\n /**\n * Read a `directed` / `multigraph` flag token.\n * @param v - the value token, or -1 when absent\n * @param name - the flag name, for issues\n * @returns the flag, or null when absent or not an integer\n */\n private readFlag(v: number, name: string): boolean | null {\n if (v < 0) {\n return null;\n }\n const t = this.requireTokens();\n // Files in the wild write the flag as a quoted integer (`directed \"1\"`); read it, with a warning.\n const quoted = t.kind[v] === TOKEN_STRING && QUOTED_INT.test(t.stringOf(v));\n if (quoted) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is written as the string ${describeValue(t, v)}; read as an integer`,\n { line: t.line[v], element: name },\n );\n } else if (t.kind[v] !== TOKEN_INT) {\n this.report.error(\n \"validation-error\",\n FLAG_TYPE_CODE,\n `flag \"${name}\" must be the integer 0 or 1, found ${describeValue(t, v)}`,\n { line: t.line[v], element: name },\n );\n return null;\n }\n const n = Number(quoted ? t.stringOf(v) : t.textOf(v));\n if (n !== 0 && n !== 1) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `flag \"${name}\" is ${n}; read as ${n !== 0 ? \"1\" : \"0\"}`,\n { line: t.line[v], element: name },\n );\n }\n return n !== 0;\n }\n\n /** Push the top-level attributes (every top-level key but graph, Creator and Version). */\n private pushTopLevel(): void {\n const t = this.requireTokens();\n for (let p = 0; p < t.count; p = t.nextPair(p)) {\n const v = p + 1;\n if (v === this.graphOpen || v === this.creatorToken || v === this.versionToken) {\n continue;\n }\n const plan = this.topPlans.get(t.textOf(p));\n if (plan !== undefined) {\n this.writeGraph(plan, v, TOP_SEQ);\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every node block and the graph block's own attributes, in file order. */\n private pushNodes(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n const v = p + 1;\n switch (key) {\n case \"node\":\n if (t.kind[v] === TOKEN_OPEN) {\n this.importNode(v);\n } else {\n this.badElement(\"node\", p);\n this.report.counts.skippedNodes++;\n }\n break;\n case \"edge\":\n break;\n case \"directed\":\n case \"multigraph\":\n if (v !== this.directedToken && v !== this.multigraphToken) {\n this.report.warning(\n \"validation-error\",\n FLAG_VALUE_CODE,\n `graph flag \"${key}\" repeated; the first value stands`,\n { line: t.line[p], element: key },\n );\n }\n break;\n default: {\n const plan = this.graphPlans.get(key);\n if (plan !== undefined) {\n this.writeGraph(plan, v, GRAPH_SEQ);\n }\n }\n }\n }\n this.flushGraphLists();\n }\n\n /** Push every edge block, in file order. */\n private pushEdges(): void {\n const t = this.requireTokens();\n const close = t.match[this.graphOpen];\n let ordinal = 0;\n for (let p = this.graphOpen + 1; p < close; p = t.nextPair(p)) {\n if (t.textOf(p) !== \"edge\") {\n continue;\n }\n const v = p + 1;\n if (t.kind[v] === TOKEN_OPEN) {\n this.importEdge(v, ordinal);\n } else {\n this.badElement(\"edge\", p);\n this.report.counts.skippedEdges++;\n }\n ordinal++;\n }\n }\n\n /**\n * Record a `node` / `edge` key whose value is not a block.\n * @param what - node or edge\n * @param p - the key token\n */\n private badElement(what: string, p: number): void {\n const t = this.requireTokens();\n this.report.error(\n \"validation-error\",\n ELEMENT_TYPE_CODE,\n `${what} must be a [ ... ] block, found ${describeValue(t, p + 1)}`,\n { line: t.line[p], element: what },\n );\n }\n\n /**\n * Push one node block.\n * @param open - the block's `[`\n */\n private importNode(open: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const ordinal = this.nodeOrdinal++;\n this.checkAbort();\n let index: number;\n let sinkId: NodeId;\n try {\n let idTok = -1;\n let labelTok = -1;\n let originalTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\") {\n idTok = this.structuralToken(idTok, p, \"id\");\n } else if (key === \"label\") {\n labelTok = labelTok < 0 ? p + 1 : labelTok;\n } else if (key === ORIGINAL_ID_KEY && options.restoreMangledIds) {\n originalTok = originalTok < 0 ? p + 1 : originalTok;\n }\n }\n if (idTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no id\", { reason: \"missing id\" });\n }\n // the file id under the ids rule, so `id 1` and `source \"1\"` meet in idMap (except under\n // \"keep\", where the integer 1 and the string \"1\" are different ids by design)\n const fileId = this.coerceFileId(idTok, this.fileIdOf(idTok, \"id\"));\n if (originalTok >= 0) {\n sinkId = this.restoredId(originalTok);\n } else {\n switch (options.nodeIdFrom) {\n case \"label\":\n if (labelTok < 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node has no label\", {\n reason: \"missing label\",\n });\n }\n sinkId = this.coerceValueToken(labelTok);\n break;\n case \"index\":\n sinkId = ordinal;\n break;\n default:\n sinkId = fileId;\n }\n }\n if (this.idMap !== null) {\n this.idMap.set(fileId, sinkId);\n }\n index = sink.addNode(sinkId);\n } catch (err) {\n this.recordNodeError(err, line);\n report.counts.skippedNodes++;\n return;\n }\n if (this.isDeclared(index)) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${JSON.stringify(sinkId)} is declared twice; later keys overwrite`,\n { line, element: String(sinkId) },\n );\n } else {\n this.markDeclared(index);\n report.counts.nodes++;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"id\" || (key === ORIGINAL_ID_KEY && options.restoreMangledIds)) {\n continue;\n }\n const plan = this.nodePlans.get(key);\n if (plan !== undefined) {\n this.writeNode(plan, index, p + 1);\n }\n }\n this.flushLists(\"node\", index);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element: String(sinkId) });\n }\n }\n\n /**\n * Push one edge block.\n * @param open - the block's `[`\n * @param ordinal - the edge's ordinal among edge blocks, for messages\n */\n private importEdge(open: number, ordinal: number): void {\n const t = this.requireTokens();\n const { sink, report, options } = this;\n const close = t.match[open];\n const line = t.line[open];\n const element = `edge #${ordinal}`;\n this.checkAbort();\n let edge: number;\n try {\n let sourceTok = -1;\n let targetTok = -1;\n let weightTok = -1;\n let directedTok = -1;\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\") {\n sourceTok = this.structuralToken(sourceTok, p, \"source\");\n } else if (key === \"target\") {\n targetTok = this.structuralToken(targetTok, p, \"target\");\n } else if (key === \"directed\") {\n directedTok = this.structuralToken(directedTok, p, \"directed\");\n } else if (key === options.weightFrom) {\n weightTok = p + 1;\n }\n }\n if (sourceTok < 0 || targetTok < 0) {\n throw new GraphFormatError(\"E_UNKNOWN_NODE\", `edge has no ${sourceTok < 0 ? \"source\" : \"target\"}`, {\n reason: \"missing endpoint\",\n });\n }\n const source = this.endpoint(sourceTok, \"source\");\n const target = this.endpoint(targetTok, \"target\");\n const weight = weightTok >= 0 ? this.weightOf(weightTok) : undefined;\n const before = sink.edgeCount;\n const sourceNew = sink.indexOf(source) === INVALID_INDEX;\n const targetNew = source !== target && sink.indexOf(target) === INVALID_INDEX;\n // an edge-level `directed` key overrides the graph's flag for that edge (mixed graphs)\n const directed = this.readFlag(directedTok, \"directed\") ?? this.headerDirected;\n edge = this.requireResolver().addEdge(source, target, directed ? \"directed\" : \"undirected\", weight, {\n line,\n element,\n });\n report.counts.edges += sink.edgeCount - before;\n // endpoints the file never declares (addMissingNodes) are nodes of the sink too\n report.counts.nodes += (sourceNew ? 1 : 0) + (targetNew ? 1 : 0);\n } catch (err) {\n this.recordEdgeError(err, line, element);\n report.counts.skippedEdges++;\n return;\n }\n this.beginElement(this.seq++);\n try {\n for (let p = open + 1; p < close; p = t.nextPair(p)) {\n const key = t.textOf(p);\n if (key === \"source\" || key === \"target\" || key === \"directed\" || key === options.weightFrom) {\n continue;\n }\n const plan = this.edgePlans.get(key);\n if (plan !== undefined) {\n this.writeEdge(plan, edge, p + 1);\n }\n }\n this.flushLists(\"edge\", edge);\n } catch (err) {\n this.touched.length = 0;\n report.recordError(err, { line, element });\n }\n }\n\n // ============================================================ ids and weights\n\n /**\n * Note a structural key token, refusing a repeat.\n * @param previous - the token seen before, or -1\n * @param p - the key token\n * @param key - the key name\n * @returns the value token\n */\n private structuralToken(previous: number, p: number, key: string): number {\n if (previous >= 0) {\n throw new GraphFormatError(\"E_INVALID_ID\", `key \"${key}\" appears twice in one block`, {\n reason: \"duplicate key\",\n key,\n });\n }\n return p + 1;\n }\n\n /**\n * The value of an id / source / target token: an integer (the GML spec's type) as a number, a\n * string (NetworkX and Gephi write them) as its text with one warning per file.\n * @param v - the value token\n * @param key - the key name, for the error\n * @returns the number or the string\n */\n private fileIdOf(v: number, key: string): number | string {\n const t = this.requireTokens();\n if (t.kind[v] === TOKEN_STRING) {\n this.report.warnOnce(\n \"validation-error\",\n STRING_ID_CODE,\n `${key} is the string \"${t.textOf(v)}\"; GML ids are integers, string ids are kept under the ids rule`,\n { line: t.line[v], element: t.stringOf(v) },\n );\n return t.stringOf(v);\n }\n if (t.kind[v] !== TOKEN_INT) {\n throw new GraphFormatError(\n \"E_INVALID_ID\",\n `${key} must be an integer or a string, found ${describeValue(t, v)}`,\n {\n reason: \"not an integer\",\n key,\n value: t.kind[v] === TOKEN_OPEN ? \"[...]\" : t.textOf(v),\n },\n );\n }\n return Number(t.textOf(v));\n }\n\n /**\n * Coerce an id / source / target value under the `ids` rule: a string by its text, an integer\n * through coerceInteger().\n * @param v - the value token\n * @param id - its value (fileIdOf())\n * @returns the id\n */\n private coerceFileId(v: number, id: number | string): NodeId {\n return typeof id === \"string\" ? this.coercer.text(id) : this.coerceInteger(v, id);\n }\n\n /**\n * Coerce an integer id token under the `ids` rule: a safe integer passes as a typed number\n * (so `01` is 1 and `-0` is 0), a larger one goes through the text rule (a string under\n * \"canonical\"), and \"string\" keeps the text as written.\n * @param v - the value token\n * @param n - its numeric value\n * @returns the id\n */\n private coerceInteger(v: number, n: number): NodeId {\n if (Number.isSafeInteger(n) && this.coercer.mode !== \"string\") {\n return this.coercer.value(n);\n }\n return this.coercer.text(this.requireTokens().textOf(v));\n }\n\n /**\n * Coerce a label token under the `ids` rule: a string by its text, a number as a typed value.\n * @param v - the value token\n * @returns the id\n */\n private coerceValueToken(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return this.coercer.text(t.stringOf(v));\n case TOKEN_INT:\n return this.coerceInteger(v, Number(t.textOf(v)));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", \"label must be a string or a number, found a record\", {\n reason: \"record label\",\n });\n default:\n return this.coercer.value(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * The id a `graphty_originalId` key restores: typed, never coerced (the exporter wrote it exactly).\n * @param v - the value token\n * @returns the original id\n */\n private restoredId(v: number): NodeId {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return t.stringOf(v);\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_ID\", `${ORIGINAL_ID_KEY} must be a string or a number`, {\n reason: \"record original id\",\n });\n default:\n return numberOfText(t.textOf(v));\n }\n }\n\n /**\n * Resolve a source / target token to a sink id.\n * @param v - the value token\n * @param key - source or target\n * @returns the id\n */\n private endpoint(v: number, key: string): NodeId {\n const id = this.coerceFileId(v, this.fileIdOf(v, key));\n return this.idMap?.get(id) ?? id;\n }\n\n /**\n * The weight of an edge from its weight token.\n * @param v - the value token\n * @returns the weight; E_INVALID_WEIGHT for a record or non-numeric text\n */\n private weightOf(v: number): number | undefined {\n const t = this.requireTokens();\n switch (t.kind[v]) {\n case TOKEN_STRING:\n return parseWeightText(t.stringOf(v));\n case TOKEN_OPEN:\n throw new GraphFormatError(\"E_INVALID_WEIGHT\", \"edge weight is a record\", { value: \"[...]\" });\n default:\n return weightFromValue(numberOfText(t.textOf(v)));\n }\n }\n\n /**\n * Record a node-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n */\n private recordNodeError(err: unknown, line: number): void {\n const { report } = this;\n if (err instanceof GraphFormatError && err.code === \"E_INVALID_ID\") {\n const { reason } = err.details;\n switch (reason) {\n case \"missing id\":\n report.error(\"missing-value\", MISSING_ID_CODE, err.message, { line, element: \"node\" });\n return;\n case \"missing label\":\n report.error(\"missing-value\", MISSING_LABEL_CODE, err.message, { line, element: \"node\" });\n return;\n case \"duplicate key\":\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element: \"node\" });\n return;\n case \"not an integer\":\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element: \"node\" });\n return;\n default:\n break;\n }\n }\n report.recordError(err, { line, element: \"node\" });\n }\n\n /**\n * Record an edge-level error under the GML code it implies.\n * @param err - the thrown value\n * @param line - the block's line\n * @param element - the edge description\n */\n private recordEdgeError(err: unknown, line: number, element: string): void {\n const { report } = this;\n if (err instanceof GraphFormatError) {\n const { reason } = err.details;\n if (err.code === \"E_UNKNOWN_NODE\" && reason === \"missing endpoint\") {\n report.error(\"missing-value\", MISSING_ENDPOINT_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"duplicate key\") {\n report.error(\"validation-error\", REPEATED_KEY_CODE, err.message, { line, element });\n return;\n }\n if (err.code === \"E_INVALID_ID\" && reason === \"not an integer\") {\n report.error(\"validation-error\", ID_TYPE_CODE, err.message, { line, element });\n return;\n }\n }\n report.recordError(err, { line, element });\n }\n\n // ============================================================ values\n\n /**\n * Write one node value.\n * @param plan - the key's plan\n * @param index - the node index\n * @param v - the value token\n */\n private writeNode(plan: ColumnPlan, index: number, v: number): void {\n if (plan.position !== null) {\n this.writeGraphics(plan, index, v);\n return;\n }\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setNodeValue(this.handleOf(plan, \"node\"), index, this.scalarOf(plan, v));\n }\n\n /**\n * Write one edge value.\n * @param plan - the key's plan\n * @param edge - the edge index\n * @param v - the value token\n */\n private writeEdge(plan: ColumnPlan, edge: number, v: number): void {\n if (plan.list) {\n this.collectItem(plan, v, this.seqNow, this.touched);\n return;\n }\n this.sink.setEdgeValue(this.handleOf(plan, \"edge\"), edge, this.scalarOf(plan, v));\n }\n\n /**\n * Write one graph value.\n * @param plan - the key's plan\n * @param v - the value token\n * @param seq - TOP_SEQ or GRAPH_SEQ\n */\n private writeGraph(plan: ColumnPlan, v: number, seq: number): void {\n if (plan.list) {\n this.collectItem(plan, v, seq, this.graphTouched);\n return;\n }\n this.sink.setGraphValue(plan.name, this.scalarOf(plan, v), graphDecl(plan));\n }\n\n /**\n * Write a node's graphics record: the position column from x / y / z, the remaining keys to\n * the json column.\n * @param plan - the graphics plan\n * @param index - the node index\n * @param v - the value token (a record)\n */\n private writeGraphics(plan: ColumnPlan, index: number, v: number): void {\n const t = this.requireTokens();\n const { sink } = this;\n const record = parseRecord(t, v);\n const { x, y, z } = record;\n const positionPlan = plan.position;\n if (positionPlan !== null && typeof x === \"number\" && typeof y === \"number\") {\n sink.setNodeValue(this.handleOf(positionPlan, \"node\"), index, [x, y, typeof z === \"number\" ? z : 0]);\n delete record.x;\n delete record.y;\n if (typeof z === \"number\") {\n delete record.z;\n }\n if (plan.rest !== null && Object.keys(record).length > 0) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, record);\n }\n return;\n }\n if (plan.rest !== null) {\n sink.setNodeValue(this.handleOf(plan.rest, \"node\"), index, record);\n }\n }\n\n /**\n * Collect one list item.\n * @param plan - the list plan\n * @param v - the value token\n * @param seq - the sequence number of the element the item belongs to\n * @param touched - the plans touched by that element\n */\n private collectItem(plan: ColumnPlan, v: number, seq: number, touched: ColumnPlan[]): void {\n const t = this.requireTokens();\n if (plan.seq !== seq) {\n plan.seq = seq;\n plan.items = [];\n touched.push(plan);\n }\n if (t.kind[v] === TOKEN_STRING) {\n const raw = t.textOf(v);\n if (raw === LIST_START_MARKER || raw === EMPTY_LIST_TEXT || raw === EMPTY_TUPLE_TEXT) {\n return;\n }\n }\n (plan.items as unknown[]).push(this.scalarOf(plan, v));\n }\n\n /**\n * Start a node or edge: later list items belong to it.\n * @param seq - the element's sequence number\n */\n private beginElement(seq: number): void {\n this.seqNow = seq;\n this.touched.length = 0;\n }\n\n /**\n * Write the lists collected for the current node or edge.\n * @param domain - node or edge\n * @param row - the row\n */\n private flushLists(domain: \"node\" | \"edge\", row: number): void {\n const { sink, touched } = this;\n for (const plan of touched) {\n const handle = this.handleOf(plan, domain);\n if (domain === \"node\") {\n sink.setNodeValue(handle, row, plan.items);\n } else {\n sink.setEdgeValue(handle, row, plan.items);\n }\n plan.items = null;\n }\n touched.length = 0;\n }\n\n /** Write the lists collected for the graph table. */\n private flushGraphLists(): void {\n const { sink, graphTouched } = this;\n for (const plan of graphTouched) {\n sink.setGraphValue(plan.name, plan.items, graphDecl(plan));\n plan.items = null;\n }\n graphTouched.length = 0;\n }\n\n /**\n * The JS value of a scalar value token (or list item) under a plan's storage class.\n * @param plan - the plan\n * @param v - the value token\n * @returns the value to push\n */\n private scalarOf(plan: ColumnPlan, v: number): unknown {\n const t = this.requireTokens();\n const kind = t.kind[v];\n switch (plan.kind) {\n case \"int\":\n return Number(t.textOf(v));\n case \"real\":\n return numberOfText(t.textOf(v));\n case \"string\":\n return kind === TOKEN_STRING ? t.stringOf(v) : t.textOf(v);\n default:\n return kind === TOKEN_STRING ? t.stringOf(v) : scalarOrRecord(t, v);\n }\n }\n\n /**\n * The handle of a plan's column, declaring it on first use. A declaration the sink refuses\n * because a column of the name exists with another declaration falls back to that column\n * (reported once); a taken role is dropped (reported once).\n * @param plan - the plan\n * @param domain - node or edge\n * @returns the handle\n */\n private handleOf(plan: ColumnPlan, domain: \"node\" | \"edge\"): ColumnHandle {\n if (plan.declared) {\n return plan.handle;\n }\n plan.declared = true;\n const { sink, report } = this;\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.role === \"position\") {\n decl.components = 3;\n }\n if (plan.role !== null) {\n decl.role = plan.role;\n }\n const resolved = declareResolved(sink, domain, decl, report, { element: plan.name });\n plan.handle = resolved.handle;\n if (resolved.renamed) {\n plan.name = resolved.decl.name;\n }\n return plan.handle;\n }\n\n // ============================================================ bookkeeping\n\n /**\n * Whether a node index was declared by a node block of this import.\n * @param index - the node index\n * @returns true when declared\n */\n private isDeclared(index: number): boolean {\n const word = index >>> 5;\n return word < this.declared.length && ((this.declared[word] >>> (index & 31)) & 1) === 1;\n }\n\n /**\n * Mark a node index as declared.\n * @param index - the node index\n */\n private markDeclared(index: number): void {\n const word = index >>> 5;\n if (word >= this.declared.length) {\n const grown = new Uint32Array(Math.max(word + 1, this.declared.length * 2));\n grown.set(this.declared);\n this.declared = grown;\n }\n this.declared[word] |= 1 << (index & 31);\n }\n\n /** Check the abort signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.elementsSinceCheck >= ABORT_CHECK_INTERVAL) {\n this.elementsSinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * The tokens, which exist after run() lexed the text.\n * @returns the tokens\n */\n private requireTokens(): GmlTokens {\n if (this.tokens === null) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"the GML text was not lexed\", { reason: \"no tokens\" });\n }\n return this.tokens;\n }\n\n /**\n * The direction resolver, which exists once the header was set.\n * @returns the resolver\n */\n private requireResolver(): DirectionResolver {\n if (this.resolver === null) {\n throw new GraphFormatError(\"E_DIRECTED\", \"the header was not set\", { reason: \"no resolver\" });\n }\n return this.resolver;\n }\n}\n\n/**\n * The KIND_* bit of a value token.\n * @param t - the tokens\n * @param v - the value token\n * @returns the bit\n */\nfunction kindBit(t: GmlTokens, v: number): number {\n switch (t.kind[v]) {\n case TOKEN_INT:\n return KIND_INT;\n case TOKEN_STRING:\n return KIND_STRING;\n case TOKEN_OPEN:\n return KIND_RECORD;\n default:\n return KIND_REAL;\n }\n}\n\n/**\n * The storage class of a schema entry: the widest value class seen.\n * @param entry - the entry\n * @returns the class\n */\nfunction kindOf(entry: KeySchema): GmlKind {\n if ((entry.kinds & KIND_RECORD) !== 0) {\n return \"record\";\n }\n if ((entry.kinds & KIND_STRING) !== 0) {\n return \"string\";\n }\n if ((entry.kinds & KIND_REAL) !== 0) {\n return \"real\";\n }\n return \"int\";\n}\n\n/**\n * The scalar dtype of a storage class.\n * @param kind - the class\n * @param entry - the entry (a wide int keeps origin int but stores f64)\n * @returns the dtype\n */\nfunction dtypeOfKind(kind: GmlKind, entry: KeySchema): ScalarDtype {\n switch (kind) {\n case \"int\":\n return entry.wide ? \"f64\" : \"i32\";\n case \"real\":\n return \"f64\";\n case \"string\":\n return \"string\";\n default:\n return \"json\";\n }\n}\n\n/**\n * The origin.type text of a plan: the GML value class of its values (`int` for wide integers\n * stored as f64 too, so the exporter writes them without a decimal point).\n * @param plan - the plan\n * @returns the type text\n */\nfunction originTypeOf(plan: ColumnPlan): string {\n return plan.kind;\n}\n\n/**\n * The declaration patch of a graph column.\n * @param plan - the plan\n * @returns the decl for setGraphValue\n */\nfunction graphDecl(plan: ColumnPlan): ColumnDecl {\n const decl: ColumnDecl = {\n name: plan.name,\n dtype: plan.dtype,\n nullable: true,\n origin: { format: \"gml\", id: plan.key, title: null, type: originTypeOf(plan), namespace: null },\n };\n if (plan.list) {\n decl.itemDtype = plan.itemDtype ?? \"string\";\n }\n if (plan.top) {\n decl.extra = { gmlTopLevel: true };\n }\n return decl;\n}\n\n/**\n * A short description of a value token for messages.\n * @param t - the tokens\n * @param v - the value token\n * @returns the description\n */\nfunction describeValue(t: GmlTokens, v: number): string {\n switch (t.kind[v]) {\n case TOKEN_OPEN:\n return \"a record\";\n case TOKEN_STRING:\n return `the string \"${t.textOf(v)}\"`;\n case TOKEN_REAL:\n return `the real ${t.textOf(v)}`;\n case TOKEN_WORD:\n return `the word ${t.textOf(v)}`;\n default:\n return t.textOf(v);\n }\n}\n\nconst SNIFF_GRAPH_START = /^(?:\\s|#[^\\n]*\\n)*graph\\s*\\[/;\nconst SNIFF_GRAPH_ANYWHERE = /(?:^|\\s)graph\\s*\\[/;\nconst SNIFF_KEY_START = /^(?:\\s|#[^\\n]*\\n)*[A-Za-z_][0-9A-Za-z_]*\\s+(?:\"|[+-]?[0-9.]|\\[)/;\n\n/**\n * Confidence that a head of bytes is GML: a `graph [` opener, or key-value text with a `graph [`\n * somewhere in the head.\n * @param head - the first bytes of the input\n * @returns 0.95 for a leading `graph [`, 0.85 for key-value text containing one, 0.4 for key-value text, 0 otherwise\n */\nfunction sniffGml(head: Uint8Array): number {\n let text = new TextDecoder(\"utf-8\", { fatal: false }).decode(head);\n if (text.charCodeAt(0) === 0xfeff) {\n text = text.slice(1);\n }\n if (SNIFF_GRAPH_START.test(text)) {\n return 0.95;\n }\n if (SNIFF_KEY_START.test(text)) {\n return SNIFF_GRAPH_ANYWHERE.test(text) ? 0.85 : 0.4;\n }\n return 0;\n}\n\n/** The GML importer plugin. */\nexport const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({\n format: \"gml\",\n extensions: Object.freeze([\".gml\"]),\n mimeTypes: Object.freeze([\"text/x-gml\", \"text/plain\"]),\n sniff: sniffGml,\n /**\n * Read a GML text into a sink.\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportSinkOptions(sink, options, report);\n reportUnusedOptions(options, report, USED_OPTIONS);\n const tokens = tokenize(await readText(input, report, resolved), report);\n throwIfAborted(resolved.signal);\n const gml = new GmlImport(sink, report, resolved, options);\n gml.run(tokens);\n if (gml.graphCount > 1) {\n report.warning(\n \"unsupported\",\n SECOND_GRAPH_CODE,\n `the input holds ${gml.graphCount - 1} more graph block(s) after the first; import() reads the first, importAll() reads every one`,\n );\n }\n // an abort raised during the last few elements (after the last periodic check) still rejects\n throwIfAborted(resolved.signal);\n return report.finish();\n },\n\n /**\n * Read every `graph [ ... ]` block of a GML text, each into its own sink; the top-level keys\n * (Creator, Version, ...) apply to each.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph block\n */\n async importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: GmlImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const first = new ImportReportBuilder(\"gml\", resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const tokens = tokenize(await readText(input, first, resolved), first);\n const reports: ImportReport[] = [];\n let count = 1;\n for (let i = 0; i < count; i++) {\n throwIfAborted(resolved.signal);\n const report = i === 0 ? first : new ImportReportBuilder(\"gml\", resolved.errorLimit);\n const sink = sinkFor(i);\n reportSinkOptions(sink, options, report);\n const gml = new GmlImport(sink, report, resolved, options, i);\n gml.run(tokens);\n count = gml.graphCount;\n reports.push(report.finish());\n }\n throwIfAborted(resolved.signal);\n return reports;\n },\n});\n\n/**\n * Tokenize a GML text; a syntax error is fatal.\n * @param text - the whole text\n * @param report - where the syntax error is recorded\n * @returns the tokens\n */\nfunction tokenize(text: string, report: ImportReportBuilder): GmlTokens {\n try {\n return tokenizeGml(text);\n } catch (err) {\n if (err instanceof GmlSyntaxError) {\n report.fail(err.code, err.message, { line: err.line });\n }\n throw err;\n }\n}\n","/**\n * The `@graphty/graph-io/gml` subpath (design section 8.2): the GML importer and exporter, their\n * option types, and their issue and loss-note codes grouped in two tables.\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n ENCODING_FALLBACK_CODE,\n ID_MERGED_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MIXED_DIRECTION_CODE,\n OPTION_IGNORED_CODE,\n SINK_OPTION_CODE,\n SYNTAX_CODE,\n UNKNOWN_ENCODING_CODE,\n} from \"../../common/codes.js\";\nimport {\n GRAPHICS_CONFLICT_CODE,\n GRAPHICS_OVERRIDDEN_CODE,\n INVALID_KEY_CODE,\n JSON_ARRAY_CODE,\n KEY_MANGLED_CODE,\n NESTED_ARRAY_CODE,\n POSITION_COMPONENTS_CODE,\n RECORD_BOOLEAN_CODE,\n RECORD_NULL_CODE,\n RECORD_NUMBER_TYPE_CODE,\n RESERVED_KEY_CODE,\n} from \"./exporter.js\";\nimport {\n DUPLICATE_NODE_CODE,\n ELEMENT_TYPE_CODE,\n FLAG_TYPE_CODE,\n FLAG_VALUE_CODE,\n ID_DROPPED_CODE,\n ID_TYPE_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MISSING_LABEL_CODE,\n NO_GRAPH_CODE,\n PRECISION_CODE,\n REPEATED_KEY_CODE,\n ROLE_TAKEN_CODE,\n SECOND_GRAPH_CODE,\n STRING_ID_CODE,\n UNKNOWN_ENTITY_CODE,\n} from \"./importer.js\";\n\nexport { gmlExporter, type GmlExportOptions } from \"./exporter.js\";\nexport { gmlImporter, type GmlImportOptions } from \"./importer.js\";\n\n/**\n * The issue codes the GML importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the GML-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const GML_ISSUE = Object.freeze({\n /** A grammar violation: an untokenisable bare token, an unclosed string or `[`, a stray `]`, a key without a value (fatal). */\n SYNTAX: SYNTAX_CODE,\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 /** No `graph [` block (fatal). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** More than one `graph` block (fatal). */\n MULTIPLE_GRAPHS: SECOND_GRAPH_CODE,\n /** A node without an `id`. */\n MISSING_ID: MISSING_ID_CODE,\n /** A node without a `label` under nodeIdFrom \"label\". */\n MISSING_LABEL: MISSING_LABEL_CODE,\n /** An edge without `source` or `target`. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id, source or target that is neither an integer nor a string. */\n ID_TYPE: ID_TYPE_CODE,\n /** String node ids, sources or targets (outside the spec's integers), kept under the ids rule; warned once. */\n STRING_ID: STRING_ID_CODE,\n /** A node id declared twice (later keys overwrite). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A structural key repeated in one element. */\n REPEATED_KEY: REPEATED_KEY_CODE,\n /** A `node` / `edge` key whose value is not a record. */\n ELEMENT_TYPE: ELEMENT_TYPE_CODE,\n /** A `directed` / `multigraph` flag that is not an integer. */\n FLAG_TYPE: FLAG_TYPE_CODE,\n /** A `directed` / `multigraph` flag outside 0 / 1, or repeated. */\n FLAG_VALUE: FLAG_VALUE_CODE,\n /** A named entity in a string that no table decodes; kept as written. */\n UNKNOWN_ENTITY: UNKNOWN_ENTITY_CODE,\n /** An integer beyond 2^53 rounded to f64. */\n PRECISION: PRECISION_CODE,\n /** A column renamed `<name>#<key>` because the sink held the name with another shape. */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column declared without its role because the sink already holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A common option the importer has no use for was given. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The sink refused the file's direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A mixed file under onMixedDirection \"error\" (fatal). */\n MIXED_DIRECTION: MIXED_DIRECTION_CODE,\n /** Under nodeIdFrom \"label\" / \"index\" the integer ids are not kept (a loss note). */\n ID_DROPPED: ID_DROPPED_CODE,\n});\n\n/** The loss-note codes the GML exporter's check() reports beyond the shared LOSS table, by name. */\nexport const GML_LOSS = Object.freeze({\n /** A json column holds numbers; GML records cannot keep int versus real (design section 8.5). */\n RECORD_NUMBER_TYPE: RECORD_NUMBER_TYPE_CODE,\n /** A json column holds booleans, written 1 / 0. */\n RECORD_BOOLEAN: RECORD_BOOLEAN_CODE,\n /** A json column holds nulls, omitted. */\n RECORD_NULL: RECORD_NULL_CODE,\n /** An array inside an array; export() throws. */\n NESTED_ARRAY: NESTED_ARRAY_CODE,\n /** A json row that is an array, written as repeated keys. */\n JSON_ARRAY: JSON_ARRAY_CODE,\n /** A column name or record key outside the GML key grammar. */\n INVALID_KEY: INVALID_KEY_CODE,\n /** A column named like a structural key. */\n RESERVED_KEY: RESERVED_KEY_CODE,\n /** A key rewritten under sanitizeKeys \"mangle\". */\n KEY_MANGLED: KEY_MANGLED_CODE,\n /** A position column with more than three components. */\n POSITION_COMPONENTS: POSITION_COMPONENTS_CODE,\n /** A graphics record whose x / y / z the position column overrides. */\n GRAPHICS_OVERRIDDEN: GRAPHICS_OVERRIDDEN_CODE,\n /** A graphics record that cannot hold the position. */\n GRAPHICS_CONFLICT: GRAPHICS_CONFLICT_CODE,\n});\n"],"names":["SHARED_NO_GRAPH_CODE","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_PRECISION_CODE","SHARED_ROLE_TAKEN_CODE"],"mappings":"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"}