@graphty/graph-io 0.3.30 → 0.3.31

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 (72) hide show
  1. package/dist/chunks/{choose-BfOLq6OX.js → choose-BJq_vp1b.js} +2 -2
  2. package/dist/chunks/{choose-BfOLq6OX.js.map → choose-BJq_vp1b.js.map} +1 -1
  3. package/dist/chunks/{constants-M8Qsjz1C.js → constants-Bw-6JQuC.js} +2 -2
  4. package/dist/chunks/{constants-M8Qsjz1C.js.map → constants-Bw-6JQuC.js.map} +1 -1
  5. package/dist/chunks/{escape-UMMpQZqs.js → escape-CnTfa_y8.js} +2 -2
  6. package/dist/chunks/{escape-UMMpQZqs.js.map → escape-CnTfa_y8.js.map} +1 -1
  7. package/dist/chunks/{export-Dq4U8Ubq.js → export-ZucVKiU4.js} +13 -3
  8. package/dist/chunks/{export-Dq4U8Ubq.js.map → export-ZucVKiU4.js.map} +1 -1
  9. package/dist/chunks/{exporter-BUosqV0K.js → exporter-BOLJIzvA.js} +5 -5
  10. package/dist/chunks/exporter-BOLJIzvA.js.map +1 -0
  11. package/dist/chunks/{exporter-Bd_VZ9ph.js → exporter-DRNkA2k0.js} +5 -5
  12. package/dist/chunks/{exporter-Bd_VZ9ph.js.map → exporter-DRNkA2k0.js.map} +1 -1
  13. package/dist/chunks/{exporter-DEk_XLLs.js → exporter-DgDjwLOm.js} +7 -8
  14. package/dist/chunks/exporter-DgDjwLOm.js.map +1 -0
  15. package/dist/chunks/{exporter-COgVm-ff.js → exporter-hc2ZuqVe.js} +4 -4
  16. package/dist/chunks/{exporter-COgVm-ff.js.map → exporter-hc2ZuqVe.js.map} +1 -1
  17. package/dist/chunks/{importer-Cj4-lXlv.js → importer-BAlFKpHP.js} +6 -6
  18. package/dist/chunks/{importer-Cj4-lXlv.js.map → importer-BAlFKpHP.js.map} +1 -1
  19. package/dist/chunks/{importer-AQ3KpNHz.js → importer-ByCd2CAY.js} +5 -5
  20. package/dist/chunks/{importer-AQ3KpNHz.js.map → importer-ByCd2CAY.js.map} +1 -1
  21. package/dist/chunks/{importer-DwSZvMDq.js → importer-CaLIrkjL.js} +5 -5
  22. package/dist/chunks/{importer-DwSZvMDq.js.map → importer-CaLIrkjL.js.map} +1 -1
  23. package/dist/chunks/{importer-CV8au8gH.js → importer-D7xB8oVV.js} +4 -4
  24. package/dist/chunks/{importer-CV8au8gH.js.map → importer-D7xB8oVV.js.map} +1 -1
  25. package/dist/chunks/{importer-BsZa2Phx.js → importer-DsNj_zoG.js} +3 -3
  26. package/dist/chunks/{importer-BsZa2Phx.js.map → importer-DsNj_zoG.js.map} +1 -1
  27. package/dist/chunks/{importer-Dkn79TjB.js → importer-WPz-AUz8.js} +4 -4
  28. package/dist/chunks/{importer-Dkn79TjB.js.map → importer-WPz-AUz8.js.map} +1 -1
  29. package/dist/chunks/{importer-DQsgmhxc.js → importer-rjFCmKfx.js} +4 -4
  30. package/dist/chunks/{importer-DQsgmhxc.js.map → importer-rjFCmKfx.js.map} +1 -1
  31. package/dist/chunks/{json-elements-CreeKoaH.js → json-elements-CkC87El2.js} +3 -3
  32. package/dist/chunks/{json-elements-CreeKoaH.js.map → json-elements-CkC87El2.js.map} +1 -1
  33. package/dist/chunks/{ontology-export-C5Xd3W-7.js → ontology-export-BRErBO6J.js} +11 -9
  34. package/dist/chunks/ontology-export-BRErBO6J.js.map +1 -0
  35. package/dist/chunks/{records-BwaH_2ll.js → records-DwfSjH8c.js} +2 -2
  36. package/dist/chunks/{records-BwaH_2ll.js.map → records-DwfSjH8c.js.map} +1 -1
  37. package/dist/chunks/{text-4HHe6YH3.js → text-BEEWD-G1.js} +2 -2
  38. package/dist/chunks/{text-4HHe6YH3.js.map → text-BEEWD-G1.js.map} +1 -1
  39. package/dist/csv.js +4 -4
  40. package/dist/cx.js +1 -1
  41. package/dist/cx2.js +2 -2
  42. package/dist/cys.js +1 -1
  43. package/dist/dot.js +1 -1
  44. package/dist/gexf.js +2 -2
  45. package/dist/gml.js +3 -3
  46. package/dist/graph-io.js +26 -26
  47. package/dist/graphml.js +2 -2
  48. package/dist/json.js +1 -1
  49. package/dist/neo4j.js +3 -3
  50. package/dist/obo.js +1 -1
  51. package/dist/pajek.js +1 -1
  52. package/dist/src/common/export.d.ts +6 -1
  53. package/dist/src/common/export.d.ts.map +1 -1
  54. package/dist/src/common/export.js +18 -2
  55. package/dist/src/common/export.js.map +1 -1
  56. package/dist/src/common/ontology-export.d.ts.map +1 -1
  57. package/dist/src/common/ontology-export.js +11 -15
  58. package/dist/src/common/ontology-export.js.map +1 -1
  59. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  60. package/dist/src/formats/cx2/exporter.js +2 -4
  61. package/dist/src/formats/cx2/exporter.js.map +1 -1
  62. package/dist/src/formats/obo/exporter.d.ts +2 -2
  63. package/dist/src/formats/obo/exporter.js +2 -2
  64. package/dist/xgmml.js +2 -2
  65. package/package.json +2 -2
  66. package/src/common/export.ts +25 -3
  67. package/src/common/ontology-export.ts +12 -17
  68. package/src/formats/cx2/exporter.ts +2 -4
  69. package/src/formats/obo/exporter.ts +2 -2
  70. package/dist/chunks/exporter-BUosqV0K.js.map +0 -1
  71. package/dist/chunks/exporter-DEk_XLLs.js.map +0 -1
  72. package/dist/chunks/ontology-export-C5Xd3W-7.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"exporter-DEk_XLLs.js","sources":["../../src/formats/cx2/exporter.ts"],"sourcesContent":["/**\n * The CX2 exporter (design/graph-io/cytoscape-and-obo/design.md section 1.3; graphty issue #307):\n * writes a snapshot as one CX2 document -- the descriptor, the pre-metadata, one\n * `attributeDeclarations` block (aliases from `origin.id`, defaults from `meta.default`),\n * `networkAttributes`, `nodes` (x / y from the position with y flipped back to screen coordinates,\n * `z` from the `z` column), `edges`, the `cx2.bypass` columns as `nodeBypasses` / `edgeBypasses`,\n * the opaque aspects a CX2 import kept (which returns its own style rules) and `status`.\n *\n * What CX2 cannot hold is announced by check() before anything is written: every edge is\n * directed (W_CX2_UNDIRECTED_AS_DIRECTED, W_MUTUAL_EXPANDED), node ids are integers (E_ID_CHARSET\n * unless `sanitizeIds: \"mangle\"`, which keeps the original in the `graphty:originalId` attribute\n * the importer restores), nested values are written as JSON text (W_CX2_JSON_AS_STRING), NaN and\n * the infinities as null (W_CX2_NONFINITE_AS_NULL), and the generic notes of checkCapabilities().\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot } from \"@graphty/graph-format\";\n\nimport {\n aspectBlock,\n declaredType,\n directionNotes,\n nonFinitePositions,\n planEdgeIds,\n planNodeIds,\n stringify,\n type WrittenIds,\n} from \"../../common/cx-export.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { isRecord, POSITION_COLUMN } from \"../../common/json-elements.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { plural } from \"../../common/plural.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 { BYPASS_NAMESPACE, CX2_FORMAT, cx2Type, ORIGINAL_ID_ATTRIBUTE } from \"./importer.js\";\n\n/**\n * The options of the CX2 exporter: the common export options; it has none of its own.\n * @category Built-in formats\n */\nexport type Cx2ExportOptions = CommonExportOptions;\n\n/**\n * The loss notes the CX2 exporter's check() returns, by name. A key is the\n * code without its severity and format prefixes.\n * @category Built-in formats\n */\nexport const CX2_LOSS = Object.freeze({\n /**\n * Every edge is written as directed, so an undirected graph, or the undirected edges of a mixed graph, read back\n * as directed.\n */\n UNDIRECTED_AS_DIRECTED: \"W_CX2_UNDIRECTED_AS_DIRECTED\",\n /** A nested (json) column is written as a string attribute holding its JSON text. */\n JSON_AS_STRING: \"W_CX2_JSON_AS_STRING\",\n /** NaN and the infinities cannot be written; they are written as null and read back unset. */\n NONFINITE_AS_NULL: \"W_CX2_NONFINITE_AS_NULL\",\n /** A mutual pair is written as two directed edges without its mark. */\n MUTUAL_EXPANDED: LOSS.MUTUAL_EXPANDED,\n /**\n * An attribute without the weight role is named like the key weights are written under; it reads back as the edge\n * weight, or is not written when the graph has weights of its own.\n */\n WEIGHT_KEY_CLASH: LOSS.WEIGHT_KEY_CLASH,\n /** A parent / parents column: CX2 has no containment. */\n HIERARCHY_DROPPED: LOSS.HIERARCHY,\n /** A start / end / timestamp column: CX2 has no time. */\n TEMPORAL_DROPPED: LOSS.TEMPORAL,\n /** An attribute with a role the format has no place for is written as a plain attribute; the role is lost. */\n ROLE_DROPPED: LOSS.ROLE,\n /**\n * An attribute type CX2 stores as another (a 32-bit float as double, an unsigned integer as long, a dictionary as\n * string); it reads back with that type.\n */\n DTYPE_UNSUPPORTED: LOSS.DTYPE,\n /**\n * Node ids the format cannot write, under `sanitizeIds: \"error\"`; the save fails with E_INVALID_ID. Pass\n * `sanitizeIds: \"mangle\"` to rewrite them.\n */\n ID_CHARSET: LOSS.ID_CHARSET,\n /** Node ids that are not integers under sanitizeIds \"mangle\": renumbered, originals kept. */\n ID_MANGLED: LOSS.ID_MANGLED,\n /** Edges without a usable id get generated integer ids. */\n EDGE_IDS_GENERATED: LOSS.EDGE_IDS_GENERATED,\n});\n\n/**\n * What CX2 keeps: directed multigraphs with self-loops, integer node ids,\n * required integer edge ids, declared string / double / integer / boolean columns and lists of\n * them, declared defaults, network attributes and the position role. f32, u32, u8 and dict columns\n * are written as the nearest declared type and read back as it.\n * @category Built-in formats\n */\nexport const CX2_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"required\",\n idCharset: \"integer\",\n dtypes: [\"string\", \"f64\", \"i32\", \"bool\"],\n components: false,\n lists: true,\n json: false,\n defaults: true,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: true,\n positions: true,\n viz: false,\n});\n\n/** The roles CX2 has a slot for, and the column names its importer gives them. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\", \"position\", \"id\"]);\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n label: \"name\",\n position: POSITION_COLUMN,\n});\n\n/** Roles whose columns are never written as attributes. */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n]);\n\n/** The aspects the exporter writes itself; an opaque aspect of the same name is not written again. */\nconst CORE_ASPECTS: ReadonlySet<string> = new Set([\n \"nodes\",\n \"edges\",\n \"attributeDeclarations\",\n \"networkAttributes\",\n \"nodeBypasses\",\n \"edgeBypasses\",\n \"metaData\",\n \"status\",\n]);\n\n/** The weight attribute name. */\nconst WEIGHT_ATTRIBUTE = \"weight\";\n\n/** One attribute column as it will be written. */\ninterface AttributePlan {\n readonly column: Column;\n /** The full attribute name. */\n readonly name: string;\n /** The key used in v (the alias, or the name). */\n readonly key: string;\n /** The declared type text. */\n readonly d: string;\n /** Whether values are written as their JSON text (a json column). */\n readonly jsonText: boolean;\n}\n\n/** Everything export() and check() need, computed once. */\ninterface Plan {\n readonly notes: LossNote[];\n readonly fatal: GraphFormatError | null;\n readonly ids: WrittenIds | null;\n readonly folding: PairFolding;\n readonly weights: ExplicitWeights;\n readonly nodeAttrs: readonly AttributePlan[];\n readonly edgeAttrs: readonly AttributePlan[];\n readonly graphAttrs: readonly AttributePlan[];\n readonly nodeBypasses: readonly Column[];\n readonly edgeBypasses: readonly Column[];\n readonly position: Column | null;\n readonly positionZ: boolean;\n readonly z: Column | null;\n readonly edgeIds: readonly number[];\n readonly originalIds: boolean;\n}\n\n/**\n * Whether a column is a bypass column of a CX2 import.\n * @param column - the column\n * @returns true for the cx2.bypass namespace\n */\nfunction isBypass(column: Column): boolean {\n return column.meta.origin?.namespace === BYPASS_NAMESPACE;\n}\n\n/**\n * Whether a column is the z (stacking order) column.\n * @param column - the column\n * @returns true for the column marked by a Cytoscape-family importer\n */\nfunction isZ(column: Column): boolean {\n return column.meta.extra.cytoscape === \"z\";\n}\n\n/**\n * Count the non-finite numbers of a column.\n * @param column - the column\n * @returns how many set cells (or list items) are NaN or infinite\n */\nfunction nonFiniteCount(column: Column): number {\n const { dtype, itemDtype } = column.meta;\n const numeric =\n dtype === \"f32\" || dtype === \"f64\" || (dtype === \"list\" && (itemDtype === \"f32\" || itemDtype === \"f64\"));\n if (!numeric) {\n return 0;\n }\n let count = 0;\n for (let i = 0; i < column.length; i++) {\n if (!column.isSet(i)) {\n continue;\n }\n const value = column.value(i);\n if (dtype === \"list\") {\n if ((value as readonly number[]).some((v) => !Number.isFinite(v))) {\n count++;\n }\n } else if (!Number.isFinite(value)) {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Plan the attribute columns of one table.\n * @param table - the table\n * @param skip - columns not written as attributes\n * @param rename - the written name of a column, when it differs (the label as `name`)\n * @param reserved - keys already used in v\n * @returns the plans\n */\nfunction planAttributes(\n table: Iterable<Column>,\n skip: (column: Column) => boolean,\n rename: (column: Column) => string,\n reserved: ReadonlySet<string> = new Set(),\n): AttributePlan[] {\n const plans: AttributePlan[] = [];\n const used = new Set<string>(reserved);\n const candidates = [...table].filter((c) => !skip(c));\n for (const column of candidates) {\n used.add(rename(column));\n }\n for (const column of candidates) {\n const name = rename(column);\n const { origin } = column.meta;\n let key = name;\n const alias = origin?.format === CX2_FORMAT && typeof origin.id === \"string\" ? origin.id : null;\n if (alias !== null && alias.length > 0 && alias !== name && !used.has(alias)) {\n key = alias;\n used.add(alias);\n }\n plans.push({ column, name, key, d: declaredType(column), jsonText: column.meta.dtype === \"json\" });\n }\n return plans;\n}\n\n/** A note-recording callback. */\ntype Note = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/**\n * The generic notes of checkCapabilities(), adapted to CX2: bypass columns hold any JSON value,\n * ids are counted by planNodeIds(), nested values are written as JSON text, and only the node\n * label is written into the \"n\" slot (an edge label keeps its own name but loses its role).\n * @param snapshot - the snapshot\n * @param common - the resolved common options\n * @param notes - the notes so far, appended to\n * @param note - the recorder\n * @returns the fatal condition, or null\n */\nfunction capabilityNotes(\n snapshot: GraphSnapshot,\n common: ResolvedExportOptions,\n notes: LossNote[],\n note: Note,\n): GraphFormatError | null {\n let fatal: GraphFormatError | null = null;\n // bypass columns are written as bypasses, which hold any JSON value\n const bypassNames = new Set(\n [...snapshot.nodes, ...snapshot.edges].filter((c) => isBypass(c) || isZ(c)).map((c) => c.meta.name),\n );\n for (const gen of checkCapabilities(snapshot, CX2_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n })) {\n if (!keepGenericNote(gen, bypassNames)) {\n continue;\n }\n if (gen.code === LOSS.JSON) {\n note(\n CX2_LOSS.JSON_AS_STRING,\n `${gen.column === null ? \"a column\" : `column \"${gen.column}\"`} holds nested values; written as a string attribute holding their JSON text`,\n gen.column,\n gen.count,\n );\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && fatal === null) {\n fatal = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n notes.push(gen);\n }\n const edgeLabel = snapshot.edges.byRole(\"label\");\n if (edgeLabel !== null) {\n note(\n LOSS.ROLE,\n `edge column \"${edgeLabel.meta.name}\" (label) is written as a plain attribute; CX2 edges have no label slot and the role is lost`,\n edgeLabel.meta.name,\n edgeLabel.length - edgeLabel.nullCount,\n );\n }\n return fatal;\n}\n\n/**\n * Whether a generic note applies to CX2 as it stands.\n * @param gen - the generic note\n * @param bypassNames - the names of the columns written as bypasses\n * @returns false for a note CX2 drops or replaces\n */\nfunction keepGenericNote(gen: LossNote, bypassNames: ReadonlySet<string>): boolean {\n if (gen.column !== null && bypassNames.has(gen.column) && (gen.code === LOSS.JSON || gen.code === LOSS.DTYPE)) {\n return false;\n }\n if (gen.code === LOSS.COLUMN_NAME_CHANGED && gen.message.startsWith(\"edge column\")) {\n // only the node label is written into the \"n\" slot; an edge label keeps its own name\n return false;\n }\n // ids are counted by planNodeIds(): CX2 also keeps integer ids beyond 2^53, which the generic rule refuses\n return gen.code !== LOSS.ID_CHARSET && gen.code !== LOSS.ID_MANGLED;\n}\n\n/**\n * Note the NaN and infinite values written as null: attribute cells, explicit weights, positions.\n * @param snapshot - the snapshot\n * @param attrs - every planned attribute\n * @param weights - the explicit weights\n * @param position - the position column, or null\n * @param note - the recorder\n */\nfunction nonFiniteNote(\n snapshot: GraphSnapshot,\n attrs: readonly AttributePlan[],\n weights: ExplicitWeights,\n position: Column | null,\n note: Note,\n): void {\n let nonfinite = 0;\n for (const p of attrs) {\n nonfinite += nonFiniteCount(p.column);\n }\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (weights.isExplicit(e) && !Number.isFinite(weights.value(e))) {\n nonfinite++;\n }\n }\n if (position !== null) {\n nonfinite += nonFinitePositions(position);\n }\n if (nonfinite > 0) {\n note(\n CX2_LOSS.NONFINITE_AS_NULL,\n `${nonfinite} NaN or infinite value${plural(nonfinite)} cannot be written in CX2; written as null, they read back unset`,\n null,\n nonfinite,\n );\n }\n}\n\n/**\n * Plan the edge attributes, noting a plain `weight` column that clashes with the weight key.\n * @param snapshot - the snapshot\n * @param weights - the explicit weights\n * @param note - the recorder\n * @returns the edge attribute plans\n */\nfunction planEdgeAttributes(snapshot: GraphSnapshot, weights: ExplicitWeights, note: Note): AttributePlan[] {\n const plainWeight = snapshot.edges.get(WEIGHT_ATTRIBUTE);\n if (plainWeight !== null && plainWeight.meta.role === null) {\n note(\n LOSS.WEIGHT_KEY_CLASH,\n weights.weighted\n ? `edge column \"${WEIGHT_ATTRIBUTE}\" is not written: the explicit weights are written under that name`\n : `edge column \"${WEIGHT_ATTRIBUTE}\" reads back as the edge weight`,\n WEIGHT_ATTRIBUTE,\n null,\n );\n }\n return planAttributes(\n snapshot.edges,\n (c) =>\n (c.meta.role !== null && (SKIPPED_ROLES.has(c.meta.role) || c.meta.role === \"id\")) ||\n isBypass(c) ||\n (weights.weighted && c === plainWeight),\n (c) => c.meta.name,\n weights.weighted ? new Set([WEIGHT_ATTRIBUTE]) : new Set(),\n );\n}\n\n/**\n * Plan an export: the notes, the fatal condition and what is written.\n * @param snapshot - the snapshot\n * @param common - the resolved common options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, common: ResolvedExportOptions): Plan {\n const notes: LossNote[] = [];\n const note: Note = (code, message, column = null, count = null) => {\n notes.push(Object.freeze({ code, message, column, count }));\n };\n let fatal = capabilityNotes(snapshot, common, notes, note);\n\n const folding = pairFolding(snapshot);\n directionNotes(snapshot, folding, common, CX2_LOSS.UNDIRECTED_AS_DIRECTED, note);\n\n const planned = planNodeIds(snapshot, common, \"CX2\", ORIGINAL_ID_ATTRIBUTE, note);\n const ids = planned instanceof GraphFormatError ? null : planned;\n if (planned instanceof GraphFormatError) {\n fatal ??= planned;\n }\n\n const weights = explicitWeights(snapshot);\n const label = snapshot.nodes.byRole(\"label\");\n const nodeAttrs = planAttributes(\n snapshot.nodes,\n (c) => (c.meta.role !== null && SKIPPED_ROLES.has(c.meta.role)) || isBypass(c) || isZ(c),\n (c) => (c === label && !snapshot.nodes.has(\"name\") ? \"name\" : c.meta.name),\n ids !== null && ids.changed > 0 ? new Set([ORIGINAL_ID_ATTRIBUTE]) : new Set(),\n );\n const edgeAttrs = planEdgeAttributes(snapshot, weights, note);\n const graphAttrs = planAttributes(\n snapshot.graph,\n () => false,\n (c) => c.meta.name,\n ).map((p) => ({ ...p, key: p.name }));\n\n const position = snapshot.nodes.byRole(\"position\");\n nonFiniteNote(snapshot, [...nodeAttrs, ...edgeAttrs, ...graphAttrs], weights, position, note);\n\n const edgeIds = planEdgeIds(snapshot, note);\n const z = [...snapshot.nodes].find(isZ) ?? null;\n const positionZ = position !== null && z === null && position.meta.extra.sourceDims === 3;\n return {\n notes,\n fatal,\n ids,\n folding,\n weights,\n nodeAttrs,\n edgeAttrs,\n graphAttrs,\n nodeBypasses: [...snapshot.nodes].filter(isBypass),\n edgeBypasses: [...snapshot.edges].filter(isBypass),\n position,\n positionZ,\n z,\n edgeIds,\n originalIds: ids !== null && ids.changed > 0,\n };\n}\n\n// ============================================================ writing\n\n/**\n * The value written for one cell.\n * @param p - the attribute plan\n * @param row - the row\n * @returns the value, or undefined for an unset cell\n */\nfunction cellValue(p: AttributePlan, row: number): unknown {\n const { column } = p;\n if (!column.isSet(row)) {\n return undefined;\n }\n const value = column.value(row);\n if (p.jsonText) {\n return JSON.stringify(value);\n }\n if (column.meta.dtype === \"list\" || column.meta.components > 1) {\n const items = Array.from(value as ArrayLike<unknown>);\n if (p.d === \"string\") {\n return JSON.stringify(items);\n }\n return items.some((v) => typeof v === \"number\" && !Number.isFinite(v)) ? null : items;\n }\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return null;\n }\n return value;\n}\n\n/**\n * The declarations of one table.\n * @param plans - the attribute plans\n * @param defaults - whether defaults and aliases may be written (not for network attributes)\n * @returns the declaration object\n */\nfunction declarations(plans: readonly AttributePlan[], defaults: boolean): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const p of plans) {\n const decl: Record<string, unknown> = { d: p.d };\n if (defaults && p.key !== p.name) {\n decl.a = p.key;\n }\n const fallback = p.column.meta.default;\n if (defaults && fallback !== undefined && fallback !== null) {\n if (defaultFits(cx2Type(p.d), fallback)) {\n decl.v = fallback;\n }\n }\n out[p.name] = decl;\n }\n return out;\n}\n\n/**\n * Whether a declared default can be written as the value of a declared type.\n * @param type - the type\n * @param fallback - the default\n * @returns true when it matches\n */\nfunction defaultFits(type: ReturnType<typeof cx2Type>, fallback: unknown): boolean {\n if (type === null) {\n return false;\n }\n if (type.list) {\n return Array.isArray(fallback);\n }\n switch (type.scalar) {\n case \"string\":\n return typeof fallback === \"string\";\n case \"boolean\":\n return typeof fallback === \"boolean\";\n default:\n return typeof fallback === \"number\" && Number.isFinite(fallback);\n }\n}\n\n/**\n * The v object of one element.\n * @param plans - the attribute plans\n * @param row - the row\n * @returns the object, or null when empty\n */\nfunction attributesOf(plans: readonly AttributePlan[], row: number): Record<string, unknown> | null {\n let out: Record<string, unknown> | null = null;\n for (const p of plans) {\n const value = cellValue(p, row);\n if (value !== undefined) {\n out ??= {};\n out[p.key] = value;\n }\n }\n return out;\n}\n\n/**\n * Write the document as text parts.\n * @param snapshot - the snapshot\n * @param p - the plan\n * @yields the document's text\n * @returns nothing\n */\nfunction* write(snapshot: GraphSnapshot, p: Plan): Generator<string, void, undefined> {\n if (p.fatal !== null) {\n throw p.fatal;\n }\n const { ids } = p;\n if (ids === null) {\n throw new GraphFormatError(\"E_INVALID_ID\", \"node ids cannot be written as CX2 integers\", { reason: \"charset\" });\n }\n const { src, dst } = snapshot.edgeList();\n const edges: number[] = [];\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!p.folding.folded(e)) {\n edges.push(e);\n }\n }\n\n const nodeDecls = declarations(p.nodeAttrs, true);\n if (p.originalIds) {\n nodeDecls[ORIGINAL_ID_ATTRIBUTE] = { d: \"string\" };\n }\n const edgeDecls = declarations(p.edgeAttrs, true);\n if (p.weights.weighted) {\n edgeDecls[WEIGHT_ATTRIBUTE] = { d: \"double\" };\n }\n const networkDecls = declarations(p.graphAttrs, false);\n const network: Record<string, unknown> = {};\n for (const a of p.graphAttrs) {\n const value = cellValue(a, 0);\n if (value !== undefined) {\n network[a.name] = value;\n }\n }\n const { meta } = snapshot;\n for (const [key, value] of [\n [\"name\", meta.name],\n [\"description\", meta.description],\n ] as const) {\n if (value !== null && !(key in network) && !(key in networkDecls)) {\n network[key] = value;\n networkDecls[key] = { d: \"string\" };\n }\n }\n const kept = isRecord(meta.extra.cx2) ? meta.extra.cx2 : {};\n const otherDecls = isRecord(kept.declarations) ? kept.declarations : {};\n const opaque = meta.sourceFormat === CX2_FORMAT && isRecord(kept.opaque) ? kept.opaque : {};\n const declarationsElement: Record<string, unknown> = { ...otherDecls };\n for (const [key, table] of [\n [\"networkAttributes\", networkDecls],\n [\"nodes\", nodeDecls],\n [\"edges\", edgeDecls],\n ] as const) {\n if (Object.keys(table).length > 0) {\n declarationsElement[key] = table;\n }\n }\n const nodeBypassRows = bypassRows(p.nodeBypasses, snapshot.nodeCount);\n const edgeBypassRows = bypassRows(p.edgeBypasses, snapshot.edgeCount).filter((e) => !p.folding.folded(e));\n const opaqueAspects = Object.entries(opaque).filter(\n (entry): entry is [string, unknown[]] => !CORE_ASPECTS.has(entry[0]) && Array.isArray(entry[1]),\n );\n\n const counts: [string, number][] = [];\n const hasDeclarations = Object.keys(declarationsElement).length > 0;\n if (hasDeclarations) {\n counts.push([\"attributeDeclarations\", 1]);\n }\n if (Object.keys(network).length > 0) {\n counts.push([\"networkAttributes\", 1]);\n }\n counts.push([\"nodes\", snapshot.nodeCount], [\"edges\", edges.length]);\n if (nodeBypassRows.length > 0) {\n counts.push([\"nodeBypasses\", nodeBypassRows.length]);\n }\n if (edgeBypassRows.length > 0) {\n counts.push([\"edgeBypasses\", edgeBypassRows.length]);\n }\n for (const [name, elements] of opaqueAspects) {\n counts.push([name, elements.length]);\n }\n\n yield '[{\"CXVersion\":\"2.0\",\"hasFragments\":false},\\n';\n yield `{\"metaData\":${stringify(counts.map(([name, elementCount]) => ({ name, elementCount })))}},\\n`;\n if (hasDeclarations) {\n yield `{\"attributeDeclarations\":[${stringify(declarationsElement)}]},\\n`;\n }\n if (Object.keys(network).length > 0) {\n yield `{\"networkAttributes\":[${stringify(network)}]},\\n`;\n }\n yield* block(\"nodes\", snapshot.nodeCount, (i) => stringify(nodeElement(p, ids, i)));\n yield* block(\"edges\", edges.length, (k) => {\n const e = edges[k];\n const element: Record<string, unknown> = {\n id: p.edgeIds[e],\n s: ids.idAt(src[e]),\n t: ids.idAt(dst[e]),\n };\n let v = attributesOf(p.edgeAttrs, e);\n if (p.weights.isExplicit(e)) {\n const w = p.weights.value(e);\n v ??= {};\n v[WEIGHT_ATTRIBUTE] = Number.isFinite(w) ? w : null;\n }\n if (v !== null) {\n element.v = v;\n }\n return stringify(element);\n });\n if (nodeBypassRows.length > 0) {\n yield* block(\"nodeBypasses\", nodeBypassRows.length, (k) => {\n const i = nodeBypassRows[k];\n return stringify({ id: ids.idAt(i), v: bypassValues(p.nodeBypasses, i) });\n });\n }\n if (edgeBypassRows.length > 0) {\n yield* block(\"edgeBypasses\", edgeBypassRows.length, (k) => {\n const e = edgeBypassRows[k];\n return stringify({ id: p.edgeIds[e], v: bypassValues(p.edgeBypasses, e) });\n });\n }\n for (const [name, elements] of opaqueAspects) {\n yield* block(name, elements.length, (k) => stringify(elements[k]));\n }\n yield '{\"status\":[{\"error\":\"\",\"success\":true}]}]\\n';\n}\n\n/**\n * The text of one aspect block, element by element.\n * @param aspect - the aspect name\n * @param count - its element count\n * @param element - the JSON text of element k\n * @returns the block's text parts\n */\nfunction block(aspect: string, count: number, element: (k: number) => string): Generator<string, void, undefined> {\n return aspectBlock(\n aspect,\n (function* elements(): Generator<string, void, undefined> {\n for (let k = 0; k < count; k++) {\n yield element(k);\n }\n })(),\n );\n}\n\n/**\n * The element of node i.\n * @param p - the plan\n * @param ids - the written ids\n * @param i - the node index\n * @returns the element\n */\nfunction nodeElement(p: Plan, ids: WrittenIds, i: number): Record<string, unknown> {\n const element: Record<string, unknown> = { id: ids.idAt(i) };\n if (p.position?.isSet(i) === true) {\n const point = p.position.value(i) as ArrayLike<number>;\n if (Number.isFinite(point[0]) && Number.isFinite(point[1])) {\n element.x = point[0];\n element.y = point[1] === 0 ? 0 : -point[1];\n if (p.positionZ && Number.isFinite(point[2])) {\n element.z = point[2];\n }\n }\n }\n if (p.z?.isSet(i) === true) {\n const z = p.z.value(i);\n if (typeof z === \"number\" && Number.isFinite(z)) {\n element.z = z;\n }\n }\n let v = attributesOf(p.nodeAttrs, i);\n if (p.originalIds && ids.isChanged(i)) {\n v ??= {};\n v[ORIGINAL_ID_ATTRIBUTE] = String(ids.originalAt(i));\n }\n if (v !== null) {\n element.v = v;\n }\n return element;\n}\n\n/**\n * The rows with at least one bypass value.\n * @param columns - the bypass columns\n * @param rows - the row count\n * @returns the rows, ascending\n */\nfunction bypassRows(columns: readonly Column[], rows: number): number[] {\n const out: number[] = [];\n if (columns.length === 0) {\n return out;\n }\n for (let i = 0; i < rows; i++) {\n if (columns.some((c) => c.isSet(i))) {\n out.push(i);\n }\n }\n return out;\n}\n\n/**\n * The bypass values of one row.\n * @param columns - the bypass columns\n * @param row - the row\n * @returns property -> value\n */\nfunction bypassValues(columns: readonly Column[], row: number): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const column of columns) {\n if (column.isSet(row)) {\n // the visual property's own name: a column renamed for a clash with an attribute keeps it in origin.id\n const property = column.meta.origin?.id;\n out[typeof property === \"string\" && property.length > 0 ? property : column.meta.name] = column.value(row);\n }\n }\n return out;\n}\n\n/**\n * The CX2 exporter plugin.\n * @category Built-in formats\n */\nexport const cx2Exporter: GraphExporter<Cx2ExportOptions> = Object.freeze({\n format: CX2_FORMAT,\n options: Object.freeze([]),\n capabilities: CX2_CAPABILITIES,\n\n /**\n * Pre-flight: what export() would lose, without writing anything.\n * @param snapshot - the snapshot\n * @param options - the common options\n * @returns the notes, empty when the export is exact\n */\n check(snapshot: GraphSnapshot, options?: Cx2ExportOptions): readonly LossNote[] {\n return Object.freeze([...plan(snapshot, resolveExportOptions(options)).notes]);\n },\n\n /**\n * Write the document as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - the common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: Cx2ExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(write(snapshot, plan(snapshot, resolveExportOptions(options))));\n },\n\n /**\n * Write the document as one string.\n * @param snapshot - the snapshot\n * @param options - the common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: Cx2ExportOptions): Promise<string> {\n return joinText(write(snapshot, plan(snapshot, resolveExportOptions(options))));\n },\n});\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ontology-export-C5Xd3W-7.js","sources":["../../src/common/ontology.ts","../../src/common/ontology-export.ts"],"sourcesContent":["/**\n * What the OBO importer and the JSON importer's `obographs` dialect share (design section 1.0, the\n * `ontology.ts` building block): the OBO column vocabulary (names, dtypes, roles), so the `.obo` and\n * the `.json` of one ontology give the same columns, and the OBO 1.4 rule for turning the IRIs\n * OBO Graphs writes back into the identifiers the `.obo` file writes (section 4.6).\n */\n\nimport { type ColumnDecl } from \"@graphty/graph-format\";\n\n/** The dtypes the OBO vocabulary uses. */\ntype OboDtype = \"string\" | \"dict\" | \"bool\" | \"list\" | \"json\";\n\n/** One column of the OBO vocabulary. */\ninterface OboColumnSpec {\n /** The dtype. */\n readonly dtype: OboDtype;\n /** The role, when the column carries one. */\n readonly role?: \"label\" | \"kind\" | undefined;\n}\n\n/**\n * The node columns of the OBO vocabulary, keyed by column name (design section 4.2). The names are\n * the OBO tag names, so a Gene Ontology user finds `namespace`, `def` and `is_obsolete` under the\n * names the GO documentation uses.\n * @category Plugin helpers\n */\nexport const OBO_NODE_COLUMNS: Readonly<Record<string, OboColumnSpec>> = Object.freeze({\n type: { dtype: \"dict\" },\n name: { dtype: \"string\", role: \"label\" },\n namespace: { dtype: \"dict\" },\n def: { dtype: \"string\" },\n \"def.xrefs\": { dtype: \"list\" },\n comment: { dtype: \"string\" },\n synonym: { dtype: \"json\" },\n xref: { dtype: \"list\" },\n \"xref.descriptions\": { dtype: \"json\" },\n alt_id: { dtype: \"list\" },\n subset: { dtype: \"list\" },\n replaced_by: { dtype: \"list\" },\n consider: { dtype: \"list\" },\n is_obsolete: { dtype: \"bool\" },\n is_anonymous: { dtype: \"bool\" },\n builtin: { dtype: \"bool\" },\n created_by: { dtype: \"string\" },\n creation_date: { dtype: \"string\" },\n intersection_of: { dtype: \"json\" },\n union_of: { dtype: \"list\" },\n equivalent_to: { dtype: \"list\" },\n disjoint_from: { dtype: \"list\" },\n property_value: { dtype: \"json\" },\n // Typedef frames, under typedefs: \"nodes\"\n domain: { dtype: \"string\" },\n range: { dtype: \"string\" },\n inverse_of: { dtype: \"string\" },\n transitive_over: { dtype: \"list\" },\n disjoint_over: { dtype: \"list\" },\n holds_over_chain: { dtype: \"json\" },\n equivalent_to_chain: { dtype: \"json\" },\n expand_assertion_to: { dtype: \"json\" },\n expand_expression_to: { dtype: \"json\" },\n is_cyclic: { dtype: \"bool\" },\n is_reflexive: { dtype: \"bool\" },\n is_symmetric: { dtype: \"bool\" },\n is_anti_symmetric: { dtype: \"bool\" },\n is_asymmetric: { dtype: \"bool\" },\n is_transitive: { dtype: \"bool\" },\n is_functional: { dtype: \"bool\" },\n is_inverse_functional: { dtype: \"bool\" },\n is_metadata_tag: { dtype: \"bool\" },\n is_class_level: { dtype: \"bool\" },\n // OBO Graphs only\n propertyType: { dtype: \"dict\" },\n // what has no column of its own\n \"obo.qualifiers\": { dtype: \"json\" },\n \"obo.unrecognized\": { dtype: \"json\" },\n});\n\n/** The edge columns of the OBO vocabulary. */\nconst OBO_EDGE_COLUMNS: Readonly<Record<string, OboColumnSpec>> = Object.freeze({\n relation: { dtype: \"dict\", role: \"kind\" },\n qualifiers: { dtype: \"json\" },\n meta: { dtype: \"json\" },\n});\n\n/**\n * The node column that marks a node made for an undeclared reference (design section 4.2).\n * @category Plugin helpers\n */\nexport const PLACEHOLDER_COLUMN = \"graphty.placeholder\";\n\n/**\n * The declaration of an OBO vocabulary column.\n * @param domain - node or edge\n * @param name - the column name (a key of OBO_NODE_COLUMNS / OBO_EDGE_COLUMNS, or the placeholder column)\n * @returns the declaration, nullable, with origin `{ format: \"obo\", id: name }`\n * @category Plugin helpers\n */\nexport function oboColumnDecl(domain: \"node\" | \"edge\", name: string): ColumnDecl {\n if (name === PLACEHOLDER_COLUMN) {\n return { name, dtype: \"bool\", nullable: true, origin: { format: \"graphty\", id: \"placeholder\" } };\n }\n const spec = (domain === \"node\" ? OBO_NODE_COLUMNS : OBO_EDGE_COLUMNS)[name];\n const decl: ColumnDecl = { name, dtype: spec.dtype, nullable: true, origin: { format: \"obo\", id: name } };\n if (spec.dtype === \"list\") {\n decl.itemDtype = \"string\";\n }\n if (spec.role !== undefined) {\n decl.role = spec.role;\n }\n return decl;\n}\n\n/**\n * The OBO PURL base every OBO Foundry IRI starts with.\n * @category Plugin helpers\n */\nexport const OBO_PURL = \"http://purl.obolibrary.org/obo/\"; // NOSONAR(S5332): an identifier the OBO standard fixes, never fetched\n\n/** The same base under https, which newer OBO Graphs writers use. */\nconst OBO_PURL_HTTPS = \"https://purl.obolibrary.org/obo/\";\n\n/**\n * The oboInOwl namespace of the OBO-to-OWL mapping's annotation properties.\n * @category Plugin helpers\n */\nexport const OBO_IN_OWL = \"http://www.geneontology.org/formats/oboInOwl#\"; // NOSONAR(S5332): an identifier the OBO standard fixes, never fetched\n\n/**\n * An IRI as the identifier the `.obo` file writes (the OBO 1.4 mapping, section 5.9, read\n * backwards): `http://purl.obolibrary.org/obo/GO_0008150` is `GO:0008150` (the prefix is the text\n * before the first underscore), and `http://purl.obolibrary.org/obo/go#regulates` (how the OWL\n * translation writes an unprefixed OBO id: subsets, relations, synonym types) is `regulates`; the\n * same under `https://purl.obolibrary.org/obo/`.\n * Every other IRI, and an OBO PURL that fits neither form (`.../obo/T/Female`), is kept.\n * @param iri - the IRI\n * @returns the CURIE or local id, or the IRI unchanged\n * @category Plugin helpers\n */\nexport function compactOboIri(iri: string): string {\n const base = [OBO_PURL, OBO_PURL_HTTPS].find((b) => iri.startsWith(b));\n if (base === undefined) {\n return iri;\n }\n const rest = iri.slice(base.length);\n const hash = rest.indexOf(\"#\");\n if (hash > 0) {\n const local = rest.slice(hash + 1);\n return local.length > 0 && !rest.slice(0, hash).includes(\"/\") ? local : iri;\n }\n const underscore = rest.indexOf(\"_\");\n if (underscore <= 0 || rest.includes(\"/\") || underscore === rest.length - 1) {\n return iri;\n }\n return `${rest.slice(0, underscore)}:${rest.slice(underscore + 1)}`;\n}\n\n/**\n * The OBO synonym scopes.\n * @category Plugin helpers\n */\nexport const SYNONYM_SCOPES: ReadonlySet<string> = new Set([\"EXACT\", \"BROAD\", \"NARROW\", \"RELATED\"]);\n\n/**\n * The OBO synonym scope of an OBO Graphs synonym predicate (`hasExactSynonym`, with or without the\n * oboInOwl namespace).\n * @param pred - the predicate\n * @returns the scope, or null for a predicate that is not one of the four\n * @category Plugin helpers\n */\nexport function synonymScopeOf(pred: string): string | null {\n const local = pred.startsWith(OBO_IN_OWL) ? pred.slice(OBO_IN_OWL.length) : pred;\n const match = /^has(Exact|Broad|Narrow|Related)Synonym$/.exec(local);\n return match === null ? null : match[1].toUpperCase();\n}\n\n/**\n * The OBO tag a `basicPropertyValues` predicate of OBO Graphs came from (the OBO-to-OWL mapping of\n * the tags that are annotations), so the `.json` of an ontology fills the same columns as its\n * `.obo`. `shorthand` is the relation's short name; every predicate not listed is a\n * `property_value`.\n * @category Plugin helpers\n */\nexport const OBOGRAPHS_PREDICATE_TAGS: ReadonlyMap<string, string> = new Map([\n [`${OBO_IN_OWL}hasOBONamespace`, \"namespace\"],\n [`${OBO_IN_OWL}hasAlternativeId`, \"alt_id\"],\n [`${OBO_IN_OWL}created_by`, \"created_by\"],\n [`${OBO_IN_OWL}creation_date`, \"creation_date\"],\n [`${OBO_PURL}IAO_0100001`, \"replaced_by\"],\n [`${OBO_IN_OWL}consider`, \"consider\"],\n [`${OBO_IN_OWL}shorthand`, \"shorthand\"],\n]);\n","/**\n * What the two ontology exporters share (the OBO flat file and the JSON exporter's `obographs`\n * dialect): the snapshot columns that fill the OBO slots (the label as `name`, the edge kind as\n * `relation`), the placeholder nodes a re-import makes again by itself, the order a re-import gives\n * the nodes, and the text of a cell. Both read the snapshot through the column vocabulary of\n * ontology.ts, so a column means the same thing in both files.\n */\n\nimport { type Column, GraphFormatError, type GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { type ExportCapabilities, type LossNote } from \"../types.js\";\nimport { COLUMN_AS_PROPERTY_VALUE_CODE, ROLE_ASSUMED_CODE } from \"./codes.js\";\nimport { checkCapabilities, LOSS } from \"./export.js\";\nimport { formatNumber } from \"./format.js\";\nimport { PLACEHOLDER_COLUMN } from \"./ontology.js\";\nimport { type ResolvedExportOptions } from \"./options.js\";\n\n/**\n * A note recorder.\n * @category Plugin helpers\n */\nexport type NoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;\n\n/** The generic notes the ontology formats replace with their own (see capabilityNotes()). */\nconst SUPERSEDED: ReadonlySet<string> = new Set([\n LOSS.DTYPE,\n LOSS.LIST,\n LOSS.JSON,\n LOSS.COMPONENTS,\n LOSS.GRAPH_ATTRIBUTES,\n]);\n\n/** The roles the ontology formats have a slot for, and the column names their importers give them. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"label\", \"kind\"]);\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({ label: \"name\", kind: \"relation\" });\n\n/**\n * The roles whose columns are never written as values (their loss notes come from checkCapabilities()).\n * @category Plugin helpers\n */\nexport const UNWRITTEN_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n \"position\",\n \"color\",\n \"size\",\n \"shape\",\n \"thickness\",\n]);\n\n/**\n * The OBO frame types.\n * @category Plugin helpers\n */\nexport type FrameKind = \"Term\" | \"Instance\" | \"Typedef\";\n\n/**\n * The frame types as a set, for checking a `type` cell.\n * @category Plugin helpers\n */\nexport const FRAME_KINDS: ReadonlySet<string> = new Set([\"Term\", \"Instance\", \"Typedef\"]);\n\n/**\n * The value of a set cell (a multi-component value as a plain array), or undefined when unset; a\n * declared default is not a value here (the formats have no defaults and say so).\n * @param column - the column\n * @param row - the row\n * @returns the value or undefined\n * @category Plugin helpers\n */\nexport function cellOf(column: Column, row: number): unknown {\n if (!column.isSet(row)) {\n return undefined;\n }\n const value: unknown = column.value(row);\n return ArrayBuffer.isView(value) ? Array.from(value as unknown as ArrayLike<number>) : value;\n}\n\n/**\n * The text of a scalar value: a number by its dtype's shortest round-tripping form (`-0` kept), a\n * boolean as `true` / `false`, a string as it is, anything else as its JSON text.\n * @param value - the value\n * @param dtype - the dtype it came from (the item dtype for a list item)\n * @returns the text\n * @category Plugin helpers\n */\nexport function textOf(value: unknown, dtype: string): string {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"boolean\":\n return value ? \"true\" : \"false\";\n case \"number\":\n return formatNumber(\n value,\n dtype === \"f32\" || dtype === \"i32\" || dtype === \"u32\" || dtype === \"u8\" ? dtype : \"f64\",\n );\n default:\n return JSON.stringify(value) ?? \"null\";\n }\n}\n\n/**\n * Whether a column has the dtype of a vocabulary column (string and dict both fit a text column;\n * the other text dtype is reported, not refused).\n * @param want - the vocabulary dtype\n * @param column - the column\n * @returns true when the column can be written into the vocabulary slot\n * @category Plugin helpers\n */\nexport function fitsVocabulary(want: string, column: Column): boolean {\n switch (want) {\n case \"list\":\n case \"bool\":\n case \"json\":\n return column.dtype === want;\n default:\n return isText(column);\n }\n}\n\n/**\n * The values of a cell that may hold one value or a list of them.\n * @param value - the cell value, or undefined\n * @returns the values\n * @category Plugin helpers\n */\nexport function valuesOf(value: unknown): readonly unknown[] {\n if (value === undefined) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n\n/** A column chosen for an OBO slot. */\ninterface Slot {\n /** The column, or null when the snapshot has none for the slot. */\n readonly column: Column | null;\n /** Whether a role-less column was chosen by its name; it reads back with the role (W_ROLE_ASSUMED). */\n readonly assumed: boolean;\n}\n\n/**\n * The column of a slot: the column with the role when it holds text, else a role-less text column\n * of the slot's name (which the importer reads back with the role).\n * @param table - the node or edge table\n * @param role - the role (`label` for `name`, `kind` for `relation`)\n * @param name - the name the importer gives the slot\n * @returns the column and whether its role is assumed\n * @category Plugin helpers\n */\nexport function slotColumn(table: GraphSnapshot[\"nodes\"], role: \"label\" | \"kind\", name: string): Slot {\n const byRole = table.byRole(role);\n if (byRole !== null) {\n return { column: isText(byRole) ? byRole : null, assumed: false };\n }\n const byName = table.get(name);\n if (byName !== null && byName.meta.role === null && isText(byName)) {\n return { column: byName, assumed: true };\n }\n return { column: null, assumed: false };\n}\n\n/**\n * Whether a column holds text (string or dict).\n * @param column - the column\n * @returns true for string and dict\n */\nfunction isText(column: Column): boolean {\n return column.dtype === \"string\" || column.dtype === \"dict\";\n}\n\n/**\n * The placeholder column (`graphty.placeholder`, a bool), or null.\n * @param snapshot - the snapshot\n * @returns the column\n */\nfunction placeholderColumn(snapshot: GraphSnapshot): Column | null {\n const column = snapshot.nodes.get(PLACEHOLDER_COLUMN);\n return column !== null && column.dtype === \"bool\" ? column : null;\n}\n\n/**\n * The nodes written without a frame (OBO) or a node record (OBO Graphs) because the re-import makes\n * them again as placeholders: a `graphty.placeholder` true cell, no other set cell, an id written\n * as it is, an edge that references it, and (in the flat file, where an edge is written on its\n * source's frame) no edge of its own.\n * @param snapshot - the snapshot\n * @param written - the logical edges written\n * @param options - `outgoingAllowed`: whether a placeholder may be an edge's source; `changed`: whether a node's id is rewritten\n * @param options.outgoingAllowed - whether a placeholder may be an edge's source\n * @param options.changed - whether a node's id is rewritten\n * @returns one flag per node, 1 for a node written without a frame\n * @category Plugin helpers\n */\nexport function framelessNodes(\n snapshot: GraphSnapshot,\n written: readonly number[],\n options: { readonly outgoingAllowed: boolean; readonly changed: (i: number) => boolean },\n): Uint8Array {\n const flags = new Uint8Array(snapshot.nodeCount);\n const placeholder = placeholderColumn(snapshot);\n if (placeholder === null) {\n return flags;\n }\n const { src, dst } = snapshot.edgeList();\n const referenced = new Uint8Array(snapshot.nodeCount);\n const sources = new Uint8Array(snapshot.nodeCount);\n for (const e of written) {\n referenced[dst[e]] = 1;\n if (options.outgoingAllowed) {\n referenced[src[e]] = 1;\n } else {\n sources[src[e]] = 1;\n }\n }\n const others = [...snapshot.nodes].filter((c) => c !== placeholder);\n for (let i = 0; i < snapshot.nodeCount; i++) {\n if (\n placeholder.isSet(i) &&\n placeholder.value(i) === true &&\n referenced[i] === 1 &&\n sources[i] === 0 &&\n !options.changed(i) &&\n others.every((c) => !c.isSet(i))\n ) {\n flags[i] = 1;\n }\n }\n return flags;\n}\n\n/**\n * How many nodes a re-import puts at another index: the written nodes keep their order and the\n * placeholders follow in the order the edges first reference them.\n * @param frameless - the framelessNodes() flags\n * @param references - the node indices in the order the written edges reference them\n * @returns the number of nodes whose index changes\n * @category Plugin helpers\n */\nexport function movedNodes(frameless: Uint8Array, references: Iterable<number>): number {\n const order: number[] = [];\n for (let i = 0; i < frameless.length; i++) {\n if (frameless[i] === 0) {\n order.push(i);\n }\n }\n const seen = new Uint8Array(frameless.length);\n for (const i of references) {\n if (frameless[i] === 1 && seen[i] === 0) {\n seen[i] = 1;\n order.push(i);\n }\n }\n let moved = 0;\n for (let k = 0; k < order.length; k++) {\n if (order[k] !== k) {\n moved++;\n }\n }\n return moved;\n}\n\n/**\n * Whether a value is a qualifier record as the importers make it: a non-empty object of names to a\n * text or a list of two or more texts (a name given once reads back as a text, never as a\n * one-item list), every name passing `nameOk`.\n * @param value - the value\n * @param nameOk - the name rule\n * @returns true when the record is written and read back unchanged\n * @category Plugin helpers\n */\nexport function isQualifierRecord(value: unknown, nameOk: (name: string) => boolean): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const entries = Object.entries(value);\n return (\n entries.length > 0 &&\n entries.every(\n ([name, v]) =>\n nameOk(name) &&\n (typeof v === \"string\" ||\n (Array.isArray(v) && v.length >= 2 && v.every((item) => typeof item === \"string\"))),\n )\n );\n}\n\n/** What capabilityNotes() needs to know about the export. */\ninterface CapabilityNoteSpec {\n /** The format's capabilities. */\n readonly caps: ExportCapabilities;\n /** The label column written as the name, or null. */\n readonly label: Column | null;\n /** Whether the label is a role-less `name` column. */\n readonly labelAssumed: boolean;\n /** Where an edge column without a slot goes, for messages (\"a qualifier\"). */\n readonly edgeSlot: string;\n /** Records a note. */\n readonly note: NoteFn;\n}\n\n/**\n * The generic notes of checkCapabilities() as the ontology formats see them. No column of the\n * snapshot's own survives as a column (the formats keep only the OBO vocabulary), so the generic\n * dtype, list, json, strides and graph-attribute notes give way to the formats' own, which say\n * where each column goes (a vocabulary column written into its slot needs no note; any other\n * becomes property values, edge qualifiers or metadata). The name-change notes stand only for the\n * label and kind columns actually written into their slot. Added: the roles without a slot (a\n * node kind, an edge label) and a role-less `name` column taking the label role.\n * @param snapshot - the snapshot\n * @param common - the common options\n * @param spec - the export's facts\n * @returns the fatal error of a mixed graph under onMixedDirection \"error\", or null\n * @category Plugin helpers\n */\nexport function capabilityNotes(\n snapshot: GraphSnapshot,\n common: ResolvedExportOptions,\n spec: CapabilityNoteSpec,\n): GraphFormatError | null {\n const { label, note } = spec;\n let fatal: GraphFormatError | null = null;\n const kind = snapshot.edges.byRole(\"kind\");\n for (const gen of checkCapabilities(snapshot, spec.caps, common, { roles: SLOT_ROLES, roleNames: ROLE_NAMES })) {\n if (SUPERSEDED.has(gen.code) || (gen.code === LOSS.COLUMN_NAME_CHANGED && !isSlotRename(gen, label, kind))) {\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && fatal === null) {\n fatal = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n note(gen.code, gen.message, gen.column, gen.count);\n }\n slotlessRoleNotes(snapshot, spec);\n return fatal;\n}\n\n/**\n * Note the roles the ontology formats have no slot for (a node kind, an edge label), and a\n * role-less `name` column taking the label role.\n * @param snapshot - the snapshot\n * @param spec - the export's facts\n */\nfunction slotlessRoleNotes(snapshot: GraphSnapshot, spec: CapabilityNoteSpec): void {\n const { label, note } = spec;\n const nodeKind = snapshot.nodes.byRole(\"kind\");\n if (nodeKind !== null) {\n note(\n LOSS.ROLE,\n `node column \"${nodeKind.meta.name}\" (kind) is written as property values; the format has no node kind slot`,\n nodeKind.meta.name,\n nodeKind.length - nodeKind.nullCount,\n );\n }\n const edgeLabel = snapshot.edges.byRole(\"label\");\n if (edgeLabel !== null) {\n note(\n LOSS.ROLE,\n `edge column \"${edgeLabel.meta.name}\" (label) is written as ${spec.edgeSlot}; the format has no edge label slot`,\n edgeLabel.meta.name,\n edgeLabel.length - edgeLabel.nullCount,\n );\n }\n if (label !== null && spec.labelAssumed) {\n note(\n ROLE_ASSUMED_CODE,\n `node column \"name\" is written as each node's name and reads back as the label`,\n \"name\",\n label.length - label.nullCount,\n );\n }\n}\n\n/**\n * Whether a name-change note is about a column written into its slot: the node label, or a text\n * edge kind column.\n * @param gen - the note\n * @param label - the node label column, or null\n * @param kind - the edge kind column, or null\n * @returns true when it is\n */\nfunction isSlotRename(gen: LossNote, label: Column | null, kind: Column | null): boolean {\n const isLabel = label !== null && gen.column === label.meta.name;\n return isLabel || (kind !== null && gen.column === kind.meta.name && isText(kind));\n}\n\n/**\n * Record the columns that read back absent: a node or edge column without a set cell on a written\n * element (the importers declare a column when a value needs it).\n * @param snapshot - the snapshot\n * @param rows - the written nodes\n * @param frameless - the frameless flags (a placeholder column set only there reads back)\n * @param written - the written edges\n * @param note - records a note\n * @category Plugin helpers\n */\nexport function emptyColumnNotes(\n snapshot: GraphSnapshot,\n rows: readonly number[],\n frameless: Uint8Array,\n written: readonly number[],\n note: NoteFn,\n): void {\n const tables = [\n [\n \"node\",\n snapshot.nodes,\n (c: Column): boolean =>\n rows.some((i) => c.isSet(i)) ||\n (c.meta.name === PLACEHOLDER_COLUMN && frameless.some((f, i) => f === 1 && c.isSet(i))),\n ],\n [\"edge\", snapshot.edges, (c: Column): boolean => written.some((e) => c.isSet(e))],\n ] as const;\n for (const [domain, table, used] of tables) {\n for (const column of table) {\n const { role, name } = column.meta;\n if (\n (role !== null && (UNWRITTEN_ROLES.has(role) || (domain === \"edge\" && role === \"id\"))) ||\n used(column)\n ) {\n continue;\n }\n note(LOSS.EMPTY_COLUMN, `${domain} column \"${name}\" has no value to write; it reads back absent`, name, 0);\n }\n }\n}\n\n/**\n * Record the note of a node column written as property values.\n * @param note - the recorder\n * @param column - the column\n * @param rows - the written nodes\n * @param how - how the values are written, for the message\n * @category Plugin helpers\n */\nexport function notePropertyColumn(note: NoteFn, column: Column, rows: readonly number[], how: string): void {\n const count = rows.filter((i) => column.isSet(i)).length;\n if (count === 0) {\n return;\n }\n const role = column.meta.role === null ? \"\" : ` (its ${column.meta.role} role is lost)`;\n note(\n COLUMN_AS_PROPERTY_VALUE_CODE,\n `node column \"${column.meta.name}\" is written as ${how} and reads back inside the property_value column, not as its own column${role}`,\n column.meta.name,\n count,\n );\n}\n"],"names":[],"mappings":";;AA0BO,MAAM,mBAA4D,OAAO,OAAO;AAAA,EACnF,MAAM,EAAE,OAAO,OAAA;AAAA,EACf,MAAM,EAAE,OAAO,UAAU,MAAM,QAAA;AAAA,EAC/B,WAAW,EAAE,OAAO,OAAA;AAAA,EACpB,KAAK,EAAE,OAAO,SAAA;AAAA,EACd,aAAa,EAAE,OAAO,OAAA;AAAA,EACtB,SAAS,EAAE,OAAO,SAAA;AAAA,EAClB,SAAS,EAAE,OAAO,OAAA;AAAA,EAClB,MAAM,EAAE,OAAO,OAAA;AAAA,EACf,qBAAqB,EAAE,OAAO,OAAA;AAAA,EAC9B,QAAQ,EAAE,OAAO,OAAA;AAAA,EACjB,QAAQ,EAAE,OAAO,OAAA;AAAA,EACjB,aAAa,EAAE,OAAO,OAAA;AAAA,EACtB,UAAU,EAAE,OAAO,OAAA;AAAA,EACnB,aAAa,EAAE,OAAO,OAAA;AAAA,EACtB,cAAc,EAAE,OAAO,OAAA;AAAA,EACvB,SAAS,EAAE,OAAO,OAAA;AAAA,EAClB,YAAY,EAAE,OAAO,SAAA;AAAA,EACrB,eAAe,EAAE,OAAO,SAAA;AAAA,EACxB,iBAAiB,EAAE,OAAO,OAAA;AAAA,EAC1B,UAAU,EAAE,OAAO,OAAA;AAAA,EACnB,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,gBAAgB,EAAE,OAAO,OAAA;AAAA;AAAA,EAEzB,QAAQ,EAAE,OAAO,SAAA;AAAA,EACjB,OAAO,EAAE,OAAO,SAAA;AAAA,EAChB,YAAY,EAAE,OAAO,SAAA;AAAA,EACrB,iBAAiB,EAAE,OAAO,OAAA;AAAA,EAC1B,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,kBAAkB,EAAE,OAAO,OAAA;AAAA,EAC3B,qBAAqB,EAAE,OAAO,OAAA;AAAA,EAC9B,qBAAqB,EAAE,OAAO,OAAA;AAAA,EAC9B,sBAAsB,EAAE,OAAO,OAAA;AAAA,EAC/B,WAAW,EAAE,OAAO,OAAA;AAAA,EACpB,cAAc,EAAE,OAAO,OAAA;AAAA,EACvB,cAAc,EAAE,OAAO,OAAA;AAAA,EACvB,mBAAmB,EAAE,OAAO,OAAA;AAAA,EAC5B,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,eAAe,EAAE,OAAO,OAAA;AAAA,EACxB,uBAAuB,EAAE,OAAO,OAAA;AAAA,EAChC,iBAAiB,EAAE,OAAO,OAAA;AAAA,EAC1B,gBAAgB,EAAE,OAAO,OAAA;AAAA;AAAA,EAEzB,cAAc,EAAE,OAAO,OAAA;AAAA;AAAA,EAEvB,kBAAkB,EAAE,OAAO,OAAA;AAAA,EAC3B,oBAAoB,EAAE,OAAO,OAAA;AACjC,CAAC;AAGD,MAAM,mBAA4D,OAAO,OAAO;AAAA,EAC5E,UAAU,EAAE,OAAO,QAAQ,MAAM,OAAA;AAAA,EACjC,YAAY,EAAE,OAAO,OAAA;AAAA,EACrB,MAAM,EAAE,OAAO,OAAA;AACnB,CAAC;AAMM,MAAM,qBAAqB;AAS3B,SAAS,cAAc,QAAyB,MAA0B;AAC7E,MAAI,SAAS,oBAAoB;AAC7B,WAAO,EAAE,MAAM,OAAO,QAAQ,UAAU,MAAM,QAAQ,EAAE,QAAQ,WAAW,IAAI,cAAA,EAAc;AAAA,EACjG;AACA,QAAM,QAAQ,WAAW,SAAS,mBAAmB,kBAAkB,IAAI;AAC3E,QAAM,OAAmB,EAAE,MAAM,OAAO,KAAK,OAAO,UAAU,MAAM,QAAQ,EAAE,QAAQ,OAAO,IAAI,OAAK;AACtG,MAAI,KAAK,UAAU,QAAQ;AACvB,SAAK,YAAY;AAAA,EACrB;AACA,MAAI,KAAK,SAAS,QAAW;AACzB,SAAK,OAAO,KAAK;AAAA,EACrB;AACA,SAAO;AACX;AAMO,MAAM,WAAW;AAGxB,MAAM,iBAAiB;AAMhB,MAAM,aAAa;AAanB,SAAS,cAAc,KAAqB;AAC/C,QAAM,OAAO,CAAC,UAAU,cAAc,EAAE,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;AACrE,MAAI,SAAS,QAAW;AACpB,WAAO;AAAA,EACX;AACA,QAAM,OAAO,IAAI,MAAM,KAAK,MAAM;AAClC,QAAM,OAAO,KAAK,QAAQ,GAAG;AAC7B,MAAI,OAAO,GAAG;AACV,UAAM,QAAQ,KAAK,MAAM,OAAO,CAAC;AACjC,WAAO,MAAM,SAAS,KAAK,CAAC,KAAK,MAAM,GAAG,IAAI,EAAE,SAAS,GAAG,IAAI,QAAQ;AAAA,EAC5E;AACA,QAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,MAAI,cAAc,KAAK,KAAK,SAAS,GAAG,KAAK,eAAe,KAAK,SAAS,GAAG;AACzE,WAAO;AAAA,EACX;AACA,SAAO,GAAG,KAAK,MAAM,GAAG,UAAU,CAAC,IAAI,KAAK,MAAM,aAAa,CAAC,CAAC;AACrE;AAMO,MAAM,qCAA0C,IAAI,CAAC,SAAS,SAAS,UAAU,SAAS,CAAC;AAS3F,SAAS,eAAe,MAA6B;AACxD,QAAM,QAAQ,KAAK,WAAW,UAAU,IAAI,KAAK,MAAM,WAAW,MAAM,IAAI;AAC5E,QAAM,QAAQ,2CAA2C,KAAK,KAAK;AACnE,SAAO,UAAU,OAAO,OAAO,MAAM,CAAC,EAAE,YAAA;AAC5C;AASO,MAAM,+CAA4D,IAAI;AAAA,EACzE,CAAC,GAAG,UAAU,mBAAmB,WAAW;AAAA,EAC5C,CAAC,GAAG,UAAU,oBAAoB,QAAQ;AAAA,EAC1C,CAAC,GAAG,UAAU,cAAc,YAAY;AAAA,EACxC,CAAC,GAAG,UAAU,iBAAiB,eAAe;AAAA,EAC9C,CAAC,GAAG,QAAQ,eAAe,aAAa;AAAA,EACxC,CAAC,GAAG,UAAU,YAAY,UAAU;AAAA,EACpC,CAAC,GAAG,UAAU,aAAa,WAAW;AAC1C,CAAC;ACtKD,MAAM,iCAAsC,IAAI;AAAA,EAC5C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACT,CAAC;AAGD,MAAM,aAAkC,oBAAI,IAAI,CAAC,SAAS,MAAM,CAAC;AACjE,MAAM,aAA+C,OAAO,OAAO,EAAE,OAAO,QAAQ,MAAM,YAAY;AAM/F,MAAM,sCAA2C,IAAI;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAYM,MAAM,cAAmC,oBAAI,IAAI,CAAC,QAAQ,YAAY,SAAS,CAAC;AAUhF,SAAS,OAAO,QAAgB,KAAsB;AACzD,MAAI,CAAC,OAAO,MAAM,GAAG,GAAG;AACpB,WAAO;AAAA,EACX;AACA,QAAM,QAAiB,OAAO,MAAM,GAAG;AACvC,SAAO,YAAY,OAAO,KAAK,IAAI,MAAM,KAAK,KAAqC,IAAI;AAC3F;AAUO,SAAS,OAAO,OAAgB,OAAuB;AAC1D,UAAQ,OAAO,OAAA;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO,QAAQ,SAAS;AAAA,IAC5B,KAAK;AACD,aAAO;AAAA,QACH;AAAA,QACA,UAAU,SAAS,UAAU,SAAS,UAAU,SAAS,UAAU,OAAO,QAAQ;AAAA,MAAA;AAAA,IAE1F;AACI,aAAO,KAAK,UAAU,KAAK,KAAK;AAAA,EAAA;AAE5C;AAUO,SAAS,eAAe,MAAc,QAAyB;AAClE,UAAQ,MAAA;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACD,aAAO,OAAO,UAAU;AAAA,IAC5B;AACI,aAAO,OAAO,MAAM;AAAA,EAAA;AAEhC;AAQO,SAAS,SAAS,OAAoC;AACzD,MAAI,UAAU,QAAW;AACrB,WAAO,CAAA;AAAA,EACX;AACA,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAChD;AAmBO,SAAS,WAAW,OAA+B,MAAwB,MAAoB;AAClG,QAAM,SAAS,MAAM,OAAO,IAAI;AAChC,MAAI,WAAW,MAAM;AACjB,WAAO,EAAE,QAAQ,OAAO,MAAM,IAAI,SAAS,MAAM,SAAS,MAAA;AAAA,EAC9D;AACA,QAAM,SAAS,MAAM,IAAI,IAAI;AAC7B,MAAI,WAAW,QAAQ,OAAO,KAAK,SAAS,QAAQ,OAAO,MAAM,GAAG;AAChE,WAAO,EAAE,QAAQ,QAAQ,SAAS,KAAA;AAAA,EACtC;AACA,SAAO,EAAE,QAAQ,MAAM,SAAS,MAAA;AACpC;AAOA,SAAS,OAAO,QAAyB;AACrC,SAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACzD;AAOA,SAAS,kBAAkB,UAAwC;AAC/D,QAAM,SAAS,SAAS,MAAM,IAAI,kBAAkB;AACpD,SAAO,WAAW,QAAQ,OAAO,UAAU,SAAS,SAAS;AACjE;AAeO,SAAS,eACZ,UACA,SACA,SACU;AACV,QAAM,QAAQ,IAAI,WAAW,SAAS,SAAS;AAC/C,QAAM,cAAc,kBAAkB,QAAQ;AAC9C,MAAI,gBAAgB,MAAM;AACtB,WAAO;AAAA,EACX;AACA,QAAM,EAAE,KAAK,QAAQ,SAAS,SAAA;AAC9B,QAAM,aAAa,IAAI,WAAW,SAAS,SAAS;AACpD,QAAM,UAAU,IAAI,WAAW,SAAS,SAAS;AACjD,aAAW,KAAK,SAAS;AACrB,eAAW,IAAI,CAAC,CAAC,IAAI;AACrB,QAAI,QAAQ,iBAAiB;AACzB,iBAAW,IAAI,CAAC,CAAC,IAAI;AAAA,IACzB,OAAO;AACH,cAAQ,IAAI,CAAC,CAAC,IAAI;AAAA,IACtB;AAAA,EACJ;AACA,QAAM,SAAS,CAAC,GAAG,SAAS,KAAK,EAAE,OAAO,CAAC,MAAM,MAAM,WAAW;AAClE,WAAS,IAAI,GAAG,IAAI,SAAS,WAAW,KAAK;AACzC,QACI,YAAY,MAAM,CAAC,KACnB,YAAY,MAAM,CAAC,MAAM,QACzB,WAAW,CAAC,MAAM,KAClB,QAAQ,CAAC,MAAM,KACf,CAAC,QAAQ,QAAQ,CAAC,KAClB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GACjC;AACE,YAAM,CAAC,IAAI;AAAA,IACf;AAAA,EACJ;AACA,SAAO;AACX;AAUO,SAAS,WAAW,WAAuB,YAAsC;AACpF,QAAM,QAAkB,CAAA;AACxB,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,QAAI,UAAU,CAAC,MAAM,GAAG;AACpB,YAAM,KAAK,CAAC;AAAA,IAChB;AAAA,EACJ;AACA,QAAM,OAAO,IAAI,WAAW,UAAU,MAAM;AAC5C,aAAW,KAAK,YAAY;AACxB,QAAI,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,GAAG;AACrC,WAAK,CAAC,IAAI;AACV,YAAM,KAAK,CAAC;AAAA,IAChB;AAAA,EACJ;AACA,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,QAAI,MAAM,CAAC,MAAM,GAAG;AAChB;AAAA,IACJ;AAAA,EACJ;AACA,SAAO;AACX;AAWO,SAAS,kBAAkB,OAAgB,QAA4C;AAC1F,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACrE,WAAO;AAAA,EACX;AACA,QAAM,UAAU,OAAO,QAAQ,KAAK;AACpC,SACI,QAAQ,SAAS,KACjB,QAAQ;AAAA,IACJ,CAAC,CAAC,MAAM,CAAC,MACL,OAAO,IAAI,MACV,OAAO,MAAM,YACT,MAAM,QAAQ,CAAC,KAAK,EAAE,UAAU,KAAK,EAAE,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ;AAAA,EAAA;AAGpG;AA8BO,SAAS,gBACZ,UACA,QACA,MACuB;AACvB,QAAM,EAAE,OAAO,KAAA,IAAS;AACxB,MAAI,QAAiC;AACrC,QAAM,OAAO,SAAS,MAAM,OAAO,MAAM;AACzC,aAAW,OAAO,kBAAkB,UAAU,KAAK,MAAM,QAAQ,EAAE,OAAO,YAAY,WAAW,WAAA,CAAY,GAAG;AAC5G,QAAI,WAAW,IAAI,IAAI,IAAI,KAAM,IAAI,SAAS,KAAK,uBAAuB,CAAC,aAAa,KAAK,OAAO,IAAI,GAAI;AACxG;AAAA,IACJ;AACA,QAAI,IAAI,SAAS,KAAK,yBAAyB,UAAU,MAAM;AAC3D,cAAQ,IAAI,iBAAiB,cAAc,IAAI,SAAS,EAAE,QAAQ,mBAAmB;AAAA,IACzF;AACA,SAAK,IAAI,MAAM,IAAI,SAAS,IAAI,QAAQ,IAAI,KAAK;AAAA,EACrD;AACA,oBAAkB,UAAU,IAAI;AAChC,SAAO;AACX;AAQA,SAAS,kBAAkB,UAAyB,MAAgC;AAChF,QAAM,EAAE,OAAO,KAAA,IAAS;AACxB,QAAM,WAAW,SAAS,MAAM,OAAO,MAAM;AAC7C,MAAI,aAAa,MAAM;AACnB;AAAA,MACI,KAAK;AAAA,MACL,gBAAgB,SAAS,KAAK,IAAI;AAAA,MAClC,SAAS,KAAK;AAAA,MACd,SAAS,SAAS,SAAS;AAAA,IAAA;AAAA,EAEnC;AACA,QAAM,YAAY,SAAS,MAAM,OAAO,OAAO;AAC/C,MAAI,cAAc,MAAM;AACpB;AAAA,MACI,KAAK;AAAA,MACL,gBAAgB,UAAU,KAAK,IAAI,2BAA2B,KAAK,QAAQ;AAAA,MAC3E,UAAU,KAAK;AAAA,MACf,UAAU,SAAS,UAAU;AAAA,IAAA;AAAA,EAErC;AACA,MAAI,UAAU,QAAQ,KAAK,cAAc;AACrC;AAAA,MACI;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,SAAS,MAAM;AAAA,IAAA;AAAA,EAE7B;AACJ;AAUA,SAAS,aAAa,KAAe,OAAsB,MAA8B;AACrF,QAAM,UAAU,UAAU,QAAQ,IAAI,WAAW,MAAM,KAAK;AAC5D,SAAO,WAAY,SAAS,QAAQ,IAAI,WAAW,KAAK,KAAK,QAAQ,OAAO,IAAI;AACpF;AAYO,SAAS,iBACZ,UACA,MACA,WACA,SACA,MACI;AACJ,QAAM,SAAS;AAAA,IACX;AAAA,MACI;AAAA,MACA,SAAS;AAAA,MACT,CAAC,MACG,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAC1B,EAAE,KAAK,SAAS,sBAAsB,UAAU,KAAK,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,MAAM,CAAC,CAAC;AAAA,IAAA;AAAA,IAE7F,CAAC,QAAQ,SAAS,OAAO,CAAC,MAAuB,QAAQ,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAAA,EAAA;AAEpF,aAAW,CAAC,QAAQ,OAAO,IAAI,KAAK,QAAQ;AACxC,eAAW,UAAU,OAAO;AACxB,YAAM,EAAE,MAAM,KAAA,IAAS,OAAO;AAC9B,UACK,SAAS,SAAS,gBAAgB,IAAI,IAAI,KAAM,WAAW,UAAU,SAAS,SAC/E,KAAK,MAAM,GACb;AACE;AAAA,MACJ;AACA,WAAK,KAAK,cAAc,GAAG,MAAM,YAAY,IAAI,iDAAiD,MAAM,CAAC;AAAA,IAC7G;AAAA,EACJ;AACJ;AAUO,SAAS,mBAAmB,MAAc,QAAgB,MAAyB,KAAmB;AACzG,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,OAAO,MAAM,CAAC,CAAC,EAAE;AAClD,MAAI,UAAU,GAAG;AACb;AAAA,EACJ;AACA,QAAM,OAAO,OAAO,KAAK,SAAS,OAAO,KAAK,SAAS,OAAO,KAAK,IAAI;AACvE;AAAA,IACI;AAAA,IACA,gBAAgB,OAAO,KAAK,IAAI,mBAAmB,GAAG,0EAA0E,IAAI;AAAA,IACpI,OAAO,KAAK;AAAA,IACZ;AAAA,EAAA;AAER;"}