@graphty/graph-io 0.3.49 → 0.3.50
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.
- package/dist/chunks/{approximations-Bzn3L-je.js → approximations-BRXsll0T.js} +2 -2
- package/dist/chunks/{approximations-Bzn3L-je.js.map → approximations-BRXsll0T.js.map} +1 -1
- package/dist/chunks/{block-iptrlMBb.js → block-yl0f_qLO.js} +27 -2
- package/dist/chunks/block-yl0f_qLO.js.map +1 -0
- package/dist/chunks/{context-C3p0RQxR.js → context-DizmppHy.js} +2 -2
- package/dist/chunks/{context-C3p0RQxR.js.map → context-DizmppHy.js.map} +1 -1
- package/dist/chunks/{credentials-DXHx7nwR.js → credentials-CmvJXYeH.js} +58 -9
- package/dist/chunks/credentials-CmvJXYeH.js.map +1 -0
- package/dist/chunks/{descriptor-DLA5kINx.js → descriptor-Dhez_Cew.js} +5 -1
- package/dist/chunks/{descriptor-DLA5kINx.js.map → descriptor-Dhez_Cew.js.map} +1 -1
- package/dist/chunks/{emit-BwHQkZle.js → emit-7Jkpg0yd.js} +132 -4
- package/dist/chunks/emit-7Jkpg0yd.js.map +1 -0
- package/dist/chunks/{exporter-nDfxIK5D.js → exporter-1Ajud15J.js} +4 -4
- package/dist/chunks/{exporter-nDfxIK5D.js.map → exporter-1Ajud15J.js.map} +1 -1
- package/dist/chunks/{exporter-D9yMtocA.js → exporter-B6yvL3wy.js} +3 -3
- package/dist/chunks/{exporter-D9yMtocA.js.map → exporter-B6yvL3wy.js.map} +1 -1
- package/dist/chunks/{exporter-_jrBTnos.js → exporter-CA5q8ROP.js} +4 -4
- package/dist/chunks/{exporter-_jrBTnos.js.map → exporter-CA5q8ROP.js.map} +1 -1
- package/dist/chunks/{exporter-D2CETOMK.js → exporter-CQQZFJ2v.js} +72 -10
- package/dist/chunks/exporter-CQQZFJ2v.js.map +1 -0
- package/dist/chunks/{generic-ymWCETAJ.js → generic-Dc21MAdg.js} +3 -3
- package/dist/chunks/{generic-ymWCETAJ.js.map → generic-Dc21MAdg.js.map} +1 -1
- package/dist/chunks/{importer-CT9mJ1nn.js → importer-C6NVpCXp.js} +7 -6
- package/dist/chunks/importer-C6NVpCXp.js.map +1 -0
- package/dist/chunks/{importer-GREKMdIf.js → importer-CKFe4q54.js} +4 -4
- package/dist/chunks/{importer-GREKMdIf.js.map → importer-CKFe4q54.js.map} +1 -1
- package/dist/chunks/{importer-PqaaKKnY.js → importer-CKbUbsJA.js} +4 -4
- package/dist/chunks/{importer-PqaaKKnY.js.map → importer-CKbUbsJA.js.map} +1 -1
- package/dist/chunks/{importer-DaLTjbds.js → importer-ClCsdgTJ.js} +97 -7
- package/dist/chunks/importer-ClCsdgTJ.js.map +1 -0
- package/dist/chunks/{importer-B92x1xY5.js → importer-CyVZTrf0.js} +3 -3
- package/dist/chunks/{importer-B92x1xY5.js.map → importer-CyVZTrf0.js.map} +1 -1
- package/dist/chunks/{importer-vRq4h3j5.js → importer-DgG4v1Ms.js} +89 -20
- package/dist/chunks/importer-DgG4v1Ms.js.map +1 -0
- package/dist/chunks/{importer-Vn5QvmmJ.js → importer-asFUrIsj.js} +2 -2
- package/dist/chunks/{importer-Vn5QvmmJ.js.map → importer-asFUrIsj.js.map} +1 -1
- package/dist/chunks/{lexicon-Clf4QIyl.js → lexicon-IVRq2Uoo.js} +2 -2
- package/dist/chunks/{lexicon-Clf4QIyl.js.map → lexicon-IVRq2Uoo.js.map} +1 -1
- package/dist/chunks/{round-trip-Zm3_ivgq.js → round-trip-Cy3_SHRZ.js} +2 -2
- package/dist/chunks/{round-trip-Zm3_ivgq.js.map → round-trip-Cy3_SHRZ.js.map} +1 -1
- package/dist/chunks/{sigv4-EokFic1V.js → sigv4-BXwVbza3.js} +3 -3
- package/dist/chunks/{sigv4-EokFic1V.js.map → sigv4-BXwVbza3.js.map} +1 -1
- package/dist/chunks/{styles-CCs214_3.js → styles-CAVmBLgp.js} +4 -4
- package/dist/chunks/{styles-CCs214_3.js.map → styles-CAVmBLgp.js.map} +1 -1
- package/dist/chunks/{styles-DPQQIig4.js → styles-CPczw1Jz.js} +4 -4
- package/dist/chunks/{styles-DPQQIig4.js.map → styles-CPczw1Jz.js.map} +1 -1
- package/dist/chunks/{styles-Cm62yyQX.js → styles-boK6Ln54.js} +65 -30
- package/dist/chunks/styles-boK6Ln54.js.map +1 -0
- package/dist/chunks/{styles-yed-UMFdNqze.js → styles-yed-XeFBQ6VS.js} +8 -8
- package/dist/chunks/{styles-yed-UMFdNqze.js.map → styles-yed-XeFBQ6VS.js.map} +1 -1
- package/dist/cx.js +2 -2
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +7 -4
- package/dist/gexf.js +2 -2
- package/dist/gml.js +8 -8
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +129 -104
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +2 -2
- package/dist/json.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/sources-cypher.js +25 -22
- package/dist/sources-cypher.js.map +1 -1
- package/dist/sources-ndex.js +2 -2
- package/dist/sources-rest.js +20 -4
- package/dist/sources-rest.js.map +1 -1
- package/dist/sources-sparql.js +40 -6
- package/dist/sources-sparql.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +34 -2
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +6 -1
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +65 -5
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +3 -1
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +2 -1
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/label-places.d.ts +7 -0
- package/dist/src/formats/dot/label-places.d.ts.map +1 -1
- package/dist/src/formats/dot/label-places.js +9 -3
- package/dist/src/formats/dot/label-places.js.map +1 -1
- package/dist/src/formats/dot/names.d.ts +13 -0
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +13 -0
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/styles.d.ts +10 -0
- package/dist/src/formats/dot/styles.d.ts.map +1 -1
- package/dist/src/formats/dot/styles.js +49 -3
- package/dist/src/formats/dot/styles.js.map +1 -1
- package/dist/src/formats/gml/styles.js +1 -1
- package/dist/src/formats/gml/styles.js.map +1 -1
- package/dist/src/formats/graphml/styles-yed.js +3 -3
- package/dist/src/formats/graphml/styles-yed.js.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.d.ts.map +1 -1
- package/dist/src/formats/graphml/styles-yfiles3.js +6 -4
- package/dist/src/formats/graphml/styles-yfiles3.js.map +1 -1
- package/dist/src/formats/json/styles.d.ts.map +1 -1
- package/dist/src/formats/json/styles.js +94 -6
- package/dist/src/formats/json/styles.js.map +1 -1
- package/dist/src/formats/pajek/draw.d.ts +8 -0
- package/dist/src/formats/pajek/draw.d.ts.map +1 -1
- package/dist/src/formats/pajek/draw.js +10 -0
- package/dist/src/formats/pajek/draw.js.map +1 -1
- package/dist/src/formats/pajek/styles.d.ts.map +1 -1
- package/dist/src/formats/pajek/styles.js +142 -25
- package/dist/src/formats/pajek/styles.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/sources/credentials.d.ts +50 -1
- package/dist/src/sources/credentials.d.ts.map +1 -1
- package/dist/src/sources/credentials.js +69 -0
- package/dist/src/sources/credentials.js.map +1 -1
- package/dist/src/sources/cypher/index.d.ts.map +1 -1
- package/dist/src/sources/cypher/index.js +12 -11
- package/dist/src/sources/cypher/index.js.map +1 -1
- package/dist/src/sources/cypher/query-builder.d.ts +6 -6
- package/dist/src/sources/cypher/query-builder.d.ts.map +1 -1
- package/dist/src/sources/cypher/query-builder.js +15 -15
- package/dist/src/sources/cypher/query-builder.js.map +1 -1
- package/dist/src/sources/rest/descriptor.d.ts.map +1 -1
- package/dist/src/sources/rest/descriptor.js +4 -0
- package/dist/src/sources/rest/descriptor.js.map +1 -1
- package/dist/src/sources/rest/openalex.d.ts +4 -2
- package/dist/src/sources/rest/openalex.d.ts.map +1 -1
- package/dist/src/sources/rest/openalex.js +4 -2
- package/dist/src/sources/rest/openalex.js.map +1 -1
- package/dist/src/sources/rest/source.d.ts.map +1 -1
- package/dist/src/sources/rest/source.js +23 -0
- package/dist/src/sources/rest/source.js.map +1 -1
- package/dist/src/sources/run.d.ts +2 -0
- package/dist/src/sources/run.d.ts.map +1 -1
- package/dist/src/sources/run.js +30 -3
- package/dist/src/sources/run.js.map +1 -1
- package/dist/src/sources/sparql/index.d.ts.map +1 -1
- package/dist/src/sources/sparql/index.js +14 -1
- package/dist/src/sources/sparql/index.js.map +1 -1
- package/dist/src/sources/sparql/query.d.ts +2 -1
- package/dist/src/sources/sparql/query.d.ts.map +1 -1
- package/dist/src/sources/sparql/query.js +55 -4
- package/dist/src/sources/sparql/query.js.map +1 -1
- package/dist/src/sources/types.d.ts +29 -0
- package/dist/src/sources/types.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.d.ts.map +1 -1
- package/dist/src/styles/canon/enums.js +8 -0
- package/dist/src/styles/canon/enums.js.map +1 -1
- package/dist/src/styles/cyjs/cascade.d.ts.map +1 -1
- package/dist/src/styles/cyjs/cascade.js +124 -0
- package/dist/src/styles/cyjs/cascade.js.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.d.ts.map +1 -1
- package/dist/src/styles/cyjs/defaults-table.js +1 -0
- package/dist/src/styles/cyjs/defaults-table.js.map +1 -1
- package/dist/src/styles/cyjs/emit.d.ts.map +1 -1
- package/dist/src/styles/cyjs/emit.js +30 -1
- package/dist/src/styles/cyjs/emit.js.map +1 -1
- package/dist/src/styles/cyjs/mappers.d.ts.map +1 -1
- package/dist/src/styles/cyjs/mappers.js +14 -0
- package/dist/src/styles/cyjs/mappers.js.map +1 -1
- package/dist/src/styles/types.d.ts +65 -0
- package/dist/src/styles/types.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.d.ts.map +1 -1
- package/dist/src/styles/vocabulary.js +21 -0
- package/dist/src/styles/vocabulary.js.map +1 -1
- package/dist/styles.js +6 -6
- package/dist/xgmml.js +3 -3
- package/package.json +2 -2
- package/src/formats/dot/exporter.ts +37 -1
- package/src/formats/dot/importer.ts +75 -4
- package/src/formats/dot/index.ts +3 -1
- package/src/formats/dot/label-places.ts +16 -3
- package/src/formats/dot/names.ts +15 -0
- package/src/formats/dot/styles.ts +55 -3
- package/src/formats/gml/styles.ts +1 -1
- package/src/formats/graphml/styles-yed.ts +3 -3
- package/src/formats/graphml/styles-yfiles3.ts +6 -4
- package/src/formats/json/styles.ts +102 -6
- package/src/formats/pajek/draw.ts +11 -0
- package/src/formats/pajek/styles.ts +151 -26
- package/src/index.ts +7 -0
- package/src/sources/credentials.ts +90 -1
- package/src/sources/cypher/index.ts +12 -11
- package/src/sources/cypher/query-builder.ts +15 -15
- package/src/sources/rest/descriptor.ts +4 -0
- package/src/sources/rest/openalex.ts +4 -2
- package/src/sources/rest/source.ts +25 -0
- package/src/sources/run.ts +35 -3
- package/src/sources/sparql/index.ts +16 -1
- package/src/sources/sparql/query.ts +58 -4
- package/src/sources/types.ts +33 -0
- package/src/styles/canon/enums.ts +9 -0
- package/src/styles/cyjs/cascade.ts +143 -0
- package/src/styles/cyjs/defaults-table.ts +1 -0
- package/src/styles/cyjs/emit.ts +35 -1
- package/src/styles/cyjs/mappers.ts +14 -0
- package/src/styles/types.ts +65 -0
- package/src/styles/vocabulary.ts +21 -0
- package/dist/chunks/block-iptrlMBb.js.map +0 -1
- package/dist/chunks/credentials-DXHx7nwR.js.map +0 -1
- package/dist/chunks/emit-BwHQkZle.js.map +0 -1
- package/dist/chunks/exporter-D2CETOMK.js.map +0 -1
- package/dist/chunks/importer-CT9mJ1nn.js.map +0 -1
- package/dist/chunks/importer-DaLTjbds.js.map +0 -1
- package/dist/chunks/importer-vRq4h3j5.js.map +0 -1
- package/dist/chunks/styles-Cm62yyQX.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as canonColor, n as noteAt, b as STYLE_ISSUE, s as scalarText, c as canonNumber, i as num6, j as canonOpacity, a as canonEnum, k as canonBoolean, f as canonText, l as isStyleValue } from "./block-
|
|
1
|
+
import { d as canonColor, n as noteAt, b as STYLE_ISSUE, s as scalarText, c as canonNumber, i as num6, j as canonOpacity, a as canonEnum, k as canonBoolean, f as canonText, l as isStyleValue } from "./block-yl0f_qLO.js";
|
|
2
2
|
const color = (raw, site) => canonColor(raw, "cytoscape", site)?.color ?? null;
|
|
3
3
|
const opacity255 = (raw, site) => {
|
|
4
4
|
const v = canonNumber(raw, site);
|
|
@@ -728,4 +728,4 @@ export {
|
|
|
728
728
|
sizeParser as s,
|
|
729
729
|
vpStep as v
|
|
730
730
|
};
|
|
731
|
-
//# sourceMappingURL=lexicon-
|
|
731
|
+
//# sourceMappingURL=lexicon-IVRq2Uoo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexicon-Clf4QIyl.js","sources":["../../src/styles/cytoscape/lexicon.ts"],"sourcesContent":["/**\n * Cytoscape desktop's visual lexicon (CX, CX2, sessions, XGMML): which visual properties set each neutral\n * property, and how each value is read. Cytoscape states opacities two ways (`NODE_TRANSPARENCY` 0..255 in the\n * desktop and CX version 1, `NODE_BACKGROUND_OPACITY` 0..1 in CX2); both are read here.\n */\n\nimport { canonColor } from \"../canon/color.js\";\nimport { canonEnum } from \"../canon/enums.js\";\nimport { canonBoolean, canonNumber, canonOpacity, num6 } from \"../canon/number.js\";\nimport { type CanonSite, noteAt, scalarText } from \"../canon/site.js\";\nimport { canonText } from \"../canon/text.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport type { StyleNotes } from \"../notes.js\";\nimport type { StyleTarget, StyleValue } from \"../types.js\";\nimport { isStyleValue } from \"../vocabulary.js\";\n\n/**\n * Reads one raw Cytoscape value as a neutral property's canonical value, noting a problem at the site.\n * @category Styles\n */\nexport type CytoscapeValueParser = (raw: unknown, site: CanonSite) => StyleValue | null;\n\n// A color; its alpha is dropped (Cytoscape keeps opacity in separate properties).\nconst color: CytoscapeValueParser = (raw, site) => canonColor(raw, \"cytoscape\", site)?.color ?? null;\n\n// Cytoscape desktop's 0..255 transparency.\nconst opacity255: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n if (v === null) {\n return null;\n }\n if (v > 255) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, String(raw));\n return null;\n }\n return num6(Math.round(v) / 255);\n};\n\n// CX2's 0..1 opacity.\nconst opacity01: CytoscapeValueParser = (raw, site) => canonOpacity(raw, \"css\", site);\nconst length: CytoscapeValueParser = (raw, site) => canonNumber(raw, site);\n// An arrow size as the neutral factor: Cytoscape's normal arrow is size 6 (default_vizmap.xml).\nexport const arrowSizeParser: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n return v === null ? null : num6(v / 6);\n};\n\n// Degrees, clockwise on screen as Cytoscape turns a label, folded into 0..360.\n// ponytail: a continuous mapping across 0 (from -30 to 30) folds to 330..30 and interpolates the long way round;\n// keep the sign when a file needs it.\nconst rotation: CytoscapeValueParser = (raw, site) => {\n const v = typeof raw === \"number\" ? raw : Number(scalarText(raw, site)?.trim() ?? Number.NaN);\n if (!Number.isFinite(v)) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, String(raw));\n return null;\n }\n return num6(((v % 360) + 360) % 360);\n};\n\n// Cytoscape desktop holds a font size as a whole number, so every value read for one is drawn rounded.\nconst fontSize: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n return v === null ? null : Math.round(v);\n};\nconst text: CytoscapeValueParser = (raw, site) => canonText(raw, site);\nconst bool: CytoscapeValueParser = (raw, site) => canonBoolean(raw, site);\n\n// CX2's `element` / `none`, or a boolean.\nconst visibility: CytoscapeValueParser = (raw, site) => {\n if (typeof raw === \"string\") {\n const t = raw.trim().toLowerCase();\n if (t === \"element\" || t === \"visible\") {\n return true;\n }\n if (t === \"none\" || t === \"hidden\") {\n return false;\n }\n }\n return canonBoolean(raw, site);\n};\n\n/** Cytoscape spellings the common shape table does not hold. */\nconst CY_SHAPES: ReadonlyMap<string, string> = new Map([[\"rounded_rectangle\", \"round-rectangle\"]]);\n\n/**\n * Cytoscape reads its enumeration names whatever their case, so a name it does not know is kept lowercase and\n * hyphenated, the form of the names it knows: `Bogus` and the `BOGUS` a writer spells it as read the same.\n * @param v - a canonical value\n * @returns the value, an `other:` one in that form\n */\nconst caseless = (v: StyleValue | null): StyleValue | null =>\n typeof v === \"string\" && v.startsWith(\"other:\") ? `other:${v.slice(6).toLowerCase().replaceAll(\"_\", \"-\")}` : v;\n\nconst shape: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n return caseless(CY_SHAPES.get(s.trim().toLowerCase()) ?? canonEnum(\"shape\", s, \"cytoscape\", site));\n};\n\n/** Cytoscape's arrow names, desktop (`DELTA`) and CX2 (`triangle`), lowercase. */\nconst CY_ARROWS: ReadonlyMap<string, string> = new Map([\n [\"none\", \"none\"],\n [\"delta\", \"triangle\"],\n // a filled delta with a shallow notch in its back, as long and wide as DELTA (Cytoscape 3.10.5 SVG export)\n [\"arrow\", \"triangle\"],\n [\"diamond\", \"diamond\"],\n [\"circle\", \"circle\"],\n [\"t\", \"tee\"],\n [\"half_top\", \"half\"],\n // the half arrow on the line's other side from HALF_TOP's\n [\"half_bottom\", \"other:half-bottom\"],\n [\"square\", \"square\"],\n [\"delta_short_1\", \"triangle\"],\n [\"delta_short_2\", \"triangle\"],\n // a short arrow whose notch is too shallow to show: drawn as the triangle it reads as\n [\"arrow_short\", \"triangle\"],\n [\"diamond_short_1\", \"diamond\"],\n [\"diamond_short_2\", \"diamond\"],\n [\"open_delta\", \"triangle-open\"],\n [\"open_circle\", \"circle-open\"],\n [\"open_diamond\", \"diamond-open\"],\n [\"open_square\", \"other:open-square\"],\n // a delta with a bar across the line behind it\n [\"cross_delta\", \"other:cross-delta\"],\n [\"cross_open_delta\", \"other:cross-open-delta\"],\n [\"open_half_circle\", \"other:open-half-circle\"],\n [\"half_circle\", \"other:half-circle\"],\n [\"triangle\", \"triangle\"],\n [\"triangle-tee\", \"tee\"],\n // CX2's spelling of CROSS_DELTA\n [\"triangle-cross\", \"other:cross-delta\"],\n [\"triangle-backcurve\", \"triangle\"],\n [\"tee\", \"tee\"],\n [\"vee\", \"vee\"],\n [\"open-circle\", \"circle-open\"],\n [\"open-triangle\", \"triangle-open\"],\n [\"open-diamond\", \"diamond-open\"],\n [\"open-square\", \"other:open-square\"],\n [\"open-delta\", \"triangle-open\"],\n [\"half-top\", \"half\"],\n [\"half-bottom\", \"other:half-bottom\"],\n]);\n\n/**\n * How much longer and wider than the neutral shape it is read as each Cytoscape arrow is drawn: the short deltas and\n * diamonds, the short arrow and the crossed deltas (a bar behind the delta), from the unit glyphs Cytoscape 3.10.5's\n * SVG export draws (a DELTA is 2 long and 1 wide, DELTA_SHORT_1 1 by 1, ARROW_SHORT 1.2 by 0.8, CROSS_DELTA 3 by 1.5).\n * Every other arrow is drawn in its shape's own proportions.\n */\nconst CY_ARROW_PROPORTIONS: ReadonlyMap<string, { readonly length: number; readonly width: number }> = new Map([\n [\"delta_short_1\", { length: 0.5, width: 1 }],\n [\"delta_short_2\", { length: 0.25, width: 1 }],\n [\"arrow_short\", { length: 0.6, width: 0.8 }],\n [\"diamond_short_1\", { length: 0.5, width: 1 }],\n [\"diamond_short_2\", { length: 0.25, width: 1 }],\n [\"cross_delta\", { length: 1.5, width: 1.5 }],\n [\"cross_open_delta\", { length: 1.5, width: 1.5 }],\n [\"triangle-cross\", { length: 1.5, width: 1.5 }],\n]);\n\n/**\n * How far from its node Cytoscape draws each arrow that stands off the node's outline, as a multiple of the arrow's\n * own length along its line, from the unit glyphs Cytoscape 3.10.5's SVG export draws back from the outline: T's bar\n * from 0.8 to 1 (4 of its 0.2), a half circle from 0.5 to 1, HALF_TOP's barb from 0.3 to 1.435, a square from 0.25\n * to 1.25. Every other arrow touches the outline.\n */\nconst CY_ARROW_GAPS: ReadonlyMap<string, number> = new Map([\n [\"t\", 4],\n [\"tee\", 4],\n [\"half_circle\", 1],\n [\"open_half_circle\", 1],\n [\"half_top\", 0.3 / 1.135],\n [\"half_bottom\", 0.3 / 1.135],\n [\"half-top\", 0.3 / 1.135],\n [\"half-bottom\", 0.3 / 1.135],\n [\"square\", 0.25],\n [\"open_square\", 0.25],\n [\"open-square\", 0.25],\n]);\n\n/** Cytoscape 2.x numbered arrow codes. */\nconst LEGACY_ARROW: readonly string[] = [\n \"none\",\n \"delta\",\n \"delta\",\n \"delta\",\n \"arrow\",\n \"arrow\",\n \"arrow\",\n \"diamond\",\n \"diamond\",\n \"diamond\",\n \"circle\",\n \"circle\",\n \"circle\",\n \"t\",\n \"t\",\n \"t\",\n \"half_top\",\n \"half_bottom\",\n];\n\n/**\n * A Cytoscape arrow name, lowercase, with a 2.x numbered code read as its name.\n * @param s - the raw name\n * @returns the key\n */\nfunction arrowKey(s: string): string {\n const key = s.trim().toLowerCase();\n return /^\\d{1,2}$/.test(key) ? (LEGACY_ARROW.at(Number(key)) ?? key) : key;\n}\n\nconst arrow: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n return caseless(CY_ARROWS.get(arrowKey(s)) ?? canonEnum(\"arrow\", s, \"cytoscape\", site));\n};\n\n/**\n * The parser of an arrow's length or width as a fraction of its neutral shape's, from the arrow's name: 1 for every\n * arrow Cytoscape draws in its shape's proportions, so a bypass over a short default draws the full shape again.\n * @param side - which proportion\n * @returns the parser; null for a name it does not know (the shape's parser notes it)\n */\nexport function arrowProportion(side: \"length\" | \"width\"): CytoscapeValueParser {\n return (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = arrowKey(s);\n return CY_ARROW_PROPORTIONS.get(key)?.[side] ?? (CY_ARROWS.has(key) ? 1 : null);\n };\n}\n\n/**\n * The parser of how far an arrow stands off its node, as a multiple of its own length (`CY_ARROW_GAPS`), from the\n * arrow's name: 0 for an arrow that touches the node.\n * @param raw - the arrow's name\n * @param site - where it was read\n * @returns the gap; null for a name it does not know (the shape's parser notes it)\n */\nexport const arrowGap: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = arrowKey(s);\n return CY_ARROW_GAPS.get(key) ?? (CY_ARROWS.has(key) ? 0 : null);\n};\n\n/** Cytoscape's line types, lowercase. */\nconst CY_LINES: ReadonlyMap<string, string> = new Map([\n [\"solid\", \"solid\"],\n [\"dot\", \"dotted\"],\n [\"dots\", \"dotted\"],\n [\"equal_dash\", \"dashed\"],\n [\"long_dash\", \"dashed\"],\n [\"dash_dot\", \"dash-dot\"],\n [\"sinewave\", \"sinewave\"],\n [\"zigzag\", \"zigzag\"],\n [\"parallel_lines\", \"double\"],\n [\"marquee_dash\", \"dashed\"],\n [\"marquee_equal\", \"dashed\"],\n [\"marquee_dash_dot\", \"dash-dot\"],\n [\"backward_slash\", \"other:backward-slash\"],\n [\"forward_slash\", \"other:forward-slash\"],\n [\"vertical_slash\", \"other:vertical-slash\"],\n [\"separate_arrow\", \"other:separate-arrow\"],\n [\"contiguous_arrow\", \"other:contiguous-arrow\"],\n [\"double\", \"double\"],\n]);\n\n/**\n * A line type read for an edge line or a node border.\n * @param kind - which enumeration the value belongs to\n * @returns the parser\n */\nfunction lineOf(kind: \"lineStyle\" | \"borderStyle\"): CytoscapeValueParser {\n return (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = s.trim().toLowerCase();\n let v: string | null;\n if (/^line_\\d{1,3}$/.test(key)) {\n v = \"solid\";\n } else if (/^dashed_\\d{1,3}$/.test(key)) {\n v = \"dashed\";\n } else {\n v = CY_LINES.get(key) ?? canonEnum(kind, s, \"cytoscape\", site);\n }\n if (v === null || isStyleValue(\"node\", kind, v) || kind === \"lineStyle\") {\n return v;\n }\n // a line type a border does not have is kept as other:, spelled as the line type's own (other:forward-slash)\n return v.startsWith(\"other:\") ? v : `other:${v}`;\n };\n}\n\n/** The parts of a Cytoscape font face. */\ninterface FontFace {\n readonly family: string;\n readonly weight: \"normal\" | \"bold\";\n readonly italic: boolean;\n}\n\n/**\n * A Java font name's own style: `Dialog.bolditalic` is the bold italic face of `Dialog`, and Java draws it bold and\n * italic whatever style the rest of the face states (`Dialog.bolditalic,plain,12` is drawn bold italic).\n * @param name - the font name\n * @returns the family without the suffix, and whether the suffix makes it bold or italic\n */\nfunction javaFace(name: string): FontFace {\n const m = /\\.(bold|italic|plain|bolditalic)$/i.exec(name);\n const suffix = m?.[1].toLowerCase() ?? \"\";\n return {\n family: m === null ? name : name.slice(0, m.index),\n weight: suffix.includes(\"bold\") ? \"bold\" : \"normal\",\n italic: suffix.includes(\"italic\"),\n };\n}\n\n/**\n * A face whose family may carry a Java style suffix, its suffix's style added to the stated one.\n * @param family - the family as written\n * @param bold - whether the face states bold\n * @param italic - whether the face states italic\n * @returns the face\n */\nfunction withSuffix(family: string, bold: boolean, italic: boolean): FontFace {\n const own = javaFace(family.trim());\n return {\n family: own.family,\n weight: bold || own.weight === \"bold\" ? \"bold\" : \"normal\",\n italic: italic || own.italic,\n };\n}\n\n/**\n * A font face: `SansSerif,plain,12`, `Dialog.bold,bold,12`, the legacy `SansSerif-0-12` (style bits 1 bold,\n * 2 italic) or CX2's `{ FONT_FAMILY, FONT_STYLE, FONT_WEIGHT }`, whose `FONT_NAME` (the font Cytoscape desktop\n * wrote it from, which its own import restores) wins over the CSS family when present. A Java style suffix on the\n * name (`SansSerif.bold`) is drawn as well.\n * @param raw - the value\n * @param site - where it was read\n * @returns the face, or null\n */\nfunction fontFace(raw: unknown, site: CanonSite): FontFace | null {\n if (raw !== null && typeof raw === \"object\" && !Array.isArray(raw)) {\n return cx2FontFace(raw as Record<string, unknown>, site);\n }\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const parts = s.split(\",\");\n if (parts.length >= 2) {\n // desktop takes the face from the name alone (`FontVisualProperty.parseSerializableString`): its style word is\n // what it writes, not what it reads, so a passthrough of `Serif,bold,12` is drawn plain (Cytoscape 3.10.5's\n // SVG of specimen-mappings-bypass-p19, passthrough-font-face) and `SansSerif.bold,bold,10` bold by its suffix\n return withSuffix(parts[0], false, false);\n }\n return legacyFontFace(s) ?? withSuffix(s, false, false);\n}\n\n/**\n * CX2's font face object.\n * @param o - the object\n * @param site - where it was read\n * @returns the face, or null without a family\n */\nfunction cx2FontFace(o: Record<string, unknown>, site: CanonSite): FontFace | null {\n const name = Object.hasOwn(o, \"FONT_NAME\") ? scalarText(o.FONT_NAME, site) : null;\n let family = Object.hasOwn(o, \"FONT_FAMILY\") ? scalarText(o.FONT_FAMILY, site) : null;\n if (name !== null && name.trim() !== \"\") {\n family = name;\n }\n if (family === null) {\n return null;\n }\n const weight = Object.hasOwn(o, \"FONT_WEIGHT\") ? String(o.FONT_WEIGHT) : \"\";\n const style = Object.hasOwn(o, \"FONT_STYLE\") ? String(o.FONT_STYLE) : \"\";\n return withSuffix(family, /bold/i.test(weight.slice(0, 32)), /italic/i.test(style.slice(0, 32)));\n}\n\n/**\n * The legacy `Family-style-size` face: the last two dash parts are numbers, the style's bits 1 bold and 2 italic.\n * @param s - the value\n * @returns the face, or null when it is not one\n */\nfunction legacyFontFace(s: string): FontFace | null {\n const dash = s.split(\"-\");\n const numeric = (t: string | undefined): boolean => /^\\d+(?:\\.\\d+)?$/.test(t ?? \"\");\n if (dash.length < 3 || !numeric(dash.at(-1)) || !numeric(dash.at(-2))) {\n return null;\n }\n const bits = Math.trunc(Number(dash.at(-2)));\n let family = dash.slice(0, -2).join(\"-\");\n let bold = (bits & 1) !== 0;\n if (/-bold$/i.test(family)) {\n family = family.slice(0, -\"-bold\".length);\n bold = true;\n }\n return withSuffix(family, bold, (bits & 2) !== 0);\n}\n\n/**\n * The faces Java draws its logical fonts in on Linux, where the oracles were drawn (the JDK's fontconfig maps\n * SansSerif and Dialog to DejaVu Sans), each before the CSS generic family it stands for. A label wraps by its width\n * in that face: a browser's own sans-serif (Liberation Sans) is 14 percent narrower, so its lines break later.\n */\nexport const JAVA_SANS = \"DejaVu Sans, sans-serif\";\nexport const JAVA_SERIF = \"DejaVu Serif, serif\";\nexport const JAVA_MONO = \"DejaVu Sans Mono, monospace\";\n\n/** The family a Java logical font name is read as (`Dialog` is drawn as a sans-serif font). */\nconst JAVA_FONTS: ReadonlyMap<string, string> = new Map([\n // CX2's CSS generic families too: Cytoscape desktop hands them to Java, which draws them as these\n [\"sans-serif\", JAVA_SANS],\n [\"monospace\", JAVA_MONO],\n [\"sansserif\", JAVA_SANS],\n [\"dialog\", JAVA_SANS],\n [\"default\", JAVA_SANS],\n [\"dialoginput\", JAVA_MONO],\n [\"monospaced\", JAVA_MONO],\n [\"serif\", JAVA_SERIF],\n]);\n\nconst fontFamily: CytoscapeValueParser = (raw, site) => {\n const family = fontFace(raw, site)?.family ?? null;\n return family === null ? null : javaFamily(family);\n};\n\n/** The CSS generic families. */\nconst CSS_GENERIC: ReadonlySet<string> = new Set([\n \"sans-serif\",\n \"serif\",\n \"monospace\",\n \"cursive\",\n \"fantasy\",\n \"system-ui\",\n]);\n\n/**\n * A Java font name as the CSS family Cytoscape draws it with: a logical name as its generic family, and any other\n * with Dialog's face after it, because Java draws a font it does not have as Dialog\n * (`Calibri-Bold` on a machine without Calibri is drawn in Dialog's face and measured so when a label wraps).\n * @param family - the Java font name, without its style suffix\n * @returns the CSS family\n */\nexport function javaFamily(family: string): string {\n const logical = JAVA_FONTS.get(family.toLowerCase());\n if (logical !== undefined) {\n return logical;\n }\n // a CSS generic family or family list (CX2 writes them) already says what stands in for a missing font\n return family.includes(\",\") || CSS_GENERIC.has(family.toLowerCase()) ? family : `${family}, ${JAVA_SANS}`;\n}\nconst fontWeight: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.weight ?? null;\nconst fontItalic: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.italic ?? null;\n\n/** A desktop anchor letter as a point of a box, x right and y down, each -1, 0 or 1. */\nconst ANCHOR: ReadonlyMap<string, readonly [number, number]> = new Map([\n [\"C\", [0, 0]],\n [\"N\", [0, -1]],\n [\"S\", [0, 1]],\n [\"E\", [1, 0]],\n [\"W\", [-1, 0]],\n [\"NE\", [1, -1]],\n [\"NW\", [-1, -1]],\n [\"SE\", [1, 1]],\n [\"SW\", [-1, 1]],\n [\"NONE\", [0, 0]],\n]);\n\n/** CX2's anchor and align words as a point of a box on one axis. */\nconst CX2_SIDE: ReadonlyMap<string, number> = new Map([\n [\"center\", 0],\n [\"left\", -1],\n [\"right\", 1],\n [\"top\", -1],\n [\"bottom\", 1],\n]);\n\n/** A label justification as the neutral text alignment. */\nconst JUSTIFY: ReadonlyMap<string, string> = new Map([\n [\"l\", \"left\"],\n [\"left\", \"left\"],\n [\"c\", \"center\"],\n [\"center\", \"center\"],\n [\"r\", \"right\"],\n [\"right\", \"right\"],\n]);\n\n/**\n * A Cytoscape label position, read whole: the point of the node (or the edge's middle) `node` and the point of the\n * label's box `label` it is pinned to, each `[x, y]` with x right and y down as -1, 0 or 1, the justification of its\n * lines, and the offset `[x, y]` in px, y down.\n * @category Styles\n */\nexport interface CytoscapeLabelPlace {\n readonly node: readonly [number, number];\n readonly label: readonly [number, number];\n readonly justify: string;\n readonly offset: readonly [number, number];\n}\n\n/**\n * The anchors of CX2's edge label position `{ EDGE_ANCHOR, LABEL_ANCHOR, ... }`, each a desktop anchor letter, as\n * `[edge x, edge y, label x, label y]`; undefined where a letter is not one.\n * @param o - the position\n * @param site - where a bad value is noted\n * @returns the four sides\n */\nfunction cx2EdgeAnchors(o: Record<string, unknown>, site: CanonSite): (number | undefined)[] {\n const letter = (key: string): readonly [number, number] | undefined =>\n ANCHOR.get((scalarText(Object.hasOwn(o, key) ? o[key] : \"C\", site) ?? \"\").trim().toUpperCase());\n return [\n ...(letter(\"EDGE_ANCHOR\") ?? [undefined, undefined]),\n ...(letter(\"LABEL_ANCHOR\") ?? [undefined, undefined]),\n ];\n}\n\n/**\n * Reads a label position: desktop's `C,C,c,0.00,0.00` (node anchor, label anchor, justification, x and y offsets)\n * or CX2's `{ HORIZONTAL_ANCHOR, VERTICAL_ANCHOR, HORIZONTAL_ALIGN, VERTICAL_ALIGN, JUSTIFICATION, MARGIN_X,\n * MARGIN_Y }` (for an edge's label `{ EDGE_ANCHOR, LABEL_ANCHOR, JUSTIFICATION, MARGIN_X, MARGIN_Y }`, the anchors\n * as desktop's letters).\n * @param raw - the value\n * @param site - where a bad value is noted\n * @returns the place, or null\n * @category Styles\n */\nexport function cytoscapeLabelPlace(raw: unknown, site: CanonSite): CytoscapeLabelPlace | null {\n if (raw !== null && typeof raw === \"object\" && !Array.isArray(raw)) {\n const o = raw as Record<string, unknown>;\n const word = (key: string): string => {\n const v = Object.hasOwn(o, key) ? scalarText(o[key], site) : null;\n return (v ?? \"center\").trim().toLowerCase();\n };\n const num = (key: string): number => {\n const v = Object.hasOwn(o, key) ? Number(o[key]) : 0;\n return Number.isFinite(v) ? v : 0;\n };\n const sides = Object.hasOwn(o, \"EDGE_ANCHOR\")\n ? cx2EdgeAnchors(o, site)\n : [\"HORIZONTAL_ANCHOR\", \"VERTICAL_ANCHOR\", \"HORIZONTAL_ALIGN\", \"VERTICAL_ALIGN\"].map((k) =>\n CX2_SIDE.get(word(k)),\n );\n if (sides.includes(undefined)) {\n noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, JSON.stringify(raw).slice(0, 64));\n return null;\n }\n const [nx, ny, lx, ly] = sides as number[];\n return {\n node: [nx, ny],\n label: [lx, ly],\n justify: JUSTIFY.get(word(\"JUSTIFICATION\")) ?? \"center\",\n offset: [num(\"MARGIN_X\"), num(\"MARGIN_Y\")],\n };\n }\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const parts = s.split(\",\").map((p) => p.trim());\n const node = ANCHOR.get(parts[0].toUpperCase());\n // a position naming only the node's anchor pins the label's opposite point there, as Cytoscape 2.x did\n const label = parts.length > 1 ? ANCHOR.get(parts[1].toUpperCase()) : node?.map((v) => -v);\n if (node === undefined || label === undefined) {\n noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, s);\n return null;\n }\n const at = (i: number): number => {\n const v = Number(parts[i] ?? 0);\n return Number.isFinite(v) ? v : 0;\n };\n return {\n node,\n label: [label[0], label[1]],\n justify: JUSTIFY.get((parts[2] ?? \"c\").toLowerCase()) ?? \"center\",\n offset: [at(3), at(4)],\n };\n}\n\n/** The neutral position of a label inside its node against each side, by `[x, y]` of the side, y down. */\nconst INSIDE: ReadonlyMap<string, string> = new Map([\n [\"0,0\", \"center\"],\n [\"0,-1\", \"inside-top\"],\n [\"0,1\", \"inside-bottom\"],\n [\"-1,0\", \"inside-left\"],\n [\"1,0\", \"inside-right\"],\n [\"-1,-1\", \"inside-top-left\"],\n [\"1,-1\", \"inside-top-right\"],\n [\"-1,1\", \"inside-bottom-left\"],\n [\"1,1\", \"inside-bottom-right\"],\n]);\n\n/**\n * The neutral `labelPosition` a Cytoscape label position starts from: where the label's point is the node's own\n * point on both axes (its center, or inside against a side or a corner), that position; anywhere else `center`,\n * with the rest said by `labelOffsetX`/`Y` and `labelShiftX`/`Y` (see `cytoscapeLabelMove()`).\n * @param place - the label position\n * @returns the neutral position\n * @category Styles\n */\nexport function cytoscapeLabelBase(place: CytoscapeLabelPlace): string {\n const inside = place.node[0] === place.label[0] && place.node[1] === place.label[1];\n return inside ? (INSIDE.get(`${place.node[0]},${place.node[1]}`) ?? \"center\") : \"center\";\n}\n\n/**\n * How far a Cytoscape label is moved from its `cytoscapeLabelBase()` position: the offset in px (y down), with the\n * node's anchor point added when the base is `center` and the anchors differ, and the shift by the label's own\n * size that pins the label's anchor point there.\n * @param place - the label position\n * @param width - the node's width (0 for an edge's middle)\n * @param height - the node's height (0 for an edge's middle)\n * @returns the offset and the shift, each `[x, y]`\n * @category Styles\n */\nexport function cytoscapeLabelMove(\n place: CytoscapeLabelPlace,\n width: number,\n height: number,\n): { readonly offset: readonly [number, number]; readonly shift: readonly [number, number] } {\n if (\n cytoscapeLabelBase(place) !== \"center\" ||\n (place.node[0] === 0 && place.node[1] === 0 && place.label[0] === 0 && place.label[1] === 0)\n ) {\n return { offset: place.offset, shift: [0, 0] };\n }\n return {\n offset: [(place.node[0] * width) / 2 + place.offset[0], (place.node[1] * height) / 2 + place.offset[1]],\n shift: [halfBack(place.label[0]), halfBack(place.label[1])],\n };\n}\n\n/**\n * How far a label is shifted, as a fraction of its own size, to pin its point `side` (-1, 0 or 1) where its middle was.\n * @param side - the label's point on one axis\n * @returns the shift (0, never -0, for the middle)\n * @category Styles\n */\nexport function halfBack(side: number): number {\n return side === 0 ? 0 : -side / 2;\n}\n\nconst labelPosition: CytoscapeValueParser = (raw, site) => {\n const place = cytoscapeLabelPlace(raw, site);\n return place === null ? null : cytoscapeLabelBase(place);\n};\n\n/**\n * The visual properties that set each neutral property, in the order Cytoscape prefers them: the first one a style\n * or any bypass mentions is the one read. Cytoscape draws a node's fill from `NODE_FILL_COLOR`; `NODE_PAINT` is its\n * parent and only counts when the child is absent everywhere.\n * @category Styles\n */\nexport const CYTOSCAPE_LEXICON: Readonly<\n Record<StyleTarget, ReadonlyMap<string, readonly (readonly [vp: string, parse: CytoscapeValueParser])[]>>\n> = Object.freeze({\n node: new Map<string, readonly (readonly [string, CytoscapeValueParser])[]>([\n [\n \"fill\",\n [\n [\"NODE_FILL_COLOR\", color],\n [\"NODE_BACKGROUND_COLOR\", color],\n [\"NODE_PAINT\", color],\n ],\n ],\n [\n \"fillOpacity\",\n [\n [\"NODE_TRANSPARENCY\", opacity255],\n [\"NODE_BACKGROUND_OPACITY\", opacity01],\n ],\n ],\n [\n \"borderColor\",\n [\n [\"NODE_BORDER_PAINT\", color],\n [\"NODE_BORDER_COLOR\", color],\n ],\n ],\n [\n \"borderOpacity\",\n [\n [\"NODE_BORDER_TRANSPARENCY\", opacity255],\n [\"NODE_BORDER_OPACITY\", opacity01],\n ],\n ],\n [\"borderWidth\", [[\"NODE_BORDER_WIDTH\", length]]],\n [\n \"borderStyle\",\n [\n [\"NODE_BORDER_STROKE\", lineOf(\"borderStyle\")],\n [\"NODE_BORDER_LINE_TYPE\", lineOf(\"borderStyle\")],\n [\"NODE_BORDER_STYLE\", lineOf(\"borderStyle\")],\n ],\n ],\n [\"shape\", [[\"NODE_SHAPE\", shape]]],\n [\"width\", [[\"NODE_WIDTH\", length]]],\n [\"height\", [[\"NODE_HEIGHT\", length]]],\n [\"label\", [[\"NODE_LABEL\", text]]],\n [\"labelColor\", [[\"NODE_LABEL_COLOR\", color]]],\n [\"labelSize\", [[\"NODE_LABEL_FONT_SIZE\", fontSize]]],\n [\n \"labelWrapWidth\",\n [\n [\"NODE_LABEL_WIDTH\", length],\n [\"NODE_LABEL_MAX_WIDTH\", length],\n ],\n ],\n [\"labelFont\", [[\"NODE_LABEL_FONT_FACE\", fontFamily]]],\n [\"labelWeight\", [[\"NODE_LABEL_FONT_FACE\", fontWeight]]],\n [\"labelItalic\", [[\"NODE_LABEL_FONT_FACE\", fontItalic]]],\n [\"labelPosition\", [[\"NODE_LABEL_POSITION\", labelPosition]]],\n [\"labelRotation\", [[\"NODE_LABEL_ROTATION\", rotation]]],\n [\n \"labelOpacity\",\n [\n [\"NODE_LABEL_TRANSPARENCY\", opacity255],\n [\"NODE_LABEL_OPACITY\", opacity01],\n ],\n ],\n [\"tooltip\", [[\"NODE_TOOLTIP\", text]]],\n [\n \"visible\",\n [\n [\"NODE_VISIBLE\", bool],\n [\"NODE_VISIBILITY\", visibility],\n ],\n ],\n ]),\n edge: new Map<string, readonly (readonly [string, CytoscapeValueParser])[]>([\n [\n \"color\",\n [\n [\"EDGE_STROKE_UNSELECTED_PAINT\", color],\n [\"EDGE_LINE_COLOR\", color],\n [\"EDGE_UNSELECTED_PAINT\", color],\n [\"EDGE_PAINT\", color],\n ],\n ],\n [\n \"opacity\",\n [\n [\"EDGE_TRANSPARENCY\", opacity255],\n [\"EDGE_OPACITY\", opacity01],\n ],\n ],\n [\"width\", [[\"EDGE_WIDTH\", length]]],\n [\n \"lineStyle\",\n [\n [\"EDGE_LINE_TYPE\", lineOf(\"lineStyle\")],\n [\"EDGE_LINE_STYLE\", lineOf(\"lineStyle\")],\n ],\n ],\n [\"sourceArrow\", [[\"EDGE_SOURCE_ARROW_SHAPE\", arrow]]],\n [\"targetArrow\", [[\"EDGE_TARGET_ARROW_SHAPE\", arrow]]],\n // One neutral size for both ends: the target's, else the source's.\n [\n \"arrowSize\",\n [\n [\"EDGE_TARGET_ARROW_SIZE\", arrowSizeParser],\n [\"EDGE_SOURCE_ARROW_SIZE\", arrowSizeParser],\n ],\n ],\n [\n \"sourceArrowColor\",\n [\n [\"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\", color],\n [\"EDGE_SOURCE_ARROW_COLOR\", color],\n ],\n ],\n [\n \"targetArrowColor\",\n [\n [\"EDGE_TARGET_ARROW_UNSELECTED_PAINT\", color],\n [\"EDGE_TARGET_ARROW_COLOR\", color],\n ],\n ],\n [\"curved\", [[\"EDGE_CURVED\", bool]]],\n [\"label\", [[\"EDGE_LABEL\", text]]],\n [\"labelColor\", [[\"EDGE_LABEL_COLOR\", color]]],\n [\"labelSize\", [[\"EDGE_LABEL_FONT_SIZE\", fontSize]]],\n [\"labelFont\", [[\"EDGE_LABEL_FONT_FACE\", fontFamily]]],\n [\"labelWeight\", [[\"EDGE_LABEL_FONT_FACE\", fontWeight]]],\n [\"labelItalic\", [[\"EDGE_LABEL_FONT_FACE\", fontItalic]]],\n [\n \"labelWrapWidth\",\n [\n [\"EDGE_LABEL_WIDTH\", length],\n [\"EDGE_LABEL_MAX_WIDTH\", length],\n ],\n ],\n [\"labelRotation\", [[\"EDGE_LABEL_ROTATION\", rotation]]],\n [\n \"labelOpacity\",\n [\n [\"EDGE_LABEL_TRANSPARENCY\", opacity255],\n [\"EDGE_LABEL_OPACITY\", opacity01],\n ],\n ],\n [\"tooltip\", [[\"EDGE_TOOLTIP\", text]]],\n [\n \"visible\",\n [\n [\"EDGE_VISIBLE\", bool],\n [\"EDGE_VISIBILITY\", visibility],\n ],\n ],\n ]),\n});\n\n/** A node's size when `nodeSizeLocked` makes `NODE_SIZE` drive width and height. */\nexport const NODE_SIZE_VP = \"NODE_SIZE\";\n\n/** The parser of node sizes, for `NODE_SIZE`. */\nexport const sizeParser: CytoscapeValueParser = length;\n\n/** The parser of colors, for the network background and `arrowColorMatchesEdge`. */\nexport const colorParser: CytoscapeValueParser = color;\n\n/**\n * The parser of 0..255 transparencies (desktop) and 0..1 opacities (CX2), by visual property.\n * @param vp - the visual property (`*_TRANSPARENCY` or `*_OPACITY`)\n * @returns its parser\n */\nexport const opacityParser = (vp: string): CytoscapeValueParser => (vp.endsWith(\"_OPACITY\") ? opacity01 : opacity255);\n\n/** Every visual property the lexicon reads. */\nconst KNOWN_VPS: ReadonlySet<string> = new Set([\n NODE_SIZE_VP,\n ...Object.values(CYTOSCAPE_LEXICON).flatMap((byProp) =>\n Array.from(byProp.values()).flatMap((list) => list.map(([vp]) => vp)),\n ),\n]);\n\n/** Geometry, selection state and paint that is not a style: dropped without a note. */\nconst IGNORED_VP =\n /^(?:NODE|EDGE|NETWORK)_[XYZ]_LOCATION$|_SELECTED|SELECTION|^NETWORK_(?!BACKGROUND)|_DEPTH$|^COMPOUND_|EDGE_BEND|EDGE_CONTROL_POINTS|NODE_NESTED_NETWORK|_Z_ORDER$|EDGE_STACKING|_LABEL_WIDTH$|_HEIGHT$|_WIDTH$/;\n\n/**\n * Whether a visual property is one no neutral property carries and that is worth a note.\n * @param vp - the visual property\n * @returns true when it is neither read nor ignored\n */\nexport function isUncarriedVp(vp: string): boolean {\n return !KNOWN_VPS.has(vp) && !IGNORED_VP.test(vp);\n}\n\n/** Cytoscape's old identifiers (2.x XGMML graphics attributes and session properties), lowercase. */\nconst IDENTIFIERS: Readonly<Record<StyleTarget, ReadonlyMap<string, string>>> = {\n node: new Map([\n [\"fill\", \"NODE_FILL_COLOR\"],\n [\"w\", \"NODE_WIDTH\"],\n [\"h\", \"NODE_HEIGHT\"],\n [\"size\", \"NODE_SIZE\"],\n [\"type\", \"NODE_SHAPE\"],\n [\"outline\", \"NODE_BORDER_PAINT\"],\n [\"width\", \"NODE_BORDER_WIDTH\"],\n [\"borderlinetype\", \"NODE_BORDER_LINE_TYPE\"],\n [\"nodelabelfont\", \"NODE_LABEL_FONT_FACE\"],\n [\"nodetransparency\", \"NODE_TRANSPARENCY_01\"],\n [\"nodelabelposition\", \"NODE_LABEL_POSITION\"],\n [\"nodefillcolor\", \"NODE_FILL_COLOR\"],\n [\"nodesize\", \"NODE_SIZE\"],\n [\"nodewidth\", \"NODE_WIDTH\"],\n [\"nodehight\", \"NODE_HEIGHT\"],\n [\"nodeheight\", \"NODE_HEIGHT\"],\n [\"nodeopacity\", \"NODE_TRANSPARENCY\"],\n [\"nodebordercolor\", \"NODE_BORDER_PAINT\"],\n [\"nodelinewidth\", \"NODE_BORDER_WIDTH\"],\n [\"nodelinestyle\", \"NODE_BORDER_LINE_TYPE\"],\n [\"nodeshape\", \"NODE_SHAPE\"],\n [\"nodefont\", \"NODE_LABEL_FONT_FACE\"],\n [\"nodefontsize\", \"NODE_LABEL_FONT_SIZE\"],\n [\"nodelabel\", \"NODE_LABEL\"],\n [\"nodelabelcolor\", \"NODE_LABEL_COLOR\"],\n [\"nodetooltip\", \"NODE_TOOLTIP\"],\n ]),\n edge: new Map([\n [\"width\", \"EDGE_WIDTH\"],\n [\"fill\", \"EDGE_STROKE_UNSELECTED_PAINT\"],\n [\"edgelinetype\", \"EDGE_LINE_TYPE\"],\n [\"edgelabelfont\", \"EDGE_LABEL_FONT_FACE\"],\n [\"sourcearrowcolor\", \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\"],\n [\"targetarrowcolor\", \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\"],\n [\"edgesourcearrowcolor\", \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\"],\n [\"edgetargetarrowcolor\", \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\"],\n [\"edgelinewidth\", \"EDGE_WIDTH\"],\n [\"edgecolor\", \"EDGE_STROKE_UNSELECTED_PAINT\"],\n [\"edgelinestyle\", \"EDGE_LINE_TYPE\"],\n [\"edgeopacity\", \"EDGE_TRANSPARENCY\"],\n [\"sourcearrow\", \"EDGE_SOURCE_ARROW_SHAPE\"],\n [\"targetarrow\", \"EDGE_TARGET_ARROW_SHAPE\"],\n [\"edgesourcearrowshape\", \"EDGE_SOURCE_ARROW_SHAPE\"],\n [\"edgetargetarrowshape\", \"EDGE_TARGET_ARROW_SHAPE\"],\n [\"edgelabel\", \"EDGE_LABEL\"],\n [\"edgefont\", \"EDGE_LABEL_FONT_FACE\"],\n [\"edgelabelcolor\", \"EDGE_LABEL_COLOR\"],\n [\"edgefontsize\", \"EDGE_LABEL_FONT_SIZE\"],\n [\"edgetooltip\", \"EDGE_TOOLTIP\"],\n [\"curved\", \"EDGE_CURVED_LEGACY\"],\n [\"edgecurved\", \"EDGE_CURVED\"],\n [\"edgebend\", \"EDGE_BEND\"],\n ]),\n};\n\n/** Objects nested deeper than this inside one element's graphics are not read. */\nconst MAX_VP_DEPTH = 8;\nconst VP_NAME = /^[A-Z][A-Z_0-9]+$/;\n\n/**\n * One graphics key as a visual property: its name (`?<key>` for one with none) and its value, a legacy encoding\n * converted.\n * @param target - nodes or edges\n * @param k - the key\n * @param v - its value\n * @returns the name and the value\n */\nfunction visualProperty(target: StyleTarget, k: string, v: unknown): [string, unknown] {\n const name = VP_NAME.test(k) ? k : IDENTIFIERS[target].get(k.toLowerCase().replace(/^cy:/, \"\"));\n if (name === undefined) {\n return [`?${k}`, v];\n }\n if (name === \"NODE_TRANSPARENCY_01\") {\n let f = Number.NaN;\n if (typeof v === \"number\") {\n f = v;\n } else if (typeof v === \"string\") {\n f = Number(v.trim());\n }\n return [\"NODE_TRANSPARENCY\", Number.isFinite(f) ? Math.round(f * 255) : null];\n }\n if (name === \"EDGE_CURVED_LEGACY\") {\n return [\"EDGE_CURVED\", typeof v === \"string\" && v.toUpperCase() === \"CURVED_LINES\"];\n }\n return [name, v];\n}\n\n/**\n * Normalizes the keys of one object of an element's graphics; a nested object is pushed onto the stack.\n * @param target - nodes or edges\n * @param top - the object and its depth\n * @param stack - the objects still to walk\n * @param out - visual property name to raw value, added to\n * @returns how many nested objects were too deep to walk\n */\nfunction normalizeObject(\n target: StyleTarget,\n top: [Record<string, unknown>, number],\n stack: [Record<string, unknown>, number][],\n out: Map<string, unknown>,\n): number {\n const [obj, depth] = top;\n let deep = 0;\n for (const k of Object.keys(obj)) {\n const v = obj[k];\n if (k === \"lockedVisualProperties\" || v === null || v === undefined) {\n continue;\n }\n // a 2.x edgeBend of one handle is a record: kept whole, as its handles\n if (typeof v === \"object\" && !Array.isArray(v) && !/^[A-Z_0-9]+$/.test(k) && k.toLowerCase() !== \"edgebend\") {\n if (depth + 1 > MAX_VP_DEPTH) {\n deep++;\n } else {\n stack.push([v as Record<string, unknown>, depth + 1]);\n }\n continue;\n }\n const [name, value] = visualProperty(target, k, v);\n // visual-property-named keys come first in 3.x graphics and win\n if (!out.has(name)) {\n out.set(name, value);\n }\n }\n return deep;\n}\n\n/**\n * One element's raw visual properties, normalized: Cytoscape's old identifiers renamed to visual property names and\n * the legacy encodings converted (`nodeTransparency` 0..1 to `NODE_TRANSPARENCY` 0..255, `curved` to\n * `EDGE_CURVED`). Nested objects (`cytoscapeNodeGraphicsAttributes` and the like) are walked with an explicit stack\n * and a depth limit, never by recursion on the file's nesting. A key with no visual property name is kept as\n * `?<key>`, so a caller can note it.\n * @param target - nodes or edges\n * @param raw - the element's graphics object\n * @param notes - where a too-deep nesting is noted\n * @returns visual property name to raw value\n * @category Styles\n */\nexport function normalizeVisualProperties(target: StyleTarget, raw: unknown, notes?: StyleNotes): Map<string, unknown> {\n if (raw === null || typeof raw !== \"object\") {\n return new Map();\n }\n const out = new Map<string, unknown>();\n const stack: [Record<string, unknown>, number][] = [[raw as Record<string, unknown>, 0]];\n let deep = 0;\n for (let top = stack.pop(); top !== undefined; top = stack.pop()) {\n deep += normalizeObject(target, top, stack, out);\n }\n if (deep > 0) {\n notes?.add(STYLE_ISSUE.NESTING, target, \"graphics\", { sample: `deeper than ${MAX_VP_DEPTH}`, count: deep });\n }\n return out;\n}\n\n/**\n * The step a continuous mapping's value is rounded to for the integer visual properties Cytoscape desktop rounds an\n * interpolated value of (cytoscape-api BasicVisualLexicon: the font sizes and the 0..255 transparencies; the latter\n * read as opacities, so 1/255).\n */\nconst INTEGER_VP_STEPS: ReadonlyMap<string, number> = new Map([\n [\"NODE_LABEL_FONT_SIZE\", 1],\n [\"EDGE_LABEL_FONT_SIZE\", 1],\n [\"NODE_TRANSPARENCY\", 1 / 255],\n [\"EDGE_TRANSPARENCY\", 1 / 255],\n]);\n\n/**\n * The step Cytoscape rounds an interpolated value of a visual property to.\n * @param vp - the visual property\n * @returns the step, or undefined for a property that holds fractions\n */\nexport function vpStep(vp: string): number | undefined {\n return INTEGER_VP_STEPS.get(vp);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lexicon-IVRq2Uoo.js","sources":["../../src/styles/cytoscape/lexicon.ts"],"sourcesContent":["/**\n * Cytoscape desktop's visual lexicon (CX, CX2, sessions, XGMML): which visual properties set each neutral\n * property, and how each value is read. Cytoscape states opacities two ways (`NODE_TRANSPARENCY` 0..255 in the\n * desktop and CX version 1, `NODE_BACKGROUND_OPACITY` 0..1 in CX2); both are read here.\n */\n\nimport { canonColor } from \"../canon/color.js\";\nimport { canonEnum } from \"../canon/enums.js\";\nimport { canonBoolean, canonNumber, canonOpacity, num6 } from \"../canon/number.js\";\nimport { type CanonSite, noteAt, scalarText } from \"../canon/site.js\";\nimport { canonText } from \"../canon/text.js\";\nimport { STYLE_ISSUE } from \"../codes.js\";\nimport type { StyleNotes } from \"../notes.js\";\nimport type { StyleTarget, StyleValue } from \"../types.js\";\nimport { isStyleValue } from \"../vocabulary.js\";\n\n/**\n * Reads one raw Cytoscape value as a neutral property's canonical value, noting a problem at the site.\n * @category Styles\n */\nexport type CytoscapeValueParser = (raw: unknown, site: CanonSite) => StyleValue | null;\n\n// A color; its alpha is dropped (Cytoscape keeps opacity in separate properties).\nconst color: CytoscapeValueParser = (raw, site) => canonColor(raw, \"cytoscape\", site)?.color ?? null;\n\n// Cytoscape desktop's 0..255 transparency.\nconst opacity255: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n if (v === null) {\n return null;\n }\n if (v > 255) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, String(raw));\n return null;\n }\n return num6(Math.round(v) / 255);\n};\n\n// CX2's 0..1 opacity.\nconst opacity01: CytoscapeValueParser = (raw, site) => canonOpacity(raw, \"css\", site);\nconst length: CytoscapeValueParser = (raw, site) => canonNumber(raw, site);\n// An arrow size as the neutral factor: Cytoscape's normal arrow is size 6 (default_vizmap.xml).\nexport const arrowSizeParser: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n return v === null ? null : num6(v / 6);\n};\n\n// Degrees, clockwise on screen as Cytoscape turns a label, folded into 0..360.\n// ponytail: a continuous mapping across 0 (from -30 to 30) folds to 330..30 and interpolates the long way round;\n// keep the sign when a file needs it.\nconst rotation: CytoscapeValueParser = (raw, site) => {\n const v = typeof raw === \"number\" ? raw : Number(scalarText(raw, site)?.trim() ?? Number.NaN);\n if (!Number.isFinite(v)) {\n noteAt(site, STYLE_ISSUE.BAD_VALUE, String(raw));\n return null;\n }\n return num6(((v % 360) + 360) % 360);\n};\n\n// Cytoscape desktop holds a font size as a whole number, so every value read for one is drawn rounded.\nconst fontSize: CytoscapeValueParser = (raw, site) => {\n const v = canonNumber(raw, site);\n return v === null ? null : Math.round(v);\n};\nconst text: CytoscapeValueParser = (raw, site) => canonText(raw, site);\nconst bool: CytoscapeValueParser = (raw, site) => canonBoolean(raw, site);\n\n// CX2's `element` / `none`, or a boolean.\nconst visibility: CytoscapeValueParser = (raw, site) => {\n if (typeof raw === \"string\") {\n const t = raw.trim().toLowerCase();\n if (t === \"element\" || t === \"visible\") {\n return true;\n }\n if (t === \"none\" || t === \"hidden\") {\n return false;\n }\n }\n return canonBoolean(raw, site);\n};\n\n/** Cytoscape spellings the common shape table does not hold. */\nconst CY_SHAPES: ReadonlyMap<string, string> = new Map([[\"rounded_rectangle\", \"round-rectangle\"]]);\n\n/**\n * Cytoscape reads its enumeration names whatever their case, so a name it does not know is kept lowercase and\n * hyphenated, the form of the names it knows: `Bogus` and the `BOGUS` a writer spells it as read the same.\n * @param v - a canonical value\n * @returns the value, an `other:` one in that form\n */\nconst caseless = (v: StyleValue | null): StyleValue | null =>\n typeof v === \"string\" && v.startsWith(\"other:\") ? `other:${v.slice(6).toLowerCase().replaceAll(\"_\", \"-\")}` : v;\n\nconst shape: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n return caseless(CY_SHAPES.get(s.trim().toLowerCase()) ?? canonEnum(\"shape\", s, \"cytoscape\", site));\n};\n\n/** Cytoscape's arrow names, desktop (`DELTA`) and CX2 (`triangle`), lowercase. */\nconst CY_ARROWS: ReadonlyMap<string, string> = new Map([\n [\"none\", \"none\"],\n [\"delta\", \"triangle\"],\n // a filled delta with a shallow notch in its back, as long and wide as DELTA (Cytoscape 3.10.5 SVG export)\n [\"arrow\", \"triangle\"],\n [\"diamond\", \"diamond\"],\n [\"circle\", \"circle\"],\n [\"t\", \"tee\"],\n [\"half_top\", \"half\"],\n // the half arrow on the line's other side from HALF_TOP's\n [\"half_bottom\", \"other:half-bottom\"],\n [\"square\", \"square\"],\n [\"delta_short_1\", \"triangle\"],\n [\"delta_short_2\", \"triangle\"],\n // a short arrow whose notch is too shallow to show: drawn as the triangle it reads as\n [\"arrow_short\", \"triangle\"],\n [\"diamond_short_1\", \"diamond\"],\n [\"diamond_short_2\", \"diamond\"],\n [\"open_delta\", \"triangle-open\"],\n [\"open_circle\", \"circle-open\"],\n [\"open_diamond\", \"diamond-open\"],\n [\"open_square\", \"other:open-square\"],\n // a delta with a bar across the line behind it\n [\"cross_delta\", \"other:cross-delta\"],\n [\"cross_open_delta\", \"other:cross-open-delta\"],\n [\"open_half_circle\", \"other:open-half-circle\"],\n [\"half_circle\", \"other:half-circle\"],\n [\"triangle\", \"triangle\"],\n [\"triangle-tee\", \"tee\"],\n // CX2's spelling of CROSS_DELTA\n [\"triangle-cross\", \"other:cross-delta\"],\n [\"triangle-backcurve\", \"triangle\"],\n [\"tee\", \"tee\"],\n [\"vee\", \"vee\"],\n [\"open-circle\", \"circle-open\"],\n [\"open-triangle\", \"triangle-open\"],\n [\"open-diamond\", \"diamond-open\"],\n [\"open-square\", \"other:open-square\"],\n [\"open-delta\", \"triangle-open\"],\n [\"half-top\", \"half\"],\n [\"half-bottom\", \"other:half-bottom\"],\n]);\n\n/**\n * How much longer and wider than the neutral shape it is read as each Cytoscape arrow is drawn: the short deltas and\n * diamonds, the short arrow and the crossed deltas (a bar behind the delta), from the unit glyphs Cytoscape 3.10.5's\n * SVG export draws (a DELTA is 2 long and 1 wide, DELTA_SHORT_1 1 by 1, ARROW_SHORT 1.2 by 0.8, CROSS_DELTA 3 by 1.5).\n * Every other arrow is drawn in its shape's own proportions.\n */\nconst CY_ARROW_PROPORTIONS: ReadonlyMap<string, { readonly length: number; readonly width: number }> = new Map([\n [\"delta_short_1\", { length: 0.5, width: 1 }],\n [\"delta_short_2\", { length: 0.25, width: 1 }],\n [\"arrow_short\", { length: 0.6, width: 0.8 }],\n [\"diamond_short_1\", { length: 0.5, width: 1 }],\n [\"diamond_short_2\", { length: 0.25, width: 1 }],\n [\"cross_delta\", { length: 1.5, width: 1.5 }],\n [\"cross_open_delta\", { length: 1.5, width: 1.5 }],\n [\"triangle-cross\", { length: 1.5, width: 1.5 }],\n]);\n\n/**\n * How far from its node Cytoscape draws each arrow that stands off the node's outline, as a multiple of the arrow's\n * own length along its line, from the unit glyphs Cytoscape 3.10.5's SVG export draws back from the outline: T's bar\n * from 0.8 to 1 (4 of its 0.2), a half circle from 0.5 to 1, HALF_TOP's barb from 0.3 to 1.435, a square from 0.25\n * to 1.25. Every other arrow touches the outline.\n */\nconst CY_ARROW_GAPS: ReadonlyMap<string, number> = new Map([\n [\"t\", 4],\n [\"tee\", 4],\n [\"half_circle\", 1],\n [\"open_half_circle\", 1],\n [\"half_top\", 0.3 / 1.135],\n [\"half_bottom\", 0.3 / 1.135],\n [\"half-top\", 0.3 / 1.135],\n [\"half-bottom\", 0.3 / 1.135],\n [\"square\", 0.25],\n [\"open_square\", 0.25],\n [\"open-square\", 0.25],\n]);\n\n/** Cytoscape 2.x numbered arrow codes. */\nconst LEGACY_ARROW: readonly string[] = [\n \"none\",\n \"delta\",\n \"delta\",\n \"delta\",\n \"arrow\",\n \"arrow\",\n \"arrow\",\n \"diamond\",\n \"diamond\",\n \"diamond\",\n \"circle\",\n \"circle\",\n \"circle\",\n \"t\",\n \"t\",\n \"t\",\n \"half_top\",\n \"half_bottom\",\n];\n\n/**\n * A Cytoscape arrow name, lowercase, with a 2.x numbered code read as its name.\n * @param s - the raw name\n * @returns the key\n */\nfunction arrowKey(s: string): string {\n const key = s.trim().toLowerCase();\n return /^\\d{1,2}$/.test(key) ? (LEGACY_ARROW.at(Number(key)) ?? key) : key;\n}\n\nconst arrow: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n return caseless(CY_ARROWS.get(arrowKey(s)) ?? canonEnum(\"arrow\", s, \"cytoscape\", site));\n};\n\n/**\n * The parser of an arrow's length or width as a fraction of its neutral shape's, from the arrow's name: 1 for every\n * arrow Cytoscape draws in its shape's proportions, so a bypass over a short default draws the full shape again.\n * @param side - which proportion\n * @returns the parser; null for a name it does not know (the shape's parser notes it)\n */\nexport function arrowProportion(side: \"length\" | \"width\"): CytoscapeValueParser {\n return (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = arrowKey(s);\n return CY_ARROW_PROPORTIONS.get(key)?.[side] ?? (CY_ARROWS.has(key) ? 1 : null);\n };\n}\n\n/**\n * The parser of how far an arrow stands off its node, as a multiple of its own length (`CY_ARROW_GAPS`), from the\n * arrow's name: 0 for an arrow that touches the node.\n * @param raw - the arrow's name\n * @param site - where it was read\n * @returns the gap; null for a name it does not know (the shape's parser notes it)\n */\nexport const arrowGap: CytoscapeValueParser = (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = arrowKey(s);\n return CY_ARROW_GAPS.get(key) ?? (CY_ARROWS.has(key) ? 0 : null);\n};\n\n/** Cytoscape's line types, lowercase. */\nconst CY_LINES: ReadonlyMap<string, string> = new Map([\n [\"solid\", \"solid\"],\n [\"dot\", \"dotted\"],\n [\"dots\", \"dotted\"],\n [\"equal_dash\", \"dashed\"],\n [\"long_dash\", \"dashed\"],\n [\"dash_dot\", \"dash-dot\"],\n [\"sinewave\", \"sinewave\"],\n [\"zigzag\", \"zigzag\"],\n [\"parallel_lines\", \"double\"],\n [\"marquee_dash\", \"dashed\"],\n [\"marquee_equal\", \"dashed\"],\n [\"marquee_dash_dot\", \"dash-dot\"],\n [\"backward_slash\", \"other:backward-slash\"],\n [\"forward_slash\", \"other:forward-slash\"],\n [\"vertical_slash\", \"other:vertical-slash\"],\n [\"separate_arrow\", \"other:separate-arrow\"],\n [\"contiguous_arrow\", \"other:contiguous-arrow\"],\n [\"double\", \"double\"],\n]);\n\n/**\n * A line type read for an edge line or a node border.\n * @param kind - which enumeration the value belongs to\n * @returns the parser\n */\nfunction lineOf(kind: \"lineStyle\" | \"borderStyle\"): CytoscapeValueParser {\n return (raw, site) => {\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const key = s.trim().toLowerCase();\n let v: string | null;\n if (/^line_\\d{1,3}$/.test(key)) {\n v = \"solid\";\n } else if (/^dashed_\\d{1,3}$/.test(key)) {\n v = \"dashed\";\n } else {\n v = CY_LINES.get(key) ?? canonEnum(kind, s, \"cytoscape\", site);\n }\n if (v === null || isStyleValue(\"node\", kind, v) || kind === \"lineStyle\") {\n return v;\n }\n // a line type a border does not have is kept as other:, spelled as the line type's own (other:forward-slash)\n return v.startsWith(\"other:\") ? v : `other:${v}`;\n };\n}\n\n/** The parts of a Cytoscape font face. */\ninterface FontFace {\n readonly family: string;\n readonly weight: \"normal\" | \"bold\";\n readonly italic: boolean;\n}\n\n/**\n * A Java font name's own style: `Dialog.bolditalic` is the bold italic face of `Dialog`, and Java draws it bold and\n * italic whatever style the rest of the face states (`Dialog.bolditalic,plain,12` is drawn bold italic).\n * @param name - the font name\n * @returns the family without the suffix, and whether the suffix makes it bold or italic\n */\nfunction javaFace(name: string): FontFace {\n const m = /\\.(bold|italic|plain|bolditalic)$/i.exec(name);\n const suffix = m?.[1].toLowerCase() ?? \"\";\n return {\n family: m === null ? name : name.slice(0, m.index),\n weight: suffix.includes(\"bold\") ? \"bold\" : \"normal\",\n italic: suffix.includes(\"italic\"),\n };\n}\n\n/**\n * A face whose family may carry a Java style suffix, its suffix's style added to the stated one.\n * @param family - the family as written\n * @param bold - whether the face states bold\n * @param italic - whether the face states italic\n * @returns the face\n */\nfunction withSuffix(family: string, bold: boolean, italic: boolean): FontFace {\n const own = javaFace(family.trim());\n return {\n family: own.family,\n weight: bold || own.weight === \"bold\" ? \"bold\" : \"normal\",\n italic: italic || own.italic,\n };\n}\n\n/**\n * A font face: `SansSerif,plain,12`, `Dialog.bold,bold,12`, the legacy `SansSerif-0-12` (style bits 1 bold,\n * 2 italic) or CX2's `{ FONT_FAMILY, FONT_STYLE, FONT_WEIGHT }`, whose `FONT_NAME` (the font Cytoscape desktop\n * wrote it from, which its own import restores) wins over the CSS family when present. A Java style suffix on the\n * name (`SansSerif.bold`) is drawn as well.\n * @param raw - the value\n * @param site - where it was read\n * @returns the face, or null\n */\nfunction fontFace(raw: unknown, site: CanonSite): FontFace | null {\n if (raw !== null && typeof raw === \"object\" && !Array.isArray(raw)) {\n return cx2FontFace(raw as Record<string, unknown>, site);\n }\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const parts = s.split(\",\");\n if (parts.length >= 2) {\n // desktop takes the face from the name alone (`FontVisualProperty.parseSerializableString`): its style word is\n // what it writes, not what it reads, so a passthrough of `Serif,bold,12` is drawn plain (Cytoscape 3.10.5's\n // SVG of specimen-mappings-bypass-p19, passthrough-font-face) and `SansSerif.bold,bold,10` bold by its suffix\n return withSuffix(parts[0], false, false);\n }\n return legacyFontFace(s) ?? withSuffix(s, false, false);\n}\n\n/**\n * CX2's font face object.\n * @param o - the object\n * @param site - where it was read\n * @returns the face, or null without a family\n */\nfunction cx2FontFace(o: Record<string, unknown>, site: CanonSite): FontFace | null {\n const name = Object.hasOwn(o, \"FONT_NAME\") ? scalarText(o.FONT_NAME, site) : null;\n let family = Object.hasOwn(o, \"FONT_FAMILY\") ? scalarText(o.FONT_FAMILY, site) : null;\n if (name !== null && name.trim() !== \"\") {\n family = name;\n }\n if (family === null) {\n return null;\n }\n const weight = Object.hasOwn(o, \"FONT_WEIGHT\") ? String(o.FONT_WEIGHT) : \"\";\n const style = Object.hasOwn(o, \"FONT_STYLE\") ? String(o.FONT_STYLE) : \"\";\n return withSuffix(family, /bold/i.test(weight.slice(0, 32)), /italic/i.test(style.slice(0, 32)));\n}\n\n/**\n * The legacy `Family-style-size` face: the last two dash parts are numbers, the style's bits 1 bold and 2 italic.\n * @param s - the value\n * @returns the face, or null when it is not one\n */\nfunction legacyFontFace(s: string): FontFace | null {\n const dash = s.split(\"-\");\n const numeric = (t: string | undefined): boolean => /^\\d+(?:\\.\\d+)?$/.test(t ?? \"\");\n if (dash.length < 3 || !numeric(dash.at(-1)) || !numeric(dash.at(-2))) {\n return null;\n }\n const bits = Math.trunc(Number(dash.at(-2)));\n let family = dash.slice(0, -2).join(\"-\");\n let bold = (bits & 1) !== 0;\n if (/-bold$/i.test(family)) {\n family = family.slice(0, -\"-bold\".length);\n bold = true;\n }\n return withSuffix(family, bold, (bits & 2) !== 0);\n}\n\n/**\n * The faces Java draws its logical fonts in on Linux, where the oracles were drawn (the JDK's fontconfig maps\n * SansSerif and Dialog to DejaVu Sans), each before the CSS generic family it stands for. A label wraps by its width\n * in that face: a browser's own sans-serif (Liberation Sans) is 14 percent narrower, so its lines break later.\n */\nexport const JAVA_SANS = \"DejaVu Sans, sans-serif\";\nexport const JAVA_SERIF = \"DejaVu Serif, serif\";\nexport const JAVA_MONO = \"DejaVu Sans Mono, monospace\";\n\n/** The family a Java logical font name is read as (`Dialog` is drawn as a sans-serif font). */\nconst JAVA_FONTS: ReadonlyMap<string, string> = new Map([\n // CX2's CSS generic families too: Cytoscape desktop hands them to Java, which draws them as these\n [\"sans-serif\", JAVA_SANS],\n [\"monospace\", JAVA_MONO],\n [\"sansserif\", JAVA_SANS],\n [\"dialog\", JAVA_SANS],\n [\"default\", JAVA_SANS],\n [\"dialoginput\", JAVA_MONO],\n [\"monospaced\", JAVA_MONO],\n [\"serif\", JAVA_SERIF],\n]);\n\nconst fontFamily: CytoscapeValueParser = (raw, site) => {\n const family = fontFace(raw, site)?.family ?? null;\n return family === null ? null : javaFamily(family);\n};\n\n/** The CSS generic families. */\nconst CSS_GENERIC: ReadonlySet<string> = new Set([\n \"sans-serif\",\n \"serif\",\n \"monospace\",\n \"cursive\",\n \"fantasy\",\n \"system-ui\",\n]);\n\n/**\n * A Java font name as the CSS family Cytoscape draws it with: a logical name as its generic family, and any other\n * with Dialog's face after it, because Java draws a font it does not have as Dialog\n * (`Calibri-Bold` on a machine without Calibri is drawn in Dialog's face and measured so when a label wraps).\n * @param family - the Java font name, without its style suffix\n * @returns the CSS family\n */\nexport function javaFamily(family: string): string {\n const logical = JAVA_FONTS.get(family.toLowerCase());\n if (logical !== undefined) {\n return logical;\n }\n // a CSS generic family or family list (CX2 writes them) already says what stands in for a missing font\n return family.includes(\",\") || CSS_GENERIC.has(family.toLowerCase()) ? family : `${family}, ${JAVA_SANS}`;\n}\nconst fontWeight: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.weight ?? null;\nconst fontItalic: CytoscapeValueParser = (raw, site) => fontFace(raw, site)?.italic ?? null;\n\n/** A desktop anchor letter as a point of a box, x right and y down, each -1, 0 or 1. */\nconst ANCHOR: ReadonlyMap<string, readonly [number, number]> = new Map([\n [\"C\", [0, 0]],\n [\"N\", [0, -1]],\n [\"S\", [0, 1]],\n [\"E\", [1, 0]],\n [\"W\", [-1, 0]],\n [\"NE\", [1, -1]],\n [\"NW\", [-1, -1]],\n [\"SE\", [1, 1]],\n [\"SW\", [-1, 1]],\n [\"NONE\", [0, 0]],\n]);\n\n/** CX2's anchor and align words as a point of a box on one axis. */\nconst CX2_SIDE: ReadonlyMap<string, number> = new Map([\n [\"center\", 0],\n [\"left\", -1],\n [\"right\", 1],\n [\"top\", -1],\n [\"bottom\", 1],\n]);\n\n/** A label justification as the neutral text alignment. */\nconst JUSTIFY: ReadonlyMap<string, string> = new Map([\n [\"l\", \"left\"],\n [\"left\", \"left\"],\n [\"c\", \"center\"],\n [\"center\", \"center\"],\n [\"r\", \"right\"],\n [\"right\", \"right\"],\n]);\n\n/**\n * A Cytoscape label position, read whole: the point of the node (or the edge's middle) `node` and the point of the\n * label's box `label` it is pinned to, each `[x, y]` with x right and y down as -1, 0 or 1, the justification of its\n * lines, and the offset `[x, y]` in px, y down.\n * @category Styles\n */\nexport interface CytoscapeLabelPlace {\n readonly node: readonly [number, number];\n readonly label: readonly [number, number];\n readonly justify: string;\n readonly offset: readonly [number, number];\n}\n\n/**\n * The anchors of CX2's edge label position `{ EDGE_ANCHOR, LABEL_ANCHOR, ... }`, each a desktop anchor letter, as\n * `[edge x, edge y, label x, label y]`; undefined where a letter is not one.\n * @param o - the position\n * @param site - where a bad value is noted\n * @returns the four sides\n */\nfunction cx2EdgeAnchors(o: Record<string, unknown>, site: CanonSite): (number | undefined)[] {\n const letter = (key: string): readonly [number, number] | undefined =>\n ANCHOR.get((scalarText(Object.hasOwn(o, key) ? o[key] : \"C\", site) ?? \"\").trim().toUpperCase());\n return [\n ...(letter(\"EDGE_ANCHOR\") ?? [undefined, undefined]),\n ...(letter(\"LABEL_ANCHOR\") ?? [undefined, undefined]),\n ];\n}\n\n/**\n * Reads a label position: desktop's `C,C,c,0.00,0.00` (node anchor, label anchor, justification, x and y offsets)\n * or CX2's `{ HORIZONTAL_ANCHOR, VERTICAL_ANCHOR, HORIZONTAL_ALIGN, VERTICAL_ALIGN, JUSTIFICATION, MARGIN_X,\n * MARGIN_Y }` (for an edge's label `{ EDGE_ANCHOR, LABEL_ANCHOR, JUSTIFICATION, MARGIN_X, MARGIN_Y }`, the anchors\n * as desktop's letters).\n * @param raw - the value\n * @param site - where a bad value is noted\n * @returns the place, or null\n * @category Styles\n */\nexport function cytoscapeLabelPlace(raw: unknown, site: CanonSite): CytoscapeLabelPlace | null {\n if (raw !== null && typeof raw === \"object\" && !Array.isArray(raw)) {\n const o = raw as Record<string, unknown>;\n const word = (key: string): string => {\n const v = Object.hasOwn(o, key) ? scalarText(o[key], site) : null;\n return (v ?? \"center\").trim().toLowerCase();\n };\n const num = (key: string): number => {\n const v = Object.hasOwn(o, key) ? Number(o[key]) : 0;\n return Number.isFinite(v) ? v : 0;\n };\n const sides = Object.hasOwn(o, \"EDGE_ANCHOR\")\n ? cx2EdgeAnchors(o, site)\n : [\"HORIZONTAL_ANCHOR\", \"VERTICAL_ANCHOR\", \"HORIZONTAL_ALIGN\", \"VERTICAL_ALIGN\"].map((k) =>\n CX2_SIDE.get(word(k)),\n );\n if (sides.includes(undefined)) {\n noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, JSON.stringify(raw).slice(0, 64));\n return null;\n }\n const [nx, ny, lx, ly] = sides as number[];\n return {\n node: [nx, ny],\n label: [lx, ly],\n justify: JUSTIFY.get(word(\"JUSTIFICATION\")) ?? \"center\",\n offset: [num(\"MARGIN_X\"), num(\"MARGIN_Y\")],\n };\n }\n const s = scalarText(raw, site);\n if (s === null) {\n return null;\n }\n const parts = s.split(\",\").map((p) => p.trim());\n const node = ANCHOR.get(parts[0].toUpperCase());\n // a position naming only the node's anchor pins the label's opposite point there, as Cytoscape 2.x did\n const label = parts.length > 1 ? ANCHOR.get(parts[1].toUpperCase()) : node?.map((v) => -v);\n if (node === undefined || label === undefined) {\n noteAt(site, STYLE_ISSUE.UNKNOWN_VALUE, s);\n return null;\n }\n const at = (i: number): number => {\n const v = Number(parts[i] ?? 0);\n return Number.isFinite(v) ? v : 0;\n };\n return {\n node,\n label: [label[0], label[1]],\n justify: JUSTIFY.get((parts[2] ?? \"c\").toLowerCase()) ?? \"center\",\n offset: [at(3), at(4)],\n };\n}\n\n/** The neutral position of a label inside its node against each side, by `[x, y]` of the side, y down. */\nconst INSIDE: ReadonlyMap<string, string> = new Map([\n [\"0,0\", \"center\"],\n [\"0,-1\", \"inside-top\"],\n [\"0,1\", \"inside-bottom\"],\n [\"-1,0\", \"inside-left\"],\n [\"1,0\", \"inside-right\"],\n [\"-1,-1\", \"inside-top-left\"],\n [\"1,-1\", \"inside-top-right\"],\n [\"-1,1\", \"inside-bottom-left\"],\n [\"1,1\", \"inside-bottom-right\"],\n]);\n\n/**\n * The neutral `labelPosition` a Cytoscape label position starts from: where the label's point is the node's own\n * point on both axes (its center, or inside against a side or a corner), that position; anywhere else `center`,\n * with the rest said by `labelOffsetX`/`Y` and `labelShiftX`/`Y` (see `cytoscapeLabelMove()`).\n * @param place - the label position\n * @returns the neutral position\n * @category Styles\n */\nexport function cytoscapeLabelBase(place: CytoscapeLabelPlace): string {\n const inside = place.node[0] === place.label[0] && place.node[1] === place.label[1];\n return inside ? (INSIDE.get(`${place.node[0]},${place.node[1]}`) ?? \"center\") : \"center\";\n}\n\n/**\n * How far a Cytoscape label is moved from its `cytoscapeLabelBase()` position: the offset in px (y down), with the\n * node's anchor point added when the base is `center` and the anchors differ, and the shift by the label's own\n * size that pins the label's anchor point there.\n * @param place - the label position\n * @param width - the node's width (0 for an edge's middle)\n * @param height - the node's height (0 for an edge's middle)\n * @returns the offset and the shift, each `[x, y]`\n * @category Styles\n */\nexport function cytoscapeLabelMove(\n place: CytoscapeLabelPlace,\n width: number,\n height: number,\n): { readonly offset: readonly [number, number]; readonly shift: readonly [number, number] } {\n if (\n cytoscapeLabelBase(place) !== \"center\" ||\n (place.node[0] === 0 && place.node[1] === 0 && place.label[0] === 0 && place.label[1] === 0)\n ) {\n return { offset: place.offset, shift: [0, 0] };\n }\n return {\n offset: [(place.node[0] * width) / 2 + place.offset[0], (place.node[1] * height) / 2 + place.offset[1]],\n shift: [halfBack(place.label[0]), halfBack(place.label[1])],\n };\n}\n\n/**\n * How far a label is shifted, as a fraction of its own size, to pin its point `side` (-1, 0 or 1) where its middle was.\n * @param side - the label's point on one axis\n * @returns the shift (0, never -0, for the middle)\n * @category Styles\n */\nexport function halfBack(side: number): number {\n return side === 0 ? 0 : -side / 2;\n}\n\nconst labelPosition: CytoscapeValueParser = (raw, site) => {\n const place = cytoscapeLabelPlace(raw, site);\n return place === null ? null : cytoscapeLabelBase(place);\n};\n\n/**\n * The visual properties that set each neutral property, in the order Cytoscape prefers them: the first one a style\n * or any bypass mentions is the one read. Cytoscape draws a node's fill from `NODE_FILL_COLOR`; `NODE_PAINT` is its\n * parent and only counts when the child is absent everywhere.\n * @category Styles\n */\nexport const CYTOSCAPE_LEXICON: Readonly<\n Record<StyleTarget, ReadonlyMap<string, readonly (readonly [vp: string, parse: CytoscapeValueParser])[]>>\n> = Object.freeze({\n node: new Map<string, readonly (readonly [string, CytoscapeValueParser])[]>([\n [\n \"fill\",\n [\n [\"NODE_FILL_COLOR\", color],\n [\"NODE_BACKGROUND_COLOR\", color],\n [\"NODE_PAINT\", color],\n ],\n ],\n [\n \"fillOpacity\",\n [\n [\"NODE_TRANSPARENCY\", opacity255],\n [\"NODE_BACKGROUND_OPACITY\", opacity01],\n ],\n ],\n [\n \"borderColor\",\n [\n [\"NODE_BORDER_PAINT\", color],\n [\"NODE_BORDER_COLOR\", color],\n ],\n ],\n [\n \"borderOpacity\",\n [\n [\"NODE_BORDER_TRANSPARENCY\", opacity255],\n [\"NODE_BORDER_OPACITY\", opacity01],\n ],\n ],\n [\"borderWidth\", [[\"NODE_BORDER_WIDTH\", length]]],\n [\n \"borderStyle\",\n [\n [\"NODE_BORDER_STROKE\", lineOf(\"borderStyle\")],\n [\"NODE_BORDER_LINE_TYPE\", lineOf(\"borderStyle\")],\n [\"NODE_BORDER_STYLE\", lineOf(\"borderStyle\")],\n ],\n ],\n [\"shape\", [[\"NODE_SHAPE\", shape]]],\n [\"width\", [[\"NODE_WIDTH\", length]]],\n [\"height\", [[\"NODE_HEIGHT\", length]]],\n [\"label\", [[\"NODE_LABEL\", text]]],\n [\"labelColor\", [[\"NODE_LABEL_COLOR\", color]]],\n [\"labelSize\", [[\"NODE_LABEL_FONT_SIZE\", fontSize]]],\n [\n \"labelWrapWidth\",\n [\n [\"NODE_LABEL_WIDTH\", length],\n [\"NODE_LABEL_MAX_WIDTH\", length],\n ],\n ],\n [\"labelFont\", [[\"NODE_LABEL_FONT_FACE\", fontFamily]]],\n [\"labelWeight\", [[\"NODE_LABEL_FONT_FACE\", fontWeight]]],\n [\"labelItalic\", [[\"NODE_LABEL_FONT_FACE\", fontItalic]]],\n [\"labelPosition\", [[\"NODE_LABEL_POSITION\", labelPosition]]],\n [\"labelRotation\", [[\"NODE_LABEL_ROTATION\", rotation]]],\n [\n \"labelOpacity\",\n [\n [\"NODE_LABEL_TRANSPARENCY\", opacity255],\n [\"NODE_LABEL_OPACITY\", opacity01],\n ],\n ],\n [\"tooltip\", [[\"NODE_TOOLTIP\", text]]],\n [\n \"visible\",\n [\n [\"NODE_VISIBLE\", bool],\n [\"NODE_VISIBILITY\", visibility],\n ],\n ],\n ]),\n edge: new Map<string, readonly (readonly [string, CytoscapeValueParser])[]>([\n [\n \"color\",\n [\n [\"EDGE_STROKE_UNSELECTED_PAINT\", color],\n [\"EDGE_LINE_COLOR\", color],\n [\"EDGE_UNSELECTED_PAINT\", color],\n [\"EDGE_PAINT\", color],\n ],\n ],\n [\n \"opacity\",\n [\n [\"EDGE_TRANSPARENCY\", opacity255],\n [\"EDGE_OPACITY\", opacity01],\n ],\n ],\n [\"width\", [[\"EDGE_WIDTH\", length]]],\n [\n \"lineStyle\",\n [\n [\"EDGE_LINE_TYPE\", lineOf(\"lineStyle\")],\n [\"EDGE_LINE_STYLE\", lineOf(\"lineStyle\")],\n ],\n ],\n [\"sourceArrow\", [[\"EDGE_SOURCE_ARROW_SHAPE\", arrow]]],\n [\"targetArrow\", [[\"EDGE_TARGET_ARROW_SHAPE\", arrow]]],\n // One neutral size for both ends: the target's, else the source's.\n [\n \"arrowSize\",\n [\n [\"EDGE_TARGET_ARROW_SIZE\", arrowSizeParser],\n [\"EDGE_SOURCE_ARROW_SIZE\", arrowSizeParser],\n ],\n ],\n [\n \"sourceArrowColor\",\n [\n [\"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\", color],\n [\"EDGE_SOURCE_ARROW_COLOR\", color],\n ],\n ],\n [\n \"targetArrowColor\",\n [\n [\"EDGE_TARGET_ARROW_UNSELECTED_PAINT\", color],\n [\"EDGE_TARGET_ARROW_COLOR\", color],\n ],\n ],\n [\"curved\", [[\"EDGE_CURVED\", bool]]],\n [\"label\", [[\"EDGE_LABEL\", text]]],\n [\"labelColor\", [[\"EDGE_LABEL_COLOR\", color]]],\n [\"labelSize\", [[\"EDGE_LABEL_FONT_SIZE\", fontSize]]],\n [\"labelFont\", [[\"EDGE_LABEL_FONT_FACE\", fontFamily]]],\n [\"labelWeight\", [[\"EDGE_LABEL_FONT_FACE\", fontWeight]]],\n [\"labelItalic\", [[\"EDGE_LABEL_FONT_FACE\", fontItalic]]],\n [\n \"labelWrapWidth\",\n [\n [\"EDGE_LABEL_WIDTH\", length],\n [\"EDGE_LABEL_MAX_WIDTH\", length],\n ],\n ],\n [\"labelRotation\", [[\"EDGE_LABEL_ROTATION\", rotation]]],\n [\n \"labelOpacity\",\n [\n [\"EDGE_LABEL_TRANSPARENCY\", opacity255],\n [\"EDGE_LABEL_OPACITY\", opacity01],\n ],\n ],\n [\"tooltip\", [[\"EDGE_TOOLTIP\", text]]],\n [\n \"visible\",\n [\n [\"EDGE_VISIBLE\", bool],\n [\"EDGE_VISIBILITY\", visibility],\n ],\n ],\n ]),\n});\n\n/** A node's size when `nodeSizeLocked` makes `NODE_SIZE` drive width and height. */\nexport const NODE_SIZE_VP = \"NODE_SIZE\";\n\n/** The parser of node sizes, for `NODE_SIZE`. */\nexport const sizeParser: CytoscapeValueParser = length;\n\n/** The parser of colors, for the network background and `arrowColorMatchesEdge`. */\nexport const colorParser: CytoscapeValueParser = color;\n\n/**\n * The parser of 0..255 transparencies (desktop) and 0..1 opacities (CX2), by visual property.\n * @param vp - the visual property (`*_TRANSPARENCY` or `*_OPACITY`)\n * @returns its parser\n */\nexport const opacityParser = (vp: string): CytoscapeValueParser => (vp.endsWith(\"_OPACITY\") ? opacity01 : opacity255);\n\n/** Every visual property the lexicon reads. */\nconst KNOWN_VPS: ReadonlySet<string> = new Set([\n NODE_SIZE_VP,\n ...Object.values(CYTOSCAPE_LEXICON).flatMap((byProp) =>\n Array.from(byProp.values()).flatMap((list) => list.map(([vp]) => vp)),\n ),\n]);\n\n/** Geometry, selection state and paint that is not a style: dropped without a note. */\nconst IGNORED_VP =\n /^(?:NODE|EDGE|NETWORK)_[XYZ]_LOCATION$|_SELECTED|SELECTION|^NETWORK_(?!BACKGROUND)|_DEPTH$|^COMPOUND_|EDGE_BEND|EDGE_CONTROL_POINTS|NODE_NESTED_NETWORK|_Z_ORDER$|EDGE_STACKING|_LABEL_WIDTH$|_HEIGHT$|_WIDTH$/;\n\n/**\n * Whether a visual property is one no neutral property carries and that is worth a note.\n * @param vp - the visual property\n * @returns true when it is neither read nor ignored\n */\nexport function isUncarriedVp(vp: string): boolean {\n return !KNOWN_VPS.has(vp) && !IGNORED_VP.test(vp);\n}\n\n/** Cytoscape's old identifiers (2.x XGMML graphics attributes and session properties), lowercase. */\nconst IDENTIFIERS: Readonly<Record<StyleTarget, ReadonlyMap<string, string>>> = {\n node: new Map([\n [\"fill\", \"NODE_FILL_COLOR\"],\n [\"w\", \"NODE_WIDTH\"],\n [\"h\", \"NODE_HEIGHT\"],\n [\"size\", \"NODE_SIZE\"],\n [\"type\", \"NODE_SHAPE\"],\n [\"outline\", \"NODE_BORDER_PAINT\"],\n [\"width\", \"NODE_BORDER_WIDTH\"],\n [\"borderlinetype\", \"NODE_BORDER_LINE_TYPE\"],\n [\"nodelabelfont\", \"NODE_LABEL_FONT_FACE\"],\n [\"nodetransparency\", \"NODE_TRANSPARENCY_01\"],\n [\"nodelabelposition\", \"NODE_LABEL_POSITION\"],\n [\"nodefillcolor\", \"NODE_FILL_COLOR\"],\n [\"nodesize\", \"NODE_SIZE\"],\n [\"nodewidth\", \"NODE_WIDTH\"],\n [\"nodehight\", \"NODE_HEIGHT\"],\n [\"nodeheight\", \"NODE_HEIGHT\"],\n [\"nodeopacity\", \"NODE_TRANSPARENCY\"],\n [\"nodebordercolor\", \"NODE_BORDER_PAINT\"],\n [\"nodelinewidth\", \"NODE_BORDER_WIDTH\"],\n [\"nodelinestyle\", \"NODE_BORDER_LINE_TYPE\"],\n [\"nodeshape\", \"NODE_SHAPE\"],\n [\"nodefont\", \"NODE_LABEL_FONT_FACE\"],\n [\"nodefontsize\", \"NODE_LABEL_FONT_SIZE\"],\n [\"nodelabel\", \"NODE_LABEL\"],\n [\"nodelabelcolor\", \"NODE_LABEL_COLOR\"],\n [\"nodetooltip\", \"NODE_TOOLTIP\"],\n ]),\n edge: new Map([\n [\"width\", \"EDGE_WIDTH\"],\n [\"fill\", \"EDGE_STROKE_UNSELECTED_PAINT\"],\n [\"edgelinetype\", \"EDGE_LINE_TYPE\"],\n [\"edgelabelfont\", \"EDGE_LABEL_FONT_FACE\"],\n [\"sourcearrowcolor\", \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\"],\n [\"targetarrowcolor\", \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\"],\n [\"edgesourcearrowcolor\", \"EDGE_SOURCE_ARROW_UNSELECTED_PAINT\"],\n [\"edgetargetarrowcolor\", \"EDGE_TARGET_ARROW_UNSELECTED_PAINT\"],\n [\"edgelinewidth\", \"EDGE_WIDTH\"],\n [\"edgecolor\", \"EDGE_STROKE_UNSELECTED_PAINT\"],\n [\"edgelinestyle\", \"EDGE_LINE_TYPE\"],\n [\"edgeopacity\", \"EDGE_TRANSPARENCY\"],\n [\"sourcearrow\", \"EDGE_SOURCE_ARROW_SHAPE\"],\n [\"targetarrow\", \"EDGE_TARGET_ARROW_SHAPE\"],\n [\"edgesourcearrowshape\", \"EDGE_SOURCE_ARROW_SHAPE\"],\n [\"edgetargetarrowshape\", \"EDGE_TARGET_ARROW_SHAPE\"],\n [\"edgelabel\", \"EDGE_LABEL\"],\n [\"edgefont\", \"EDGE_LABEL_FONT_FACE\"],\n [\"edgelabelcolor\", \"EDGE_LABEL_COLOR\"],\n [\"edgefontsize\", \"EDGE_LABEL_FONT_SIZE\"],\n [\"edgetooltip\", \"EDGE_TOOLTIP\"],\n [\"curved\", \"EDGE_CURVED_LEGACY\"],\n [\"edgecurved\", \"EDGE_CURVED\"],\n [\"edgebend\", \"EDGE_BEND\"],\n ]),\n};\n\n/** Objects nested deeper than this inside one element's graphics are not read. */\nconst MAX_VP_DEPTH = 8;\nconst VP_NAME = /^[A-Z][A-Z_0-9]+$/;\n\n/**\n * One graphics key as a visual property: its name (`?<key>` for one with none) and its value, a legacy encoding\n * converted.\n * @param target - nodes or edges\n * @param k - the key\n * @param v - its value\n * @returns the name and the value\n */\nfunction visualProperty(target: StyleTarget, k: string, v: unknown): [string, unknown] {\n const name = VP_NAME.test(k) ? k : IDENTIFIERS[target].get(k.toLowerCase().replace(/^cy:/, \"\"));\n if (name === undefined) {\n return [`?${k}`, v];\n }\n if (name === \"NODE_TRANSPARENCY_01\") {\n let f = Number.NaN;\n if (typeof v === \"number\") {\n f = v;\n } else if (typeof v === \"string\") {\n f = Number(v.trim());\n }\n return [\"NODE_TRANSPARENCY\", Number.isFinite(f) ? Math.round(f * 255) : null];\n }\n if (name === \"EDGE_CURVED_LEGACY\") {\n return [\"EDGE_CURVED\", typeof v === \"string\" && v.toUpperCase() === \"CURVED_LINES\"];\n }\n return [name, v];\n}\n\n/**\n * Normalizes the keys of one object of an element's graphics; a nested object is pushed onto the stack.\n * @param target - nodes or edges\n * @param top - the object and its depth\n * @param stack - the objects still to walk\n * @param out - visual property name to raw value, added to\n * @returns how many nested objects were too deep to walk\n */\nfunction normalizeObject(\n target: StyleTarget,\n top: [Record<string, unknown>, number],\n stack: [Record<string, unknown>, number][],\n out: Map<string, unknown>,\n): number {\n const [obj, depth] = top;\n let deep = 0;\n for (const k of Object.keys(obj)) {\n const v = obj[k];\n if (k === \"lockedVisualProperties\" || v === null || v === undefined) {\n continue;\n }\n // a 2.x edgeBend of one handle is a record: kept whole, as its handles\n if (typeof v === \"object\" && !Array.isArray(v) && !/^[A-Z_0-9]+$/.test(k) && k.toLowerCase() !== \"edgebend\") {\n if (depth + 1 > MAX_VP_DEPTH) {\n deep++;\n } else {\n stack.push([v as Record<string, unknown>, depth + 1]);\n }\n continue;\n }\n const [name, value] = visualProperty(target, k, v);\n // visual-property-named keys come first in 3.x graphics and win\n if (!out.has(name)) {\n out.set(name, value);\n }\n }\n return deep;\n}\n\n/**\n * One element's raw visual properties, normalized: Cytoscape's old identifiers renamed to visual property names and\n * the legacy encodings converted (`nodeTransparency` 0..1 to `NODE_TRANSPARENCY` 0..255, `curved` to\n * `EDGE_CURVED`). Nested objects (`cytoscapeNodeGraphicsAttributes` and the like) are walked with an explicit stack\n * and a depth limit, never by recursion on the file's nesting. A key with no visual property name is kept as\n * `?<key>`, so a caller can note it.\n * @param target - nodes or edges\n * @param raw - the element's graphics object\n * @param notes - where a too-deep nesting is noted\n * @returns visual property name to raw value\n * @category Styles\n */\nexport function normalizeVisualProperties(target: StyleTarget, raw: unknown, notes?: StyleNotes): Map<string, unknown> {\n if (raw === null || typeof raw !== \"object\") {\n return new Map();\n }\n const out = new Map<string, unknown>();\n const stack: [Record<string, unknown>, number][] = [[raw as Record<string, unknown>, 0]];\n let deep = 0;\n for (let top = stack.pop(); top !== undefined; top = stack.pop()) {\n deep += normalizeObject(target, top, stack, out);\n }\n if (deep > 0) {\n notes?.add(STYLE_ISSUE.NESTING, target, \"graphics\", { sample: `deeper than ${MAX_VP_DEPTH}`, count: deep });\n }\n return out;\n}\n\n/**\n * The step a continuous mapping's value is rounded to for the integer visual properties Cytoscape desktop rounds an\n * interpolated value of (cytoscape-api BasicVisualLexicon: the font sizes and the 0..255 transparencies; the latter\n * read as opacities, so 1/255).\n */\nconst INTEGER_VP_STEPS: ReadonlyMap<string, number> = new Map([\n [\"NODE_LABEL_FONT_SIZE\", 1],\n [\"EDGE_LABEL_FONT_SIZE\", 1],\n [\"NODE_TRANSPARENCY\", 1 / 255],\n [\"EDGE_TRANSPARENCY\", 1 / 255],\n]);\n\n/**\n * The step Cytoscape rounds an interpolated value of a visual property to.\n * @param vp - the visual property\n * @returns the step, or undefined for a property that holds fractions\n */\nexport function vpStep(vp: string): number | undefined {\n return INTEGER_VP_STEPS.get(vp);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as parseStyleBlock, o as styleFingerprint, q as blockStyles, r as resolveStyles } from "./block-
|
|
1
|
+
import { m as parseStyleBlock, o as styleFingerprint, q as blockStyles, r as resolveStyles } from "./block-yl0f_qLO.js";
|
|
2
2
|
function blockValues(snapshot, ex) {
|
|
3
3
|
const cache = /* @__PURE__ */ new Map();
|
|
4
4
|
return (target, property) => {
|
|
@@ -76,4 +76,4 @@ export {
|
|
|
76
76
|
elementValues as e,
|
|
77
77
|
takeFromBlock as t
|
|
78
78
|
};
|
|
79
|
-
//# sourceMappingURL=round-trip-
|
|
79
|
+
//# sourceMappingURL=round-trip-Cy3_SHRZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round-trip-Zm3_ivgq.js","sources":["../../src/styles/io/round-trip.ts"],"sourcesContent":["/**\n * The round-trip repair every styled format shares: for a file graphty wrote, a value read from the format's own\n * drawing keys that is only what graphty's writer writes for the `graphty.styles` block's exact value (a pentagon\n * written as a hexagon, an opacity rounded to 255 steps) is read as the block's value, so a re-import gives back the\n * same rules. A value another program changed since stays the truth. Each format passes what its writer writes for an\n * element, read back the way its reader reads it.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { styleFingerprint } from \"../plan/features.js\";\nimport { resolveStyles } from \"../plan/resolve.js\";\nimport type { ExtractedStyles, StyleColumn, StyleProperty, StyleTarget, StyleValue } from \"../types.js\";\nimport { blockStyles, parseStyleBlock } from \"./block.js\";\n\n/** One element's value of a property, null when it has none. */\nexport type ElementValues = (property: string) => StyleValue | null;\n\n/** The block's values of a property, one per element. */\ntype BlockValues = (target: StyleTarget, property: string) => readonly (StyleValue | null)[];\n\n/**\n * The values a `graphty.styles` block gives every element, worked out once per property.\n * @param snapshot - the graph\n * @param ex - the block's styles\n * @returns the block's values\n */\nfunction blockValues(snapshot: GraphSnapshot, ex: ExtractedStyles): BlockValues {\n const cache = new Map<string, readonly (StyleValue | null)[]>();\n return (target, property) => {\n const key = `${target} ${property}`;\n let held = cache.get(key);\n if (held === undefined) {\n held = resolveStyles(ex, target, property as StyleProperty, snapshot);\n cache.set(key, held);\n }\n return held;\n };\n}\n\n/**\n * Each element's values of the properties a writer writes, as a getter per element; any other property reads as null.\n * @param picture - each element's value of a property\n * @param target - nodes or edges\n * @param properties - the properties the writer writes\n * @returns the getter\n */\nexport function elementValues(\n picture: BlockValues,\n target: StyleTarget,\n properties: readonly string[],\n): (i: number) => ElementValues {\n const columns = new Map<string, readonly (StyleValue | null)[]>();\n for (const p of properties) {\n columns.set(p, picture(target, p));\n }\n return (i) => (property) => columns.get(property)?.[i] ?? null;\n}\n\n/** One target's round trip, as a format describes it. */\ninterface RoundTrip {\n /** The values the reader read, per property; a property whose values change gets a new array. */\n readonly values: Partial<Record<string, StyleColumn>>;\n /** The properties compared with the block's. */\n readonly properties: Iterable<string>;\n /** The properties the writer is given the block's values of; any other reads as null. Default: every one. */\n readonly writes?: readonly string[];\n /**\n * An element's block values written the way the writer writes them and read back the way the reader reads them.\n * @param i - the element\n * @param want - the element's block values\n * @returns the values read back, or null when the element is not compared\n */\n readBack(i: number, want: ElementValues): ElementValues | null;\n /**\n * Whether a property's value of an element may be taken from the block at all (before comparing). Default: always.\n * @param property - the property\n * @param wanted - the block's value\n * @param native - the value read\n */\n take?(property: string, wanted: StyleValue | null, native: StyleValue | null): boolean;\n}\n\n/**\n * Wherever a value read is not the block's but is what the writer writes for the block's value, takes the block's.\n * @param target - nodes or edges\n * @param n - the element count\n * @param block - the block's values\n * @param trip - the target's round trip; its values change in place\n */\nfunction takeBlockValues(target: StyleTarget, n: number, block: BlockValues, trip: RoundTrip): void {\n const { values } = trip;\n const get = blockGetter(target, block, trip.writes);\n const properties = [...trip.properties];\n const changed = new Map<string, (StyleValue | null)[]>();\n for (let i = 0; i < n; i++) {\n const want = get(i);\n const back = trip.readBack(i, want);\n if (back === null) {\n continue;\n }\n for (const property of properties) {\n const w = want(property);\n if (takes(trip, property, w, values[property]?.[i] ?? null, back)) {\n columnOf(changed, values, property, n)[i] = w;\n }\n }\n }\n for (const [property, column] of changed) {\n values[property] = column;\n }\n}\n\n/**\n * Each element's block values, limited to the properties the writer is given when it is given only some.\n * @param target - nodes or edges\n * @param block - the block's values\n * @param writes - the properties the writer is given, or undefined for every one\n * @returns the element's values, by element\n */\nfunction blockGetter(\n target: StyleTarget,\n block: BlockValues,\n writes: readonly string[] | undefined,\n): (i: number) => ElementValues {\n if (writes !== undefined) {\n return elementValues(block, target, writes);\n }\n return (i) => (p) => block(target, p)[i] ?? null;\n}\n\n/**\n * Whether the block's value replaces the value read: the format allows it, they differ, and the value read is what the\n * writer writes for the block's value.\n * @param trip - the target's round trip\n * @param property - the property\n * @param wanted - the block's value\n * @param native - the value read\n * @param back - the element's block values written and read back\n * @returns whether to take the block's value\n */\nfunction takes(\n trip: RoundTrip,\n property: string,\n wanted: StyleValue | null,\n native: StyleValue | null,\n back: ElementValues,\n): boolean {\n return trip.take?.(property, wanted, native) !== false && native !== wanted && native === (back(property) ?? null);\n}\n\n/**\n * The changed copy of a property's values, made on first use.\n * @param changed - the changed copies so far\n * @param values - the values read\n * @param property - the property\n * @param n - the element count\n * @returns the property's changed copy\n */\nfunction columnOf(\n changed: Map<string, (StyleValue | null)[]>,\n values: Partial<Record<string, StyleColumn>>,\n property: string,\n n: number,\n): (StyleValue | null)[] {\n let column = changed.get(property);\n if (column === undefined) {\n const own = values[property];\n column = own === undefined ? new Array<StyleValue | null>(n).fill(null) : [...own];\n changed.set(property, column);\n }\n return column;\n}\n\n/**\n * For a file graphty wrote: wherever a value read from the format's own keys is not the `graphty.styles` block's\n * value but is what graphty's writer writes for it, takes the block's value, so a re-import gives back the same rules.\n * A block that does not parse or describes another graph changes nothing.\n * @param snapshot - the graph\n * @param text - the block's text, or null when the file has none\n * @param format - the format the block was read from\n * @param trip - each target's round trip, given the block's values and its styles; null leaves the target as read\n */\nexport function takeFromBlock(\n snapshot: GraphSnapshot,\n text: string | null,\n format: string,\n trip: (target: StyleTarget, block: BlockValues, styles: ExtractedStyles) => RoundTrip | null,\n): void {\n const parsed = text === null ? null : parseStyleBlock(text, styleFingerprint(snapshot));\n const ex = parsed?.ok === true ? blockStyles(parsed.block, snapshot, format) : null;\n if (ex === null) {\n return;\n }\n const block = blockValues(snapshot, ex);\n for (const target of [\"node\", \"edge\"] as const) {\n const t = trip(target, block, ex);\n if (t !== null) {\n takeBlockValues(target, target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount, block, t);\n }\n }\n}\n"],"names":[],"mappings":";AA2BA,SAAS,YAAY,UAAyB,IAAkC;AAC5E,QAAM,4BAAY,IAAA;AAClB,SAAO,CAAC,QAAQ,aAAa;AACzB,UAAM,MAAM,GAAG,MAAM,IAAI,QAAQ;AACjC,QAAI,OAAO,MAAM,IAAI,GAAG;AACxB,QAAI,SAAS,QAAW;AACpB,aAAO,cAAc,IAAI,QAAQ,UAA2B,QAAQ;AACpE,YAAM,IAAI,KAAK,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACX;AACJ;AASO,SAAS,cACZ,SACA,QACA,YAC4B;AAC5B,QAAM,8BAAc,IAAA;AACpB,aAAW,KAAK,YAAY;AACxB,YAAQ,IAAI,GAAG,QAAQ,QAAQ,CAAC,CAAC;AAAA,EACrC;AACA,SAAO,CAAC,MAAM,CAAC,aAAa,QAAQ,IAAI,QAAQ,IAAI,CAAC,KAAK;AAC9D;AAiCA,SAAS,gBAAgB,QAAqB,GAAW,OAAoB,MAAuB;AAChG,QAAM,EAAE,WAAW;AACnB,QAAM,MAAM,YAAY,QAAQ,OAAO,KAAK,MAAM;AAClD,QAAM,aAAa,CAAC,GAAG,KAAK,UAAU;AACtC,QAAM,8BAAc,IAAA;AACpB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,UAAM,OAAO,IAAI,CAAC;AAClB,UAAM,OAAO,KAAK,SAAS,GAAG,IAAI;AAClC,QAAI,SAAS,MAAM;AACf;AAAA,IACJ;AACA,eAAW,YAAY,YAAY;AAC/B,YAAM,IAAI,KAAK,QAAQ;AACvB,UAAI,MAAM,MAAM,UAAU,GAAG,OAAO,QAAQ,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG;AAC/D,iBAAS,SAAS,QAAQ,UAAU,CAAC,EAAE,CAAC,IAAI;AAAA,MAChD;AAAA,IACJ;AAAA,EACJ;AACA,aAAW,CAAC,UAAU,MAAM,KAAK,SAAS;AACtC,WAAO,QAAQ,IAAI;AAAA,EACvB;AACJ;AASA,SAAS,YACL,QACA,OACA,QAC4B;AAC5B,MAAI,WAAW,QAAW;AACtB,WAAO,cAAc,OAAO,QAAQ,MAAM;AAAA,EAC9C;AACA,SAAO,CAAC,MAAM,CAAC,MAAM,MAAM,QAAQ,CAAC,EAAE,CAAC,KAAK;AAChD;AAYA,SAAS,MACL,MACA,UACA,QACA,QACA,MACO;AACP,SAAO,KAAK,OAAO,UAAU,QAAQ,MAAM,MAAM,SAAS,WAAW,UAAU,YAAY,KAAK,QAAQ,KAAK;AACjH;AAUA,SAAS,SACL,SACA,QACA,UACA,GACqB;AACrB,MAAI,SAAS,QAAQ,IAAI,QAAQ;AACjC,MAAI,WAAW,QAAW;AACtB,UAAM,MAAM,OAAO,QAAQ;AAC3B,aAAS,QAAQ,SAAY,IAAI,MAAyB,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG;AACjF,YAAQ,IAAI,UAAU,MAAM;AAAA,EAChC;AACA,SAAO;AACX;AAWO,SAAS,cACZ,UACA,MACA,QACA,MACI;AACJ,QAAM,SAAS,SAAS,OAAO,OAAO,gBAAgB,MAAM,iBAAiB,QAAQ,CAAC;AACtF,QAAM,KAAK,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,UAAU,MAAM,IAAI;AAC/E,MAAI,OAAO,MAAM;AACb;AAAA,EACJ;AACA,QAAM,QAAQ,YAAY,UAAU,EAAE;AACtC,aAAW,UAAU,CAAC,QAAQ,MAAM,GAAY;AAC5C,UAAM,IAAI,KAAK,QAAQ,OAAO,EAAE;AAChC,QAAI,MAAM,MAAM;AACZ,sBAAgB,QAAQ,WAAW,SAAS,SAAS,YAAY,SAAS,WAAW,OAAO,CAAC;AAAA,IACjG;AAAA,EACJ;AACJ;"}
|
|
1
|
+
{"version":3,"file":"round-trip-Cy3_SHRZ.js","sources":["../../src/styles/io/round-trip.ts"],"sourcesContent":["/**\n * The round-trip repair every styled format shares: for a file graphty wrote, a value read from the format's own\n * drawing keys that is only what graphty's writer writes for the `graphty.styles` block's exact value (a pentagon\n * written as a hexagon, an opacity rounded to 255 steps) is read as the block's value, so a re-import gives back the\n * same rules. A value another program changed since stays the truth. Each format passes what its writer writes for an\n * element, read back the way its reader reads it.\n */\n\nimport type { GraphSnapshot } from \"@graphty/graph-format\";\n\nimport { styleFingerprint } from \"../plan/features.js\";\nimport { resolveStyles } from \"../plan/resolve.js\";\nimport type { ExtractedStyles, StyleColumn, StyleProperty, StyleTarget, StyleValue } from \"../types.js\";\nimport { blockStyles, parseStyleBlock } from \"./block.js\";\n\n/** One element's value of a property, null when it has none. */\nexport type ElementValues = (property: string) => StyleValue | null;\n\n/** The block's values of a property, one per element. */\ntype BlockValues = (target: StyleTarget, property: string) => readonly (StyleValue | null)[];\n\n/**\n * The values a `graphty.styles` block gives every element, worked out once per property.\n * @param snapshot - the graph\n * @param ex - the block's styles\n * @returns the block's values\n */\nfunction blockValues(snapshot: GraphSnapshot, ex: ExtractedStyles): BlockValues {\n const cache = new Map<string, readonly (StyleValue | null)[]>();\n return (target, property) => {\n const key = `${target} ${property}`;\n let held = cache.get(key);\n if (held === undefined) {\n held = resolveStyles(ex, target, property as StyleProperty, snapshot);\n cache.set(key, held);\n }\n return held;\n };\n}\n\n/**\n * Each element's values of the properties a writer writes, as a getter per element; any other property reads as null.\n * @param picture - each element's value of a property\n * @param target - nodes or edges\n * @param properties - the properties the writer writes\n * @returns the getter\n */\nexport function elementValues(\n picture: BlockValues,\n target: StyleTarget,\n properties: readonly string[],\n): (i: number) => ElementValues {\n const columns = new Map<string, readonly (StyleValue | null)[]>();\n for (const p of properties) {\n columns.set(p, picture(target, p));\n }\n return (i) => (property) => columns.get(property)?.[i] ?? null;\n}\n\n/** One target's round trip, as a format describes it. */\ninterface RoundTrip {\n /** The values the reader read, per property; a property whose values change gets a new array. */\n readonly values: Partial<Record<string, StyleColumn>>;\n /** The properties compared with the block's. */\n readonly properties: Iterable<string>;\n /** The properties the writer is given the block's values of; any other reads as null. Default: every one. */\n readonly writes?: readonly string[];\n /**\n * An element's block values written the way the writer writes them and read back the way the reader reads them.\n * @param i - the element\n * @param want - the element's block values\n * @returns the values read back, or null when the element is not compared\n */\n readBack(i: number, want: ElementValues): ElementValues | null;\n /**\n * Whether a property's value of an element may be taken from the block at all (before comparing). Default: always.\n * @param property - the property\n * @param wanted - the block's value\n * @param native - the value read\n */\n take?(property: string, wanted: StyleValue | null, native: StyleValue | null): boolean;\n}\n\n/**\n * Wherever a value read is not the block's but is what the writer writes for the block's value, takes the block's.\n * @param target - nodes or edges\n * @param n - the element count\n * @param block - the block's values\n * @param trip - the target's round trip; its values change in place\n */\nfunction takeBlockValues(target: StyleTarget, n: number, block: BlockValues, trip: RoundTrip): void {\n const { values } = trip;\n const get = blockGetter(target, block, trip.writes);\n const properties = [...trip.properties];\n const changed = new Map<string, (StyleValue | null)[]>();\n for (let i = 0; i < n; i++) {\n const want = get(i);\n const back = trip.readBack(i, want);\n if (back === null) {\n continue;\n }\n for (const property of properties) {\n const w = want(property);\n if (takes(trip, property, w, values[property]?.[i] ?? null, back)) {\n columnOf(changed, values, property, n)[i] = w;\n }\n }\n }\n for (const [property, column] of changed) {\n values[property] = column;\n }\n}\n\n/**\n * Each element's block values, limited to the properties the writer is given when it is given only some.\n * @param target - nodes or edges\n * @param block - the block's values\n * @param writes - the properties the writer is given, or undefined for every one\n * @returns the element's values, by element\n */\nfunction blockGetter(\n target: StyleTarget,\n block: BlockValues,\n writes: readonly string[] | undefined,\n): (i: number) => ElementValues {\n if (writes !== undefined) {\n return elementValues(block, target, writes);\n }\n return (i) => (p) => block(target, p)[i] ?? null;\n}\n\n/**\n * Whether the block's value replaces the value read: the format allows it, they differ, and the value read is what the\n * writer writes for the block's value.\n * @param trip - the target's round trip\n * @param property - the property\n * @param wanted - the block's value\n * @param native - the value read\n * @param back - the element's block values written and read back\n * @returns whether to take the block's value\n */\nfunction takes(\n trip: RoundTrip,\n property: string,\n wanted: StyleValue | null,\n native: StyleValue | null,\n back: ElementValues,\n): boolean {\n return trip.take?.(property, wanted, native) !== false && native !== wanted && native === (back(property) ?? null);\n}\n\n/**\n * The changed copy of a property's values, made on first use.\n * @param changed - the changed copies so far\n * @param values - the values read\n * @param property - the property\n * @param n - the element count\n * @returns the property's changed copy\n */\nfunction columnOf(\n changed: Map<string, (StyleValue | null)[]>,\n values: Partial<Record<string, StyleColumn>>,\n property: string,\n n: number,\n): (StyleValue | null)[] {\n let column = changed.get(property);\n if (column === undefined) {\n const own = values[property];\n column = own === undefined ? new Array<StyleValue | null>(n).fill(null) : [...own];\n changed.set(property, column);\n }\n return column;\n}\n\n/**\n * For a file graphty wrote: wherever a value read from the format's own keys is not the `graphty.styles` block's\n * value but is what graphty's writer writes for it, takes the block's value, so a re-import gives back the same rules.\n * A block that does not parse or describes another graph changes nothing.\n * @param snapshot - the graph\n * @param text - the block's text, or null when the file has none\n * @param format - the format the block was read from\n * @param trip - each target's round trip, given the block's values and its styles; null leaves the target as read\n */\nexport function takeFromBlock(\n snapshot: GraphSnapshot,\n text: string | null,\n format: string,\n trip: (target: StyleTarget, block: BlockValues, styles: ExtractedStyles) => RoundTrip | null,\n): void {\n const parsed = text === null ? null : parseStyleBlock(text, styleFingerprint(snapshot));\n const ex = parsed?.ok === true ? blockStyles(parsed.block, snapshot, format) : null;\n if (ex === null) {\n return;\n }\n const block = blockValues(snapshot, ex);\n for (const target of [\"node\", \"edge\"] as const) {\n const t = trip(target, block, ex);\n if (t !== null) {\n takeBlockValues(target, target === \"node\" ? snapshot.nodeCount : snapshot.edgeCount, block, t);\n }\n }\n}\n"],"names":[],"mappings":";AA2BA,SAAS,YAAY,UAAyB,IAAkC;AAC5E,QAAM,4BAAY,IAAA;AAClB,SAAO,CAAC,QAAQ,aAAa;AACzB,UAAM,MAAM,GAAG,MAAM,IAAI,QAAQ;AACjC,QAAI,OAAO,MAAM,IAAI,GAAG;AACxB,QAAI,SAAS,QAAW;AACpB,aAAO,cAAc,IAAI,QAAQ,UAA2B,QAAQ;AACpE,YAAM,IAAI,KAAK,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACX;AACJ;AASO,SAAS,cACZ,SACA,QACA,YAC4B;AAC5B,QAAM,8BAAc,IAAA;AACpB,aAAW,KAAK,YAAY;AACxB,YAAQ,IAAI,GAAG,QAAQ,QAAQ,CAAC,CAAC;AAAA,EACrC;AACA,SAAO,CAAC,MAAM,CAAC,aAAa,QAAQ,IAAI,QAAQ,IAAI,CAAC,KAAK;AAC9D;AAiCA,SAAS,gBAAgB,QAAqB,GAAW,OAAoB,MAAuB;AAChG,QAAM,EAAE,WAAW;AACnB,QAAM,MAAM,YAAY,QAAQ,OAAO,KAAK,MAAM;AAClD,QAAM,aAAa,CAAC,GAAG,KAAK,UAAU;AACtC,QAAM,8BAAc,IAAA;AACpB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,UAAM,OAAO,IAAI,CAAC;AAClB,UAAM,OAAO,KAAK,SAAS,GAAG,IAAI;AAClC,QAAI,SAAS,MAAM;AACf;AAAA,IACJ;AACA,eAAW,YAAY,YAAY;AAC/B,YAAM,IAAI,KAAK,QAAQ;AACvB,UAAI,MAAM,MAAM,UAAU,GAAG,OAAO,QAAQ,IAAI,CAAC,KAAK,MAAM,IAAI,GAAG;AAC/D,iBAAS,SAAS,QAAQ,UAAU,CAAC,EAAE,CAAC,IAAI;AAAA,MAChD;AAAA,IACJ;AAAA,EACJ;AACA,aAAW,CAAC,UAAU,MAAM,KAAK,SAAS;AACtC,WAAO,QAAQ,IAAI;AAAA,EACvB;AACJ;AASA,SAAS,YACL,QACA,OACA,QAC4B;AAC5B,MAAI,WAAW,QAAW;AACtB,WAAO,cAAc,OAAO,QAAQ,MAAM;AAAA,EAC9C;AACA,SAAO,CAAC,MAAM,CAAC,MAAM,MAAM,QAAQ,CAAC,EAAE,CAAC,KAAK;AAChD;AAYA,SAAS,MACL,MACA,UACA,QACA,QACA,MACO;AACP,SAAO,KAAK,OAAO,UAAU,QAAQ,MAAM,MAAM,SAAS,WAAW,UAAU,YAAY,KAAK,QAAQ,KAAK;AACjH;AAUA,SAAS,SACL,SACA,QACA,UACA,GACqB;AACrB,MAAI,SAAS,QAAQ,IAAI,QAAQ;AACjC,MAAI,WAAW,QAAW;AACtB,UAAM,MAAM,OAAO,QAAQ;AAC3B,aAAS,QAAQ,SAAY,IAAI,MAAyB,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG;AACjF,YAAQ,IAAI,UAAU,MAAM;AAAA,EAChC;AACA,SAAO;AACX;AAWO,SAAS,cACZ,UACA,MACA,QACA,MACI;AACJ,QAAM,SAAS,SAAS,OAAO,OAAO,gBAAgB,MAAM,iBAAiB,QAAQ,CAAC;AACtF,QAAM,KAAK,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,UAAU,MAAM,IAAI;AAC/E,MAAI,OAAO,MAAM;AACb;AAAA,EACJ;AACA,QAAM,QAAQ,YAAY,UAAU,EAAE;AACtC,aAAW,UAAU,CAAC,QAAQ,MAAM,GAAY;AAC5C,UAAM,IAAI,KAAK,QAAQ,OAAO,EAAE;AAChC,QAAI,MAAM,MAAM;AACZ,sBAAgB,QAAQ,WAAW,SAAS,SAAS,YAAY,SAAS,WAAW,OAAO,CAAC;AAAA,IACjG;AAAA,EACJ;AACJ;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as detectRuntime } from "./context-
|
|
2
|
-
import { b as failAlone } from "./credentials-
|
|
1
|
+
import { d as detectRuntime } from "./context-DizmppHy.js";
|
|
2
|
+
import { b as failAlone } from "./credentials-CmvJXYeH.js";
|
|
3
3
|
const K = new Uint32Array([
|
|
4
4
|
1116352408,
|
|
5
5
|
1899447441,
|
|
@@ -244,4 +244,4 @@ export {
|
|
|
244
244
|
sha256Hex,
|
|
245
245
|
signRequest
|
|
246
246
|
};
|
|
247
|
-
//# sourceMappingURL=sigv4-
|
|
247
|
+
//# sourceMappingURL=sigv4-BXwVbza3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sigv4-EokFic1V.js","sources":["../../src/sources/sha256.ts","../../src/sources/sigv4.ts"],"sourcesContent":["/**\n * SHA-256 in plain JavaScript (FIPS 180-4), for the one place Web Crypto is missing: a browser page\n * that is not a secure context (plain http on a host other than localhost) has no\n * `crypto.subtle`. Only the content hash uses it; signing still needs Web Crypto.\n */\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,\n 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,\n 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,\n 0xc67178f2,\n]);\n\n/**\n * Rotate a 32-bit word right.\n * @param x - the word\n * @param n - the bits\n * @returns the rotated word\n */\nfunction rotr(x: number, n: number): number {\n return (x >>> n) | (x << (32 - n));\n}\n\n/**\n * Pad a message to whole 64-byte blocks, with its bit length at the end.\n * @param data - the message\n * @returns the padded message\n */\nfunction pad(data: Uint8Array): Uint8Array {\n const blocks = Math.ceil((data.length + 9) / 64);\n const out = new Uint8Array(blocks * 64);\n out.set(data);\n out[data.length] = 0x80;\n const view = new DataView(out.buffer);\n view.setUint32(out.length - 8, Math.floor(data.length / 0x20000000));\n view.setUint32(out.length - 4, (data.length * 8) >>> 0);\n return out;\n}\n\n/**\n * Run one 64-byte block through the compression function.\n * @param h - the running hash, updated in place\n * @param w - the 64-word schedule, scratch\n * @param view - the padded message\n * @param offset - where the block starts\n */\nfunction compress(h: Uint32Array, w: Uint32Array, view: DataView, offset: number): void {\n for (let i = 0; i < 16; i++) {\n w[i] = view.getUint32(offset + i * 4);\n }\n for (let i = 16; i < 64; i++) {\n const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);\n const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;\n }\n let [a, b, c, d, e, f, g, hh] = h;\n for (let i = 0; i < 64; i++) {\n const t1 = (hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + K[i] + w[i]) >>> 0;\n const t2 = ((rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) >>> 0;\n }\n const next = [a, b, c, d, e, f, g, hh];\n for (let i = 0; i < 8; i++) {\n h[i] = (h[i] + next[i]) >>> 0;\n }\n}\n\n/**\n * SHA-256 of bytes.\n * @param data - the bytes\n * @returns the 32-byte digest\n */\nexport function sha256Bytes(data: Uint8Array): ArrayBuffer {\n const h = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]);\n const padded = pad(data);\n const view = new DataView(padded.buffer);\n const w = new Uint32Array(64);\n for (let offset = 0; offset < padded.length; offset += 64) {\n compress(h, w, view, offset);\n }\n const out = new DataView(new ArrayBuffer(32));\n h.forEach((word, i) => {\n out.setUint32(i * 4, word);\n });\n return out.buffer;\n}\n","/**\n * AWS Signature Version 4 over Web Crypto (design sections 6.3 and 12.4), loaded by\n * `credentials.awsSigV4` on first use. No AWS SDK: it signs the request `ctx.fetch` is about to\n * send, every header that request carries plus `host`, and is checked against AWS's published\n * signature test suite. graph-io never reads `~/.aws` or the environment.\n */\n\nimport { detectRuntime } from \"./context.js\";\nimport { type AwsSigV4Options } from \"./credentials.js\";\nimport { failAlone } from \"./fail.js\";\nimport { sha256Bytes } from \"./sha256.js\";\n\n/** Headers never signed: proxies and clients may change them in flight. */\nconst UNSIGNED = new Set([\"user-agent\", \"expect\", \"x-amzn-trace-id\", \"authorization\", \"content-length\"]);\n\n/**\n * The UTF-8 bytes of a string.\n * @param text - the text\n * @returns the bytes\n */\nfunction utf8(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\n/**\n * Code-unit order of two strings.\n * @param a - one string\n * @param b - another\n * @returns negative, zero or positive\n */\nfunction compareText(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n return a < b ? -1 : 1;\n}\n\n/**\n * Web Crypto: the global one, or Node 18's, which is not global without a flag. A browser page that\n * is not a secure context (plain http on a host other than localhost) has none.\n * @returns the subtle crypto, or null where there is none\n */\nasync function subtle(): Promise<SubtleCrypto | null> {\n const global = (globalThis as { crypto?: Crypto }).crypto;\n if (global?.subtle !== undefined) {\n return global.subtle;\n }\n if (detectRuntime() !== \"node\") {\n return null;\n }\n const name = \"node:crypto\";\n return ((await import(/* @vite-ignore */ name)) as { webcrypto: Crypto }).webcrypto.subtle;\n}\n\n/**\n * Lowercase hex of bytes.\n * @param bytes - the bytes\n * @returns hex\n */\nfunction hex(bytes: ArrayBuffer): string {\n return Array.from(new Uint8Array(bytes), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/**\n * SHA-256 of bytes, as hex.\n * @param data - the bytes\n * @returns the digest\n */\nasync function sha256(data: Uint8Array | ArrayBuffer): Promise<string> {\n const s = await subtle();\n if (s === null) {\n return hex(sha256Bytes(data instanceof Uint8Array ? data : new Uint8Array(data)));\n }\n return hex(await s.digest(\"SHA-256\", data as BufferSource));\n}\n\n/**\n * SHA-256 as 64 lowercase hexadecimal digits: of bytes exactly as given, or of a text's UTF-8 bytes\n * (the Cypher source's content hash, a project file's record of a file it loaded). Web Crypto where\n * there is one, else plain JavaScript (a page that is not a secure context). Experimental.\n * @param data - the bytes or the text\n * @returns the digest\n */\nexport function sha256Hex(data: string | Uint8Array): Promise<string> {\n return sha256(typeof data === \"string\" ? utf8(data) : data);\n}\n\n/**\n * HMAC-SHA-256.\n * @param key - the key\n * @param data - the message\n * @returns the MAC\n */\nasync function hmac(key: Uint8Array | ArrayBuffer, data: string): Promise<ArrayBuffer> {\n const s = await subtle();\n if (s === null) {\n failAlone(\"E_SOURCE_RUNTIME\", \"AWS signing needs Web Crypto, which a browser has only on a secure page\", {\n runtime: detectRuntime(),\n reason: \"needs-secure-context\",\n });\n }\n const k = await s.importKey(\"raw\", key as BufferSource, { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n return s.sign(\"HMAC\", k, utf8(data) as BufferSource);\n}\n\n/**\n * RFC 3986 encoding, as SigV4 asks: every byte but letters, digits and `-_.~`.\n * @param text - the text\n * @returns the encoded text\n */\nfunction encode(text: string): string {\n return encodeURIComponent(text).replaceAll(\n /[!'()*]/g,\n (c) => `%${(c.codePointAt(0) ?? 0).toString(16).toUpperCase()}`,\n );\n}\n\n/**\n * The canonical query string: every pair encoded, sorted by key then value.\n * @param url - the request URL\n * @returns the canonical query\n */\nfunction canonicalQuery(url: URL): string {\n return [...url.searchParams]\n .map(([k, v]) => [encode(k), encode(v)] as const)\n .sort(([ak, av], [bk, bv]) => compareText(ak, bk) || compareText(av, bv))\n .map(([k, v]) => `${k}=${v}`)\n .join(\"&\");\n}\n\n/**\n * The `YYYYMMDDTHHMMSSZ` form of a time.\n * @param date - the time\n * @returns the AWS timestamp\n */\nfunction amzDate(date: Date): string {\n return date\n .toISOString()\n .replaceAll(/[-:]/g, \"\")\n .replace(/\\.\\d{3}/, \"\");\n}\n\n/**\n * Sign a request with AWS SigV4 (`Authorization`, `X-Amz-Date` and, for temporary credentials,\n * `X-Amz-Security-Token`). In a browser, long-term keys (no session token) are refused, since every\n * script on the page could read them: use temporary credentials from an identity pool.\n * @param request - the request\n * @param options - region, service (default \"neptune-db\") and the credentials or a provider\n * @param now - the signing time; tests fix it. An `X-Amz-Date` already on the request wins.\n * @returns the signed request\n */\nexport async function signRequest(\n request: Request,\n options: AwsSigV4Options,\n now: Date = new Date(),\n): Promise<Request> {\n const creds = typeof options.credentials === \"function\" ? await options.credentials() : options.credentials;\n const runtime = detectRuntime();\n if ((runtime === \"browser\" || runtime === \"worker\") && (creds.sessionToken ?? \"\") === \"\") {\n failAlone(\"E_SOURCE_PARAM\", \"long-term AWS keys are never used in a browser\", {\n name: \"credential\",\n reason: \"long-term-key\",\n });\n }\n const service = options.service ?? \"neptune-db\";\n const url = new URL(request.url);\n const headers = new Headers(request.headers);\n const stamp = headers.get(\"x-amz-date\") ?? amzDate(now);\n headers.set(\"x-amz-date\", stamp);\n if (creds.sessionToken !== undefined && creds.sessionToken !== \"\") {\n headers.set(\"x-amz-security-token\", creds.sessionToken);\n }\n const method = request.method.toUpperCase();\n const body = method === \"GET\" || method === \"HEAD\" ? new Uint8Array(0) : await request.clone().arrayBuffer();\n\n const signed = new Map<string, string>([[\"host\", url.host]]);\n headers.forEach((value, name) => {\n if (!UNSIGNED.has(name)) {\n signed.set(name, value.trim().replaceAll(/\\s+/g, \" \"));\n }\n });\n // SigV4 sorts header names by code unit, not by locale\n const names = [...signed.keys()].sort((a, b) => Number(a > b) - Number(a < b));\n const signedHeaders = names.join(\";\");\n const canonical = [\n method,\n // non-S3 services encode the already-encoded path once more\n url.pathname.split(\"/\").map(encode).join(\"/\"),\n canonicalQuery(url),\n ...names.map((n) => `${n}:${signed.get(n) ?? \"\"}`),\n \"\",\n signedHeaders,\n await sha256(body),\n ].join(\"\\n\");\n\n const day = stamp.slice(0, 8);\n const scope = `${day}/${options.region}/${service}/aws4_request`;\n const toSign = [\"AWS4-HMAC-SHA256\", stamp, scope, await sha256(utf8(canonical))].join(\"\\n\");\n let key: ArrayBuffer = await hmac(utf8(`AWS4${creds.secretAccessKey}`), day);\n for (const part of [options.region, service, \"aws4_request\"]) {\n key = await hmac(key, part);\n }\n const signature = hex(await hmac(key, toSign));\n headers.set(\n \"Authorization\",\n `AWS4-HMAC-SHA256 Credential=${creds.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`,\n );\n return new Request(request, { headers });\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sigv4-BXwVbza3.js","sources":["../../src/sources/sha256.ts","../../src/sources/sigv4.ts"],"sourcesContent":["/**\n * SHA-256 in plain JavaScript (FIPS 180-4), for the one place Web Crypto is missing: a browser page\n * that is not a secure context (plain http on a host other than localhost) has no\n * `crypto.subtle`. Only the content hash uses it; signing still needs Web Crypto.\n */\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,\n 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,\n 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8,\n 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,\n 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,\n 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,\n 0xc67178f2,\n]);\n\n/**\n * Rotate a 32-bit word right.\n * @param x - the word\n * @param n - the bits\n * @returns the rotated word\n */\nfunction rotr(x: number, n: number): number {\n return (x >>> n) | (x << (32 - n));\n}\n\n/**\n * Pad a message to whole 64-byte blocks, with its bit length at the end.\n * @param data - the message\n * @returns the padded message\n */\nfunction pad(data: Uint8Array): Uint8Array {\n const blocks = Math.ceil((data.length + 9) / 64);\n const out = new Uint8Array(blocks * 64);\n out.set(data);\n out[data.length] = 0x80;\n const view = new DataView(out.buffer);\n view.setUint32(out.length - 8, Math.floor(data.length / 0x20000000));\n view.setUint32(out.length - 4, (data.length * 8) >>> 0);\n return out;\n}\n\n/**\n * Run one 64-byte block through the compression function.\n * @param h - the running hash, updated in place\n * @param w - the 64-word schedule, scratch\n * @param view - the padded message\n * @param offset - where the block starts\n */\nfunction compress(h: Uint32Array, w: Uint32Array, view: DataView, offset: number): void {\n for (let i = 0; i < 16; i++) {\n w[i] = view.getUint32(offset + i * 4);\n }\n for (let i = 16; i < 64; i++) {\n const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);\n const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);\n w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;\n }\n let [a, b, c, d, e, f, g, hh] = h;\n for (let i = 0; i < 64; i++) {\n const t1 = (hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + K[i] + w[i]) >>> 0;\n const t2 = ((rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) >>> 0;\n }\n const next = [a, b, c, d, e, f, g, hh];\n for (let i = 0; i < 8; i++) {\n h[i] = (h[i] + next[i]) >>> 0;\n }\n}\n\n/**\n * SHA-256 of bytes.\n * @param data - the bytes\n * @returns the 32-byte digest\n */\nexport function sha256Bytes(data: Uint8Array): ArrayBuffer {\n const h = new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n ]);\n const padded = pad(data);\n const view = new DataView(padded.buffer);\n const w = new Uint32Array(64);\n for (let offset = 0; offset < padded.length; offset += 64) {\n compress(h, w, view, offset);\n }\n const out = new DataView(new ArrayBuffer(32));\n h.forEach((word, i) => {\n out.setUint32(i * 4, word);\n });\n return out.buffer;\n}\n","/**\n * AWS Signature Version 4 over Web Crypto (design sections 6.3 and 12.4), loaded by\n * `credentials.awsSigV4` on first use. No AWS SDK: it signs the request `ctx.fetch` is about to\n * send, every header that request carries plus `host`, and is checked against AWS's published\n * signature test suite. graph-io never reads `~/.aws` or the environment.\n */\n\nimport { detectRuntime } from \"./context.js\";\nimport { type AwsSigV4Options } from \"./credentials.js\";\nimport { failAlone } from \"./fail.js\";\nimport { sha256Bytes } from \"./sha256.js\";\n\n/** Headers never signed: proxies and clients may change them in flight. */\nconst UNSIGNED = new Set([\"user-agent\", \"expect\", \"x-amzn-trace-id\", \"authorization\", \"content-length\"]);\n\n/**\n * The UTF-8 bytes of a string.\n * @param text - the text\n * @returns the bytes\n */\nfunction utf8(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\n/**\n * Code-unit order of two strings.\n * @param a - one string\n * @param b - another\n * @returns negative, zero or positive\n */\nfunction compareText(a: string, b: string): number {\n if (a === b) {\n return 0;\n }\n return a < b ? -1 : 1;\n}\n\n/**\n * Web Crypto: the global one, or Node 18's, which is not global without a flag. A browser page that\n * is not a secure context (plain http on a host other than localhost) has none.\n * @returns the subtle crypto, or null where there is none\n */\nasync function subtle(): Promise<SubtleCrypto | null> {\n const global = (globalThis as { crypto?: Crypto }).crypto;\n if (global?.subtle !== undefined) {\n return global.subtle;\n }\n if (detectRuntime() !== \"node\") {\n return null;\n }\n const name = \"node:crypto\";\n return ((await import(/* @vite-ignore */ name)) as { webcrypto: Crypto }).webcrypto.subtle;\n}\n\n/**\n * Lowercase hex of bytes.\n * @param bytes - the bytes\n * @returns hex\n */\nfunction hex(bytes: ArrayBuffer): string {\n return Array.from(new Uint8Array(bytes), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/**\n * SHA-256 of bytes, as hex.\n * @param data - the bytes\n * @returns the digest\n */\nasync function sha256(data: Uint8Array | ArrayBuffer): Promise<string> {\n const s = await subtle();\n if (s === null) {\n return hex(sha256Bytes(data instanceof Uint8Array ? data : new Uint8Array(data)));\n }\n return hex(await s.digest(\"SHA-256\", data as BufferSource));\n}\n\n/**\n * SHA-256 as 64 lowercase hexadecimal digits: of bytes exactly as given, or of a text's UTF-8 bytes\n * (the Cypher source's content hash, a project file's record of a file it loaded). Web Crypto where\n * there is one, else plain JavaScript (a page that is not a secure context). Experimental.\n * @param data - the bytes or the text\n * @returns the digest\n */\nexport function sha256Hex(data: string | Uint8Array): Promise<string> {\n return sha256(typeof data === \"string\" ? utf8(data) : data);\n}\n\n/**\n * HMAC-SHA-256.\n * @param key - the key\n * @param data - the message\n * @returns the MAC\n */\nasync function hmac(key: Uint8Array | ArrayBuffer, data: string): Promise<ArrayBuffer> {\n const s = await subtle();\n if (s === null) {\n failAlone(\"E_SOURCE_RUNTIME\", \"AWS signing needs Web Crypto, which a browser has only on a secure page\", {\n runtime: detectRuntime(),\n reason: \"needs-secure-context\",\n });\n }\n const k = await s.importKey(\"raw\", key as BufferSource, { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n return s.sign(\"HMAC\", k, utf8(data) as BufferSource);\n}\n\n/**\n * RFC 3986 encoding, as SigV4 asks: every byte but letters, digits and `-_.~`.\n * @param text - the text\n * @returns the encoded text\n */\nfunction encode(text: string): string {\n return encodeURIComponent(text).replaceAll(\n /[!'()*]/g,\n (c) => `%${(c.codePointAt(0) ?? 0).toString(16).toUpperCase()}`,\n );\n}\n\n/**\n * The canonical query string: every pair encoded, sorted by key then value.\n * @param url - the request URL\n * @returns the canonical query\n */\nfunction canonicalQuery(url: URL): string {\n return [...url.searchParams]\n .map(([k, v]) => [encode(k), encode(v)] as const)\n .sort(([ak, av], [bk, bv]) => compareText(ak, bk) || compareText(av, bv))\n .map(([k, v]) => `${k}=${v}`)\n .join(\"&\");\n}\n\n/**\n * The `YYYYMMDDTHHMMSSZ` form of a time.\n * @param date - the time\n * @returns the AWS timestamp\n */\nfunction amzDate(date: Date): string {\n return date\n .toISOString()\n .replaceAll(/[-:]/g, \"\")\n .replace(/\\.\\d{3}/, \"\");\n}\n\n/**\n * Sign a request with AWS SigV4 (`Authorization`, `X-Amz-Date` and, for temporary credentials,\n * `X-Amz-Security-Token`). In a browser, long-term keys (no session token) are refused, since every\n * script on the page could read them: use temporary credentials from an identity pool.\n * @param request - the request\n * @param options - region, service (default \"neptune-db\") and the credentials or a provider\n * @param now - the signing time; tests fix it. An `X-Amz-Date` already on the request wins.\n * @returns the signed request\n */\nexport async function signRequest(\n request: Request,\n options: AwsSigV4Options,\n now: Date = new Date(),\n): Promise<Request> {\n const creds = typeof options.credentials === \"function\" ? await options.credentials() : options.credentials;\n const runtime = detectRuntime();\n if ((runtime === \"browser\" || runtime === \"worker\") && (creds.sessionToken ?? \"\") === \"\") {\n failAlone(\"E_SOURCE_PARAM\", \"long-term AWS keys are never used in a browser\", {\n name: \"credential\",\n reason: \"long-term-key\",\n });\n }\n const service = options.service ?? \"neptune-db\";\n const url = new URL(request.url);\n const headers = new Headers(request.headers);\n const stamp = headers.get(\"x-amz-date\") ?? amzDate(now);\n headers.set(\"x-amz-date\", stamp);\n if (creds.sessionToken !== undefined && creds.sessionToken !== \"\") {\n headers.set(\"x-amz-security-token\", creds.sessionToken);\n }\n const method = request.method.toUpperCase();\n const body = method === \"GET\" || method === \"HEAD\" ? new Uint8Array(0) : await request.clone().arrayBuffer();\n\n const signed = new Map<string, string>([[\"host\", url.host]]);\n headers.forEach((value, name) => {\n if (!UNSIGNED.has(name)) {\n signed.set(name, value.trim().replaceAll(/\\s+/g, \" \"));\n }\n });\n // SigV4 sorts header names by code unit, not by locale\n const names = [...signed.keys()].sort((a, b) => Number(a > b) - Number(a < b));\n const signedHeaders = names.join(\";\");\n const canonical = [\n method,\n // non-S3 services encode the already-encoded path once more\n url.pathname.split(\"/\").map(encode).join(\"/\"),\n canonicalQuery(url),\n ...names.map((n) => `${n}:${signed.get(n) ?? \"\"}`),\n \"\",\n signedHeaders,\n await sha256(body),\n ].join(\"\\n\");\n\n const day = stamp.slice(0, 8);\n const scope = `${day}/${options.region}/${service}/aws4_request`;\n const toSign = [\"AWS4-HMAC-SHA256\", stamp, scope, await sha256(utf8(canonical))].join(\"\\n\");\n let key: ArrayBuffer = await hmac(utf8(`AWS4${creds.secretAccessKey}`), day);\n for (const part of [options.region, service, \"aws4_request\"]) {\n key = await hmac(key, part);\n }\n const signature = hex(await hmac(key, toSign));\n headers.set(\n \"Authorization\",\n `AWS4-HMAC-SHA256 Credential=${creds.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`,\n );\n return new Request(request, { headers });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { e as explicitWeights } from "./export-Cha4dRFz.js";
|
|
2
|
-
import { b as STYLE_ISSUE, h as StyleNotes, Q as refSource, U as resolveRules, w as STYLE_PROPERTIES, i as num6, D as degreeValues, C as canonicalFor, y as toolDefaults, l as isStyleValue, W as evalContinuous, X as numberOf, Z as discreteLookup, n as noteAt, S as STYLE_BLOCK_NAME, p as plainCell } from "./block-
|
|
2
|
+
import { b as STYLE_ISSUE, h as StyleNotes, Q as refSource, U as resolveRules, w as STYLE_PROPERTIES, i as num6, D as degreeValues, C as canonicalFor, y as toolDefaults, l as isStyleValue, W as evalContinuous, X as numberOf, Z as discreteLookup, n as noteAt, S as STYLE_BLOCK_NAME, p as plainCell } from "./block-yl0f_qLO.js";
|
|
3
3
|
import { e as escapeXmlAttribute } from "./escape-CuCIzNMB.js";
|
|
4
|
-
import { j as javaFamily, J as JAVA_MONO, a as JAVA_SERIF, b as JAVA_SANS, v as vpStep, c as colorParser, C as CYTOSCAPE_LEXICON, s as sizeParser, d as cytoscapeLabelPlace, i as isUncarriedVp, e as arrowSizeParser, f as arrowProportion, g as arrowGap, o as opacityParser, h as cytoscapeLabelMove, k as cytoscapeLabelBase, l as halfBack, N as NODE_SIZE_VP, n as normalizeVisualProperties } from "./lexicon-
|
|
4
|
+
import { j as javaFamily, J as JAVA_MONO, a as JAVA_SERIF, b as JAVA_SANS, v as vpStep, c as colorParser, C as CYTOSCAPE_LEXICON, s as sizeParser, d as cytoscapeLabelPlace, i as isUncarriedVp, e as arrowSizeParser, f as arrowProportion, g as arrowGap, o as opacityParser, h as cytoscapeLabelMove, k as cytoscapeLabelBase, l as halfBack, N as NODE_SIZE_VP, n as normalizeVisualProperties } from "./lexicon-IVRq2Uoo.js";
|
|
5
5
|
import { d as canonBends } from "./bends-BGXjv_U4.js";
|
|
6
|
-
import { t as takeFromBlock } from "./round-trip-
|
|
6
|
+
import { t as takeFromBlock } from "./round-trip-Cy3_SHRZ.js";
|
|
7
7
|
import { M as MIXED_DIRECTION_CODE, D as DIRECTION_FORCED_CODE, b as DIRECTION_REFUSED_CODE, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, I as ID_MERGED_CODE, R as ROLE_TAKEN_CODE, C as COLUMN_RENAMED_CODE, W as AMBIGUOUS_GRAPH_NAME_CODE, Y as GRAPH_NOT_FOUND_CODE, i as MULTIPLE_GRAPHS_CODE, c as STRAY_TEXT_CODE, d as UNKNOWN_ELEMENT_CODE, U as UNKNOWN_ATTR_TYPE_CODE, aA as EQUATION_AS_TEXT_CODE, a1 as PARENT_CYCLE_CODE, m as UNKNOWN_PARENT_CODE, l as DUPLICATE_ATTRIBUTE_CODE, f as DANGLING_REFERENCE_CODE, P as PRECISION_CODE, a2 as WIDENED_CODE, T as BAD_VALUE_CODE, j as DUPLICATE_EDGE_ID_CODE, k as DUPLICATE_NODE_CODE, n as MISSING_ENDPOINT_CODE, o as MISSING_ID_CODE, N as NO_GRAPH_CODE, r as ENCODING_CONFLICT_CODE, s as UNKNOWN_ENCODING_CODE, t as ENCODING_FALLBACK_CODE, u as INVALID_ENCODING_CODE, v as INVALID_UTF8_CODE, E as EMPTY_INPUT_CODE, X as XML_NESTING_CODE, w as XML_SYNTAX_CODE, y as ELEMENT_ISSUE, z as INPUT_ISSUE, aH as STORAGE_CLASS_CODE, ak as WEIGHT_KEY_CLASH_CODE, a9 as ROLE_ASSUMED_CODE, aw as COLUMN_RENAMED_LOSS_CODE, A as ID_TEXT_TYPE_CODE, al as MUTUAL_EXPANDED_CODE, G as PARENTS_DROPPED_CODE, F as ROLE_DROPPED_CODE, aJ as TEMPORAL_TEXT_DROPPED_CODE, aI as TEMPORAL_DROPPED_CODE, ab as XML_ILLEGAL_CHAR_CODE } from "./report-CwMfYa9J.js";
|
|
8
8
|
function emptyCytoscapeStyle() {
|
|
9
9
|
const target = () => ({
|
|
@@ -3231,4 +3231,4 @@ export {
|
|
|
3231
3231
|
readXgmmlFileStyles as y,
|
|
3232
3232
|
MIME_TYPES as z
|
|
3233
3233
|
};
|
|
3234
|
-
//# sourceMappingURL=styles-
|
|
3234
|
+
//# sourceMappingURL=styles-CAVmBLgp.js.map
|